blob: 767d8c978cadb7634e746e639f5918c9fed3c77b [file] [log] [blame]
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001//===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===//
2//
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 {
33public:
34 enum OperandKindX8632 {
35 k__Start = Operand::kTarget,
36 kMem,
37 kSplit
38 };
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 {
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -070041 Str << "<OperandX8632>";
42 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070043
44protected:
45 OperandX8632(OperandKindX8632 Kind, Type Ty)
46 : Operand(static_cast<OperandKind>(Kind), Ty) {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -070047 ~OperandX8632() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070048
49private:
Jim Stichnoth0795ba02014-10-01 14:23:01 -070050 OperandX8632(const OperandX8632 &) = delete;
51 OperandX8632 &operator=(const OperandX8632 &) = delete;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070052};
53
54// OperandX8632Mem represents the m32 addressing mode, with optional
55// base and index registers, a constant offset, and a fixed shift
56// value for the index register.
57class OperandX8632Mem : public OperandX8632 {
58public:
Jan Voung3bd9f1a2014-06-18 10:50:57 -070059 enum SegmentRegisters {
60 DefaultSegment = -1,
Jan Vounga3a01a22014-07-14 10:32:41 -070061#define X(val, name) val,
62 SEG_REGX8632_TABLE
Jan Voung3bd9f1a2014-06-18 10:50:57 -070063#undef X
64 SegReg_NUM
65 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070066 static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base,
67 Constant *Offset, Variable *Index = NULL,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070068 uint16_t Shift = 0,
69 SegmentRegisters SegmentReg = DefaultSegment) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070070 return new (Func->allocate<OperandX8632Mem>())
Jan Voung3bd9f1a2014-06-18 10:50:57 -070071 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070072 }
73 Variable *getBase() const { return Base; }
74 Constant *getOffset() const { return Offset; }
75 Variable *getIndex() const { return Index; }
Jan Voung3bd9f1a2014-06-18 10:50:57 -070076 uint16_t getShift() const { return Shift; }
77 SegmentRegisters getSegmentRegister() const { return SegmentReg; }
Jan Voung8acded02014-09-22 18:02:25 -070078 x86::Address toAsmAddress(Assembler *Asm) const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070079 void emit(const Cfg *Func) const override;
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -070080 using OperandX8632::dump;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070081 void dump(const Cfg *Func, Ostream &Str) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070082
83 static bool classof(const Operand *Operand) {
84 return Operand->getKind() == static_cast<OperandKind>(kMem);
85 }
86
87private:
88 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070089 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
Jim Stichnoth0795ba02014-10-01 14:23:01 -070090 OperandX8632Mem(const OperandX8632Mem &) = delete;
91 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
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 {
107public:
108 enum Portion {
109 Low,
110 High
111 };
112 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
113 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
114 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700115 void emit(const Cfg *Func) const override;
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -0700116 using OperandX8632::dump;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700117 void dump(const Cfg *Func, Ostream &Str) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700118
119 static bool classof(const Operand *Operand) {
120 return Operand->getKind() == static_cast<OperandKind>(kSplit);
121 }
122
123private:
124 VariableSplit(Cfg *Func, Variable *Var, Portion Part)
125 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) {
126 assert(Var->getType() == IceType_f64);
127 Vars = Func->allocateArrayOf<Variable *>(1);
128 Vars[0] = Var;
129 NumVars = 1;
130 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700131 VariableSplit(const VariableSplit &) = delete;
132 VariableSplit &operator=(const VariableSplit &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700133 ~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700134 Cfg *Func; // Held only for the destructor.
135 Variable *Var;
136 Portion Part;
137};
138
Jim Stichnoth800dab22014-09-20 12:25:02 -0700139// SpillVariable decorates a Variable by linking it to another
140// Variable. When stack frame offsets are computed, the SpillVariable
141// is given a distinct stack slot only if its linked Variable has a
142// register. If the linked Variable has a stack slot, then the
143// Variable and SpillVariable share that slot.
144class SpillVariable : public Variable {
145public:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700146 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index,
147 const IceString &Name) {
148 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index, Name);
Jim Stichnoth800dab22014-09-20 12:25:02 -0700149 }
150 const static OperandKind SpillVariableKind =
151 static_cast<OperandKind>(kVariable_Target);
152 static bool classof(const Operand *Operand) {
153 return Operand->getKind() == SpillVariableKind;
154 }
155 void setLinkedTo(Variable *Var) { LinkedTo = Var; }
156 Variable *getLinkedTo() const { return LinkedTo; }
157 // Inherit dump() and emit() from Variable.
158private:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700159 SpillVariable(Type Ty, SizeT Index, const IceString &Name)
160 : Variable(SpillVariableKind, Ty, Index, Name), LinkedTo(NULL) {}
Jim Stichnoth800dab22014-09-20 12:25:02 -0700161 Variable *LinkedTo;
162};
163
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700164class InstX8632 : public InstTarget {
165public:
166 enum InstKindX8632 {
167 k__Start = Inst::Target,
168 Adc,
169 Add,
Matt Wala8d1072e2014-07-11 15:43:51 -0700170 Addps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700171 Addss,
Matt Wala105b7042014-08-11 19:56:19 -0700172 Adjuststack,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700173 And,
Matt Wala0a450512014-07-30 12:44:39 -0700174 Blendvps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700175 Br,
Jan Vounge4da26f2014-07-15 17:52:39 -0700176 Bsf,
177 Bsr,
Jan Voung7fa813b2014-07-18 13:01:08 -0700178 Bswap,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700179 Call,
Matt Walaafeaee42014-08-07 13:47:30 -0700180 Cbwdq,
Jan Vounge4da26f2014-07-15 17:52:39 -0700181 Cmov,
Matt Walace0ca8f2014-07-24 12:34:20 -0700182 Cmpps,
Jan Vounga3a01a22014-07-14 10:32:41 -0700183 Cmpxchg,
184 Cmpxchg8b,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700185 Cvt,
186 Div,
Matt Wala8d1072e2014-07-11 15:43:51 -0700187 Divps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700188 Divss,
189 Fld,
190 Fstp,
191 Icmp,
192 Idiv,
193 Imul,
Matt Wala0a450512014-07-30 12:44:39 -0700194 Insertps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700195 Label,
Matt Wala49889232014-07-18 12:45:09 -0700196 Lea,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700197 Load,
Jan Voung5cd240d2014-06-25 10:36:46 -0700198 Mfence,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700199 Mov,
Matt Wala49889232014-07-18 12:45:09 -0700200 Movd,
Matt Wala928f1292014-07-07 16:50:46 -0700201 Movp,
Jan Voung5cd240d2014-06-25 10:36:46 -0700202 Movq,
Matt Wala49889232014-07-18 12:45:09 -0700203 Movss,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700204 Movsx,
205 Movzx,
206 Mul,
Matt Wala8d1072e2014-07-11 15:43:51 -0700207 Mulps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700208 Mulss,
Jan Vounga3a01a22014-07-14 10:32:41 -0700209 Neg,
Matt Walac3302742014-08-15 16:21:56 -0700210 Nop,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700211 Or,
Matt Wala7fa22d82014-07-17 12:41:31 -0700212 Padd,
Matt Wala83b80362014-07-16 10:21:30 -0700213 Pand,
Matt Wala9cb61e22014-07-24 09:44:42 -0700214 Pandn,
Matt Wala0a450512014-07-30 12:44:39 -0700215 Pblendvb,
Matt Wala83b80362014-07-16 10:21:30 -0700216 Pcmpeq,
217 Pcmpgt,
Matt Wala0a450512014-07-30 12:44:39 -0700218 Pextr,
219 Pinsr,
220 Pmull,
Matt Wala7fa22d82014-07-17 12:41:31 -0700221 Pmuludq,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700222 Pop,
Matt Wala7fa22d82014-07-17 12:41:31 -0700223 Por,
224 Pshufd,
Matt Wala83b80362014-07-16 10:21:30 -0700225 Psll,
226 Psra,
227 Psub,
Matt Wala7fa22d82014-07-17 12:41:31 -0700228 Push,
Matt Wala928f1292014-07-07 16:50:46 -0700229 Pxor,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700230 Ret,
Jan Voung7fa813b2014-07-18 13:01:08 -0700231 Rol,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700232 Sar,
233 Sbb,
234 Shl,
235 Shld,
236 Shr,
237 Shrd,
Matt Wala7fa22d82014-07-17 12:41:31 -0700238 Shufps,
Jan Voungf37fbbe2014-07-09 16:13:13 -0700239 Sqrtss,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700240 Store,
Matt Wala105b7042014-08-11 19:56:19 -0700241 StoreP,
Jan Voung5cd240d2014-06-25 10:36:46 -0700242 StoreQ,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700243 Sub,
Matt Wala8d1072e2014-07-11 15:43:51 -0700244 Subps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700245 Subss,
246 Test,
247 Ucomiss,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700248 UD2,
Jan Voung5cd240d2014-06-25 10:36:46 -0700249 Xadd,
Jan Vounga3a01a22014-07-14 10:32:41 -0700250 Xchg,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700251 Xor
252 };
Jan Vounge4da26f2014-07-15 17:52:39 -0700253
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700254 static const char *getWidthString(Type Ty);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700255 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700256
257protected:
258 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
259 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700260 ~InstX8632() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700261 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
262 return Inst->getKind() == static_cast<InstKind>(MyKind);
263 }
264
265private:
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700266 InstX8632(const InstX8632 &) = delete;
267 InstX8632 &operator=(const InstX8632 &) = delete;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700268};
269
270// InstX8632Label represents an intra-block label that is the
271// target of an intra-block branch. These are used for lowering i1
272// calculations, Select instructions, and 64-bit compares on a 32-bit
273// architecture, without basic block splitting. Basic block splitting
274// is not so desirable for several reasons, one of which is the impact
275// on decisions based on whether a variable's live range spans
276// multiple basic blocks.
277//
278// Intra-block control flow must be used with caution. Consider the
279// sequence for "c = (a >= b ? x : y)".
280// cmp a, b
281// br lt, L1
282// mov c, x
283// jmp L2
284// L1:
285// mov c, y
286// L2:
287//
288// Labels L1 and L2 are intra-block labels. Without knowledge of the
289// intra-block control flow, liveness analysis will determine the "mov
290// c, x" instruction to be dead. One way to prevent this is to insert
291// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
292// instructions, e.g.:
293//
294// cmp a, b
295// br lt, L1
296// mov c, x
297// jmp L2
298// FakeUse(c)
299// L1:
300// mov c, y
301// L2:
302//
303// The down-side is that "mov c, x" can never be dead-code eliminated
304// even if there are no uses of c. As unlikely as this situation is,
305// it may be prevented by running dead code elimination before
306// lowering.
307class InstX8632Label : public InstX8632 {
308public:
309 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
310 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
311 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700312 uint32_t getEmitInstCount() const override { return 0; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700313 IceString getName(const Cfg *Func) const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700314 void emit(const Cfg *Func) const override;
315 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700316
317private:
318 InstX8632Label(Cfg *Func, TargetX8632 *Target);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700319 InstX8632Label(const InstX8632Label &) = delete;
320 InstX8632Label &operator=(const InstX8632Label &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700321 ~InstX8632Label() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700322 SizeT Number; // used only for unique label string generation
323};
324
325// Conditional and unconditional branch instruction.
326class InstX8632Br : public InstX8632 {
327public:
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700328 // Create a conditional branch to a node.
329 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
Jan Voungbd385e42014-09-18 18:18:10 -0700330 CfgNode *TargetFalse, CondX86::BrCond Condition) {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700331 const InstX8632Label *NoLabel = NULL;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700332 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700333 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700334 }
335 // Create an unconditional branch to a node.
336 static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700337 const CfgNode *NoCondTarget = NULL;
338 const InstX8632Label *NoLabel = NULL;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700339 return new (Func->allocate<InstX8632Br>())
Jan Voungbd385e42014-09-18 18:18:10 -0700340 InstX8632Br(Func, NoCondTarget, Target, NoLabel, CondX86::Br_None);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700341 }
342 // Create a non-terminator conditional branch to a node, with a
343 // fallthrough to the next instruction in the current node. This is
344 // used for switch lowering.
Jan Voungbd385e42014-09-18 18:18:10 -0700345 static InstX8632Br *create(Cfg *Func, CfgNode *Target,
346 CondX86::BrCond Condition) {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700347 const CfgNode *NoUncondTarget = NULL;
348 const InstX8632Label *NoLabel = NULL;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700349 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700350 InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700351 }
352 // Create a conditional intra-block branch (or unconditional, if
Jim Stichnoth18735602014-09-16 19:59:35 -0700353 // Condition==Br_None) to a label in the current block.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700354 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
Jan Voungbd385e42014-09-18 18:18:10 -0700355 CondX86::BrCond Condition) {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700356 const CfgNode *NoCondTarget = NULL;
357 const CfgNode *NoUncondTarget = NULL;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700358 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700359 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700360 }
Jim Stichnothff9c7062014-09-18 04:50:49 -0700361 const CfgNode *getTargetTrue() const { return TargetTrue; }
362 const CfgNode *getTargetFalse() const { return TargetFalse; }
363 bool optimizeBranch(const CfgNode *NextNode);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700364 uint32_t getEmitInstCount() const override {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700365 uint32_t Sum = 0;
Jim Stichnoth18735602014-09-16 19:59:35 -0700366 if (Label)
Jim Stichnothff9c7062014-09-18 04:50:49 -0700367 ++Sum;
368 if (getTargetTrue())
369 ++Sum;
Jim Stichnoth18735602014-09-16 19:59:35 -0700370 if (getTargetFalse())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700371 ++Sum;
372 return Sum;
Jim Stichnoth18735602014-09-16 19:59:35 -0700373 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700374 void emit(const Cfg *Func) const override;
375 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700376 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
377
378private:
Jim Stichnothff9c7062014-09-18 04:50:49 -0700379 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
Jan Voungbd385e42014-09-18 18:18:10 -0700380 const InstX8632Label *Label, CondX86::BrCond Condition);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700381 InstX8632Br(const InstX8632Br &) = delete;
382 InstX8632Br &operator=(const InstX8632Br &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700383 ~InstX8632Br() override {}
Jan Voungbd385e42014-09-18 18:18:10 -0700384 CondX86::BrCond Condition;
Jim Stichnothff9c7062014-09-18 04:50:49 -0700385 const CfgNode *TargetTrue;
386 const CfgNode *TargetFalse;
387 const InstX8632Label *Label; // Intra-block branch target
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700388};
389
Matt Wala105b7042014-08-11 19:56:19 -0700390// AdjustStack instruction - subtracts esp by the given amount and
391// updates the stack offset during code emission.
392class InstX8632AdjustStack : public InstX8632 {
393public:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700394 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
Matt Wala105b7042014-08-11 19:56:19 -0700395 return new (Func->allocate<InstX8632AdjustStack>())
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700396 InstX8632AdjustStack(Func, Amount, Esp);
Matt Wala105b7042014-08-11 19:56:19 -0700397 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700398 void emit(const Cfg *Func) const override;
399 void emitIAS(const Cfg *Func) const override;
400 void dump(const Cfg *Func) const override;
Matt Wala105b7042014-08-11 19:56:19 -0700401 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
402
403private:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700404 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700405 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
406 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
Matt Wala105b7042014-08-11 19:56:19 -0700407 SizeT Amount;
408};
409
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700410// Call instruction. Arguments should have already been pushed.
411class InstX8632Call : public InstX8632 {
412public:
413 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
414 return new (Func->allocate<InstX8632Call>())
415 InstX8632Call(Func, Dest, CallTarget);
416 }
417 Operand *getCallTarget() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700418 void emit(const Cfg *Func) const override;
419 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700420 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
421
422private:
423 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700424 InstX8632Call(const InstX8632Call &) = delete;
425 InstX8632Call &operator=(const InstX8632Call &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700426 ~InstX8632Call() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700427};
428
Jan Voung3b43b892014-09-24 13:32:39 -0700429// Emit a one-operand (GPR) instruction.
Jan Voungaf2780c2014-09-26 11:14:30 -0700430void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
431 const x86::AssemblerX86::GPREmitterOneOp &Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700432
Jan Voung7fa813b2014-07-18 13:01:08 -0700433// Instructions of the form x := op(x).
434template <InstX8632::InstKindX8632 K>
Jan Voung3b43b892014-09-24 13:32:39 -0700435class InstX8632InplaceopGPR : public InstX8632 {
Jan Voung7fa813b2014-07-18 13:01:08 -0700436public:
Jan Voung3b43b892014-09-24 13:32:39 -0700437 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) {
438 return new (Func->allocate<InstX8632InplaceopGPR>())
439 InstX8632InplaceopGPR(Func, SrcDest);
Jan Voung7fa813b2014-07-18 13:01:08 -0700440 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700441 void emit(const Cfg *Func) const override {
Jan Voung7fa813b2014-07-18 13:01:08 -0700442 Ostream &Str = Func->getContext()->getStrEmit();
443 assert(getSrcSize() == 1);
444 Str << "\t" << Opcode << "\t";
445 getSrc(0)->emit(Func);
446 Str << "\n";
447 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700448 void emitIAS(const Cfg *Func) const override {
Jan Voung3b43b892014-09-24 13:32:39 -0700449 assert(getSrcSize() == 1);
450 const Variable *Var = getDest();
451 Type Ty = Var->getType();
Jan Voungaf2780c2014-09-26 11:14:30 -0700452 emitIASOpTyGPR(Func, Ty, Var, Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700453 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700454 void dump(const Cfg *Func) const override {
Jan Voung7fa813b2014-07-18 13:01:08 -0700455 Ostream &Str = Func->getContext()->getStrDump();
456 dumpDest(Func);
457 Str << " = " << Opcode << "." << getDest()->getType() << " ";
458 dumpSources(Func);
459 }
460 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
461
462private:
Jan Voung3b43b892014-09-24 13:32:39 -0700463 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest)
Jan Voung7fa813b2014-07-18 13:01:08 -0700464 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
465 addSource(SrcDest);
466 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700467 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
468 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700469 ~InstX8632InplaceopGPR() override {}
Jan Voung7fa813b2014-07-18 13:01:08 -0700470 static const char *Opcode;
Jan Voung3b43b892014-09-24 13:32:39 -0700471 static const x86::AssemblerX86::GPREmitterOneOp Emitter;
Jan Voung7fa813b2014-07-18 13:01:08 -0700472};
473
Jan Voung3b43b892014-09-24 13:32:39 -0700474// Emit a two-operand (GPR) instruction, where the dest operand is a
475// Variable that's guaranteed to be a register.
476void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
477 const Operand *Src,
478 const x86::AssemblerX86::GPREmitterRegOp &Emitter);
479
Jan Voung7fa813b2014-07-18 13:01:08 -0700480// Instructions of the form x := op(y)
Jan Vounga3a01a22014-07-14 10:32:41 -0700481template <InstX8632::InstKindX8632 K>
Jan Voung3b43b892014-09-24 13:32:39 -0700482class InstX8632UnaryopGPR : public InstX8632 {
Jan Vounga3a01a22014-07-14 10:32:41 -0700483public:
Jan Voung3b43b892014-09-24 13:32:39 -0700484 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
485 return new (Func->allocate<InstX8632UnaryopGPR>())
486 InstX8632UnaryopGPR(Func, Dest, Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700487 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700488 void emit(const Cfg *Func) const override {
Jan Vounga3a01a22014-07-14 10:32:41 -0700489 Ostream &Str = Func->getContext()->getStrEmit();
490 assert(getSrcSize() == 1);
491 Str << "\t" << Opcode << "\t";
Jan Vounge4da26f2014-07-15 17:52:39 -0700492 getDest()->emit(Func);
493 Str << ", ";
Jan Vounga3a01a22014-07-14 10:32:41 -0700494 getSrc(0)->emit(Func);
495 Str << "\n";
496 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700497 void emitIAS(const Cfg *Func) const override {
Jan Voung3b43b892014-09-24 13:32:39 -0700498 assert(getSrcSize() == 1);
499 const Variable *Var = getDest();
500 Type Ty = Var->getType();
501 const Operand *Src = getSrc(0);
502 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter);
503 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700504 void dump(const Cfg *Func) const override {
Jan Vounga3a01a22014-07-14 10:32:41 -0700505 Ostream &Str = Func->getContext()->getStrDump();
506 dumpDest(Func);
507 Str << " = " << Opcode << "." << getDest()->getType() << " ";
508 dumpSources(Func);
509 }
510 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
511
512private:
Jan Voung3b43b892014-09-24 13:32:39 -0700513 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
Jan Vounge4da26f2014-07-15 17:52:39 -0700514 : InstX8632(Func, K, 1, Dest) {
515 addSource(Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700516 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700517 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
518 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700519 ~InstX8632UnaryopGPR() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -0700520 static const char *Opcode;
Jan Voung3b43b892014-09-24 13:32:39 -0700521 static const x86::AssemblerX86::GPREmitterRegOp Emitter;
Jan Vounga3a01a22014-07-14 10:32:41 -0700522};
523
Jan Voung8acded02014-09-22 18:02:25 -0700524void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
525 const Operand *Src,
Jan Voung3b43b892014-09-24 13:32:39 -0700526 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700527
528template <InstX8632::InstKindX8632 K>
529class InstX8632UnaryopXmm : public InstX8632 {
530public:
531 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) {
532 return new (Func->allocate<InstX8632UnaryopXmm>())
533 InstX8632UnaryopXmm(Func, Dest, Src);
534 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700535 void emit(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700536 Ostream &Str = Func->getContext()->getStrEmit();
537 assert(getSrcSize() == 1);
538 Str << "\t" << Opcode << "\t";
539 getDest()->emit(Func);
540 Str << ", ";
541 getSrc(0)->emit(Func);
542 Str << "\n";
543 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700544 void emitIAS(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700545 Type Ty = getDest()->getType();
546 assert(getSrcSize() == 1);
547 emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(0), Emitter);
548 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700549 void dump(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700550 Ostream &Str = Func->getContext()->getStrDump();
551 dumpDest(Func);
552 Str << " = " << Opcode << "." << getDest()->getType() << " ";
553 dumpSources(Func);
554 }
555 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
556
557private:
558 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
559 : InstX8632(Func, K, 1, Dest) {
560 addSource(Src);
561 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700562 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
563 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700564 ~InstX8632UnaryopXmm() override {}
Jan Voung8acded02014-09-22 18:02:25 -0700565 static const char *Opcode;
Jan Voung3b43b892014-09-24 13:32:39 -0700566 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter;
Jan Voung8acded02014-09-22 18:02:25 -0700567};
568
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700569// See the definition of emitTwoAddress() for a description of
570// ShiftHack.
571void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
572 bool ShiftHack = false);
573
574template <InstX8632::InstKindX8632 K, bool ShiftHack = false>
575class InstX8632Binop : public InstX8632 {
576public:
Jan Voungaf2780c2014-09-26 11:14:30 -0700577 // Create a binary-op instruction like shifts.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700578 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) {
579 return new (Func->allocate<InstX8632Binop>())
580 InstX8632Binop(Func, Dest, Source);
581 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700582 void emit(const Cfg *Func) const override {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700583 emitTwoAddress(Opcode, this, Func, ShiftHack);
584 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700585 void dump(const Cfg *Func) const override {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700586 Ostream &Str = Func->getContext()->getStrDump();
587 dumpDest(Func);
588 Str << " = " << Opcode << "." << getDest()->getType() << " ";
589 dumpSources(Func);
590 }
591 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
592
593private:
594 InstX8632Binop(Cfg *Func, Variable *Dest, Operand *Source)
595 : InstX8632(Func, K, 2, Dest) {
596 addSource(Dest);
597 addSource(Source);
598 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700599 InstX8632Binop(const InstX8632Binop &) = delete;
600 InstX8632Binop &operator=(const InstX8632Binop &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700601 ~InstX8632Binop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700602 static const char *Opcode;
603};
604
Jan Voungaf2780c2014-09-26 11:14:30 -0700605template <InstX8632::InstKindX8632 K>
606class InstX8632BinopGPR : public InstX8632 {
607public:
608 // Create an ordinary binary-op instruction like add or sub.
609 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) {
610 return new (Func->allocate<InstX8632BinopGPR>())
611 InstX8632BinopGPR(Func, Dest, Source);
612 }
613 void emit(const Cfg *Func) const override {
614 const bool ShiftHack = false;
615 emitTwoAddress(Opcode, this, Func, ShiftHack);
616 }
617 void emitIAS(const Cfg *Func) const override {
618 Type Ty = getDest()->getType();
619 assert(getSrcSize() == 2);
620 emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter);
621 }
622 void dump(const Cfg *Func) const override {
623 Ostream &Str = Func->getContext()->getStrDump();
624 dumpDest(Func);
625 Str << " = " << Opcode << "." << getDest()->getType() << " ";
626 dumpSources(Func);
627 }
628 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
629
630private:
631 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
632 : InstX8632(Func, K, 2, Dest) {
633 addSource(Dest);
634 addSource(Source);
635 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700636 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
637 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
Jan Voungaf2780c2014-09-26 11:14:30 -0700638 ~InstX8632BinopGPR() override {}
639 static const char *Opcode;
640 static const x86::AssemblerX86::GPREmitterRegOp Emitter;
641};
642
Jan Voung8acded02014-09-22 18:02:25 -0700643template <InstX8632::InstKindX8632 K, bool NeedsElementType>
644class InstX8632BinopXmm : public InstX8632 {
645public:
646 // Create an XMM binary-op instruction like addss or addps.
647 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
648 return new (Func->allocate<InstX8632BinopXmm>())
649 InstX8632BinopXmm(Func, Dest, Source);
650 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700651 void emit(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700652 const bool ShiftHack = false;
653 emitTwoAddress(Opcode, this, Func, ShiftHack);
654 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700655 void emitIAS(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700656 Type Ty = getDest()->getType();
657 if (NeedsElementType)
658 Ty = typeElementType(Ty);
659 assert(getSrcSize() == 2);
660 emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(1), Emitter);
661 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700662 void dump(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700663 Ostream &Str = Func->getContext()->getStrDump();
664 dumpDest(Func);
665 Str << " = " << Opcode << "." << getDest()->getType() << " ";
666 dumpSources(Func);
667 }
668 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
669
670private:
671 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
672 : InstX8632(Func, K, 2, Dest) {
673 addSource(Dest);
674 addSource(Source);
675 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700676 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
677 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700678 ~InstX8632BinopXmm() override {}
Jan Voung8acded02014-09-22 18:02:25 -0700679 static const char *Opcode;
Jan Voung3b43b892014-09-24 13:32:39 -0700680 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter;
Jan Voung8acded02014-09-22 18:02:25 -0700681};
682
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700683template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
684public:
685 // Create a ternary-op instruction like div or idiv.
686 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
687 Operand *Source2) {
688 return new (Func->allocate<InstX8632Ternop>())
689 InstX8632Ternop(Func, Dest, Source1, Source2);
690 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700691 void emit(const Cfg *Func) const override {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700692 Ostream &Str = Func->getContext()->getStrEmit();
693 assert(getSrcSize() == 3);
694 Str << "\t" << Opcode << "\t";
Matt Wala49889232014-07-18 12:45:09 -0700695 getDest()->emit(Func);
696 Str << ", ";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700697 getSrc(1)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700698 Str << ", ";
699 getSrc(2)->emit(Func);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700700 Str << "\n";
701 }
Jan Voungaf2780c2014-09-26 11:14:30 -0700702 void emitIAS(const Cfg *Func) const override { emit(Func); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700703 void dump(const Cfg *Func) const override {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -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 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
713 : InstX8632(Func, K, 3, Dest) {
714 addSource(Dest);
715 addSource(Source1);
716 addSource(Source2);
717 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700718 InstX8632Ternop(const InstX8632Ternop &) = delete;
719 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700720 ~InstX8632Ternop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700721 static const char *Opcode;
722};
723
Matt Wala49889232014-07-18 12:45:09 -0700724// Instructions of the form x := y op z
725template <InstX8632::InstKindX8632 K>
726class InstX8632ThreeAddressop : public InstX8632 {
727public:
728 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
729 Operand *Source0, Operand *Source1) {
730 return new (Func->allocate<InstX8632ThreeAddressop>())
731 InstX8632ThreeAddressop(Func, Dest, Source0, Source1);
732 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700733 void emit(const Cfg *Func) const override {
Matt Wala49889232014-07-18 12:45:09 -0700734 Ostream &Str = Func->getContext()->getStrEmit();
735 assert(getSrcSize() == 2);
736 Str << "\t" << Opcode << "\t";
737 getDest()->emit(Func);
738 Str << ", ";
739 getSrc(0)->emit(Func);
740 Str << ", ";
741 getSrc(1)->emit(Func);
742 Str << "\n";
743 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700744 void dump(const Cfg *Func) const override {
Matt Wala49889232014-07-18 12:45:09 -0700745 Ostream &Str = Func->getContext()->getStrDump();
746 dumpDest(Func);
747 Str << " = " << Opcode << "." << getDest()->getType() << " ";
748 dumpSources(Func);
749 }
750 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
751
752private:
753 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
754 Operand *Source1)
755 : InstX8632(Func, K, 2, Dest) {
756 addSource(Source0);
757 addSource(Source1);
758 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700759 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
760 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700761 ~InstX8632ThreeAddressop() override {}
Matt Wala49889232014-07-18 12:45:09 -0700762 static const char *Opcode;
763};
764
Matt Walae58178a2014-08-12 13:15:04 -0700765bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
766
767// Base class for assignment instructions
768template <InstX8632::InstKindX8632 K>
769class InstX8632Movlike : public InstX8632 {
770public:
771 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
772 return new (Func->allocate<InstX8632Movlike>())
773 InstX8632Movlike(Func, Dest, Source);
774 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700775 bool isRedundantAssign() const override {
Matt Walae58178a2014-08-12 13:15:04 -0700776 return checkForRedundantAssign(getDest(), getSrc(0));
777 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700778 bool isSimpleAssign() const override { return true; }
779 void emit(const Cfg *Func) const override;
780 void dump(const Cfg *Func) const override {
Matt Walae58178a2014-08-12 13:15:04 -0700781 Ostream &Str = Func->getContext()->getStrDump();
782 Str << Opcode << "." << getDest()->getType() << " ";
783 dumpDest(Func);
784 Str << ", ";
785 dumpSources(Func);
786 }
787 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
788
789private:
790 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source)
791 : InstX8632(Func, K, 1, Dest) {
792 addSource(Source);
793 }
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700794 InstX8632Movlike(const InstX8632Movlike &) = delete;
795 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700796 ~InstX8632Movlike() override {}
Matt Walae58178a2014-08-12 13:15:04 -0700797
798 static const char *Opcode;
799};
800
Jan Voung3b43b892014-09-24 13:32:39 -0700801typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap;
802typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg;
803typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf;
804typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr;
805typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea;
Matt Wala51e8cfb2014-08-08 08:39:40 -0700806// Cbwdq instruction - wrapper for cbw, cwd, and cdq
Jan Voung3b43b892014-09-24 13:32:39 -0700807typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq;
808typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd;
809typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss;
Matt Walae58178a2014-08-12 13:15:04 -0700810// Move/assignment instruction - wrapper for mov/movss/movsd.
811typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov;
812// Move packed - copy 128 bit values between XMM registers, or mem128
813// and XMM registers.
814typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp;
815// Movq - copy between XMM registers, or mem64 and XMM registers.
816typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq;
Jan Voungaf2780c2014-09-26 11:14:30 -0700817typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add;
Jan Voung8acded02014-09-22 18:02:25 -0700818typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps;
Jan Voungaf2780c2014-09-26 11:14:30 -0700819typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc;
Jan Voung8acded02014-09-22 18:02:25 -0700820typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss;
821typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd;
Jan Voungaf2780c2014-09-26 11:14:30 -0700822typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub;
Jan Voung8acded02014-09-22 18:02:25 -0700823typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps;
824typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss;
Jan Voungaf2780c2014-09-26 11:14:30 -0700825typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb;
Jan Voung8acded02014-09-22 18:02:25 -0700826typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub;
Jan Voungaf2780c2014-09-26 11:14:30 -0700827typedef InstX8632BinopGPR<InstX8632::And> InstX8632And;
Jan Voung8acded02014-09-22 18:02:25 -0700828typedef InstX8632BinopXmm<InstX8632::Pand, false> InstX8632Pand;
829typedef InstX8632BinopXmm<InstX8632::Pandn, false> InstX8632Pandn;
Jan Voungaf2780c2014-09-26 11:14:30 -0700830typedef InstX8632BinopGPR<InstX8632::Or> InstX8632Or;
Jan Voung8acded02014-09-22 18:02:25 -0700831typedef InstX8632BinopXmm<InstX8632::Por, false> InstX8632Por;
Jan Voungaf2780c2014-09-26 11:14:30 -0700832typedef InstX8632BinopGPR<InstX8632::Xor> InstX8632Xor;
Jan Voung8acded02014-09-22 18:02:25 -0700833typedef InstX8632BinopXmm<InstX8632::Pxor, false> InstX8632Pxor;
Jan Voung0ac50dc2014-09-30 08:36:06 -0700834typedef InstX8632BinopGPR<InstX8632::Imul> InstX8632Imul;
Jan Voung8acded02014-09-22 18:02:25 -0700835typedef InstX8632BinopXmm<InstX8632::Mulps, true> InstX8632Mulps;
836typedef InstX8632BinopXmm<InstX8632::Mulss, false> InstX8632Mulss;
Matt Wala0a450512014-07-30 12:44:39 -0700837typedef InstX8632Binop<InstX8632::Pmull> InstX8632Pmull;
Jan Voung8acded02014-09-22 18:02:25 -0700838typedef InstX8632BinopXmm<InstX8632::Pmuludq, false> InstX8632Pmuludq;
839typedef InstX8632BinopXmm<InstX8632::Divps, true> InstX8632Divps;
840typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss;
Jan Voung7fa813b2014-07-18 13:01:08 -0700841typedef InstX8632Binop<InstX8632::Rol, true> InstX8632Rol;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700842typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl;
Matt Wala83b80362014-07-16 10:21:30 -0700843typedef InstX8632Binop<InstX8632::Psll> InstX8632Psll;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700844typedef InstX8632Binop<InstX8632::Shr, true> InstX8632Shr;
845typedef InstX8632Binop<InstX8632::Sar, true> InstX8632Sar;
Matt Wala83b80362014-07-16 10:21:30 -0700846typedef InstX8632Binop<InstX8632::Psra> InstX8632Psra;
Jan Voung0ac50dc2014-09-30 08:36:06 -0700847typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq;
848typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt;
Matt Walacfe51462014-07-25 15:57:56 -0700849// TODO: movss is only a binary operation when the source and dest
850// operands are both registers. In other cases, it behaves like a copy
851// (mov-like) operation. Eventually, InstX8632Movss should assert that
852// both its source and dest operands are registers, and the lowering
853// code should use _mov instead of _movss in cases where a copy
854// operation is intended.
855typedef InstX8632Binop<InstX8632::Movss> InstX8632Movss;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700856typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv;
857typedef InstX8632Ternop<InstX8632::Div> InstX8632Div;
Matt Wala0a450512014-07-30 12:44:39 -0700858typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
859typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
Matt Wala49889232014-07-18 12:45:09 -0700860typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
Matt Wala0a450512014-07-30 12:44:39 -0700861typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
862typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
863typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
Matt Wala49889232014-07-18 12:45:09 -0700864typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700865
Jan Vounga3a01a22014-07-14 10:32:41 -0700866// Base class for a lockable x86-32 instruction (emits a locked prefix).
867class InstX8632Lockable : public InstX8632 {
Jan Vounga3a01a22014-07-14 10:32:41 -0700868protected:
869 bool Locked;
870
871 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
872 Variable *Dest, bool Locked)
873 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
874 // Assume that such instructions are used for Atomics and be careful
875 // with optimizations.
876 HasSideEffects = Locked;
877 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700878 ~InstX8632Lockable() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -0700879
880private:
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700881 InstX8632Lockable(const InstX8632Lockable &) = delete;
882 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
Jan Vounga3a01a22014-07-14 10:32:41 -0700883};
884
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700885// Mul instruction - unsigned multiply.
886class InstX8632Mul : public InstX8632 {
887public:
888 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
889 Operand *Source2) {
890 return new (Func->allocate<InstX8632Mul>())
891 InstX8632Mul(Func, Dest, Source1, Source2);
892 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700893 void emit(const Cfg *Func) const override;
Jan Voungaf2780c2014-09-26 11:14:30 -0700894 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700895 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700896 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
897
898private:
899 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700900 InstX8632Mul(const InstX8632Mul &) = delete;
901 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700902 ~InstX8632Mul() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700903};
904
905// Shld instruction - shift across a pair of operands. TODO: Verify
906// that the validator accepts the shld instruction.
907class InstX8632Shld : public InstX8632 {
908public:
909 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
910 Variable *Source2) {
911 return new (Func->allocate<InstX8632Shld>())
912 InstX8632Shld(Func, Dest, Source1, Source2);
913 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700914 void emit(const Cfg *Func) const override;
915 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700916 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
917
918private:
919 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
920 Variable *Source2);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700921 InstX8632Shld(const InstX8632Shld &) = delete;
922 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700923 ~InstX8632Shld() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700924};
925
926// Shrd instruction - shift across a pair of operands. TODO: Verify
927// that the validator accepts the shrd instruction.
928class InstX8632Shrd : public InstX8632 {
929public:
930 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
931 Variable *Source2) {
932 return new (Func->allocate<InstX8632Shrd>())
933 InstX8632Shrd(Func, Dest, Source1, Source2);
934 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700935 void emit(const Cfg *Func) const override;
936 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700937 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
938
939private:
940 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
941 Variable *Source2);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700942 InstX8632Shrd(const InstX8632Shrd &) = delete;
943 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700944 ~InstX8632Shrd() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700945};
946
Jan Vounge4da26f2014-07-15 17:52:39 -0700947// Conditional move instruction.
948class InstX8632Cmov : public InstX8632 {
949public:
950 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voungbd385e42014-09-18 18:18:10 -0700951 CondX86::BrCond Cond) {
Jan Vounge4da26f2014-07-15 17:52:39 -0700952 return new (Func->allocate<InstX8632Cmov>())
953 InstX8632Cmov(Func, Dest, Source, Cond);
954 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700955 void emit(const Cfg *Func) const override;
956 void emitIAS(const Cfg *Func) const override;
957 void dump(const Cfg *Func) const override;
Jan Vounge4da26f2014-07-15 17:52:39 -0700958 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
959
960private:
Jan Voungbd385e42014-09-18 18:18:10 -0700961 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
962 CondX86::BrCond Cond);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700963 InstX8632Cmov(const InstX8632Cmov &) = delete;
964 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700965 ~InstX8632Cmov() override {}
Jan Vounge4da26f2014-07-15 17:52:39 -0700966
Jan Voungbd385e42014-09-18 18:18:10 -0700967 CondX86::BrCond Condition;
Jan Vounge4da26f2014-07-15 17:52:39 -0700968};
969
Matt Walace0ca8f2014-07-24 12:34:20 -0700970// Cmpps instruction - compare packed singled-precision floating point
971// values
972class InstX8632Cmpps : public InstX8632 {
973public:
Matt Walace0ca8f2014-07-24 12:34:20 -0700974 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voungbd385e42014-09-18 18:18:10 -0700975 CondX86::CmppsCond Condition) {
Matt Walace0ca8f2014-07-24 12:34:20 -0700976 return new (Func->allocate<InstX8632Cmpps>())
977 InstX8632Cmpps(Func, Dest, Source, Condition);
978 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700979 void emit(const Cfg *Func) const override;
980 void emitIAS(const Cfg *Func) const override;
981 void dump(const Cfg *Func) const override;
Matt Walace0ca8f2014-07-24 12:34:20 -0700982 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
983
984private:
Jan Voungbd385e42014-09-18 18:18:10 -0700985 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
986 CondX86::CmppsCond Cond);
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700987 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
988 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700989 ~InstX8632Cmpps() override {}
Matt Walace0ca8f2014-07-24 12:34:20 -0700990
Jan Voungbd385e42014-09-18 18:18:10 -0700991 CondX86::CmppsCond Condition;
Matt Walace0ca8f2014-07-24 12:34:20 -0700992};
993
Jan Vounga3a01a22014-07-14 10:32:41 -0700994// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
995// equals eax. If so, the ZF is set and <desired> is stored in <dest>.
996// If not, ZF is cleared and <dest> is copied to eax (or subregister).
997// <dest> can be a register or memory, while <desired> must be a register.
998// It is the user's responsiblity to mark eax with a FakeDef.
999class InstX8632Cmpxchg : public InstX8632Lockable {
1000public:
1001 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1002 Variable *Desired, bool Locked) {
1003 return new (Func->allocate<InstX8632Cmpxchg>())
1004 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
1005 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001006 void emit(const Cfg *Func) const override;
1007 void emitIAS(const Cfg *Func) const override;
1008 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001009 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
1010
1011private:
1012 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1013 Variable *Desired, bool Locked);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001014 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1015 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001016 ~InstX8632Cmpxchg() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001017};
1018
1019// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
1020// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
1021// If not, ZF is cleared and <m64> is copied to edx:eax.
1022// The caller is responsible for inserting FakeDefs to mark edx
1023// and eax as modified.
1024// <m64> must be a memory operand.
1025class InstX8632Cmpxchg8b : public InstX8632Lockable {
1026public:
Jan Voung03532e52014-09-23 13:32:18 -07001027 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
Jan Vounga3a01a22014-07-14 10:32:41 -07001028 Variable *Edx, Variable *Eax, Variable *Ecx,
1029 Variable *Ebx, bool Locked) {
1030 return new (Func->allocate<InstX8632Cmpxchg8b>())
1031 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
1032 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001033 void emit(const Cfg *Func) const override;
1034 void emitIAS(const Cfg *Func) const override;
1035 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001036 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
1037
1038private:
Jan Voung03532e52014-09-23 13:32:18 -07001039 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
Jan Vounga3a01a22014-07-14 10:32:41 -07001040 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001041 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1042 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001043 ~InstX8632Cmpxchg8b() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001044};
1045
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001046// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
1047// as appropriate. s=float, d=double, i=int. X and Y are determined
1048// from dest/src types. Sign and zero extension on the integer
1049// operand needs to be done separately.
1050class InstX8632Cvt : public InstX8632 {
1051public:
Jim Stichnothb63cd882014-09-08 10:47:23 -07001052 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
1053 bool Trunc) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001054 return new (Func->allocate<InstX8632Cvt>())
Jim Stichnothb63cd882014-09-08 10:47:23 -07001055 InstX8632Cvt(Func, Dest, Source, Trunc);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001056 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001057 void emit(const Cfg *Func) const override;
1058 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001059 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
1060
1061private:
Jim Stichnothb63cd882014-09-08 10:47:23 -07001062 bool Trunc;
1063 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, bool Trunc);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001064 InstX8632Cvt(const InstX8632Cvt &) = delete;
1065 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001066 ~InstX8632Cvt() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001067};
1068
1069// cmp - Integer compare instruction.
1070class InstX8632Icmp : public InstX8632 {
1071public:
1072 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1073 return new (Func->allocate<InstX8632Icmp>())
1074 InstX8632Icmp(Func, Src1, Src2);
1075 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001076 void emit(const Cfg *Func) const override;
1077 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001078 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
1079
1080private:
1081 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001082 InstX8632Icmp(const InstX8632Icmp &) = delete;
1083 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001084 ~InstX8632Icmp() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001085};
1086
1087// ucomiss/ucomisd - floating-point compare instruction.
1088class InstX8632Ucomiss : public InstX8632 {
1089public:
1090 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1091 return new (Func->allocate<InstX8632Ucomiss>())
1092 InstX8632Ucomiss(Func, Src1, Src2);
1093 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001094 void emit(const Cfg *Func) const override;
1095 void emitIAS(const Cfg *Func) const override;
1096 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001097 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
1098
1099private:
1100 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001101 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1102 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001103 ~InstX8632Ucomiss() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001104};
1105
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001106// UD2 instruction.
1107class InstX8632UD2 : public InstX8632 {
1108public:
1109 static InstX8632UD2 *create(Cfg *Func) {
1110 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
1111 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001112 void emit(const Cfg *Func) const override;
1113 void dump(const Cfg *Func) const override;
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001114 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
1115
1116private:
1117 InstX8632UD2(Cfg *Func);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001118 InstX8632UD2(const InstX8632UD2 &) = delete;
1119 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001120 ~InstX8632UD2() override {}
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001121};
1122
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001123// Test instruction.
1124class InstX8632Test : public InstX8632 {
1125public:
1126 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
1127 return new (Func->allocate<InstX8632Test>())
1128 InstX8632Test(Func, Source1, Source2);
1129 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001130 void emit(const Cfg *Func) const override;
1131 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001132 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
1133
1134private:
1135 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001136 InstX8632Test(const InstX8632Test &) = delete;
1137 InstX8632Test &operator=(const InstX8632Test &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001138 ~InstX8632Test() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001139};
1140
Jan Voung5cd240d2014-06-25 10:36:46 -07001141// Mfence instruction.
1142class InstX8632Mfence : public InstX8632 {
1143public:
1144 static InstX8632Mfence *create(Cfg *Func) {
1145 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
1146 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001147 void emit(const Cfg *Func) const override;
Jan Voungaf2780c2014-09-26 11:14:30 -07001148 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001149 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001150 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
1151
1152private:
1153 InstX8632Mfence(Cfg *Func);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001154 InstX8632Mfence(const InstX8632Mfence &) = delete;
1155 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001156 ~InstX8632Mfence() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001157};
1158
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001159// This is essentially a "mov" instruction with an OperandX8632Mem
1160// operand instead of Variable as the destination. It's important
1161// for liveness that there is no Dest operand.
1162class InstX8632Store : public InstX8632 {
1163public:
1164 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1165 return new (Func->allocate<InstX8632Store>())
1166 InstX8632Store(Func, Value, Mem);
1167 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001168 void emit(const Cfg *Func) const override;
1169 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001170 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
1171
1172private:
1173 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001174 InstX8632Store(const InstX8632Store &) = delete;
1175 InstX8632Store &operator=(const InstX8632Store &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001176 ~InstX8632Store() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001177};
1178
Matt Wala105b7042014-08-11 19:56:19 -07001179class InstX8632StoreP : public InstX8632 {
1180public:
1181 static InstX8632StoreP *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1182 return new (Func->allocate<InstX8632StoreP>())
1183 InstX8632StoreP(Func, Value, Mem);
1184 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001185 void emit(const Cfg *Func) const override;
1186 void dump(const Cfg *Func) const override;
Matt Wala105b7042014-08-11 19:56:19 -07001187 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
1188
1189private:
1190 InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001191 InstX8632StoreP(const InstX8632StoreP &) = delete;
1192 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001193 ~InstX8632StoreP() override {}
Matt Wala105b7042014-08-11 19:56:19 -07001194};
1195
Jan Voung5cd240d2014-06-25 10:36:46 -07001196// This is essentially a "movq" instruction with an OperandX8632Mem
1197// operand instead of Variable as the destination. It's important
1198// for liveness that there is no Dest operand.
1199class InstX8632StoreQ : public InstX8632 {
1200public:
1201 static InstX8632StoreQ *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1202 return new (Func->allocate<InstX8632StoreQ>())
1203 InstX8632StoreQ(Func, Value, Mem);
1204 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001205 void emit(const Cfg *Func) const override;
1206 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001207 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1208
1209private:
1210 InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001211 InstX8632StoreQ(const InstX8632StoreQ &) = delete;
1212 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001213 ~InstX8632StoreQ() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001214};
1215
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001216// Movsx - copy from a narrower integer type to a wider integer
1217// type, with sign extension.
1218class InstX8632Movsx : public InstX8632 {
1219public:
1220 static InstX8632Movsx *create(Cfg *Func, Variable *Dest, Operand *Source) {
1221 return new (Func->allocate<InstX8632Movsx>())
1222 InstX8632Movsx(Func, Dest, Source);
1223 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001224 void emit(const Cfg *Func) const override;
1225 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001226 static bool classof(const Inst *Inst) { return isClassof(Inst, Movsx); }
1227
1228private:
1229 InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001230 InstX8632Movsx(const InstX8632Movsx &) = delete;
1231 InstX8632Movsx &operator=(const InstX8632Movsx &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001232 ~InstX8632Movsx() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001233};
1234
Jim Stichnothad403532014-09-25 12:44:17 -07001235// Movzx - copy from a narrower integer type to a wider integer
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001236// type, with zero extension.
1237class InstX8632Movzx : public InstX8632 {
1238public:
1239 static InstX8632Movzx *create(Cfg *Func, Variable *Dest, Operand *Source) {
1240 return new (Func->allocate<InstX8632Movzx>())
1241 InstX8632Movzx(Func, Dest, Source);
1242 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001243 void emit(const Cfg *Func) const override;
1244 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001245 static bool classof(const Inst *Inst) { return isClassof(Inst, Movzx); }
1246
1247private:
1248 InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001249 InstX8632Movzx(const InstX8632Movzx &) = delete;
1250 InstX8632Movzx &operator=(const InstX8632Movzx &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001251 ~InstX8632Movzx() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001252};
1253
Matt Walac3302742014-08-15 16:21:56 -07001254// Nop instructions of varying length
1255class InstX8632Nop : public InstX8632 {
1256public:
1257 // TODO: Replace with enum.
1258 typedef unsigned NopVariant;
1259
1260 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1261 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1262 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001263 void emit(const Cfg *Func) const override;
1264 void emitIAS(const Cfg *Func) const override;
1265 void dump(const Cfg *Func) const override;
Matt Walac3302742014-08-15 16:21:56 -07001266 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1267
1268private:
1269 InstX8632Nop(Cfg *Func, SizeT Length);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001270 InstX8632Nop(const InstX8632Nop &) = delete;
1271 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001272 ~InstX8632Nop() override {}
Matt Walac3302742014-08-15 16:21:56 -07001273
1274 NopVariant Variant;
1275};
1276
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001277// Fld - load a value onto the x87 FP stack.
1278class InstX8632Fld : public InstX8632 {
1279public:
1280 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1281 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1282 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001283 void emit(const Cfg *Func) const override;
1284 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001285 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1286
1287private:
1288 InstX8632Fld(Cfg *Func, Operand *Src);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001289 InstX8632Fld(const InstX8632Fld &) = delete;
1290 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001291 ~InstX8632Fld() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001292};
1293
1294// Fstp - store x87 st(0) into memory and pop st(0).
1295class InstX8632Fstp : public InstX8632 {
1296public:
1297 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1298 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1299 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001300 void emit(const Cfg *Func) const override;
1301 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001302 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
1303
1304private:
1305 InstX8632Fstp(Cfg *Func, Variable *Dest);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001306 InstX8632Fstp(const InstX8632Fstp &) = delete;
1307 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001308 ~InstX8632Fstp() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001309};
1310
1311class InstX8632Pop : public InstX8632 {
1312public:
1313 static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
1314 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
1315 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001316 void emit(const Cfg *Func) const override;
1317 void emitIAS(const Cfg *Func) const override;
1318 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001319 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1320
1321private:
1322 InstX8632Pop(Cfg *Func, Variable *Dest);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001323 InstX8632Pop(const InstX8632Pop &) = delete;
1324 InstX8632Pop &operator=(const InstX8632Pop &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001325 ~InstX8632Pop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001326};
1327
1328class InstX8632Push : public InstX8632 {
1329public:
1330 static InstX8632Push *create(Cfg *Func, Operand *Source,
1331 bool SuppressStackAdjustment) {
1332 return new (Func->allocate<InstX8632Push>())
1333 InstX8632Push(Func, Source, SuppressStackAdjustment);
1334 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001335 void emit(const Cfg *Func) const override;
1336 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001337 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1338
1339private:
1340 InstX8632Push(Cfg *Func, Operand *Source, bool SuppressStackAdjustment);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001341 InstX8632Push(const InstX8632Push &) = delete;
1342 InstX8632Push &operator=(const InstX8632Push &) = delete;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001343 bool SuppressStackAdjustment;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001344 ~InstX8632Push() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001345};
1346
1347// Ret instruction. Currently only supports the "ret" version that
1348// does not pop arguments. This instruction takes a Source operand
1349// (for non-void returning functions) for liveness analysis, though
1350// a FakeUse before the ret would do just as well.
1351class InstX8632Ret : public InstX8632 {
1352public:
1353 static InstX8632Ret *create(Cfg *Func, Variable *Source = NULL) {
1354 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1355 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001356 void emit(const Cfg *Func) const override;
1357 void emitIAS(const Cfg *Func) const override;
1358 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001359 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1360
1361private:
1362 InstX8632Ret(Cfg *Func, Variable *Source);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001363 InstX8632Ret(const InstX8632Ret &) = delete;
1364 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001365 ~InstX8632Ret() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001366};
1367
Jan Voung5cd240d2014-06-25 10:36:46 -07001368// Exchanging Add instruction. Exchanges the first operand (destination
1369// operand) with the second operand (source operand), then loads the sum
1370// of the two values into the destination operand. The destination may be
1371// a register or memory, while the source must be a register.
1372//
1373// Both the dest and source are updated. The caller should then insert a
1374// FakeDef to reflect the second udpate.
Jan Vounga3a01a22014-07-14 10:32:41 -07001375class InstX8632Xadd : public InstX8632Lockable {
Jan Voung5cd240d2014-06-25 10:36:46 -07001376public:
1377 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1378 bool Locked) {
1379 return new (Func->allocate<InstX8632Xadd>())
1380 InstX8632Xadd(Func, Dest, Source, Locked);
1381 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001382 void emit(const Cfg *Func) const override;
1383 void emitIAS(const Cfg *Func) const override;
1384 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001385 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1386
1387private:
Jan Voung5cd240d2014-06-25 10:36:46 -07001388 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001389 InstX8632Xadd(const InstX8632Xadd &) = delete;
1390 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001391 ~InstX8632Xadd() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001392};
1393
Jan Vounga3a01a22014-07-14 10:32:41 -07001394// Exchange instruction. Exchanges the first operand (destination
1395// operand) with the second operand (source operand). At least one of
1396// the operands must be a register (and the other can be reg or mem).
1397// Both the Dest and Source are updated. If there is a memory operand,
1398// then the instruction is automatically "locked" without the need for
1399// a lock prefix.
1400class InstX8632Xchg : public InstX8632 {
1401public:
1402 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1403 return new (Func->allocate<InstX8632Xchg>())
1404 InstX8632Xchg(Func, Dest, Source);
1405 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001406 void emit(const Cfg *Func) const override;
1407 void emitIAS(const Cfg *Func) const override;
1408 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001409 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
1410
1411private:
1412 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
Jim Stichnoth0795ba02014-10-01 14:23:01 -07001413 InstX8632Xchg(const InstX8632Xchg &) = delete;
1414 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001415 ~InstX8632Xchg() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001416};
1417
Jim Stichnoth6e992142014-07-30 14:45:20 -07001418// Declare partial template specializations of emit() methods that
1419// already have default implementations. Without this, there is the
1420// possibility of ODR violations and link errors.
1421template <> void InstX8632Addss::emit(const Cfg *Func) const;
1422template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
Matt Wala51e8cfb2014-08-08 08:39:40 -07001423template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
Jim Stichnoth6e992142014-07-30 14:45:20 -07001424template <> void InstX8632Div::emit(const Cfg *Func) const;
1425template <> void InstX8632Divss::emit(const Cfg *Func) const;
1426template <> void InstX8632Idiv::emit(const Cfg *Func) const;
1427template <> void InstX8632Imul::emit(const Cfg *Func) const;
1428template <> void InstX8632Lea::emit(const Cfg *Func) const;
1429template <> void InstX8632Mulss::emit(const Cfg *Func) const;
1430template <> void InstX8632Padd::emit(const Cfg *Func) const;
1431template <> void InstX8632Pblendvb::emit(const Cfg *Func) const;
1432template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const;
1433template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const;
1434template <> void InstX8632Pextr::emit(const Cfg *Func) const;
1435template <> void InstX8632Pinsr::emit(const Cfg *Func) const;
1436template <> void InstX8632Pmull::emit(const Cfg *Func) const;
1437template <> void InstX8632Pmuludq::emit(const Cfg *Func) const;
1438template <> void InstX8632Psll::emit(const Cfg *Func) const;
1439template <> void InstX8632Psra::emit(const Cfg *Func) const;
1440template <> void InstX8632Psub::emit(const Cfg *Func) const;
1441template <> void InstX8632Sqrtss::emit(const Cfg *Func) const;
1442template <> void InstX8632Subss::emit(const Cfg *Func) const;
1443
Jan Voungaf2780c2014-09-26 11:14:30 -07001444template <> void InstX8632Div::emitIAS(const Cfg *Func) const;
1445template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001446template <> void InstX8632Imul::emitIAS(const Cfg *Func) const;
Jan Voung03532e52014-09-23 13:32:18 -07001447template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const;
Jan Voung3b43b892014-09-24 13:32:39 -07001448template <> void InstX8632Movd::emitIAS(const Cfg *Func) const;
Jan Voung03532e52014-09-23 13:32:18 -07001449
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001450} // end of namespace Ice
1451
1452#endif // SUBZERO_SRC_ICEINSTX8632_H