blob: 834e061374b28acc6c4e679c079eea49153f0cd6 [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
19#include "IceDefs.h"
20#include "IceInst.h"
21#include "IceInstX8632.def"
22#include "IceOperand.h"
23
24namespace Ice {
25
26class TargetX8632;
27
28// OperandX8632 extends the Operand hierarchy. Its subclasses are
29// OperandX8632Mem and VariableSplit.
30class OperandX8632 : public Operand {
31public:
32 enum OperandKindX8632 {
33 k__Start = Operand::kTarget,
34 kMem,
35 kSplit
36 };
37 virtual void emit(const Cfg *Func) const = 0;
38 void dump(const Cfg *Func) const;
39
40protected:
41 OperandX8632(OperandKindX8632 Kind, Type Ty)
42 : Operand(static_cast<OperandKind>(Kind), Ty) {}
43 virtual ~OperandX8632() {}
44
45private:
46 OperandX8632(const OperandX8632 &) LLVM_DELETED_FUNCTION;
47 OperandX8632 &operator=(const OperandX8632 &) LLVM_DELETED_FUNCTION;
48};
49
50// OperandX8632Mem represents the m32 addressing mode, with optional
51// base and index registers, a constant offset, and a fixed shift
52// value for the index register.
53class OperandX8632Mem : public OperandX8632 {
54public:
Jan Voung3bd9f1a2014-06-18 10:50:57 -070055 enum SegmentRegisters {
56 DefaultSegment = -1,
Jan Vounga3a01a22014-07-14 10:32:41 -070057#define X(val, name) val,
58 SEG_REGX8632_TABLE
Jan Voung3bd9f1a2014-06-18 10:50:57 -070059#undef X
60 SegReg_NUM
61 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070062 static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base,
63 Constant *Offset, Variable *Index = NULL,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070064 uint16_t Shift = 0,
65 SegmentRegisters SegmentReg = DefaultSegment) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070066 return new (Func->allocate<OperandX8632Mem>())
Jan Voung3bd9f1a2014-06-18 10:50:57 -070067 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070068 }
69 Variable *getBase() const { return Base; }
70 Constant *getOffset() const { return Offset; }
71 Variable *getIndex() const { return Index; }
Jan Voung3bd9f1a2014-06-18 10:50:57 -070072 uint16_t getShift() const { return Shift; }
73 SegmentRegisters getSegmentRegister() const { return SegmentReg; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070074 virtual void emit(const Cfg *Func) const;
75 virtual void dump(const Cfg *Func) const;
76
77 static bool classof(const Operand *Operand) {
78 return Operand->getKind() == static_cast<OperandKind>(kMem);
79 }
80
81private:
82 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070083 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070084 OperandX8632Mem(const OperandX8632Mem &) LLVM_DELETED_FUNCTION;
85 OperandX8632Mem &operator=(const OperandX8632Mem &) LLVM_DELETED_FUNCTION;
86 virtual ~OperandX8632Mem() {}
87 Variable *Base;
88 Constant *Offset;
89 Variable *Index;
Jan Voung3bd9f1a2014-06-18 10:50:57 -070090 uint16_t Shift;
91 SegmentRegisters SegmentReg : 16;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070092};
93
94// VariableSplit is a way to treat an f64 memory location as a pair
95// of i32 locations (Low and High). This is needed for some cases
96// of the Bitcast instruction. Since it's not possible for integer
97// registers to access the XMM registers and vice versa, the
98// lowering forces the f64 to be spilled to the stack and then
99// accesses through the VariableSplit.
100class VariableSplit : public OperandX8632 {
101public:
102 enum Portion {
103 Low,
104 High
105 };
106 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
107 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
108 }
109 virtual void emit(const Cfg *Func) const;
110 virtual void dump(const Cfg *Func) const;
111
112 static bool classof(const Operand *Operand) {
113 return Operand->getKind() == static_cast<OperandKind>(kSplit);
114 }
115
116private:
117 VariableSplit(Cfg *Func, Variable *Var, Portion Part)
118 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) {
119 assert(Var->getType() == IceType_f64);
120 Vars = Func->allocateArrayOf<Variable *>(1);
121 Vars[0] = Var;
122 NumVars = 1;
123 }
124 VariableSplit(const VariableSplit &) LLVM_DELETED_FUNCTION;
125 VariableSplit &operator=(const VariableSplit &) LLVM_DELETED_FUNCTION;
126 virtual ~VariableSplit() { Func->deallocateArrayOf<Variable *>(Vars); }
127 Cfg *Func; // Held only for the destructor.
128 Variable *Var;
129 Portion Part;
130};
131
132class InstX8632 : public InstTarget {
133public:
134 enum InstKindX8632 {
135 k__Start = Inst::Target,
136 Adc,
137 Add,
Matt Wala8d1072e2014-07-11 15:43:51 -0700138 Addps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700139 Addss,
Matt Wala105b7042014-08-11 19:56:19 -0700140 Adjuststack,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700141 And,
Matt Wala0a450512014-07-30 12:44:39 -0700142 Blendvps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700143 Br,
Jan Vounge4da26f2014-07-15 17:52:39 -0700144 Bsf,
145 Bsr,
Jan Voung7fa813b2014-07-18 13:01:08 -0700146 Bswap,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700147 Call,
Matt Walaafeaee42014-08-07 13:47:30 -0700148 Cbwdq,
Jan Vounge4da26f2014-07-15 17:52:39 -0700149 Cmov,
Matt Walace0ca8f2014-07-24 12:34:20 -0700150 Cmpps,
Jan Vounga3a01a22014-07-14 10:32:41 -0700151 Cmpxchg,
152 Cmpxchg8b,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700153 Cvt,
154 Div,
Matt Wala8d1072e2014-07-11 15:43:51 -0700155 Divps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700156 Divss,
157 Fld,
158 Fstp,
159 Icmp,
160 Idiv,
161 Imul,
Matt Wala0a450512014-07-30 12:44:39 -0700162 Insertps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700163 Label,
Matt Wala49889232014-07-18 12:45:09 -0700164 Lea,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700165 Load,
Jan Voung5cd240d2014-06-25 10:36:46 -0700166 Mfence,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700167 Mov,
Matt Wala49889232014-07-18 12:45:09 -0700168 Movd,
Matt Wala928f1292014-07-07 16:50:46 -0700169 Movp,
Jan Voung5cd240d2014-06-25 10:36:46 -0700170 Movq,
Matt Wala49889232014-07-18 12:45:09 -0700171 Movss,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700172 Movsx,
173 Movzx,
174 Mul,
Matt Wala8d1072e2014-07-11 15:43:51 -0700175 Mulps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700176 Mulss,
Jan Vounga3a01a22014-07-14 10:32:41 -0700177 Neg,
Matt Walac3302742014-08-15 16:21:56 -0700178 Nop,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700179 Or,
Matt Wala7fa22d82014-07-17 12:41:31 -0700180 Padd,
Matt Wala83b80362014-07-16 10:21:30 -0700181 Pand,
Matt Wala9cb61e22014-07-24 09:44:42 -0700182 Pandn,
Matt Wala0a450512014-07-30 12:44:39 -0700183 Pblendvb,
Matt Wala83b80362014-07-16 10:21:30 -0700184 Pcmpeq,
185 Pcmpgt,
Matt Wala0a450512014-07-30 12:44:39 -0700186 Pextr,
187 Pinsr,
188 Pmull,
Matt Wala7fa22d82014-07-17 12:41:31 -0700189 Pmuludq,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700190 Pop,
Matt Wala7fa22d82014-07-17 12:41:31 -0700191 Por,
192 Pshufd,
Matt Wala83b80362014-07-16 10:21:30 -0700193 Psll,
194 Psra,
195 Psub,
Matt Wala7fa22d82014-07-17 12:41:31 -0700196 Push,
Matt Wala928f1292014-07-07 16:50:46 -0700197 Pxor,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700198 Ret,
Jan Voung7fa813b2014-07-18 13:01:08 -0700199 Rol,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700200 Sar,
201 Sbb,
202 Shl,
203 Shld,
204 Shr,
205 Shrd,
Matt Wala7fa22d82014-07-17 12:41:31 -0700206 Shufps,
Jan Voungf37fbbe2014-07-09 16:13:13 -0700207 Sqrtss,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700208 Store,
Matt Wala105b7042014-08-11 19:56:19 -0700209 StoreP,
Jan Voung5cd240d2014-06-25 10:36:46 -0700210 StoreQ,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700211 Sub,
Matt Wala8d1072e2014-07-11 15:43:51 -0700212 Subps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700213 Subss,
214 Test,
215 Ucomiss,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700216 UD2,
Jan Voung5cd240d2014-06-25 10:36:46 -0700217 Xadd,
Jan Vounga3a01a22014-07-14 10:32:41 -0700218 Xchg,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700219 Xor
220 };
Jan Vounge4da26f2014-07-15 17:52:39 -0700221
222 enum BrCond {
223#define X(tag, dump, emit) tag,
224 ICEINSTX8632BR_TABLE
225#undef X
226 Br_None
227 };
228
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700229 static const char *getWidthString(Type Ty);
230 virtual void emit(const Cfg *Func) const = 0;
231 virtual void dump(const Cfg *Func) const;
232
233protected:
234 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
235 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
236 virtual ~InstX8632() {}
237 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
238 return Inst->getKind() == static_cast<InstKind>(MyKind);
239 }
240
241private:
242 InstX8632(const InstX8632 &) LLVM_DELETED_FUNCTION;
243 InstX8632 &operator=(const InstX8632 &) LLVM_DELETED_FUNCTION;
244};
245
246// InstX8632Label represents an intra-block label that is the
247// target of an intra-block branch. These are used for lowering i1
248// calculations, Select instructions, and 64-bit compares on a 32-bit
249// architecture, without basic block splitting. Basic block splitting
250// is not so desirable for several reasons, one of which is the impact
251// on decisions based on whether a variable's live range spans
252// multiple basic blocks.
253//
254// Intra-block control flow must be used with caution. Consider the
255// sequence for "c = (a >= b ? x : y)".
256// cmp a, b
257// br lt, L1
258// mov c, x
259// jmp L2
260// L1:
261// mov c, y
262// L2:
263//
264// Labels L1 and L2 are intra-block labels. Without knowledge of the
265// intra-block control flow, liveness analysis will determine the "mov
266// c, x" instruction to be dead. One way to prevent this is to insert
267// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
268// instructions, e.g.:
269//
270// cmp a, b
271// br lt, L1
272// mov c, x
273// jmp L2
274// FakeUse(c)
275// L1:
276// mov c, y
277// L2:
278//
279// The down-side is that "mov c, x" can never be dead-code eliminated
280// even if there are no uses of c. As unlikely as this situation is,
281// it may be prevented by running dead code elimination before
282// lowering.
283class InstX8632Label : public InstX8632 {
284public:
285 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
286 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
287 }
288 IceString getName(const Cfg *Func) const;
289 virtual void emit(const Cfg *Func) const;
290 virtual void dump(const Cfg *Func) const;
291
292private:
293 InstX8632Label(Cfg *Func, TargetX8632 *Target);
294 InstX8632Label(const InstX8632Label &) LLVM_DELETED_FUNCTION;
295 InstX8632Label &operator=(const InstX8632Label &) LLVM_DELETED_FUNCTION;
296 virtual ~InstX8632Label() {}
297 SizeT Number; // used only for unique label string generation
298};
299
300// Conditional and unconditional branch instruction.
301class InstX8632Br : public InstX8632 {
302public:
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700303 // Create a conditional branch to a node.
304 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
305 CfgNode *TargetFalse, BrCond Condition) {
306 return new (Func->allocate<InstX8632Br>())
307 InstX8632Br(Func, TargetTrue, TargetFalse, NULL, Condition);
308 }
309 // Create an unconditional branch to a node.
310 static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
311 return new (Func->allocate<InstX8632Br>())
312 InstX8632Br(Func, NULL, Target, NULL, Br_None);
313 }
314 // Create a non-terminator conditional branch to a node, with a
315 // fallthrough to the next instruction in the current node. This is
316 // used for switch lowering.
317 static InstX8632Br *create(Cfg *Func, CfgNode *Target, BrCond Condition) {
318 return new (Func->allocate<InstX8632Br>())
319 InstX8632Br(Func, Target, NULL, NULL, Condition);
320 }
321 // Create a conditional intra-block branch (or unconditional, if
322 // Condition==None) to a label in the current block.
323 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
324 BrCond Condition) {
325 return new (Func->allocate<InstX8632Br>())
326 InstX8632Br(Func, NULL, NULL, Label, Condition);
327 }
328 CfgNode *getTargetTrue() const { return TargetTrue; }
329 CfgNode *getTargetFalse() const { return TargetFalse; }
330 virtual void emit(const Cfg *Func) const;
331 virtual void dump(const Cfg *Func) const;
332 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
333
334private:
335 InstX8632Br(Cfg *Func, CfgNode *TargetTrue, CfgNode *TargetFalse,
336 InstX8632Label *Label, BrCond Condition);
337 InstX8632Br(const InstX8632Br &) LLVM_DELETED_FUNCTION;
338 InstX8632Br &operator=(const InstX8632Br &) LLVM_DELETED_FUNCTION;
339 virtual ~InstX8632Br() {}
340 BrCond Condition;
341 CfgNode *TargetTrue;
342 CfgNode *TargetFalse;
343 InstX8632Label *Label; // Intra-block branch target
344};
345
Matt Wala105b7042014-08-11 19:56:19 -0700346// AdjustStack instruction - subtracts esp by the given amount and
347// updates the stack offset during code emission.
348class InstX8632AdjustStack : public InstX8632 {
349public:
350 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount) {
351 return new (Func->allocate<InstX8632AdjustStack>())
352 InstX8632AdjustStack(Func, Amount);
353 }
354 virtual void emit(const Cfg *Func) const;
355 virtual void dump(const Cfg *Func) const;
356 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
357
358private:
359 InstX8632AdjustStack(Cfg *Func, SizeT Amount);
360 InstX8632AdjustStack(const InstX8632AdjustStack &) LLVM_DELETED_FUNCTION;
361 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &)
362 LLVM_DELETED_FUNCTION;
363 SizeT Amount;
364};
365
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700366// Call instruction. Arguments should have already been pushed.
367class InstX8632Call : public InstX8632 {
368public:
369 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
370 return new (Func->allocate<InstX8632Call>())
371 InstX8632Call(Func, Dest, CallTarget);
372 }
373 Operand *getCallTarget() const { return getSrc(0); }
374 virtual void emit(const Cfg *Func) const;
375 virtual void dump(const Cfg *Func) const;
376 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
377
378private:
379 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
380 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION;
381 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION;
382 virtual ~InstX8632Call() {}
383};
384
Jan Voung7fa813b2014-07-18 13:01:08 -0700385// Instructions of the form x := op(x).
386template <InstX8632::InstKindX8632 K>
387class InstX8632Inplaceop : public InstX8632 {
388public:
389 static InstX8632Inplaceop *create(Cfg *Func, Operand *SrcDest) {
390 return new (Func->allocate<InstX8632Inplaceop>())
391 InstX8632Inplaceop(Func, SrcDest);
392 }
393 virtual void emit(const Cfg *Func) const {
394 Ostream &Str = Func->getContext()->getStrEmit();
395 assert(getSrcSize() == 1);
396 Str << "\t" << Opcode << "\t";
397 getSrc(0)->emit(Func);
398 Str << "\n";
399 }
400 virtual void dump(const Cfg *Func) const {
401 Ostream &Str = Func->getContext()->getStrDump();
402 dumpDest(Func);
403 Str << " = " << Opcode << "." << getDest()->getType() << " ";
404 dumpSources(Func);
405 }
406 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
407
408private:
409 InstX8632Inplaceop(Cfg *Func, Operand *SrcDest)
410 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
411 addSource(SrcDest);
412 }
413 InstX8632Inplaceop(const InstX8632Inplaceop &) LLVM_DELETED_FUNCTION;
414 InstX8632Inplaceop &
415 operator=(const InstX8632Inplaceop &) LLVM_DELETED_FUNCTION;
416 virtual ~InstX8632Inplaceop() {}
417 static const char *Opcode;
418};
419
420// Instructions of the form x := op(y)
Jan Vounga3a01a22014-07-14 10:32:41 -0700421template <InstX8632::InstKindX8632 K>
422class InstX8632Unaryop : public InstX8632 {
423public:
Jan Vounge4da26f2014-07-15 17:52:39 -0700424 static InstX8632Unaryop *create(Cfg *Func, Variable *Dest, Operand *Src) {
Jan Vounga3a01a22014-07-14 10:32:41 -0700425 return new (Func->allocate<InstX8632Unaryop>())
Jan Vounge4da26f2014-07-15 17:52:39 -0700426 InstX8632Unaryop(Func, Dest, Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700427 }
428 virtual void emit(const Cfg *Func) const {
429 Ostream &Str = Func->getContext()->getStrEmit();
430 assert(getSrcSize() == 1);
431 Str << "\t" << Opcode << "\t";
Jan Vounge4da26f2014-07-15 17:52:39 -0700432 getDest()->emit(Func);
433 Str << ", ";
Jan Vounga3a01a22014-07-14 10:32:41 -0700434 getSrc(0)->emit(Func);
435 Str << "\n";
436 }
437 virtual void dump(const Cfg *Func) const {
438 Ostream &Str = Func->getContext()->getStrDump();
439 dumpDest(Func);
440 Str << " = " << Opcode << "." << getDest()->getType() << " ";
441 dumpSources(Func);
442 }
443 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
444
445private:
Jan Vounge4da26f2014-07-15 17:52:39 -0700446 InstX8632Unaryop(Cfg *Func, Variable *Dest, Operand *Src)
447 : InstX8632(Func, K, 1, Dest) {
448 addSource(Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700449 }
450 InstX8632Unaryop(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION;
451 InstX8632Unaryop &operator=(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION;
452 virtual ~InstX8632Unaryop() {}
453 static const char *Opcode;
454};
455
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700456// See the definition of emitTwoAddress() for a description of
457// ShiftHack.
458void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
459 bool ShiftHack = false);
460
461template <InstX8632::InstKindX8632 K, bool ShiftHack = false>
462class InstX8632Binop : public InstX8632 {
463public:
464 // Create an ordinary binary-op instruction like add or sub.
465 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) {
466 return new (Func->allocate<InstX8632Binop>())
467 InstX8632Binop(Func, Dest, Source);
468 }
469 virtual void emit(const Cfg *Func) const {
470 emitTwoAddress(Opcode, this, Func, ShiftHack);
471 }
472 virtual void dump(const Cfg *Func) const {
473 Ostream &Str = Func->getContext()->getStrDump();
474 dumpDest(Func);
475 Str << " = " << Opcode << "." << getDest()->getType() << " ";
476 dumpSources(Func);
477 }
478 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
479
480private:
481 InstX8632Binop(Cfg *Func, Variable *Dest, Operand *Source)
482 : InstX8632(Func, K, 2, Dest) {
483 addSource(Dest);
484 addSource(Source);
485 }
486 InstX8632Binop(const InstX8632Binop &) LLVM_DELETED_FUNCTION;
487 InstX8632Binop &operator=(const InstX8632Binop &) LLVM_DELETED_FUNCTION;
488 virtual ~InstX8632Binop() {}
489 static const char *Opcode;
490};
491
492template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
493public:
494 // Create a ternary-op instruction like div or idiv.
495 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
496 Operand *Source2) {
497 return new (Func->allocate<InstX8632Ternop>())
498 InstX8632Ternop(Func, Dest, Source1, Source2);
499 }
500 virtual void emit(const Cfg *Func) const {
501 Ostream &Str = Func->getContext()->getStrEmit();
502 assert(getSrcSize() == 3);
503 Str << "\t" << Opcode << "\t";
Matt Wala49889232014-07-18 12:45:09 -0700504 getDest()->emit(Func);
505 Str << ", ";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700506 getSrc(1)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700507 Str << ", ";
508 getSrc(2)->emit(Func);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700509 Str << "\n";
510 }
511 virtual void dump(const Cfg *Func) const {
512 Ostream &Str = Func->getContext()->getStrDump();
513 dumpDest(Func);
514 Str << " = " << Opcode << "." << getDest()->getType() << " ";
515 dumpSources(Func);
516 }
517 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
518
519private:
520 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
521 : InstX8632(Func, K, 3, Dest) {
522 addSource(Dest);
523 addSource(Source1);
524 addSource(Source2);
525 }
526 InstX8632Ternop(const InstX8632Ternop &) LLVM_DELETED_FUNCTION;
527 InstX8632Ternop &operator=(const InstX8632Ternop &) LLVM_DELETED_FUNCTION;
528 virtual ~InstX8632Ternop() {}
529 static const char *Opcode;
530};
531
Matt Wala49889232014-07-18 12:45:09 -0700532// Instructions of the form x := y op z
533template <InstX8632::InstKindX8632 K>
534class InstX8632ThreeAddressop : public InstX8632 {
535public:
536 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
537 Operand *Source0, Operand *Source1) {
538 return new (Func->allocate<InstX8632ThreeAddressop>())
539 InstX8632ThreeAddressop(Func, Dest, Source0, Source1);
540 }
541 virtual void emit(const Cfg *Func) const {
542 Ostream &Str = Func->getContext()->getStrEmit();
543 assert(getSrcSize() == 2);
544 Str << "\t" << Opcode << "\t";
545 getDest()->emit(Func);
546 Str << ", ";
547 getSrc(0)->emit(Func);
548 Str << ", ";
549 getSrc(1)->emit(Func);
550 Str << "\n";
551 }
552 virtual void dump(const Cfg *Func) const {
553 Ostream &Str = Func->getContext()->getStrDump();
554 dumpDest(Func);
555 Str << " = " << Opcode << "." << getDest()->getType() << " ";
556 dumpSources(Func);
557 }
558 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
559
560private:
561 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
562 Operand *Source1)
563 : InstX8632(Func, K, 2, Dest) {
564 addSource(Source0);
565 addSource(Source1);
566 }
567 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &)
568 LLVM_DELETED_FUNCTION;
569 InstX8632ThreeAddressop &
570 operator=(const InstX8632ThreeAddressop &) LLVM_DELETED_FUNCTION;
571 virtual ~InstX8632ThreeAddressop() {}
572 static const char *Opcode;
573};
574
Matt Walae58178a2014-08-12 13:15:04 -0700575bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
576
577// Base class for assignment instructions
578template <InstX8632::InstKindX8632 K>
579class InstX8632Movlike : public InstX8632 {
580public:
581 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
582 return new (Func->allocate<InstX8632Movlike>())
583 InstX8632Movlike(Func, Dest, Source);
584 }
585 virtual bool isRedundantAssign() const {
586 return checkForRedundantAssign(getDest(), getSrc(0));
587 }
588 virtual void emit(const Cfg *Func) const;
589 virtual void dump(const Cfg *Func) const {
590 Ostream &Str = Func->getContext()->getStrDump();
591 Str << Opcode << "." << getDest()->getType() << " ";
592 dumpDest(Func);
593 Str << ", ";
594 dumpSources(Func);
595 }
596 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
597
598private:
599 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source)
600 : InstX8632(Func, K, 1, Dest) {
601 addSource(Source);
602 }
603 InstX8632Movlike(const InstX8632Movlike &) LLVM_DELETED_FUNCTION;
604 InstX8632Movlike &operator=(const InstX8632Movlike &) LLVM_DELETED_FUNCTION;
605 virtual ~InstX8632Movlike() {}
606
607 static const char *Opcode;
608};
609
Jan Voung7fa813b2014-07-18 13:01:08 -0700610typedef InstX8632Inplaceop<InstX8632::Bswap> InstX8632Bswap;
611typedef InstX8632Inplaceop<InstX8632::Neg> InstX8632Neg;
Jan Vounge4da26f2014-07-15 17:52:39 -0700612typedef InstX8632Unaryop<InstX8632::Bsf> InstX8632Bsf;
613typedef InstX8632Unaryop<InstX8632::Bsr> InstX8632Bsr;
Matt Wala49889232014-07-18 12:45:09 -0700614typedef InstX8632Unaryop<InstX8632::Lea> InstX8632Lea;
615typedef InstX8632Unaryop<InstX8632::Movd> InstX8632Movd;
Jan Vounge4da26f2014-07-15 17:52:39 -0700616typedef InstX8632Unaryop<InstX8632::Sqrtss> InstX8632Sqrtss;
Matt Wala51e8cfb2014-08-08 08:39:40 -0700617// Cbwdq instruction - wrapper for cbw, cwd, and cdq
618typedef InstX8632Unaryop<InstX8632::Cbwdq> InstX8632Cbwdq;
Matt Walae58178a2014-08-12 13:15:04 -0700619// Move/assignment instruction - wrapper for mov/movss/movsd.
620typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov;
621// Move packed - copy 128 bit values between XMM registers, or mem128
622// and XMM registers.
623typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp;
624// Movq - copy between XMM registers, or mem64 and XMM registers.
625typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700626typedef InstX8632Binop<InstX8632::Add> InstX8632Add;
Matt Wala8d1072e2014-07-11 15:43:51 -0700627typedef InstX8632Binop<InstX8632::Addps> InstX8632Addps;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700628typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc;
629typedef InstX8632Binop<InstX8632::Addss> InstX8632Addss;
Matt Wala7fa22d82014-07-17 12:41:31 -0700630typedef InstX8632Binop<InstX8632::Padd> InstX8632Padd;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700631typedef InstX8632Binop<InstX8632::Sub> InstX8632Sub;
Matt Wala8d1072e2014-07-11 15:43:51 -0700632typedef InstX8632Binop<InstX8632::Subps> InstX8632Subps;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700633typedef InstX8632Binop<InstX8632::Subss> InstX8632Subss;
634typedef InstX8632Binop<InstX8632::Sbb> InstX8632Sbb;
Matt Wala83b80362014-07-16 10:21:30 -0700635typedef InstX8632Binop<InstX8632::Psub> InstX8632Psub;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700636typedef InstX8632Binop<InstX8632::And> InstX8632And;
Matt Wala83b80362014-07-16 10:21:30 -0700637typedef InstX8632Binop<InstX8632::Pand> InstX8632Pand;
Matt Wala9cb61e22014-07-24 09:44:42 -0700638typedef InstX8632Binop<InstX8632::Pandn> InstX8632Pandn;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700639typedef InstX8632Binop<InstX8632::Or> InstX8632Or;
Matt Wala7fa22d82014-07-17 12:41:31 -0700640typedef InstX8632Binop<InstX8632::Por> InstX8632Por;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700641typedef InstX8632Binop<InstX8632::Xor> InstX8632Xor;
Matt Wala928f1292014-07-07 16:50:46 -0700642typedef InstX8632Binop<InstX8632::Pxor> InstX8632Pxor;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700643typedef InstX8632Binop<InstX8632::Imul> InstX8632Imul;
Matt Wala8d1072e2014-07-11 15:43:51 -0700644typedef InstX8632Binop<InstX8632::Mulps> InstX8632Mulps;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700645typedef InstX8632Binop<InstX8632::Mulss> InstX8632Mulss;
Matt Wala0a450512014-07-30 12:44:39 -0700646typedef InstX8632Binop<InstX8632::Pmull> InstX8632Pmull;
Matt Wala7fa22d82014-07-17 12:41:31 -0700647typedef InstX8632Binop<InstX8632::Pmuludq> InstX8632Pmuludq;
Matt Wala8d1072e2014-07-11 15:43:51 -0700648typedef InstX8632Binop<InstX8632::Divps> InstX8632Divps;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700649typedef InstX8632Binop<InstX8632::Divss> InstX8632Divss;
Jan Voung7fa813b2014-07-18 13:01:08 -0700650typedef InstX8632Binop<InstX8632::Rol, true> InstX8632Rol;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700651typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl;
Matt Wala83b80362014-07-16 10:21:30 -0700652typedef InstX8632Binop<InstX8632::Psll> InstX8632Psll;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700653typedef InstX8632Binop<InstX8632::Shr, true> InstX8632Shr;
654typedef InstX8632Binop<InstX8632::Sar, true> InstX8632Sar;
Matt Wala83b80362014-07-16 10:21:30 -0700655typedef InstX8632Binop<InstX8632::Psra> InstX8632Psra;
656typedef InstX8632Binop<InstX8632::Pcmpeq> InstX8632Pcmpeq;
657typedef InstX8632Binop<InstX8632::Pcmpgt> InstX8632Pcmpgt;
Matt Walacfe51462014-07-25 15:57:56 -0700658// TODO: movss is only a binary operation when the source and dest
659// operands are both registers. In other cases, it behaves like a copy
660// (mov-like) operation. Eventually, InstX8632Movss should assert that
661// both its source and dest operands are registers, and the lowering
662// code should use _mov instead of _movss in cases where a copy
663// operation is intended.
664typedef InstX8632Binop<InstX8632::Movss> InstX8632Movss;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700665typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv;
666typedef InstX8632Ternop<InstX8632::Div> InstX8632Div;
Matt Wala0a450512014-07-30 12:44:39 -0700667typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
668typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
Matt Wala49889232014-07-18 12:45:09 -0700669typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
Matt Wala0a450512014-07-30 12:44:39 -0700670typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
671typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
672typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
Matt Wala49889232014-07-18 12:45:09 -0700673typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700674
Jan Vounga3a01a22014-07-14 10:32:41 -0700675// Base class for a lockable x86-32 instruction (emits a locked prefix).
676class InstX8632Lockable : public InstX8632 {
677public:
678 virtual void emit(const Cfg *Func) const = 0;
679 virtual void dump(const Cfg *Func) const;
680
681protected:
682 bool Locked;
683
684 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
685 Variable *Dest, bool Locked)
686 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
687 // Assume that such instructions are used for Atomics and be careful
688 // with optimizations.
689 HasSideEffects = Locked;
690 }
Jan Voung1e889582014-07-30 14:33:37 -0700691 virtual ~InstX8632Lockable() {}
Jan Vounga3a01a22014-07-14 10:32:41 -0700692
693private:
694 InstX8632Lockable(const InstX8632Lockable &) LLVM_DELETED_FUNCTION;
695 InstX8632Lockable &operator=(const InstX8632Lockable &) LLVM_DELETED_FUNCTION;
696};
697
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700698// Mul instruction - unsigned multiply.
699class InstX8632Mul : public InstX8632 {
700public:
701 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
702 Operand *Source2) {
703 return new (Func->allocate<InstX8632Mul>())
704 InstX8632Mul(Func, Dest, Source1, Source2);
705 }
706 virtual void emit(const Cfg *Func) const;
707 virtual void dump(const Cfg *Func) const;
708 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
709
710private:
711 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
712 InstX8632Mul(const InstX8632Mul &) LLVM_DELETED_FUNCTION;
713 InstX8632Mul &operator=(const InstX8632Mul &) LLVM_DELETED_FUNCTION;
714 virtual ~InstX8632Mul() {}
715};
716
717// Shld instruction - shift across a pair of operands. TODO: Verify
718// that the validator accepts the shld instruction.
719class InstX8632Shld : public InstX8632 {
720public:
721 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
722 Variable *Source2) {
723 return new (Func->allocate<InstX8632Shld>())
724 InstX8632Shld(Func, Dest, Source1, Source2);
725 }
726 virtual void emit(const Cfg *Func) const;
727 virtual void dump(const Cfg *Func) const;
728 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
729
730private:
731 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
732 Variable *Source2);
733 InstX8632Shld(const InstX8632Shld &) LLVM_DELETED_FUNCTION;
734 InstX8632Shld &operator=(const InstX8632Shld &) LLVM_DELETED_FUNCTION;
735 virtual ~InstX8632Shld() {}
736};
737
738// Shrd instruction - shift across a pair of operands. TODO: Verify
739// that the validator accepts the shrd instruction.
740class InstX8632Shrd : public InstX8632 {
741public:
742 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
743 Variable *Source2) {
744 return new (Func->allocate<InstX8632Shrd>())
745 InstX8632Shrd(Func, Dest, Source1, Source2);
746 }
747 virtual void emit(const Cfg *Func) const;
748 virtual void dump(const Cfg *Func) const;
749 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
750
751private:
752 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
753 Variable *Source2);
754 InstX8632Shrd(const InstX8632Shrd &) LLVM_DELETED_FUNCTION;
755 InstX8632Shrd &operator=(const InstX8632Shrd &) LLVM_DELETED_FUNCTION;
756 virtual ~InstX8632Shrd() {}
757};
758
Jan Vounge4da26f2014-07-15 17:52:39 -0700759// Conditional move instruction.
760class InstX8632Cmov : public InstX8632 {
761public:
762 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
763 BrCond Cond) {
764 return new (Func->allocate<InstX8632Cmov>())
765 InstX8632Cmov(Func, Dest, Source, Cond);
766 }
767 virtual void emit(const Cfg *Func) const;
768 virtual void dump(const Cfg *Func) const;
769 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
770
771private:
772 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond);
773 InstX8632Cmov(const InstX8632Cmov &) LLVM_DELETED_FUNCTION;
774 InstX8632Cmov &operator=(const InstX8632Cmov &) LLVM_DELETED_FUNCTION;
775 virtual ~InstX8632Cmov() {}
776
777 BrCond Condition;
778};
779
Matt Walace0ca8f2014-07-24 12:34:20 -0700780// Cmpps instruction - compare packed singled-precision floating point
781// values
782class InstX8632Cmpps : public InstX8632 {
783public:
784 enum CmppsCond {
785#define X(tag, emit) tag,
786 ICEINSTX8632CMPPS_TABLE
787#undef X
788 Cmpps_Invalid
789 };
790
791 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
792 CmppsCond Condition) {
793 return new (Func->allocate<InstX8632Cmpps>())
794 InstX8632Cmpps(Func, Dest, Source, Condition);
795 }
796 virtual void emit(const Cfg *Func) const;
797 virtual void dump(const Cfg *Func) const;
798 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
799
800private:
801 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond);
802 InstX8632Cmpps(const InstX8632Cmpps &) LLVM_DELETED_FUNCTION;
803 InstX8632Cmpps &operator=(const InstX8632Cmpps &) LLVM_DELETED_FUNCTION;
804 virtual ~InstX8632Cmpps() {}
805
806 CmppsCond Condition;
807};
808
Jan Vounga3a01a22014-07-14 10:32:41 -0700809// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
810// equals eax. If so, the ZF is set and <desired> is stored in <dest>.
811// If not, ZF is cleared and <dest> is copied to eax (or subregister).
812// <dest> can be a register or memory, while <desired> must be a register.
813// It is the user's responsiblity to mark eax with a FakeDef.
814class InstX8632Cmpxchg : public InstX8632Lockable {
815public:
816 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
817 Variable *Desired, bool Locked) {
818 return new (Func->allocate<InstX8632Cmpxchg>())
819 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
820 }
821 virtual void emit(const Cfg *Func) const;
822 virtual void dump(const Cfg *Func) const;
823 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
824
825private:
826 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
827 Variable *Desired, bool Locked);
828 InstX8632Cmpxchg(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION;
829 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION;
830 virtual ~InstX8632Cmpxchg() {}
831};
832
833// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
834// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
835// If not, ZF is cleared and <m64> is copied to edx:eax.
836// The caller is responsible for inserting FakeDefs to mark edx
837// and eax as modified.
838// <m64> must be a memory operand.
839class InstX8632Cmpxchg8b : public InstX8632Lockable {
840public:
841 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632 *Dest,
842 Variable *Edx, Variable *Eax, Variable *Ecx,
843 Variable *Ebx, bool Locked) {
844 return new (Func->allocate<InstX8632Cmpxchg8b>())
845 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
846 }
847 virtual void emit(const Cfg *Func) const;
848 virtual void dump(const Cfg *Func) const;
849 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
850
851private:
852 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Dest, Variable *Edx,
853 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
854 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION;
855 InstX8632Cmpxchg8b &
856 operator=(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION;
857 virtual ~InstX8632Cmpxchg8b() {}
858};
859
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700860// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
861// as appropriate. s=float, d=double, i=int. X and Y are determined
862// from dest/src types. Sign and zero extension on the integer
863// operand needs to be done separately.
864class InstX8632Cvt : public InstX8632 {
865public:
866 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source) {
867 return new (Func->allocate<InstX8632Cvt>())
868 InstX8632Cvt(Func, Dest, Source);
869 }
870 virtual void emit(const Cfg *Func) const;
871 virtual void dump(const Cfg *Func) const;
872 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
873
874private:
875 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source);
876 InstX8632Cvt(const InstX8632Cvt &) LLVM_DELETED_FUNCTION;
877 InstX8632Cvt &operator=(const InstX8632Cvt &) LLVM_DELETED_FUNCTION;
878 virtual ~InstX8632Cvt() {}
879};
880
881// cmp - Integer compare instruction.
882class InstX8632Icmp : public InstX8632 {
883public:
884 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
885 return new (Func->allocate<InstX8632Icmp>())
886 InstX8632Icmp(Func, Src1, Src2);
887 }
888 virtual void emit(const Cfg *Func) const;
889 virtual void dump(const Cfg *Func) const;
890 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
891
892private:
893 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
894 InstX8632Icmp(const InstX8632Icmp &) LLVM_DELETED_FUNCTION;
895 InstX8632Icmp &operator=(const InstX8632Icmp &) LLVM_DELETED_FUNCTION;
896 virtual ~InstX8632Icmp() {}
897};
898
899// ucomiss/ucomisd - floating-point compare instruction.
900class InstX8632Ucomiss : public InstX8632 {
901public:
902 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
903 return new (Func->allocate<InstX8632Ucomiss>())
904 InstX8632Ucomiss(Func, Src1, Src2);
905 }
906 virtual void emit(const Cfg *Func) const;
907 virtual void dump(const Cfg *Func) const;
908 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
909
910private:
911 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
912 InstX8632Ucomiss(const InstX8632Ucomiss &) LLVM_DELETED_FUNCTION;
913 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) LLVM_DELETED_FUNCTION;
914 virtual ~InstX8632Ucomiss() {}
915};
916
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700917// UD2 instruction.
918class InstX8632UD2 : public InstX8632 {
919public:
920 static InstX8632UD2 *create(Cfg *Func) {
921 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
922 }
923 virtual void emit(const Cfg *Func) const;
924 virtual void dump(const Cfg *Func) const;
925 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
926
927private:
928 InstX8632UD2(Cfg *Func);
929 InstX8632UD2(const InstX8632UD2 &) LLVM_DELETED_FUNCTION;
930 InstX8632UD2 &operator=(const InstX8632UD2 &) LLVM_DELETED_FUNCTION;
931 virtual ~InstX8632UD2() {}
932};
933
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700934// Test instruction.
935class InstX8632Test : public InstX8632 {
936public:
937 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
938 return new (Func->allocate<InstX8632Test>())
939 InstX8632Test(Func, Source1, Source2);
940 }
941 virtual void emit(const Cfg *Func) const;
942 virtual void dump(const Cfg *Func) const;
943 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
944
945private:
946 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
947 InstX8632Test(const InstX8632Test &) LLVM_DELETED_FUNCTION;
948 InstX8632Test &operator=(const InstX8632Test &) LLVM_DELETED_FUNCTION;
949 virtual ~InstX8632Test() {}
950};
951
Jan Voung5cd240d2014-06-25 10:36:46 -0700952// Mfence instruction.
953class InstX8632Mfence : public InstX8632 {
954public:
955 static InstX8632Mfence *create(Cfg *Func) {
956 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
957 }
958 virtual void emit(const Cfg *Func) const;
959 virtual void dump(const Cfg *Func) const;
960 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
961
962private:
963 InstX8632Mfence(Cfg *Func);
964 InstX8632Mfence(const InstX8632Mfence &) LLVM_DELETED_FUNCTION;
965 InstX8632Mfence &operator=(const InstX8632Mfence &) LLVM_DELETED_FUNCTION;
966 virtual ~InstX8632Mfence() {}
967};
968
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700969// This is essentially a "mov" instruction with an OperandX8632Mem
970// operand instead of Variable as the destination. It's important
971// for liveness that there is no Dest operand.
972class InstX8632Store : public InstX8632 {
973public:
974 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
975 return new (Func->allocate<InstX8632Store>())
976 InstX8632Store(Func, Value, Mem);
977 }
978 virtual void emit(const Cfg *Func) const;
979 virtual void dump(const Cfg *Func) const;
980 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
981
982private:
983 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
984 InstX8632Store(const InstX8632Store &) LLVM_DELETED_FUNCTION;
985 InstX8632Store &operator=(const InstX8632Store &) LLVM_DELETED_FUNCTION;
986 virtual ~InstX8632Store() {}
987};
988
Matt Wala105b7042014-08-11 19:56:19 -0700989class InstX8632StoreP : public InstX8632 {
990public:
991 static InstX8632StoreP *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
992 return new (Func->allocate<InstX8632StoreP>())
993 InstX8632StoreP(Func, Value, Mem);
994 }
995 virtual void emit(const Cfg *Func) const;
996 virtual void dump(const Cfg *Func) const;
997 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
998
999private:
1000 InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem);
1001 InstX8632StoreP(const InstX8632StoreP &) LLVM_DELETED_FUNCTION;
1002 InstX8632StoreP &operator=(const InstX8632StoreP &) LLVM_DELETED_FUNCTION;
1003 virtual ~InstX8632StoreP() {}
1004};
1005
Jan Voung5cd240d2014-06-25 10:36:46 -07001006// This is essentially a "movq" instruction with an OperandX8632Mem
1007// operand instead of Variable as the destination. It's important
1008// for liveness that there is no Dest operand.
1009class InstX8632StoreQ : public InstX8632 {
1010public:
1011 static InstX8632StoreQ *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1012 return new (Func->allocate<InstX8632StoreQ>())
1013 InstX8632StoreQ(Func, Value, Mem);
1014 }
1015 virtual void emit(const Cfg *Func) const;
1016 virtual void dump(const Cfg *Func) const;
1017 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1018
1019private:
1020 InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem);
1021 InstX8632StoreQ(const InstX8632StoreQ &) LLVM_DELETED_FUNCTION;
1022 InstX8632StoreQ &operator=(const InstX8632StoreQ &) LLVM_DELETED_FUNCTION;
1023 virtual ~InstX8632StoreQ() {}
1024};
1025
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001026// Movsx - copy from a narrower integer type to a wider integer
1027// type, with sign extension.
1028class InstX8632Movsx : public InstX8632 {
1029public:
1030 static InstX8632Movsx *create(Cfg *Func, Variable *Dest, Operand *Source) {
1031 return new (Func->allocate<InstX8632Movsx>())
1032 InstX8632Movsx(Func, Dest, Source);
1033 }
1034 virtual void emit(const Cfg *Func) const;
1035 virtual void dump(const Cfg *Func) const;
1036 static bool classof(const Inst *Inst) { return isClassof(Inst, Movsx); }
1037
1038private:
1039 InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source);
1040 InstX8632Movsx(const InstX8632Movsx &) LLVM_DELETED_FUNCTION;
1041 InstX8632Movsx &operator=(const InstX8632Movsx &) LLVM_DELETED_FUNCTION;
1042 virtual ~InstX8632Movsx() {}
1043};
1044
1045// Movsx - copy from a narrower integer type to a wider integer
1046// type, with zero extension.
1047class InstX8632Movzx : public InstX8632 {
1048public:
1049 static InstX8632Movzx *create(Cfg *Func, Variable *Dest, Operand *Source) {
1050 return new (Func->allocate<InstX8632Movzx>())
1051 InstX8632Movzx(Func, Dest, Source);
1052 }
1053 virtual void emit(const Cfg *Func) const;
1054 virtual void dump(const Cfg *Func) const;
1055 static bool classof(const Inst *Inst) { return isClassof(Inst, Movzx); }
1056
1057private:
1058 InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source);
1059 InstX8632Movzx(const InstX8632Movzx &) LLVM_DELETED_FUNCTION;
1060 InstX8632Movzx &operator=(const InstX8632Movzx &) LLVM_DELETED_FUNCTION;
1061 virtual ~InstX8632Movzx() {}
1062};
1063
Matt Walac3302742014-08-15 16:21:56 -07001064// Nop instructions of varying length
1065class InstX8632Nop : public InstX8632 {
1066public:
1067 // TODO: Replace with enum.
1068 typedef unsigned NopVariant;
1069
1070 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1071 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1072 }
1073 virtual void emit(const Cfg *Func) const;
1074 virtual void dump(const Cfg *Func) const;
1075 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1076
1077private:
1078 InstX8632Nop(Cfg *Func, SizeT Length);
1079 InstX8632Nop(const InstX8632Nop &) LLVM_DELETED_FUNCTION;
1080 InstX8632Nop &operator=(const InstX8632Nop &) LLVM_DELETED_FUNCTION;
1081 virtual ~InstX8632Nop() {}
1082
1083 NopVariant Variant;
1084};
1085
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001086// Fld - load a value onto the x87 FP stack.
1087class InstX8632Fld : public InstX8632 {
1088public:
1089 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1090 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1091 }
1092 virtual void emit(const Cfg *Func) const;
1093 virtual void dump(const Cfg *Func) const;
1094 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1095
1096private:
1097 InstX8632Fld(Cfg *Func, Operand *Src);
1098 InstX8632Fld(const InstX8632Fld &) LLVM_DELETED_FUNCTION;
1099 InstX8632Fld &operator=(const InstX8632Fld &) LLVM_DELETED_FUNCTION;
1100 virtual ~InstX8632Fld() {}
1101};
1102
1103// Fstp - store x87 st(0) into memory and pop st(0).
1104class InstX8632Fstp : public InstX8632 {
1105public:
1106 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1107 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1108 }
1109 virtual void emit(const Cfg *Func) const;
1110 virtual void dump(const Cfg *Func) const;
1111 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
1112
1113private:
1114 InstX8632Fstp(Cfg *Func, Variable *Dest);
1115 InstX8632Fstp(const InstX8632Fstp &) LLVM_DELETED_FUNCTION;
1116 InstX8632Fstp &operator=(const InstX8632Fstp &) LLVM_DELETED_FUNCTION;
1117 virtual ~InstX8632Fstp() {}
1118};
1119
1120class InstX8632Pop : public InstX8632 {
1121public:
1122 static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
1123 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
1124 }
1125 virtual void emit(const Cfg *Func) const;
1126 virtual void dump(const Cfg *Func) const;
1127 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1128
1129private:
1130 InstX8632Pop(Cfg *Func, Variable *Dest);
1131 InstX8632Pop(const InstX8632Pop &) LLVM_DELETED_FUNCTION;
1132 InstX8632Pop &operator=(const InstX8632Pop &) LLVM_DELETED_FUNCTION;
1133 virtual ~InstX8632Pop() {}
1134};
1135
1136class InstX8632Push : public InstX8632 {
1137public:
1138 static InstX8632Push *create(Cfg *Func, Operand *Source,
1139 bool SuppressStackAdjustment) {
1140 return new (Func->allocate<InstX8632Push>())
1141 InstX8632Push(Func, Source, SuppressStackAdjustment);
1142 }
1143 virtual void emit(const Cfg *Func) const;
1144 virtual void dump(const Cfg *Func) const;
1145 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1146
1147private:
1148 InstX8632Push(Cfg *Func, Operand *Source, bool SuppressStackAdjustment);
1149 InstX8632Push(const InstX8632Push &) LLVM_DELETED_FUNCTION;
1150 InstX8632Push &operator=(const InstX8632Push &) LLVM_DELETED_FUNCTION;
1151 bool SuppressStackAdjustment;
1152 virtual ~InstX8632Push() {}
1153};
1154
1155// Ret instruction. Currently only supports the "ret" version that
1156// does not pop arguments. This instruction takes a Source operand
1157// (for non-void returning functions) for liveness analysis, though
1158// a FakeUse before the ret would do just as well.
1159class InstX8632Ret : public InstX8632 {
1160public:
1161 static InstX8632Ret *create(Cfg *Func, Variable *Source = NULL) {
1162 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1163 }
1164 virtual void emit(const Cfg *Func) const;
1165 virtual void dump(const Cfg *Func) const;
1166 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1167
1168private:
1169 InstX8632Ret(Cfg *Func, Variable *Source);
1170 InstX8632Ret(const InstX8632Ret &) LLVM_DELETED_FUNCTION;
1171 InstX8632Ret &operator=(const InstX8632Ret &) LLVM_DELETED_FUNCTION;
1172 virtual ~InstX8632Ret() {}
1173};
1174
Jan Voung5cd240d2014-06-25 10:36:46 -07001175// Exchanging Add instruction. Exchanges the first operand (destination
1176// operand) with the second operand (source operand), then loads the sum
1177// of the two values into the destination operand. The destination may be
1178// a register or memory, while the source must be a register.
1179//
1180// Both the dest and source are updated. The caller should then insert a
1181// FakeDef to reflect the second udpate.
Jan Vounga3a01a22014-07-14 10:32:41 -07001182class InstX8632Xadd : public InstX8632Lockable {
Jan Voung5cd240d2014-06-25 10:36:46 -07001183public:
1184 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1185 bool Locked) {
1186 return new (Func->allocate<InstX8632Xadd>())
1187 InstX8632Xadd(Func, Dest, Source, Locked);
1188 }
1189 virtual void emit(const Cfg *Func) const;
1190 virtual void dump(const Cfg *Func) const;
1191 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1192
1193private:
Jan Voung5cd240d2014-06-25 10:36:46 -07001194 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
1195 InstX8632Xadd(const InstX8632Xadd &) LLVM_DELETED_FUNCTION;
1196 InstX8632Xadd &operator=(const InstX8632Xadd &) LLVM_DELETED_FUNCTION;
1197 virtual ~InstX8632Xadd() {}
1198};
1199
Jan Vounga3a01a22014-07-14 10:32:41 -07001200// Exchange instruction. Exchanges the first operand (destination
1201// operand) with the second operand (source operand). At least one of
1202// the operands must be a register (and the other can be reg or mem).
1203// Both the Dest and Source are updated. If there is a memory operand,
1204// then the instruction is automatically "locked" without the need for
1205// a lock prefix.
1206class InstX8632Xchg : public InstX8632 {
1207public:
1208 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1209 return new (Func->allocate<InstX8632Xchg>())
1210 InstX8632Xchg(Func, Dest, Source);
1211 }
1212 virtual void emit(const Cfg *Func) const;
1213 virtual void dump(const Cfg *Func) const;
1214 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
1215
1216private:
1217 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
1218 InstX8632Xchg(const InstX8632Xchg &) LLVM_DELETED_FUNCTION;
1219 InstX8632Xchg &operator=(const InstX8632Xchg &) LLVM_DELETED_FUNCTION;
1220 virtual ~InstX8632Xchg() {}
1221};
1222
Jim Stichnoth6e992142014-07-30 14:45:20 -07001223// Declare partial template specializations of emit() methods that
1224// already have default implementations. Without this, there is the
1225// possibility of ODR violations and link errors.
1226template <> void InstX8632Addss::emit(const Cfg *Func) const;
1227template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
Matt Wala51e8cfb2014-08-08 08:39:40 -07001228template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
Jim Stichnoth6e992142014-07-30 14:45:20 -07001229template <> void InstX8632Div::emit(const Cfg *Func) const;
1230template <> void InstX8632Divss::emit(const Cfg *Func) const;
1231template <> void InstX8632Idiv::emit(const Cfg *Func) const;
1232template <> void InstX8632Imul::emit(const Cfg *Func) const;
1233template <> void InstX8632Lea::emit(const Cfg *Func) const;
1234template <> void InstX8632Mulss::emit(const Cfg *Func) const;
1235template <> void InstX8632Padd::emit(const Cfg *Func) const;
1236template <> void InstX8632Pblendvb::emit(const Cfg *Func) const;
1237template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const;
1238template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const;
1239template <> void InstX8632Pextr::emit(const Cfg *Func) const;
1240template <> void InstX8632Pinsr::emit(const Cfg *Func) const;
1241template <> void InstX8632Pmull::emit(const Cfg *Func) const;
1242template <> void InstX8632Pmuludq::emit(const Cfg *Func) const;
1243template <> void InstX8632Psll::emit(const Cfg *Func) const;
1244template <> void InstX8632Psra::emit(const Cfg *Func) const;
1245template <> void InstX8632Psub::emit(const Cfg *Func) const;
1246template <> void InstX8632Sqrtss::emit(const Cfg *Func) const;
1247template <> void InstX8632Subss::emit(const Cfg *Func) const;
1248
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001249} // end of namespace Ice
1250
1251#endif // SUBZERO_SRC_ICEINSTX8632_H