blob: 976ccc4d316b3c5dc11fdf615032e16900adc7c7 [file] [log] [blame]
Jan Voungb36ad9b2015-04-21 17:01:49 -07001//===- subzero/src/IceInstX8632.h - x86-32 machine instructions -*- C++ -*-===//
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07002//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the InstX8632 and OperandX8632 classes and
11// their subclasses. This represents the machine instructions and
12// operands used for x86-32 code selection.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICEINSTX8632_H
17#define SUBZERO_SRC_ICEINSTX8632_H
18
Jan Voung8acded02014-09-22 18:02:25 -070019#include "assembler_ia32.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070020#include "IceDefs.h"
21#include "IceInst.h"
Jan Voungbd385e42014-09-18 18:18:10 -070022#include "IceConditionCodesX8632.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070023#include "IceInstX8632.def"
24#include "IceOperand.h"
25
26namespace Ice {
27
28class TargetX8632;
29
30// OperandX8632 extends the Operand hierarchy. Its subclasses are
31// OperandX8632Mem and VariableSplit.
32class OperandX8632 : public Operand {
Jim Stichnothc6ead202015-02-24 09:30:30 -080033 OperandX8632() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -070034 OperandX8632(const OperandX8632 &) = delete;
35 OperandX8632 &operator=(const OperandX8632 &) = delete;
36
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070037public:
Jim Stichnothdd842db2015-01-27 12:53:53 -080038 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit };
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -070039 using Operand::dump;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070040 void dump(const Cfg *, Ostream &Str) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -080041 if (ALLOW_DUMP)
42 Str << "<OperandX8632>";
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -070043 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070044
45protected:
46 OperandX8632(OperandKindX8632 Kind, Type Ty)
47 : Operand(static_cast<OperandKind>(Kind), Ty) {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -070048 ~OperandX8632() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070049};
50
51// OperandX8632Mem represents the m32 addressing mode, with optional
52// base and index registers, a constant offset, and a fixed shift
53// value for the index register.
54class OperandX8632Mem : public OperandX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -080055 OperandX8632Mem() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -070056 OperandX8632Mem(const OperandX8632Mem &) = delete;
57 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
58
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070059public:
Jan Voung3bd9f1a2014-06-18 10:50:57 -070060 enum SegmentRegisters {
61 DefaultSegment = -1,
Jan Voungfe14fb82014-10-13 15:56:32 -070062#define X(val, name, prefix) val,
Jan Vounga3a01a22014-07-14 10:32:41 -070063 SEG_REGX8632_TABLE
Jan Voung3bd9f1a2014-06-18 10:50:57 -070064#undef X
65 SegReg_NUM
66 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070067 static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base,
Jim Stichnothae953202014-12-20 06:17:49 -080068 Constant *Offset, Variable *Index = nullptr,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070069 uint16_t Shift = 0,
70 SegmentRegisters SegmentReg = DefaultSegment) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070071 return new (Func->allocate<OperandX8632Mem>())
Jan Voung3bd9f1a2014-06-18 10:50:57 -070072 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070073 }
74 Variable *getBase() const { return Base; }
75 Constant *getOffset() const { return Offset; }
76 Variable *getIndex() const { return Index; }
Jan Voung3bd9f1a2014-06-18 10:50:57 -070077 uint16_t getShift() const { return Shift; }
78 SegmentRegisters getSegmentRegister() const { return SegmentReg; }
Jan Voung90ccc3f2015-04-30 14:15:10 -070079 void emitSegmentOverride(X8632::AssemblerX8632 *Asm) const;
80 X8632::Address toAsmAddress(Assembler *Asm) const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070081 void emit(const Cfg *Func) const override;
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -070082 using OperandX8632::dump;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070083 void dump(const Cfg *Func, Ostream &Str) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070084
85 static bool classof(const Operand *Operand) {
86 return Operand->getKind() == static_cast<OperandKind>(kMem);
87 }
88
89private:
90 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070091 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
Jim Stichnothb56c8f42014-09-26 09:28:46 -070092 ~OperandX8632Mem() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070093 Variable *Base;
94 Constant *Offset;
95 Variable *Index;
Jan Voung3bd9f1a2014-06-18 10:50:57 -070096 uint16_t Shift;
97 SegmentRegisters SegmentReg : 16;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070098};
99
100// VariableSplit is a way to treat an f64 memory location as a pair
101// of i32 locations (Low and High). This is needed for some cases
102// of the Bitcast instruction. Since it's not possible for integer
103// registers to access the XMM registers and vice versa, the
104// lowering forces the f64 to be spilled to the stack and then
105// accesses through the VariableSplit.
106class VariableSplit : public OperandX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800107 VariableSplit() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700108 VariableSplit(const VariableSplit &) = delete;
109 VariableSplit &operator=(const VariableSplit &) = delete;
110
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700111public:
Jim Stichnothdd842db2015-01-27 12:53:53 -0800112 enum Portion { Low, High };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700113 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
114 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
115 }
Jan Voungfe14fb82014-10-13 15:56:32 -0700116 int32_t getOffset() const { return Part == High ? 4 : 0; }
117
Jan Voung90ccc3f2015-04-30 14:15:10 -0700118 X8632::Address toAsmAddress(const Cfg *Func) const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700119 void emit(const Cfg *Func) const override;
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -0700120 using OperandX8632::dump;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700121 void dump(const Cfg *Func, Ostream &Str) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700122
123 static bool classof(const Operand *Operand) {
124 return Operand->getKind() == static_cast<OperandKind>(kSplit);
125 }
126
127private:
128 VariableSplit(Cfg *Func, Variable *Var, Portion Part)
129 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) {
130 assert(Var->getType() == IceType_f64);
131 Vars = Func->allocateArrayOf<Variable *>(1);
132 Vars[0] = Var;
133 NumVars = 1;
134 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700135 ~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700136 Cfg *Func; // Held only for the destructor.
137 Variable *Var;
138 Portion Part;
139};
140
Jim Stichnoth800dab22014-09-20 12:25:02 -0700141// SpillVariable decorates a Variable by linking it to another
142// Variable. When stack frame offsets are computed, the SpillVariable
143// is given a distinct stack slot only if its linked Variable has a
144// register. If the linked Variable has a stack slot, then the
145// Variable and SpillVariable share that slot.
146class SpillVariable : public Variable {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800147 SpillVariable() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700148 SpillVariable(const SpillVariable &) = delete;
149 SpillVariable &operator=(const SpillVariable &) = delete;
150
Jim Stichnoth800dab22014-09-20 12:25:02 -0700151public:
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800152 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) {
153 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index);
Jim Stichnoth800dab22014-09-20 12:25:02 -0700154 }
155 const static OperandKind SpillVariableKind =
156 static_cast<OperandKind>(kVariable_Target);
157 static bool classof(const Operand *Operand) {
158 return Operand->getKind() == SpillVariableKind;
159 }
160 void setLinkedTo(Variable *Var) { LinkedTo = Var; }
161 Variable *getLinkedTo() const { return LinkedTo; }
162 // Inherit dump() and emit() from Variable.
163private:
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800164 SpillVariable(Type Ty, SizeT Index)
Jim Stichnothae953202014-12-20 06:17:49 -0800165 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {}
Jim Stichnoth800dab22014-09-20 12:25:02 -0700166 Variable *LinkedTo;
167};
168
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700169class InstX8632 : public InstTarget {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800170 InstX8632() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700171 InstX8632(const InstX8632 &) = delete;
172 InstX8632 &operator=(const InstX8632 &) = delete;
173
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700174public:
175 enum InstKindX8632 {
176 k__Start = Inst::Target,
177 Adc,
178 Add,
Matt Wala8d1072e2014-07-11 15:43:51 -0700179 Addps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700180 Addss,
Matt Wala105b7042014-08-11 19:56:19 -0700181 Adjuststack,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700182 And,
Matt Wala0a450512014-07-30 12:44:39 -0700183 Blendvps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700184 Br,
Jan Vounge4da26f2014-07-15 17:52:39 -0700185 Bsf,
186 Bsr,
Jan Voung7fa813b2014-07-18 13:01:08 -0700187 Bswap,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700188 Call,
Matt Walaafeaee42014-08-07 13:47:30 -0700189 Cbwdq,
Jan Vounge4da26f2014-07-15 17:52:39 -0700190 Cmov,
Matt Walace0ca8f2014-07-24 12:34:20 -0700191 Cmpps,
Jan Vounga3a01a22014-07-14 10:32:41 -0700192 Cmpxchg,
193 Cmpxchg8b,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700194 Cvt,
195 Div,
Matt Wala8d1072e2014-07-11 15:43:51 -0700196 Divps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700197 Divss,
198 Fld,
199 Fstp,
200 Icmp,
201 Idiv,
202 Imul,
Matt Wala0a450512014-07-30 12:44:39 -0700203 Insertps,
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800204 Jmp,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700205 Label,
Matt Wala49889232014-07-18 12:45:09 -0700206 Lea,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700207 Load,
Jan Voung5cd240d2014-06-25 10:36:46 -0700208 Mfence,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700209 Mov,
Matt Wala49889232014-07-18 12:45:09 -0700210 Movd,
Matt Wala928f1292014-07-07 16:50:46 -0700211 Movp,
Jan Voung5cd240d2014-06-25 10:36:46 -0700212 Movq,
Jan Vounge4dc61b2014-10-06 08:53:52 -0700213 MovssRegs,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700214 Movsx,
215 Movzx,
216 Mul,
Matt Wala8d1072e2014-07-11 15:43:51 -0700217 Mulps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700218 Mulss,
Jan Vounga3a01a22014-07-14 10:32:41 -0700219 Neg,
Matt Walac3302742014-08-15 16:21:56 -0700220 Nop,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700221 Or,
Matt Wala7fa22d82014-07-17 12:41:31 -0700222 Padd,
Matt Wala83b80362014-07-16 10:21:30 -0700223 Pand,
Matt Wala9cb61e22014-07-24 09:44:42 -0700224 Pandn,
Matt Wala0a450512014-07-30 12:44:39 -0700225 Pblendvb,
Matt Wala83b80362014-07-16 10:21:30 -0700226 Pcmpeq,
227 Pcmpgt,
Matt Wala0a450512014-07-30 12:44:39 -0700228 Pextr,
229 Pinsr,
230 Pmull,
Matt Wala7fa22d82014-07-17 12:41:31 -0700231 Pmuludq,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700232 Pop,
Matt Wala7fa22d82014-07-17 12:41:31 -0700233 Por,
234 Pshufd,
Matt Wala83b80362014-07-16 10:21:30 -0700235 Psll,
236 Psra,
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700237 Psrl,
Matt Wala83b80362014-07-16 10:21:30 -0700238 Psub,
Matt Wala7fa22d82014-07-17 12:41:31 -0700239 Push,
Matt Wala928f1292014-07-07 16:50:46 -0700240 Pxor,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700241 Ret,
Jan Voung7fa813b2014-07-18 13:01:08 -0700242 Rol,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700243 Sar,
244 Sbb,
Jim Stichnothf48b3202015-05-04 10:22:17 -0700245 Setcc,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700246 Shl,
247 Shld,
248 Shr,
249 Shrd,
Matt Wala7fa22d82014-07-17 12:41:31 -0700250 Shufps,
Jan Voungf37fbbe2014-07-09 16:13:13 -0700251 Sqrtss,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700252 Store,
Matt Wala105b7042014-08-11 19:56:19 -0700253 StoreP,
Jan Voung5cd240d2014-06-25 10:36:46 -0700254 StoreQ,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700255 Sub,
Matt Wala8d1072e2014-07-11 15:43:51 -0700256 Subps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700257 Subss,
258 Test,
259 Ucomiss,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700260 UD2,
Jan Voung5cd240d2014-06-25 10:36:46 -0700261 Xadd,
Jan Vounga3a01a22014-07-14 10:32:41 -0700262 Xchg,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700263 Xor
264 };
Jan Vounge4da26f2014-07-15 17:52:39 -0700265
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700266 static const char *getWidthString(Type Ty);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700267 static const char *getFldString(Type Ty);
Jim Stichnoth537b5ba2015-05-19 09:48:44 -0700268 static CondX86::BrCond getOppositeCondition(CondX86::BrCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700269 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700270
271protected:
272 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
273 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700274 ~InstX8632() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700275 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
276 return Inst->getKind() == static_cast<InstKind>(MyKind);
277 }
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700278 // Most instructions that operate on vector arguments require vector
279 // memory operands to be fully aligned (16-byte alignment for PNaCl
280 // vector types). The stack frame layout and call ABI ensure proper
281 // alignment for stack operands, but memory operands (originating
282 // from load/store bitcode instructions) only have element-size
283 // alignment guarantees. This function validates that none of the
284 // operands is a memory operand of vector type, calling
285 // report_fatal_error() if one is found. This function should be
286 // called during emission, and maybe also in the ctor (as long as
287 // that fits the lowering style).
288 void validateVectorAddrMode() const {
289 if (getDest())
290 validateVectorAddrModeOpnd(getDest());
291 for (SizeT i = 0; i < getSrcSize(); ++i) {
292 validateVectorAddrModeOpnd(getSrc(i));
293 }
294 }
Jan Voung44c3a802015-03-27 16:29:08 -0700295
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700296private:
297 static void validateVectorAddrModeOpnd(const Operand *Opnd) {
298 if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) {
299 llvm::report_fatal_error("Possible misaligned vector memory operation");
300 }
301 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700302};
303
Jan Voung7e1e4852014-10-24 10:29:30 -0700304// InstX8632Label represents an intra-block label that is the target
305// of an intra-block branch. The offset between the label and the
306// branch must be fit into one byte (considered "near"). These are
307// used for lowering i1 calculations, Select instructions, and 64-bit
308// compares on a 32-bit architecture, without basic block splitting.
309// Basic block splitting is not so desirable for several reasons, one
310// of which is the impact on decisions based on whether a variable's
311// live range spans multiple basic blocks.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700312//
313// Intra-block control flow must be used with caution. Consider the
314// sequence for "c = (a >= b ? x : y)".
315// cmp a, b
316// br lt, L1
317// mov c, x
318// jmp L2
319// L1:
320// mov c, y
321// L2:
322//
323// Labels L1 and L2 are intra-block labels. Without knowledge of the
324// intra-block control flow, liveness analysis will determine the "mov
325// c, x" instruction to be dead. One way to prevent this is to insert
326// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
327// instructions, e.g.:
328//
329// cmp a, b
330// br lt, L1
331// mov c, x
332// jmp L2
333// FakeUse(c)
334// L1:
335// mov c, y
336// L2:
337//
338// The down-side is that "mov c, x" can never be dead-code eliminated
339// even if there are no uses of c. As unlikely as this situation is,
340// it may be prevented by running dead code elimination before
341// lowering.
342class InstX8632Label : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800343 InstX8632Label() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700344 InstX8632Label(const InstX8632Label &) = delete;
345 InstX8632Label &operator=(const InstX8632Label &) = delete;
346
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700347public:
348 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
349 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
350 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700351 uint32_t getEmitInstCount() const override { return 0; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700352 IceString getName(const Cfg *Func) const;
Jan Voung7e1e4852014-10-24 10:29:30 -0700353 SizeT getNumber() const { return Number; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700354 void emit(const Cfg *Func) const override;
Jan Voung7e1e4852014-10-24 10:29:30 -0700355 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700356 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700357
358private:
359 InstX8632Label(Cfg *Func, TargetX8632 *Target);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700360 ~InstX8632Label() override {}
Jan Voung7e1e4852014-10-24 10:29:30 -0700361 SizeT Number; // used for unique label generation.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700362};
363
364// Conditional and unconditional branch instruction.
365class InstX8632Br : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800366 InstX8632Br() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700367 InstX8632Br(const InstX8632Br &) = delete;
368 InstX8632Br &operator=(const InstX8632Br &) = delete;
369
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700370public:
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700371 // Create a conditional branch to a node.
372 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
Jan Voungbd385e42014-09-18 18:18:10 -0700373 CfgNode *TargetFalse, CondX86::BrCond Condition) {
Jim Stichnoth98712a32014-10-24 10:59:02 -0700374 assert(Condition != CondX86::Br_None);
Jim Stichnothae953202014-12-20 06:17:49 -0800375 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700376 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700377 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700378 }
379 // Create an unconditional branch to a node.
380 static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
Jim Stichnothae953202014-12-20 06:17:49 -0800381 const CfgNode *NoCondTarget = nullptr;
382 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700383 return new (Func->allocate<InstX8632Br>())
Jan Voungbd385e42014-09-18 18:18:10 -0700384 InstX8632Br(Func, NoCondTarget, Target, NoLabel, CondX86::Br_None);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700385 }
386 // Create a non-terminator conditional branch to a node, with a
387 // fallthrough to the next instruction in the current node. This is
388 // used for switch lowering.
Jan Voungbd385e42014-09-18 18:18:10 -0700389 static InstX8632Br *create(Cfg *Func, CfgNode *Target,
390 CondX86::BrCond Condition) {
Jim Stichnoth98712a32014-10-24 10:59:02 -0700391 assert(Condition != CondX86::Br_None);
Jim Stichnothae953202014-12-20 06:17:49 -0800392 const CfgNode *NoUncondTarget = nullptr;
393 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700394 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700395 InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700396 }
397 // Create a conditional intra-block branch (or unconditional, if
Jim Stichnoth18735602014-09-16 19:59:35 -0700398 // Condition==Br_None) to a label in the current block.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700399 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
Jan Voungbd385e42014-09-18 18:18:10 -0700400 CondX86::BrCond Condition) {
Jim Stichnothae953202014-12-20 06:17:49 -0800401 const CfgNode *NoCondTarget = nullptr;
402 const CfgNode *NoUncondTarget = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700403 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700404 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700405 }
Jim Stichnothff9c7062014-09-18 04:50:49 -0700406 const CfgNode *getTargetTrue() const { return TargetTrue; }
407 const CfgNode *getTargetFalse() const { return TargetFalse; }
408 bool optimizeBranch(const CfgNode *NextNode);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700409 uint32_t getEmitInstCount() const override {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700410 uint32_t Sum = 0;
Jim Stichnoth18735602014-09-16 19:59:35 -0700411 if (Label)
Jim Stichnothff9c7062014-09-18 04:50:49 -0700412 ++Sum;
413 if (getTargetTrue())
414 ++Sum;
Jim Stichnoth18735602014-09-16 19:59:35 -0700415 if (getTargetFalse())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700416 ++Sum;
417 return Sum;
Jim Stichnoth18735602014-09-16 19:59:35 -0700418 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700419 bool isUnconditionalBranch() const override {
420 return !Label && Condition == CondX86::Br_None;
421 }
422 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700423 void emit(const Cfg *Func) const override;
Jan Voung7e1e4852014-10-24 10:29:30 -0700424 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700425 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700426 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
427
428private:
Jim Stichnothff9c7062014-09-18 04:50:49 -0700429 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
Jan Voungbd385e42014-09-18 18:18:10 -0700430 const InstX8632Label *Label, CondX86::BrCond Condition);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700431 ~InstX8632Br() override {}
Jan Voungbd385e42014-09-18 18:18:10 -0700432 CondX86::BrCond Condition;
Jim Stichnothff9c7062014-09-18 04:50:49 -0700433 const CfgNode *TargetTrue;
434 const CfgNode *TargetFalse;
435 const InstX8632Label *Label; // Intra-block branch target
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700436};
437
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800438// Jump to a target outside this function, such as tailcall, nacljump,
439// naclret, unreachable. This is different from a Branch instruction
440// in that there is no intra-function control flow to represent.
441class InstX8632Jmp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800442 InstX8632Jmp() = delete;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800443 InstX8632Jmp(const InstX8632Jmp &) = delete;
444 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete;
445
446public:
447 static InstX8632Jmp *create(Cfg *Func, Operand *Target) {
448 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target);
449 }
450 Operand *getJmpTarget() const { return getSrc(0); }
451 void emit(const Cfg *Func) const override;
452 void emitIAS(const Cfg *Func) const override;
453 void dump(const Cfg *Func) const override;
454 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); }
455
456private:
457 InstX8632Jmp(Cfg *Func, Operand *Target);
458};
459
Matt Wala105b7042014-08-11 19:56:19 -0700460// AdjustStack instruction - subtracts esp by the given amount and
461// updates the stack offset during code emission.
462class InstX8632AdjustStack : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800463 InstX8632AdjustStack() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700464 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
465 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
466
Matt Wala105b7042014-08-11 19:56:19 -0700467public:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700468 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
Matt Wala105b7042014-08-11 19:56:19 -0700469 return new (Func->allocate<InstX8632AdjustStack>())
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700470 InstX8632AdjustStack(Func, Amount, Esp);
Matt Wala105b7042014-08-11 19:56:19 -0700471 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700472 void emit(const Cfg *Func) const override;
473 void emitIAS(const Cfg *Func) const override;
474 void dump(const Cfg *Func) const override;
Matt Wala105b7042014-08-11 19:56:19 -0700475 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
476
477private:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700478 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
Matt Wala105b7042014-08-11 19:56:19 -0700479 SizeT Amount;
480};
481
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700482// Call instruction. Arguments should have already been pushed.
483class InstX8632Call : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800484 InstX8632Call() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700485 InstX8632Call(const InstX8632Call &) = delete;
486 InstX8632Call &operator=(const InstX8632Call &) = delete;
487
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700488public:
489 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
490 return new (Func->allocate<InstX8632Call>())
491 InstX8632Call(Func, Dest, CallTarget);
492 }
493 Operand *getCallTarget() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700494 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700495 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700496 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700497 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
498
499private:
500 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700501 ~InstX8632Call() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700502};
503
Jan Voung3b43b892014-09-24 13:32:39 -0700504// Emit a one-operand (GPR) instruction.
Jan Voungaf2780c2014-09-26 11:14:30 -0700505void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700506 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700507
Jan Voung7fa813b2014-07-18 13:01:08 -0700508// Instructions of the form x := op(x).
509template <InstX8632::InstKindX8632 K>
Jan Voung3b43b892014-09-24 13:32:39 -0700510class InstX8632InplaceopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800511 InstX8632InplaceopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700512 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
513 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
514
Jan Voung7fa813b2014-07-18 13:01:08 -0700515public:
Jan Voung3b43b892014-09-24 13:32:39 -0700516 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) {
517 return new (Func->allocate<InstX8632InplaceopGPR>())
518 InstX8632InplaceopGPR(Func, SrcDest);
Jan Voung7fa813b2014-07-18 13:01:08 -0700519 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700520 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800521 if (!ALLOW_DUMP)
522 return;
Jan Voung7fa813b2014-07-18 13:01:08 -0700523 Ostream &Str = Func->getContext()->getStrEmit();
524 assert(getSrcSize() == 1);
525 Str << "\t" << Opcode << "\t";
526 getSrc(0)->emit(Func);
Jan Voung7fa813b2014-07-18 13:01:08 -0700527 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700528 void emitIAS(const Cfg *Func) const override {
Jan Voung3b43b892014-09-24 13:32:39 -0700529 assert(getSrcSize() == 1);
530 const Variable *Var = getDest();
531 Type Ty = Var->getType();
Jan Voungaf2780c2014-09-26 11:14:30 -0700532 emitIASOpTyGPR(Func, Ty, Var, Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700533 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700534 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800535 if (!ALLOW_DUMP)
536 return;
Jan Voung7fa813b2014-07-18 13:01:08 -0700537 Ostream &Str = Func->getContext()->getStrDump();
538 dumpDest(Func);
539 Str << " = " << Opcode << "." << getDest()->getType() << " ";
540 dumpSources(Func);
541 }
542 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
543
544private:
Jan Voung3b43b892014-09-24 13:32:39 -0700545 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest)
Jan Voung7fa813b2014-07-18 13:01:08 -0700546 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
547 addSource(SrcDest);
548 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700549 ~InstX8632InplaceopGPR() override {}
Jan Voung7fa813b2014-07-18 13:01:08 -0700550 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700551 static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
Jan Voung7fa813b2014-07-18 13:01:08 -0700552};
553
Jan Voung3b43b892014-09-24 13:32:39 -0700554// Emit a two-operand (GPR) instruction, where the dest operand is a
555// Variable that's guaranteed to be a register.
Jan Voung39d4aca2014-10-15 15:16:54 -0700556template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
Jan Voung3b43b892014-09-24 13:32:39 -0700557void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
558 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700559 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700560
Jan Voung39d4aca2014-10-15 15:16:54 -0700561// Instructions of the form x := op(y).
Jan Vounga3a01a22014-07-14 10:32:41 -0700562template <InstX8632::InstKindX8632 K>
Jan Voung3b43b892014-09-24 13:32:39 -0700563class InstX8632UnaryopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800564 InstX8632UnaryopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700565 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
566 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
567
Jan Vounga3a01a22014-07-14 10:32:41 -0700568public:
Jan Voung3b43b892014-09-24 13:32:39 -0700569 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
570 return new (Func->allocate<InstX8632UnaryopGPR>())
571 InstX8632UnaryopGPR(Func, Dest, Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700572 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700573 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800574 if (!ALLOW_DUMP)
575 return;
Jan Vounga3a01a22014-07-14 10:32:41 -0700576 Ostream &Str = Func->getContext()->getStrEmit();
577 assert(getSrcSize() == 1);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700578 Type SrcTy = getSrc(0)->getType();
579 Type DestTy = getDest()->getType();
580 Str << "\t" << Opcode << getWidthString(SrcTy);
581 // Movsx and movzx need both the source and dest type width letter
582 // to define the operation. The other unary operations have the
583 // same source and dest type and as a result need only one letter.
584 if (SrcTy != DestTy)
585 Str << getWidthString(DestTy);
586 Str << "\t";
Jan Vounga3a01a22014-07-14 10:32:41 -0700587 getSrc(0)->emit(Func);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700588 Str << ", ";
589 getDest()->emit(Func);
Jan Vounga3a01a22014-07-14 10:32:41 -0700590 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700591 void emitIAS(const Cfg *Func) const override {
Jan Voung3b43b892014-09-24 13:32:39 -0700592 assert(getSrcSize() == 1);
593 const Variable *Var = getDest();
594 Type Ty = Var->getType();
595 const Operand *Src = getSrc(0);
596 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter);
597 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700598 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800599 if (!ALLOW_DUMP)
600 return;
Jan Vounga3a01a22014-07-14 10:32:41 -0700601 Ostream &Str = Func->getContext()->getStrDump();
602 dumpDest(Func);
Jan Voung39d4aca2014-10-15 15:16:54 -0700603 Str << " = " << Opcode << "." << getSrc(0)->getType() << " ";
Jan Vounga3a01a22014-07-14 10:32:41 -0700604 dumpSources(Func);
605 }
606 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
607
608private:
Jan Voung3b43b892014-09-24 13:32:39 -0700609 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
Jan Vounge4da26f2014-07-15 17:52:39 -0700610 : InstX8632(Func, K, 1, Dest) {
611 addSource(Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700612 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700613 ~InstX8632UnaryopGPR() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -0700614 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700615 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
Jan Vounga3a01a22014-07-14 10:32:41 -0700616};
617
Jan Vounge4dc61b2014-10-06 08:53:52 -0700618void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
619 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700620 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700621
622template <InstX8632::InstKindX8632 K>
623class InstX8632UnaryopXmm : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800624 InstX8632UnaryopXmm() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700625 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
626 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
627
Jan Voung8acded02014-09-22 18:02:25 -0700628public:
629 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) {
630 return new (Func->allocate<InstX8632UnaryopXmm>())
631 InstX8632UnaryopXmm(Func, Dest, Src);
632 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700633 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800634 if (!ALLOW_DUMP)
635 return;
Jan Voung8acded02014-09-22 18:02:25 -0700636 Ostream &Str = Func->getContext()->getStrEmit();
637 assert(getSrcSize() == 1);
638 Str << "\t" << Opcode << "\t";
Jan Voung8acded02014-09-22 18:02:25 -0700639 getSrc(0)->emit(Func);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700640 Str << ", ";
641 getDest()->emit(Func);
Jan Voung8acded02014-09-22 18:02:25 -0700642 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700643 void emitIAS(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700644 Type Ty = getDest()->getType();
645 assert(getSrcSize() == 1);
Jan Vounge4dc61b2014-10-06 08:53:52 -0700646 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(0), Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700647 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700648 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800649 if (!ALLOW_DUMP)
650 return;
Jan Voung8acded02014-09-22 18:02:25 -0700651 Ostream &Str = Func->getContext()->getStrDump();
652 dumpDest(Func);
653 Str << " = " << Opcode << "." << getDest()->getType() << " ";
654 dumpSources(Func);
655 }
656 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
657
658private:
659 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
660 : InstX8632(Func, K, 1, Dest) {
661 addSource(Src);
662 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700663 ~InstX8632UnaryopXmm() override {}
Jan Voung8acded02014-09-22 18:02:25 -0700664 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700665 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
Jan Voung8acded02014-09-22 18:02:25 -0700666};
667
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700668// See the definition of emitTwoAddress() for a description of
669// ShiftHack.
670void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
671 bool ShiftHack = false);
672
Jan Voung8bcca042014-10-03 21:58:02 -0700673void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
674 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700675 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter);
Jan Voung8bcca042014-10-03 21:58:02 -0700676
677template <InstX8632::InstKindX8632 K>
678class InstX8632BinopGPRShift : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800679 InstX8632BinopGPRShift() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700680 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
681 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
682
Jan Voung8bcca042014-10-03 21:58:02 -0700683public:
684 // Create a binary-op GPR shift instruction.
685 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest,
686 Operand *Source) {
687 return new (Func->allocate<InstX8632BinopGPRShift>())
688 InstX8632BinopGPRShift(Func, Dest, Source);
689 }
690 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800691 if (!ALLOW_DUMP)
692 return;
Jan Voung8bcca042014-10-03 21:58:02 -0700693 const bool ShiftHack = true;
694 emitTwoAddress(Opcode, this, Func, ShiftHack);
695 }
696 void emitIAS(const Cfg *Func) const override {
697 Type Ty = getDest()->getType();
698 assert(getSrcSize() == 2);
699 emitIASGPRShift(Func, Ty, getDest(), getSrc(1), Emitter);
700 }
701 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800702 if (!ALLOW_DUMP)
703 return;
Jan Voung8bcca042014-10-03 21:58:02 -0700704 Ostream &Str = Func->getContext()->getStrDump();
705 dumpDest(Func);
706 Str << " = " << Opcode << "." << getDest()->getType() << " ";
707 dumpSources(Func);
708 }
709 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
710
711private:
712 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
713 : InstX8632(Func, K, 2, Dest) {
714 addSource(Dest);
715 addSource(Source);
716 }
Jan Voung8bcca042014-10-03 21:58:02 -0700717 ~InstX8632BinopGPRShift() override {}
718 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700719 static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
Jan Voung8bcca042014-10-03 21:58:02 -0700720};
721
Jan Voungaf2780c2014-09-26 11:14:30 -0700722template <InstX8632::InstKindX8632 K>
723class InstX8632BinopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800724 InstX8632BinopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700725 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
726 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
727
Jan Voungaf2780c2014-09-26 11:14:30 -0700728public:
729 // Create an ordinary binary-op instruction like add or sub.
730 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) {
731 return new (Func->allocate<InstX8632BinopGPR>())
732 InstX8632BinopGPR(Func, Dest, Source);
733 }
734 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800735 if (!ALLOW_DUMP)
736 return;
Jan Voungaf2780c2014-09-26 11:14:30 -0700737 const bool ShiftHack = false;
738 emitTwoAddress(Opcode, this, Func, ShiftHack);
739 }
740 void emitIAS(const Cfg *Func) const override {
741 Type Ty = getDest()->getType();
742 assert(getSrcSize() == 2);
743 emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter);
744 }
745 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800746 if (!ALLOW_DUMP)
747 return;
Jan Voungaf2780c2014-09-26 11:14:30 -0700748 Ostream &Str = Func->getContext()->getStrDump();
749 dumpDest(Func);
750 Str << " = " << Opcode << "." << getDest()->getType() << " ";
751 dumpSources(Func);
752 }
753 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
754
755private:
756 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
757 : InstX8632(Func, K, 2, Dest) {
758 addSource(Dest);
759 addSource(Source);
760 }
Jan Voungaf2780c2014-09-26 11:14:30 -0700761 ~InstX8632BinopGPR() override {}
762 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700763 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
Jan Voungaf2780c2014-09-26 11:14:30 -0700764};
765
Jan Voung8acded02014-09-22 18:02:25 -0700766template <InstX8632::InstKindX8632 K, bool NeedsElementType>
767class InstX8632BinopXmm : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800768 InstX8632BinopXmm() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700769 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
770 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
771
Jan Voung8acded02014-09-22 18:02:25 -0700772public:
773 // Create an XMM binary-op instruction like addss or addps.
774 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
775 return new (Func->allocate<InstX8632BinopXmm>())
776 InstX8632BinopXmm(Func, Dest, Source);
777 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700778 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800779 if (!ALLOW_DUMP)
780 return;
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700781 validateVectorAddrMode();
Jan Voung8acded02014-09-22 18:02:25 -0700782 const bool ShiftHack = false;
783 emitTwoAddress(Opcode, this, Func, ShiftHack);
784 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700785 void emitIAS(const Cfg *Func) const override {
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700786 validateVectorAddrMode();
Jan Voung8acded02014-09-22 18:02:25 -0700787 Type Ty = getDest()->getType();
788 if (NeedsElementType)
789 Ty = typeElementType(Ty);
790 assert(getSrcSize() == 2);
Jan Vounge4dc61b2014-10-06 08:53:52 -0700791 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700792 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700793 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800794 if (!ALLOW_DUMP)
795 return;
Jan Voung8acded02014-09-22 18:02:25 -0700796 Ostream &Str = Func->getContext()->getStrDump();
797 dumpDest(Func);
798 Str << " = " << Opcode << "." << getDest()->getType() << " ";
799 dumpSources(Func);
800 }
801 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
802
803private:
804 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
805 : InstX8632(Func, K, 2, Dest) {
806 addSource(Dest);
807 addSource(Source);
808 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700809 ~InstX8632BinopXmm() override {}
Jan Voung8acded02014-09-22 18:02:25 -0700810 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700811 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
Jan Voung8acded02014-09-22 18:02:25 -0700812};
813
Jan Voung8bcca042014-10-03 21:58:02 -0700814void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
815 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700816 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter);
Jan Voung8bcca042014-10-03 21:58:02 -0700817
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700818template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false>
Jan Voung8bcca042014-10-03 21:58:02 -0700819class InstX8632BinopXmmShift : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800820 InstX8632BinopXmmShift() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700821 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
822 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
823
Jan Voung8bcca042014-10-03 21:58:02 -0700824public:
825 // Create an XMM binary-op shift operation.
826 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest,
827 Operand *Source) {
828 return new (Func->allocate<InstX8632BinopXmmShift>())
829 InstX8632BinopXmmShift(Func, Dest, Source);
830 }
831 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800832 if (!ALLOW_DUMP)
833 return;
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700834 validateVectorAddrMode();
Jan Voung8bcca042014-10-03 21:58:02 -0700835 const bool ShiftHack = false;
836 emitTwoAddress(Opcode, this, Func, ShiftHack);
837 }
838 void emitIAS(const Cfg *Func) const override {
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700839 validateVectorAddrMode();
Jan Voung8bcca042014-10-03 21:58:02 -0700840 Type Ty = getDest()->getType();
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700841 assert(AllowAllTypes || isVectorType(Ty));
Jan Voung8bcca042014-10-03 21:58:02 -0700842 Type ElementTy = typeElementType(Ty);
843 assert(getSrcSize() == 2);
844 emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter);
845 }
846 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800847 if (!ALLOW_DUMP)
848 return;
Jan Voung8bcca042014-10-03 21:58:02 -0700849 Ostream &Str = Func->getContext()->getStrDump();
850 dumpDest(Func);
851 Str << " = " << Opcode << "." << getDest()->getType() << " ";
852 dumpSources(Func);
853 }
854 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
855
856private:
857 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
858 : InstX8632(Func, K, 2, Dest) {
859 addSource(Dest);
860 addSource(Source);
861 }
Jan Voung8bcca042014-10-03 21:58:02 -0700862 ~InstX8632BinopXmmShift() override {}
863 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700864 static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
Jan Voung8bcca042014-10-03 21:58:02 -0700865};
866
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700867template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800868 InstX8632Ternop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700869 InstX8632Ternop(const InstX8632Ternop &) = delete;
870 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
871
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700872public:
873 // Create a ternary-op instruction like div or idiv.
874 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
875 Operand *Source2) {
876 return new (Func->allocate<InstX8632Ternop>())
877 InstX8632Ternop(Func, Dest, Source1, Source2);
878 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700879 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800880 if (!ALLOW_DUMP)
881 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700882 Ostream &Str = Func->getContext()->getStrEmit();
883 assert(getSrcSize() == 3);
884 Str << "\t" << Opcode << "\t";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700885 getSrc(2)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700886 Str << ", ";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700887 getSrc(1)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700888 Str << ", ";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700889 getDest()->emit(Func);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700890 }
Jan Voung962befa2014-10-15 09:32:58 -0700891 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700892 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800893 if (!ALLOW_DUMP)
894 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700895 Ostream &Str = Func->getContext()->getStrDump();
896 dumpDest(Func);
897 Str << " = " << Opcode << "." << getDest()->getType() << " ";
898 dumpSources(Func);
899 }
900 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
901
902private:
903 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
904 : InstX8632(Func, K, 3, Dest) {
905 addSource(Dest);
906 addSource(Source1);
907 addSource(Source2);
908 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700909 ~InstX8632Ternop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700910 static const char *Opcode;
911};
912
Matt Wala49889232014-07-18 12:45:09 -0700913// Instructions of the form x := y op z
914template <InstX8632::InstKindX8632 K>
915class InstX8632ThreeAddressop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800916 InstX8632ThreeAddressop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700917 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
918 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
919
Matt Wala49889232014-07-18 12:45:09 -0700920public:
921 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
922 Operand *Source0, Operand *Source1) {
923 return new (Func->allocate<InstX8632ThreeAddressop>())
924 InstX8632ThreeAddressop(Func, Dest, Source0, Source1);
925 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700926 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800927 if (!ALLOW_DUMP)
928 return;
Matt Wala49889232014-07-18 12:45:09 -0700929 Ostream &Str = Func->getContext()->getStrEmit();
930 assert(getSrcSize() == 2);
931 Str << "\t" << Opcode << "\t";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700932 getSrc(1)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700933 Str << ", ";
934 getSrc(0)->emit(Func);
935 Str << ", ";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700936 getDest()->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700937 }
Jan Voung962befa2014-10-15 09:32:58 -0700938 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700939 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800940 if (!ALLOW_DUMP)
941 return;
Matt Wala49889232014-07-18 12:45:09 -0700942 Ostream &Str = Func->getContext()->getStrDump();
943 dumpDest(Func);
944 Str << " = " << Opcode << "." << getDest()->getType() << " ";
945 dumpSources(Func);
946 }
947 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
948
949private:
950 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
951 Operand *Source1)
952 : InstX8632(Func, K, 2, Dest) {
953 addSource(Source0);
954 addSource(Source1);
955 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700956 ~InstX8632ThreeAddressop() override {}
Matt Wala49889232014-07-18 12:45:09 -0700957 static const char *Opcode;
958};
959
Matt Walae58178a2014-08-12 13:15:04 -0700960// Base class for assignment instructions
961template <InstX8632::InstKindX8632 K>
962class InstX8632Movlike : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800963 InstX8632Movlike() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700964 InstX8632Movlike(const InstX8632Movlike &) = delete;
965 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
966
Matt Walae58178a2014-08-12 13:15:04 -0700967public:
968 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
969 return new (Func->allocate<InstX8632Movlike>())
970 InstX8632Movlike(Func, Dest, Source);
971 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700972 bool isRedundantAssign() const override {
Matt Walae58178a2014-08-12 13:15:04 -0700973 return checkForRedundantAssign(getDest(), getSrc(0));
974 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700975 bool isSimpleAssign() const override { return true; }
976 void emit(const Cfg *Func) const override;
Jan Voungfe14fb82014-10-13 15:56:32 -0700977 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700978 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800979 if (!ALLOW_DUMP)
980 return;
Matt Walae58178a2014-08-12 13:15:04 -0700981 Ostream &Str = Func->getContext()->getStrDump();
982 Str << Opcode << "." << getDest()->getType() << " ";
983 dumpDest(Func);
984 Str << ", ";
985 dumpSources(Func);
986 }
987 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
988
989private:
990 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source)
991 : InstX8632(Func, K, 1, Dest) {
992 addSource(Source);
993 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700994 ~InstX8632Movlike() override {}
Matt Walae58178a2014-08-12 13:15:04 -0700995
996 static const char *Opcode;
997};
998
Jan Voung3b43b892014-09-24 13:32:39 -0700999typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap;
1000typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg;
1001typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf;
1002typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr;
1003typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea;
Matt Wala51e8cfb2014-08-08 08:39:40 -07001004// Cbwdq instruction - wrapper for cbw, cwd, and cdq
Jan Voung3b43b892014-09-24 13:32:39 -07001005typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq;
Jan Voung39d4aca2014-10-15 15:16:54 -07001006typedef InstX8632UnaryopGPR<InstX8632::Movsx> InstX8632Movsx;
1007typedef InstX8632UnaryopGPR<InstX8632::Movzx> InstX8632Movzx;
Jan Voung3b43b892014-09-24 13:32:39 -07001008typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd;
1009typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss;
Matt Walae58178a2014-08-12 13:15:04 -07001010// Move/assignment instruction - wrapper for mov/movss/movsd.
1011typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov;
1012// Move packed - copy 128 bit values between XMM registers, or mem128
1013// and XMM registers.
1014typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp;
1015// Movq - copy between XMM registers, or mem64 and XMM registers.
1016typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq;
Jan Voungaf2780c2014-09-26 11:14:30 -07001017typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add;
Jan Voung8acded02014-09-22 18:02:25 -07001018typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps;
Jan Voungaf2780c2014-09-26 11:14:30 -07001019typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc;
Jan Voung8acded02014-09-22 18:02:25 -07001020typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss;
1021typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd;
Jan Voungaf2780c2014-09-26 11:14:30 -07001022typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub;
Jan Voung8acded02014-09-22 18:02:25 -07001023typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps;
1024typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss;
Jan Voungaf2780c2014-09-26 11:14:30 -07001025typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb;
Jan Voung8acded02014-09-22 18:02:25 -07001026typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub;
Jan Voungaf2780c2014-09-26 11:14:30 -07001027typedef InstX8632BinopGPR<InstX8632::And> InstX8632And;
Jan Voung8acded02014-09-22 18:02:25 -07001028typedef InstX8632BinopXmm<InstX8632::Pand, false> InstX8632Pand;
1029typedef InstX8632BinopXmm<InstX8632::Pandn, false> InstX8632Pandn;
Jan Voungaf2780c2014-09-26 11:14:30 -07001030typedef InstX8632BinopGPR<InstX8632::Or> InstX8632Or;
Jan Voung8acded02014-09-22 18:02:25 -07001031typedef InstX8632BinopXmm<InstX8632::Por, false> InstX8632Por;
Jan Voungaf2780c2014-09-26 11:14:30 -07001032typedef InstX8632BinopGPR<InstX8632::Xor> InstX8632Xor;
Jan Voung8acded02014-09-22 18:02:25 -07001033typedef InstX8632BinopXmm<InstX8632::Pxor, false> InstX8632Pxor;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001034typedef InstX8632BinopGPR<InstX8632::Imul> InstX8632Imul;
Jan Voung8acded02014-09-22 18:02:25 -07001035typedef InstX8632BinopXmm<InstX8632::Mulps, true> InstX8632Mulps;
1036typedef InstX8632BinopXmm<InstX8632::Mulss, false> InstX8632Mulss;
Jan Voung8bcca042014-10-03 21:58:02 -07001037typedef InstX8632BinopXmm<InstX8632::Pmull, true> InstX8632Pmull;
Jan Voung8acded02014-09-22 18:02:25 -07001038typedef InstX8632BinopXmm<InstX8632::Pmuludq, false> InstX8632Pmuludq;
1039typedef InstX8632BinopXmm<InstX8632::Divps, true> InstX8632Divps;
1040typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss;
Jan Voung8bcca042014-10-03 21:58:02 -07001041typedef InstX8632BinopGPRShift<InstX8632::Rol> InstX8632Rol;
1042typedef InstX8632BinopGPRShift<InstX8632::Shl> InstX8632Shl;
1043typedef InstX8632BinopXmmShift<InstX8632::Psll> InstX8632Psll;
Jim Stichnoth8c980d02015-03-19 13:01:50 -07001044typedef InstX8632BinopXmmShift<InstX8632::Psrl, true> InstX8632Psrl;
Jan Voung8bcca042014-10-03 21:58:02 -07001045typedef InstX8632BinopGPRShift<InstX8632::Shr> InstX8632Shr;
1046typedef InstX8632BinopGPRShift<InstX8632::Sar> InstX8632Sar;
1047typedef InstX8632BinopXmmShift<InstX8632::Psra> InstX8632Psra;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001048typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq;
1049typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001050// movss is only a binary operation when the source and dest
1051// operands are both registers (the high bits of dest are left untouched).
1052// In other cases, it behaves like a copy (mov-like) operation (and the
1053// high bits of dest are cleared).
1054// InstX8632Movss will assert that both its source and dest operands are
1055// registers, so the lowering code should use _mov instead of _movss
1056// in cases where a copy operation is intended.
1057typedef InstX8632BinopXmm<InstX8632::MovssRegs, false> InstX8632MovssRegs;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001058typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv;
1059typedef InstX8632Ternop<InstX8632::Div> InstX8632Div;
Matt Wala0a450512014-07-30 12:44:39 -07001060typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
1061typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
Matt Wala49889232014-07-18 12:45:09 -07001062typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
Matt Wala0a450512014-07-30 12:44:39 -07001063typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
1064typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
1065typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
Matt Wala49889232014-07-18 12:45:09 -07001066typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001067
Jan Vounga3a01a22014-07-14 10:32:41 -07001068// Base class for a lockable x86-32 instruction (emits a locked prefix).
1069class InstX8632Lockable : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001070 InstX8632Lockable() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001071 InstX8632Lockable(const InstX8632Lockable &) = delete;
1072 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
1073
Jan Vounga3a01a22014-07-14 10:32:41 -07001074protected:
1075 bool Locked;
1076
1077 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
1078 Variable *Dest, bool Locked)
1079 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
1080 // Assume that such instructions are used for Atomics and be careful
1081 // with optimizations.
1082 HasSideEffects = Locked;
1083 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001084 ~InstX8632Lockable() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001085};
1086
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001087// Mul instruction - unsigned multiply.
1088class InstX8632Mul : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001089 InstX8632Mul() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001090 InstX8632Mul(const InstX8632Mul &) = delete;
1091 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
1092
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001093public:
1094 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
1095 Operand *Source2) {
1096 return new (Func->allocate<InstX8632Mul>())
1097 InstX8632Mul(Func, Dest, Source1, Source2);
1098 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001099 void emit(const Cfg *Func) const override;
Jan Voungaf2780c2014-09-26 11:14:30 -07001100 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001101 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001102 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
1103
1104private:
1105 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001106 ~InstX8632Mul() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001107};
1108
Jan Voung88355762014-11-01 09:40:20 -07001109// Shld instruction - shift across a pair of operands.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001110class InstX8632Shld : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001111 InstX8632Shld() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001112 InstX8632Shld(const InstX8632Shld &) = delete;
1113 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
1114
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001115public:
1116 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
1117 Variable *Source2) {
1118 return new (Func->allocate<InstX8632Shld>())
1119 InstX8632Shld(Func, Dest, Source1, Source2);
1120 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001121 void emit(const Cfg *Func) const override;
Jan Voung962befa2014-10-15 09:32:58 -07001122 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001123 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001124 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
1125
1126private:
1127 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
1128 Variable *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001129 ~InstX8632Shld() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001130};
1131
Jan Voung88355762014-11-01 09:40:20 -07001132// Shrd instruction - shift across a pair of operands.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001133class InstX8632Shrd : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001134 InstX8632Shrd() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001135 InstX8632Shrd(const InstX8632Shrd &) = delete;
1136 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
1137
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001138public:
1139 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
1140 Variable *Source2) {
1141 return new (Func->allocate<InstX8632Shrd>())
1142 InstX8632Shrd(Func, Dest, Source1, Source2);
1143 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001144 void emit(const Cfg *Func) const override;
Jan Voung962befa2014-10-15 09:32:58 -07001145 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001146 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001147 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
1148
1149private:
1150 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
1151 Variable *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001152 ~InstX8632Shrd() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001153};
1154
Jan Vounge4da26f2014-07-15 17:52:39 -07001155// Conditional move instruction.
1156class InstX8632Cmov : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001157 InstX8632Cmov() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001158 InstX8632Cmov(const InstX8632Cmov &) = delete;
1159 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
1160
Jan Vounge4da26f2014-07-15 17:52:39 -07001161public:
1162 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voungbd385e42014-09-18 18:18:10 -07001163 CondX86::BrCond Cond) {
Jan Vounge4da26f2014-07-15 17:52:39 -07001164 return new (Func->allocate<InstX8632Cmov>())
1165 InstX8632Cmov(Func, Dest, Source, Cond);
1166 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001167 void emit(const Cfg *Func) const override;
1168 void emitIAS(const Cfg *Func) const override;
1169 void dump(const Cfg *Func) const override;
Jan Vounge4da26f2014-07-15 17:52:39 -07001170 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
1171
1172private:
Jan Voungbd385e42014-09-18 18:18:10 -07001173 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
1174 CondX86::BrCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001175 ~InstX8632Cmov() override {}
Jan Vounge4da26f2014-07-15 17:52:39 -07001176
Jan Voungbd385e42014-09-18 18:18:10 -07001177 CondX86::BrCond Condition;
Jan Vounge4da26f2014-07-15 17:52:39 -07001178};
1179
Matt Walace0ca8f2014-07-24 12:34:20 -07001180// Cmpps instruction - compare packed singled-precision floating point
1181// values
1182class InstX8632Cmpps : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001183 InstX8632Cmpps() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001184 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
1185 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
1186
Matt Walace0ca8f2014-07-24 12:34:20 -07001187public:
Matt Walace0ca8f2014-07-24 12:34:20 -07001188 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voungbd385e42014-09-18 18:18:10 -07001189 CondX86::CmppsCond Condition) {
Matt Walace0ca8f2014-07-24 12:34:20 -07001190 return new (Func->allocate<InstX8632Cmpps>())
1191 InstX8632Cmpps(Func, Dest, Source, Condition);
1192 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001193 void emit(const Cfg *Func) const override;
1194 void emitIAS(const Cfg *Func) const override;
1195 void dump(const Cfg *Func) const override;
Matt Walace0ca8f2014-07-24 12:34:20 -07001196 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
1197
1198private:
Jan Voungbd385e42014-09-18 18:18:10 -07001199 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
1200 CondX86::CmppsCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001201 ~InstX8632Cmpps() override {}
Matt Walace0ca8f2014-07-24 12:34:20 -07001202
Jan Voungbd385e42014-09-18 18:18:10 -07001203 CondX86::CmppsCond Condition;
Matt Walace0ca8f2014-07-24 12:34:20 -07001204};
1205
Jan Vounga3a01a22014-07-14 10:32:41 -07001206// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
1207// equals eax. If so, the ZF is set and <desired> is stored in <dest>.
1208// If not, ZF is cleared and <dest> is copied to eax (or subregister).
1209// <dest> can be a register or memory, while <desired> must be a register.
1210// It is the user's responsiblity to mark eax with a FakeDef.
1211class InstX8632Cmpxchg : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001212 InstX8632Cmpxchg() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001213 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1214 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
1215
Jan Vounga3a01a22014-07-14 10:32:41 -07001216public:
1217 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1218 Variable *Desired, bool Locked) {
1219 return new (Func->allocate<InstX8632Cmpxchg>())
1220 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
1221 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001222 void emit(const Cfg *Func) const override;
1223 void emitIAS(const Cfg *Func) const override;
1224 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001225 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
1226
1227private:
1228 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1229 Variable *Desired, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001230 ~InstX8632Cmpxchg() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001231};
1232
1233// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
1234// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
1235// If not, ZF is cleared and <m64> is copied to edx:eax.
1236// The caller is responsible for inserting FakeDefs to mark edx
1237// and eax as modified.
1238// <m64> must be a memory operand.
1239class InstX8632Cmpxchg8b : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001240 InstX8632Cmpxchg8b() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001241 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1242 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
1243
Jan Vounga3a01a22014-07-14 10:32:41 -07001244public:
Jan Voung03532e52014-09-23 13:32:18 -07001245 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
Jan Vounga3a01a22014-07-14 10:32:41 -07001246 Variable *Edx, Variable *Eax, Variable *Ecx,
1247 Variable *Ebx, bool Locked) {
1248 return new (Func->allocate<InstX8632Cmpxchg8b>())
1249 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
1250 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001251 void emit(const Cfg *Func) const override;
1252 void emitIAS(const Cfg *Func) const override;
1253 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001254 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
1255
1256private:
Jan Voung03532e52014-09-23 13:32:18 -07001257 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
Jan Vounga3a01a22014-07-14 10:32:41 -07001258 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001259 ~InstX8632Cmpxchg8b() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001260};
1261
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001262// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
1263// as appropriate. s=float, d=double, i=int. X and Y are determined
1264// from dest/src types. Sign and zero extension on the integer
1265// operand needs to be done separately.
1266class InstX8632Cvt : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001267 InstX8632Cvt() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001268 InstX8632Cvt(const InstX8632Cvt &) = delete;
1269 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
1270
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001271public:
Jan Voung699bf022014-10-08 13:52:10 -07001272 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
Jim Stichnothb63cd882014-09-08 10:47:23 -07001273 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voung699bf022014-10-08 13:52:10 -07001274 CvtVariant Variant) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001275 return new (Func->allocate<InstX8632Cvt>())
Jan Voung699bf022014-10-08 13:52:10 -07001276 InstX8632Cvt(Func, Dest, Source, Variant);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001277 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001278 void emit(const Cfg *Func) const override;
Jan Voung699bf022014-10-08 13:52:10 -07001279 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001280 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001281 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
Jan Voung699bf022014-10-08 13:52:10 -07001282 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001283
1284private:
Jan Voung699bf022014-10-08 13:52:10 -07001285 CvtVariant Variant;
1286 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001287 ~InstX8632Cvt() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001288};
1289
1290// cmp - Integer compare instruction.
1291class InstX8632Icmp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001292 InstX8632Icmp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001293 InstX8632Icmp(const InstX8632Icmp &) = delete;
1294 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
1295
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001296public:
1297 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1298 return new (Func->allocate<InstX8632Icmp>())
1299 InstX8632Icmp(Func, Src1, Src2);
1300 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001301 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001302 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001303 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001304 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
1305
1306private:
1307 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001308 ~InstX8632Icmp() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001309};
1310
1311// ucomiss/ucomisd - floating-point compare instruction.
1312class InstX8632Ucomiss : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001313 InstX8632Ucomiss() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001314 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1315 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
1316
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001317public:
1318 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1319 return new (Func->allocate<InstX8632Ucomiss>())
1320 InstX8632Ucomiss(Func, Src1, Src2);
1321 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001322 void emit(const Cfg *Func) const override;
1323 void emitIAS(const Cfg *Func) const override;
1324 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001325 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
1326
1327private:
1328 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001329 ~InstX8632Ucomiss() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001330};
1331
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001332// UD2 instruction.
1333class InstX8632UD2 : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001334 InstX8632UD2() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001335 InstX8632UD2(const InstX8632UD2 &) = delete;
1336 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
1337
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001338public:
1339 static InstX8632UD2 *create(Cfg *Func) {
1340 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
1341 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001342 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001343 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001344 void dump(const Cfg *Func) const override;
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001345 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
1346
1347private:
Jim Stichnothc6ead202015-02-24 09:30:30 -08001348 explicit InstX8632UD2(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001349 ~InstX8632UD2() override {}
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001350};
1351
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001352// Test instruction.
1353class InstX8632Test : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001354 InstX8632Test() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001355 InstX8632Test(const InstX8632Test &) = delete;
1356 InstX8632Test &operator=(const InstX8632Test &) = delete;
1357
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001358public:
1359 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
1360 return new (Func->allocate<InstX8632Test>())
1361 InstX8632Test(Func, Source1, Source2);
1362 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001363 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001364 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001365 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001366 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
1367
1368private:
1369 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001370 ~InstX8632Test() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001371};
1372
Jan Voung5cd240d2014-06-25 10:36:46 -07001373// Mfence instruction.
1374class InstX8632Mfence : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001375 InstX8632Mfence() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001376 InstX8632Mfence(const InstX8632Mfence &) = delete;
1377 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
1378
Jan Voung5cd240d2014-06-25 10:36:46 -07001379public:
1380 static InstX8632Mfence *create(Cfg *Func) {
1381 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
1382 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001383 void emit(const Cfg *Func) const override;
Jan Voungaf2780c2014-09-26 11:14:30 -07001384 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001385 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001386 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
1387
1388private:
Jim Stichnothc6ead202015-02-24 09:30:30 -08001389 explicit InstX8632Mfence(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001390 ~InstX8632Mfence() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001391};
1392
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001393// This is essentially a "mov" instruction with an OperandX8632Mem
1394// operand instead of Variable as the destination. It's important
1395// for liveness that there is no Dest operand.
1396class InstX8632Store : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001397 InstX8632Store() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001398 InstX8632Store(const InstX8632Store &) = delete;
1399 InstX8632Store &operator=(const InstX8632Store &) = delete;
1400
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001401public:
1402 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1403 return new (Func->allocate<InstX8632Store>())
1404 InstX8632Store(Func, Value, Mem);
1405 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001406 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -07001407 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001408 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001409 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
1410
1411private:
1412 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001413 ~InstX8632Store() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001414};
1415
Jan Vounge4dc61b2014-10-06 08:53:52 -07001416// This is essentially a vector "mov" instruction with an OperandX8632Mem
1417// operand instead of Variable as the destination. It's important
1418// for liveness that there is no Dest operand. The source must be an
1419// Xmm register, since Dest is mem.
Matt Wala105b7042014-08-11 19:56:19 -07001420class InstX8632StoreP : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001421 InstX8632StoreP() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001422 InstX8632StoreP(const InstX8632StoreP &) = delete;
1423 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
1424
Matt Wala105b7042014-08-11 19:56:19 -07001425public:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001426 static InstX8632StoreP *create(Cfg *Func, Variable *Value,
1427 OperandX8632Mem *Mem) {
Matt Wala105b7042014-08-11 19:56:19 -07001428 return new (Func->allocate<InstX8632StoreP>())
1429 InstX8632StoreP(Func, Value, Mem);
1430 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001431 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001432 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001433 void dump(const Cfg *Func) const override;
Matt Wala105b7042014-08-11 19:56:19 -07001434 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
1435
1436private:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001437 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001438 ~InstX8632StoreP() override {}
Matt Wala105b7042014-08-11 19:56:19 -07001439};
1440
Jan Voung5cd240d2014-06-25 10:36:46 -07001441class InstX8632StoreQ : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001442 InstX8632StoreQ() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001443 InstX8632StoreQ(const InstX8632StoreQ &) = delete;
1444 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
1445
Jan Voung5cd240d2014-06-25 10:36:46 -07001446public:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001447 static InstX8632StoreQ *create(Cfg *Func, Variable *Value,
1448 OperandX8632Mem *Mem) {
Jan Voung5cd240d2014-06-25 10:36:46 -07001449 return new (Func->allocate<InstX8632StoreQ>())
1450 InstX8632StoreQ(Func, Value, Mem);
1451 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001452 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001453 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001454 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001455 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1456
1457private:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001458 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001459 ~InstX8632StoreQ() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001460};
1461
Matt Walac3302742014-08-15 16:21:56 -07001462// Nop instructions of varying length
1463class InstX8632Nop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001464 InstX8632Nop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001465 InstX8632Nop(const InstX8632Nop &) = delete;
1466 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
1467
Matt Walac3302742014-08-15 16:21:56 -07001468public:
1469 // TODO: Replace with enum.
1470 typedef unsigned NopVariant;
1471
1472 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1473 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1474 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001475 void emit(const Cfg *Func) const override;
1476 void emitIAS(const Cfg *Func) const override;
1477 void dump(const Cfg *Func) const override;
Matt Walac3302742014-08-15 16:21:56 -07001478 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1479
1480private:
1481 InstX8632Nop(Cfg *Func, SizeT Length);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001482 ~InstX8632Nop() override {}
Matt Walac3302742014-08-15 16:21:56 -07001483
1484 NopVariant Variant;
1485};
1486
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001487// Fld - load a value onto the x87 FP stack.
1488class InstX8632Fld : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001489 InstX8632Fld() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001490 InstX8632Fld(const InstX8632Fld &) = delete;
1491 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
1492
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001493public:
1494 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1495 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1496 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001497 void emit(const Cfg *Func) const override;
Jan Voung479e5632014-10-08 21:05:27 -07001498 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001499 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001500 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1501
1502private:
1503 InstX8632Fld(Cfg *Func, Operand *Src);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001504 ~InstX8632Fld() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001505};
1506
1507// Fstp - store x87 st(0) into memory and pop st(0).
1508class InstX8632Fstp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001509 InstX8632Fstp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001510 InstX8632Fstp(const InstX8632Fstp &) = delete;
1511 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
1512
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001513public:
1514 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1515 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1516 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001517 void emit(const Cfg *Func) const override;
Jan Voung479e5632014-10-08 21:05:27 -07001518 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001519 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001520 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
1521
1522private:
1523 InstX8632Fstp(Cfg *Func, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001524 ~InstX8632Fstp() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001525};
1526
1527class InstX8632Pop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001528 InstX8632Pop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001529 InstX8632Pop(const InstX8632Pop &) = delete;
1530 InstX8632Pop &operator=(const InstX8632Pop &) = delete;
1531
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001532public:
1533 static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
1534 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
1535 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001536 void emit(const Cfg *Func) const override;
1537 void emitIAS(const Cfg *Func) const override;
1538 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001539 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1540
1541private:
1542 InstX8632Pop(Cfg *Func, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001543 ~InstX8632Pop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001544};
1545
1546class InstX8632Push : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001547 InstX8632Push() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001548 InstX8632Push(const InstX8632Push &) = delete;
1549 InstX8632Push &operator=(const InstX8632Push &) = delete;
1550
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001551public:
Jan Voung0b9eee52014-10-07 11:20:10 -07001552 static InstX8632Push *create(Cfg *Func, Variable *Source) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001553 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001554 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001555 void emit(const Cfg *Func) const override;
Jan Voung0b9eee52014-10-07 11:20:10 -07001556 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001557 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001558 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1559
1560private:
Jan Voung0b9eee52014-10-07 11:20:10 -07001561 InstX8632Push(Cfg *Func, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001562 ~InstX8632Push() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001563};
1564
1565// Ret instruction. Currently only supports the "ret" version that
1566// does not pop arguments. This instruction takes a Source operand
1567// (for non-void returning functions) for liveness analysis, though
1568// a FakeUse before the ret would do just as well.
1569class InstX8632Ret : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001570 InstX8632Ret() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001571 InstX8632Ret(const InstX8632Ret &) = delete;
1572 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
1573
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001574public:
Jim Stichnothae953202014-12-20 06:17:49 -08001575 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001576 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1577 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001578 void emit(const Cfg *Func) const override;
1579 void emitIAS(const Cfg *Func) const override;
1580 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001581 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1582
1583private:
1584 InstX8632Ret(Cfg *Func, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001585 ~InstX8632Ret() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001586};
1587
Jim Stichnothf48b3202015-05-04 10:22:17 -07001588// Conditional set-byte instruction.
1589class InstX8632Setcc : public InstX8632 {
1590 InstX8632Setcc() = delete;
1591 InstX8632Setcc(const InstX8632Cmov &) = delete;
1592 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete;
1593
1594public:
1595 static InstX8632Setcc *create(Cfg *Func, Variable *Dest,
1596 CondX86::BrCond Cond) {
1597 return new (Func->allocate<InstX8632Setcc>())
1598 InstX8632Setcc(Func, Dest, Cond);
1599 }
1600 void emit(const Cfg *Func) const override;
1601 void emitIAS(const Cfg *Func) const override;
1602 void dump(const Cfg *Func) const override;
1603 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); }
1604
1605private:
1606 InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond);
1607 ~InstX8632Setcc() override {}
1608
1609 const CondX86::BrCond Condition;
1610};
1611
Jan Voung5cd240d2014-06-25 10:36:46 -07001612// Exchanging Add instruction. Exchanges the first operand (destination
1613// operand) with the second operand (source operand), then loads the sum
1614// of the two values into the destination operand. The destination may be
1615// a register or memory, while the source must be a register.
1616//
1617// Both the dest and source are updated. The caller should then insert a
1618// FakeDef to reflect the second udpate.
Jan Vounga3a01a22014-07-14 10:32:41 -07001619class InstX8632Xadd : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001620 InstX8632Xadd() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001621 InstX8632Xadd(const InstX8632Xadd &) = delete;
1622 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
1623
Jan Voung5cd240d2014-06-25 10:36:46 -07001624public:
1625 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1626 bool Locked) {
1627 return new (Func->allocate<InstX8632Xadd>())
1628 InstX8632Xadd(Func, Dest, Source, Locked);
1629 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001630 void emit(const Cfg *Func) const override;
1631 void emitIAS(const Cfg *Func) const override;
1632 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001633 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1634
1635private:
Jan Voung5cd240d2014-06-25 10:36:46 -07001636 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001637 ~InstX8632Xadd() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001638};
1639
Jan Vounga3a01a22014-07-14 10:32:41 -07001640// Exchange instruction. Exchanges the first operand (destination
1641// operand) with the second operand (source operand). At least one of
1642// the operands must be a register (and the other can be reg or mem).
1643// Both the Dest and Source are updated. If there is a memory operand,
1644// then the instruction is automatically "locked" without the need for
1645// a lock prefix.
1646class InstX8632Xchg : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001647 InstX8632Xchg() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001648 InstX8632Xchg(const InstX8632Xchg &) = delete;
1649 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
1650
Jan Vounga3a01a22014-07-14 10:32:41 -07001651public:
1652 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1653 return new (Func->allocate<InstX8632Xchg>())
1654 InstX8632Xchg(Func, Dest, Source);
1655 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001656 void emit(const Cfg *Func) const override;
1657 void emitIAS(const Cfg *Func) const override;
1658 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001659 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
1660
1661private:
1662 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001663 ~InstX8632Xchg() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001664};
1665
Jim Stichnoth6e992142014-07-30 14:45:20 -07001666// Declare partial template specializations of emit() methods that
1667// already have default implementations. Without this, there is the
1668// possibility of ODR violations and link errors.
1669template <> void InstX8632Addss::emit(const Cfg *Func) const;
1670template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
Matt Wala51e8cfb2014-08-08 08:39:40 -07001671template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
Jim Stichnoth6e992142014-07-30 14:45:20 -07001672template <> void InstX8632Div::emit(const Cfg *Func) const;
1673template <> void InstX8632Divss::emit(const Cfg *Func) const;
1674template <> void InstX8632Idiv::emit(const Cfg *Func) const;
1675template <> void InstX8632Imul::emit(const Cfg *Func) const;
1676template <> void InstX8632Lea::emit(const Cfg *Func) const;
1677template <> void InstX8632Mulss::emit(const Cfg *Func) const;
1678template <> void InstX8632Padd::emit(const Cfg *Func) const;
1679template <> void InstX8632Pblendvb::emit(const Cfg *Func) const;
1680template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const;
1681template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const;
1682template <> void InstX8632Pextr::emit(const Cfg *Func) const;
1683template <> void InstX8632Pinsr::emit(const Cfg *Func) const;
1684template <> void InstX8632Pmull::emit(const Cfg *Func) const;
1685template <> void InstX8632Pmuludq::emit(const Cfg *Func) const;
1686template <> void InstX8632Psll::emit(const Cfg *Func) const;
1687template <> void InstX8632Psra::emit(const Cfg *Func) const;
Jim Stichnoth8c980d02015-03-19 13:01:50 -07001688template <> void InstX8632Psrl::emit(const Cfg *Func) const;
Jim Stichnoth6e992142014-07-30 14:45:20 -07001689template <> void InstX8632Psub::emit(const Cfg *Func) const;
1690template <> void InstX8632Sqrtss::emit(const Cfg *Func) const;
1691template <> void InstX8632Subss::emit(const Cfg *Func) const;
1692
Jan Voungd026c442014-10-13 14:06:50 -07001693template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001694template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const;
Jan Voungaf2780c2014-09-26 11:14:30 -07001695template <> void InstX8632Div::emitIAS(const Cfg *Func) const;
1696template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001697template <> void InstX8632Imul::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001698template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const;
Jan Voung3b43b892014-09-24 13:32:39 -07001699template <> void InstX8632Movd::emitIAS(const Cfg *Func) const;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001700template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const;
Jan Voungd026c442014-10-13 14:06:50 -07001701template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001702template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const;
1703template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const;
Jan Voung39d4aca2014-10-15 15:16:54 -07001704template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const;
1705template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const;
Jan Voung8bcca042014-10-03 21:58:02 -07001706template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001707template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const;
1708template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const;
Jan Voung03532e52014-09-23 13:32:18 -07001709
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001710} // end of namespace Ice
1711
1712#endif // SUBZERO_SRC_ICEINSTX8632_H