blob: d9a841956aacc61bc81d999dca3d0a6170598c0b [file] [log] [blame]
Jan Voungb36ad9b2015-04-21 17:01:49 -07001//===- subzero/src/IceInstX8632.h - x86-32 machine instructions -*- C++ -*-===//
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07002//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the InstX8632 and OperandX8632 classes and
11// their subclasses. This represents the machine instructions and
12// operands used for x86-32 code selection.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICEINSTX8632_H
17#define SUBZERO_SRC_ICEINSTX8632_H
18
John Portoaff4ccf2015-06-10 16:35:06 -070019#include "IceAssemblerX8632.h"
Jan Voung3bfd99a2015-05-22 16:35:25 -070020#include "IceConditionCodesX8632.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070021#include "IceDefs.h"
22#include "IceInst.h"
23#include "IceInstX8632.def"
24#include "IceOperand.h"
25
26namespace Ice {
27
28class TargetX8632;
29
30// OperandX8632 extends the Operand hierarchy. Its subclasses are
31// OperandX8632Mem and VariableSplit.
32class OperandX8632 : public Operand {
Jim Stichnothc6ead202015-02-24 09:30:30 -080033 OperandX8632() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -070034 OperandX8632(const OperandX8632 &) = delete;
35 OperandX8632 &operator=(const OperandX8632 &) = delete;
36
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070037public:
Jim Stichnothdd842db2015-01-27 12:53:53 -080038 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit };
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -070039 using Operand::dump;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070040 void dump(const Cfg *, Ostream &Str) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -080041 if (ALLOW_DUMP)
42 Str << "<OperandX8632>";
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -070043 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070044
45protected:
46 OperandX8632(OperandKindX8632 Kind, Type Ty)
47 : Operand(static_cast<OperandKind>(Kind), Ty) {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -070048 ~OperandX8632() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070049};
50
51// OperandX8632Mem represents the m32 addressing mode, with optional
52// base and index registers, a constant offset, and a fixed shift
53// value for the index register.
54class OperandX8632Mem : public OperandX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -080055 OperandX8632Mem() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -070056 OperandX8632Mem(const OperandX8632Mem &) = delete;
57 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
58
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070059public:
Jan Voung3bd9f1a2014-06-18 10:50:57 -070060 enum SegmentRegisters {
61 DefaultSegment = -1,
Jan Voungfe14fb82014-10-13 15:56:32 -070062#define X(val, name, prefix) val,
Jan Vounga3a01a22014-07-14 10:32:41 -070063 SEG_REGX8632_TABLE
Jan Voung3bd9f1a2014-06-18 10:50:57 -070064#undef X
65 SegReg_NUM
66 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070067 static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base,
Jim Stichnothae953202014-12-20 06:17:49 -080068 Constant *Offset, Variable *Index = nullptr,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070069 uint16_t Shift = 0,
70 SegmentRegisters SegmentReg = DefaultSegment) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070071 return new (Func->allocate<OperandX8632Mem>())
Jan Voung3bd9f1a2014-06-18 10:50:57 -070072 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070073 }
74 Variable *getBase() const { return Base; }
75 Constant *getOffset() const { return Offset; }
76 Variable *getIndex() const { return Index; }
Jan Voung3bd9f1a2014-06-18 10:50:57 -070077 uint16_t getShift() const { return Shift; }
78 SegmentRegisters getSegmentRegister() const { return SegmentReg; }
Jan Voung90ccc3f2015-04-30 14:15:10 -070079 void emitSegmentOverride(X8632::AssemblerX8632 *Asm) const;
80 X8632::Address toAsmAddress(Assembler *Asm) const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070081 void emit(const Cfg *Func) const override;
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -070082 using OperandX8632::dump;
Jim Stichnothb56c8f42014-09-26 09:28:46 -070083 void dump(const Cfg *Func, Ostream &Str) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070084
85 static bool classof(const Operand *Operand) {
86 return Operand->getKind() == static_cast<OperandKind>(kMem);
87 }
88
89private:
90 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070091 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
Jim Stichnothb56c8f42014-09-26 09:28:46 -070092 ~OperandX8632Mem() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070093 Variable *Base;
94 Constant *Offset;
95 Variable *Index;
Jan Voung3bd9f1a2014-06-18 10:50:57 -070096 uint16_t Shift;
97 SegmentRegisters SegmentReg : 16;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070098};
99
100// VariableSplit is a way to treat an f64 memory location as a pair
101// of i32 locations (Low and High). This is needed for some cases
102// of the Bitcast instruction. Since it's not possible for integer
103// registers to access the XMM registers and vice versa, the
104// lowering forces the f64 to be spilled to the stack and then
105// accesses through the VariableSplit.
106class VariableSplit : public OperandX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800107 VariableSplit() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700108 VariableSplit(const VariableSplit &) = delete;
109 VariableSplit &operator=(const VariableSplit &) = delete;
110
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700111public:
Jim Stichnothdd842db2015-01-27 12:53:53 -0800112 enum Portion { Low, High };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700113 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
114 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
115 }
Jan Voungfe14fb82014-10-13 15:56:32 -0700116 int32_t getOffset() const { return Part == High ? 4 : 0; }
117
Jan Voung90ccc3f2015-04-30 14:15:10 -0700118 X8632::Address toAsmAddress(const Cfg *Func) const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700119 void emit(const Cfg *Func) const override;
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -0700120 using OperandX8632::dump;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700121 void dump(const Cfg *Func, Ostream &Str) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700122
123 static bool classof(const Operand *Operand) {
124 return Operand->getKind() == static_cast<OperandKind>(kSplit);
125 }
126
127private:
128 VariableSplit(Cfg *Func, Variable *Var, Portion Part)
129 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) {
130 assert(Var->getType() == IceType_f64);
131 Vars = Func->allocateArrayOf<Variable *>(1);
132 Vars[0] = Var;
133 NumVars = 1;
134 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700135 ~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700136 Cfg *Func; // Held only for the destructor.
137 Variable *Var;
138 Portion Part;
139};
140
Jim Stichnoth800dab22014-09-20 12:25:02 -0700141// SpillVariable decorates a Variable by linking it to another
142// Variable. When stack frame offsets are computed, the SpillVariable
143// is given a distinct stack slot only if its linked Variable has a
144// register. If the linked Variable has a stack slot, then the
145// Variable and SpillVariable share that slot.
146class SpillVariable : public Variable {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800147 SpillVariable() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700148 SpillVariable(const SpillVariable &) = delete;
149 SpillVariable &operator=(const SpillVariable &) = delete;
150
Jim Stichnoth800dab22014-09-20 12:25:02 -0700151public:
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800152 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) {
153 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index);
Jim Stichnoth800dab22014-09-20 12:25:02 -0700154 }
155 const static OperandKind SpillVariableKind =
156 static_cast<OperandKind>(kVariable_Target);
157 static bool classof(const Operand *Operand) {
158 return Operand->getKind() == SpillVariableKind;
159 }
160 void setLinkedTo(Variable *Var) { LinkedTo = Var; }
161 Variable *getLinkedTo() const { return LinkedTo; }
162 // Inherit dump() and emit() from Variable.
163private:
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800164 SpillVariable(Type Ty, SizeT Index)
Jim Stichnothae953202014-12-20 06:17:49 -0800165 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {}
Jim Stichnoth800dab22014-09-20 12:25:02 -0700166 Variable *LinkedTo;
167};
168
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700169class InstX8632 : public InstTarget {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800170 InstX8632() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700171 InstX8632(const InstX8632 &) = delete;
172 InstX8632 &operator=(const InstX8632 &) = delete;
173
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700174public:
175 enum InstKindX8632 {
176 k__Start = Inst::Target,
177 Adc,
178 Add,
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700179 AddRMW,
Matt Wala8d1072e2014-07-11 15:43:51 -0700180 Addps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700181 Addss,
Matt Wala105b7042014-08-11 19:56:19 -0700182 Adjuststack,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700183 And,
Matt Wala0a450512014-07-30 12:44:39 -0700184 Blendvps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700185 Br,
Jan Vounge4da26f2014-07-15 17:52:39 -0700186 Bsf,
187 Bsr,
Jan Voung7fa813b2014-07-18 13:01:08 -0700188 Bswap,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700189 Call,
Matt Walaafeaee42014-08-07 13:47:30 -0700190 Cbwdq,
Jan Vounge4da26f2014-07-15 17:52:39 -0700191 Cmov,
Matt Walace0ca8f2014-07-24 12:34:20 -0700192 Cmpps,
Jan Vounga3a01a22014-07-14 10:32:41 -0700193 Cmpxchg,
194 Cmpxchg8b,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700195 Cvt,
196 Div,
Matt Wala8d1072e2014-07-11 15:43:51 -0700197 Divps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700198 Divss,
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700199 FakeRMW,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700200 Fld,
201 Fstp,
202 Icmp,
203 Idiv,
204 Imul,
Matt Wala0a450512014-07-30 12:44:39 -0700205 Insertps,
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800206 Jmp,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700207 Label,
Matt Wala49889232014-07-18 12:45:09 -0700208 Lea,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700209 Load,
Jan Voung5cd240d2014-06-25 10:36:46 -0700210 Mfence,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700211 Mov,
Matt Wala49889232014-07-18 12:45:09 -0700212 Movd,
Matt Wala928f1292014-07-07 16:50:46 -0700213 Movp,
Jan Voung5cd240d2014-06-25 10:36:46 -0700214 Movq,
Jan Vounge4dc61b2014-10-06 08:53:52 -0700215 MovssRegs,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700216 Movsx,
217 Movzx,
218 Mul,
Matt Wala8d1072e2014-07-11 15:43:51 -0700219 Mulps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700220 Mulss,
Jan Vounga3a01a22014-07-14 10:32:41 -0700221 Neg,
Matt Walac3302742014-08-15 16:21:56 -0700222 Nop,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700223 Or,
Matt Wala7fa22d82014-07-17 12:41:31 -0700224 Padd,
Matt Wala83b80362014-07-16 10:21:30 -0700225 Pand,
Matt Wala9cb61e22014-07-24 09:44:42 -0700226 Pandn,
Matt Wala0a450512014-07-30 12:44:39 -0700227 Pblendvb,
Matt Wala83b80362014-07-16 10:21:30 -0700228 Pcmpeq,
229 Pcmpgt,
Matt Wala0a450512014-07-30 12:44:39 -0700230 Pextr,
231 Pinsr,
232 Pmull,
Matt Wala7fa22d82014-07-17 12:41:31 -0700233 Pmuludq,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700234 Pop,
Matt Wala7fa22d82014-07-17 12:41:31 -0700235 Por,
236 Pshufd,
Matt Wala83b80362014-07-16 10:21:30 -0700237 Psll,
238 Psra,
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700239 Psrl,
Matt Wala83b80362014-07-16 10:21:30 -0700240 Psub,
Matt Wala7fa22d82014-07-17 12:41:31 -0700241 Push,
Matt Wala928f1292014-07-07 16:50:46 -0700242 Pxor,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700243 Ret,
Jan Voung7fa813b2014-07-18 13:01:08 -0700244 Rol,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700245 Sar,
246 Sbb,
Jim Stichnothf48b3202015-05-04 10:22:17 -0700247 Setcc,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700248 Shl,
249 Shld,
250 Shr,
251 Shrd,
Matt Wala7fa22d82014-07-17 12:41:31 -0700252 Shufps,
Jan Voungf37fbbe2014-07-09 16:13:13 -0700253 Sqrtss,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700254 Store,
Matt Wala105b7042014-08-11 19:56:19 -0700255 StoreP,
Jan Voung5cd240d2014-06-25 10:36:46 -0700256 StoreQ,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700257 Sub,
Matt Wala8d1072e2014-07-11 15:43:51 -0700258 Subps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700259 Subss,
260 Test,
261 Ucomiss,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700262 UD2,
Jan Voung5cd240d2014-06-25 10:36:46 -0700263 Xadd,
Jan Vounga3a01a22014-07-14 10:32:41 -0700264 Xchg,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700265 Xor
266 };
Jan Vounge4da26f2014-07-15 17:52:39 -0700267
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700268 static const char *getWidthString(Type Ty);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700269 static const char *getFldString(Type Ty);
Jim Stichnoth537b5ba2015-05-19 09:48:44 -0700270 static CondX86::BrCond getOppositeCondition(CondX86::BrCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700271 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700272
Jan Voung3bfd99a2015-05-22 16:35:25 -0700273 // Shared emit routines for common forms of instructions.
274 // See the definition of emitTwoAddress() for a description of
275 // ShiftHack.
276 static void emitTwoAddress(const char *Opcode, const Inst *Inst,
277 const Cfg *Func, bool ShiftHack = false);
278
279 static void
280 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
281 const Operand *Src,
282 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter);
283
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700284protected:
285 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
286 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700287 ~InstX8632() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700288 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
289 return Inst->getKind() == static_cast<InstKind>(MyKind);
290 }
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700291 // Most instructions that operate on vector arguments require vector
292 // memory operands to be fully aligned (16-byte alignment for PNaCl
293 // vector types). The stack frame layout and call ABI ensure proper
294 // alignment for stack operands, but memory operands (originating
295 // from load/store bitcode instructions) only have element-size
296 // alignment guarantees. This function validates that none of the
297 // operands is a memory operand of vector type, calling
298 // report_fatal_error() if one is found. This function should be
299 // called during emission, and maybe also in the ctor (as long as
300 // that fits the lowering style).
301 void validateVectorAddrMode() const {
302 if (getDest())
303 validateVectorAddrModeOpnd(getDest());
304 for (SizeT i = 0; i < getSrcSize(); ++i) {
305 validateVectorAddrModeOpnd(getSrc(i));
306 }
307 }
Jan Voung44c3a802015-03-27 16:29:08 -0700308
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700309private:
310 static void validateVectorAddrModeOpnd(const Operand *Opnd) {
311 if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) {
312 llvm::report_fatal_error("Possible misaligned vector memory operation");
313 }
314 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700315};
316
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700317// InstX8632FakeRMW represents a non-atomic read-modify-write operation on a
318// memory location. An InstX8632FakeRMW is a "fake" instruction in that it
319// still needs to be lowered to some actual RMW instruction.
320//
321// If A is some memory address, D is some data value to apply, and OP is an
322// arithmetic operator, the instruction operates as: (*A) = (*A) OP D
323class InstX8632FakeRMW : public InstX8632 {
324 InstX8632FakeRMW() = delete;
325 InstX8632FakeRMW(const InstX8632FakeRMW &) = delete;
326 InstX8632FakeRMW &operator=(const InstX8632FakeRMW &) = delete;
327
328public:
329 static InstX8632FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr,
330 Variable *Beacon, InstArithmetic::OpKind Op,
331 uint32_t Align = 1) {
332 // TODO(stichnot): Stop ignoring alignment specification.
333 (void)Align;
334 return new (Func->allocate<InstX8632FakeRMW>())
335 InstX8632FakeRMW(Func, Data, Addr, Op, Beacon);
336 }
337 Operand *getAddr() const { return getSrc(1); }
338 Operand *getData() const { return getSrc(0); }
339 InstArithmetic::OpKind getOp() const { return Op; }
340 Variable *getBeacon() const { return llvm::cast<Variable>(getSrc(2)); }
341 void dump(const Cfg *Func) const override;
342 static bool classof(const Inst *Inst) { return isClassof(Inst, FakeRMW); }
343
344private:
345 InstArithmetic::OpKind Op;
346 InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
347 InstArithmetic::OpKind Op, Variable *Beacon);
348 ~InstX8632FakeRMW() override {}
349};
350
Jan Voung7e1e4852014-10-24 10:29:30 -0700351// InstX8632Label represents an intra-block label that is the target
352// of an intra-block branch. The offset between the label and the
353// branch must be fit into one byte (considered "near"). These are
354// used for lowering i1 calculations, Select instructions, and 64-bit
355// compares on a 32-bit architecture, without basic block splitting.
356// Basic block splitting is not so desirable for several reasons, one
357// of which is the impact on decisions based on whether a variable's
358// live range spans multiple basic blocks.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700359//
360// Intra-block control flow must be used with caution. Consider the
361// sequence for "c = (a >= b ? x : y)".
362// cmp a, b
363// br lt, L1
364// mov c, x
365// jmp L2
366// L1:
367// mov c, y
368// L2:
369//
370// Labels L1 and L2 are intra-block labels. Without knowledge of the
371// intra-block control flow, liveness analysis will determine the "mov
372// c, x" instruction to be dead. One way to prevent this is to insert
373// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
374// instructions, e.g.:
375//
376// cmp a, b
377// br lt, L1
378// mov c, x
379// jmp L2
380// FakeUse(c)
381// L1:
382// mov c, y
383// L2:
384//
385// The down-side is that "mov c, x" can never be dead-code eliminated
386// even if there are no uses of c. As unlikely as this situation is,
387// it may be prevented by running dead code elimination before
388// lowering.
389class InstX8632Label : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800390 InstX8632Label() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700391 InstX8632Label(const InstX8632Label &) = delete;
392 InstX8632Label &operator=(const InstX8632Label &) = delete;
393
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700394public:
395 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
396 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
397 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700398 uint32_t getEmitInstCount() const override { return 0; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700399 IceString getName(const Cfg *Func) const;
Jan Voung7e1e4852014-10-24 10:29:30 -0700400 SizeT getNumber() const { return Number; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700401 void emit(const Cfg *Func) const override;
Jan Voung7e1e4852014-10-24 10:29:30 -0700402 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700403 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700404
405private:
406 InstX8632Label(Cfg *Func, TargetX8632 *Target);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700407 ~InstX8632Label() override {}
Jan Voung7e1e4852014-10-24 10:29:30 -0700408 SizeT Number; // used for unique label generation.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700409};
410
411// Conditional and unconditional branch instruction.
412class InstX8632Br : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800413 InstX8632Br() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700414 InstX8632Br(const InstX8632Br &) = delete;
415 InstX8632Br &operator=(const InstX8632Br &) = delete;
416
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700417public:
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700418 // Create a conditional branch to a node.
419 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
Jan Voungbd385e42014-09-18 18:18:10 -0700420 CfgNode *TargetFalse, CondX86::BrCond Condition) {
Jim Stichnoth98712a32014-10-24 10:59:02 -0700421 assert(Condition != CondX86::Br_None);
Jim Stichnothae953202014-12-20 06:17:49 -0800422 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700423 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700424 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700425 }
426 // Create an unconditional branch to a node.
427 static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
Jim Stichnothae953202014-12-20 06:17:49 -0800428 const CfgNode *NoCondTarget = nullptr;
429 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700430 return new (Func->allocate<InstX8632Br>())
Jan Voungbd385e42014-09-18 18:18:10 -0700431 InstX8632Br(Func, NoCondTarget, Target, NoLabel, CondX86::Br_None);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700432 }
433 // Create a non-terminator conditional branch to a node, with a
434 // fallthrough to the next instruction in the current node. This is
435 // used for switch lowering.
Jan Voungbd385e42014-09-18 18:18:10 -0700436 static InstX8632Br *create(Cfg *Func, CfgNode *Target,
437 CondX86::BrCond Condition) {
Jim Stichnoth98712a32014-10-24 10:59:02 -0700438 assert(Condition != CondX86::Br_None);
Jim Stichnothae953202014-12-20 06:17:49 -0800439 const CfgNode *NoUncondTarget = nullptr;
440 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700441 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700442 InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700443 }
444 // Create a conditional intra-block branch (or unconditional, if
Jim Stichnoth18735602014-09-16 19:59:35 -0700445 // Condition==Br_None) to a label in the current block.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700446 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
Jan Voungbd385e42014-09-18 18:18:10 -0700447 CondX86::BrCond Condition) {
Jim Stichnothae953202014-12-20 06:17:49 -0800448 const CfgNode *NoCondTarget = nullptr;
449 const CfgNode *NoUncondTarget = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700450 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700451 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700452 }
Jim Stichnothff9c7062014-09-18 04:50:49 -0700453 const CfgNode *getTargetTrue() const { return TargetTrue; }
454 const CfgNode *getTargetFalse() const { return TargetFalse; }
455 bool optimizeBranch(const CfgNode *NextNode);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700456 uint32_t getEmitInstCount() const override {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700457 uint32_t Sum = 0;
Jim Stichnoth18735602014-09-16 19:59:35 -0700458 if (Label)
Jim Stichnothff9c7062014-09-18 04:50:49 -0700459 ++Sum;
460 if (getTargetTrue())
461 ++Sum;
Jim Stichnoth18735602014-09-16 19:59:35 -0700462 if (getTargetFalse())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700463 ++Sum;
464 return Sum;
Jim Stichnoth18735602014-09-16 19:59:35 -0700465 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700466 bool isUnconditionalBranch() const override {
467 return !Label && Condition == CondX86::Br_None;
468 }
469 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700470 void emit(const Cfg *Func) const override;
Jan Voung7e1e4852014-10-24 10:29:30 -0700471 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700472 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700473 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
474
475private:
Jim Stichnothff9c7062014-09-18 04:50:49 -0700476 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
Jan Voungbd385e42014-09-18 18:18:10 -0700477 const InstX8632Label *Label, CondX86::BrCond Condition);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700478 ~InstX8632Br() override {}
Jan Voungbd385e42014-09-18 18:18:10 -0700479 CondX86::BrCond Condition;
Jim Stichnothff9c7062014-09-18 04:50:49 -0700480 const CfgNode *TargetTrue;
481 const CfgNode *TargetFalse;
482 const InstX8632Label *Label; // Intra-block branch target
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700483};
484
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800485// Jump to a target outside this function, such as tailcall, nacljump,
486// naclret, unreachable. This is different from a Branch instruction
487// in that there is no intra-function control flow to represent.
488class InstX8632Jmp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800489 InstX8632Jmp() = delete;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800490 InstX8632Jmp(const InstX8632Jmp &) = delete;
491 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete;
492
493public:
494 static InstX8632Jmp *create(Cfg *Func, Operand *Target) {
495 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target);
496 }
497 Operand *getJmpTarget() const { return getSrc(0); }
498 void emit(const Cfg *Func) const override;
499 void emitIAS(const Cfg *Func) const override;
500 void dump(const Cfg *Func) const override;
501 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); }
502
503private:
504 InstX8632Jmp(Cfg *Func, Operand *Target);
505};
506
Matt Wala105b7042014-08-11 19:56:19 -0700507// AdjustStack instruction - subtracts esp by the given amount and
508// updates the stack offset during code emission.
509class InstX8632AdjustStack : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800510 InstX8632AdjustStack() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700511 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
512 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
513
Matt Wala105b7042014-08-11 19:56:19 -0700514public:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700515 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
Matt Wala105b7042014-08-11 19:56:19 -0700516 return new (Func->allocate<InstX8632AdjustStack>())
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700517 InstX8632AdjustStack(Func, Amount, Esp);
Matt Wala105b7042014-08-11 19:56:19 -0700518 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700519 void emit(const Cfg *Func) const override;
520 void emitIAS(const Cfg *Func) const override;
521 void dump(const Cfg *Func) const override;
Matt Wala105b7042014-08-11 19:56:19 -0700522 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
523
524private:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700525 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
Matt Wala105b7042014-08-11 19:56:19 -0700526 SizeT Amount;
527};
528
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700529// Call instruction. Arguments should have already been pushed.
530class InstX8632Call : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800531 InstX8632Call() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700532 InstX8632Call(const InstX8632Call &) = delete;
533 InstX8632Call &operator=(const InstX8632Call &) = delete;
534
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700535public:
536 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
537 return new (Func->allocate<InstX8632Call>())
538 InstX8632Call(Func, Dest, CallTarget);
539 }
540 Operand *getCallTarget() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700541 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700542 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700543 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700544 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
545
546private:
547 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700548 ~InstX8632Call() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700549};
550
Jan Voung3b43b892014-09-24 13:32:39 -0700551// Emit a one-operand (GPR) instruction.
Jan Voungaf2780c2014-09-26 11:14:30 -0700552void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700553 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter);
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700554void emitIASAsAddrOpTyGPR(
555 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
556 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700557
Jan Voung7fa813b2014-07-18 13:01:08 -0700558// Instructions of the form x := op(x).
559template <InstX8632::InstKindX8632 K>
Jan Voung3b43b892014-09-24 13:32:39 -0700560class InstX8632InplaceopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800561 InstX8632InplaceopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700562 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
563 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
564
Jan Voung7fa813b2014-07-18 13:01:08 -0700565public:
Jan Voung3b43b892014-09-24 13:32:39 -0700566 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) {
567 return new (Func->allocate<InstX8632InplaceopGPR>())
568 InstX8632InplaceopGPR(Func, SrcDest);
Jan Voung7fa813b2014-07-18 13:01:08 -0700569 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700570 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800571 if (!ALLOW_DUMP)
572 return;
Jan Voung7fa813b2014-07-18 13:01:08 -0700573 Ostream &Str = Func->getContext()->getStrEmit();
574 assert(getSrcSize() == 1);
575 Str << "\t" << Opcode << "\t";
576 getSrc(0)->emit(Func);
Jan Voung7fa813b2014-07-18 13:01:08 -0700577 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700578 void emitIAS(const Cfg *Func) const override {
Jan Voung3b43b892014-09-24 13:32:39 -0700579 assert(getSrcSize() == 1);
580 const Variable *Var = getDest();
581 Type Ty = Var->getType();
Jan Voungaf2780c2014-09-26 11:14:30 -0700582 emitIASOpTyGPR(Func, Ty, Var, Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700583 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700584 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800585 if (!ALLOW_DUMP)
586 return;
Jan Voung7fa813b2014-07-18 13:01:08 -0700587 Ostream &Str = Func->getContext()->getStrDump();
588 dumpDest(Func);
589 Str << " = " << Opcode << "." << getDest()->getType() << " ";
590 dumpSources(Func);
591 }
592 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
593
594private:
Jan Voung3b43b892014-09-24 13:32:39 -0700595 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest)
Jan Voung7fa813b2014-07-18 13:01:08 -0700596 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
597 addSource(SrcDest);
598 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700599 ~InstX8632InplaceopGPR() override {}
Jan Voung7fa813b2014-07-18 13:01:08 -0700600 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700601 static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
Jan Voung7fa813b2014-07-18 13:01:08 -0700602};
603
Jan Voung3b43b892014-09-24 13:32:39 -0700604// Emit a two-operand (GPR) instruction, where the dest operand is a
605// Variable that's guaranteed to be a register.
Jan Voung39d4aca2014-10-15 15:16:54 -0700606template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
Jan Voung3b43b892014-09-24 13:32:39 -0700607void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
608 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700609 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700610
Jan Voung39d4aca2014-10-15 15:16:54 -0700611// Instructions of the form x := op(y).
Jan Vounga3a01a22014-07-14 10:32:41 -0700612template <InstX8632::InstKindX8632 K>
Jan Voung3b43b892014-09-24 13:32:39 -0700613class InstX8632UnaryopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800614 InstX8632UnaryopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700615 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
616 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
617
Jan Vounga3a01a22014-07-14 10:32:41 -0700618public:
Jan Voung3b43b892014-09-24 13:32:39 -0700619 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
620 return new (Func->allocate<InstX8632UnaryopGPR>())
621 InstX8632UnaryopGPR(Func, Dest, Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700622 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700623 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800624 if (!ALLOW_DUMP)
625 return;
Jan Vounga3a01a22014-07-14 10:32:41 -0700626 Ostream &Str = Func->getContext()->getStrEmit();
627 assert(getSrcSize() == 1);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700628 Type SrcTy = getSrc(0)->getType();
629 Type DestTy = getDest()->getType();
630 Str << "\t" << Opcode << getWidthString(SrcTy);
631 // Movsx and movzx need both the source and dest type width letter
632 // to define the operation. The other unary operations have the
633 // same source and dest type and as a result need only one letter.
634 if (SrcTy != DestTy)
635 Str << getWidthString(DestTy);
636 Str << "\t";
Jan Vounga3a01a22014-07-14 10:32:41 -0700637 getSrc(0)->emit(Func);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700638 Str << ", ";
639 getDest()->emit(Func);
Jan Vounga3a01a22014-07-14 10:32:41 -0700640 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700641 void emitIAS(const Cfg *Func) const override {
Jan Voung3b43b892014-09-24 13:32:39 -0700642 assert(getSrcSize() == 1);
643 const Variable *Var = getDest();
644 Type Ty = Var->getType();
645 const Operand *Src = getSrc(0);
646 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter);
647 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700648 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800649 if (!ALLOW_DUMP)
650 return;
Jan Vounga3a01a22014-07-14 10:32:41 -0700651 Ostream &Str = Func->getContext()->getStrDump();
652 dumpDest(Func);
Jan Voung39d4aca2014-10-15 15:16:54 -0700653 Str << " = " << Opcode << "." << getSrc(0)->getType() << " ";
Jan Vounga3a01a22014-07-14 10:32:41 -0700654 dumpSources(Func);
655 }
656 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
657
658private:
Jan Voung3b43b892014-09-24 13:32:39 -0700659 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
Jan Vounge4da26f2014-07-15 17:52:39 -0700660 : InstX8632(Func, K, 1, Dest) {
661 addSource(Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700662 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700663 ~InstX8632UnaryopGPR() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -0700664 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700665 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
Jan Vounga3a01a22014-07-14 10:32:41 -0700666};
667
Jan Vounge4dc61b2014-10-06 08:53:52 -0700668void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
669 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700670 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700671
672template <InstX8632::InstKindX8632 K>
673class InstX8632UnaryopXmm : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800674 InstX8632UnaryopXmm() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700675 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
676 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
677
Jan Voung8acded02014-09-22 18:02:25 -0700678public:
679 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) {
680 return new (Func->allocate<InstX8632UnaryopXmm>())
681 InstX8632UnaryopXmm(Func, Dest, Src);
682 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700683 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800684 if (!ALLOW_DUMP)
685 return;
Jan Voung8acded02014-09-22 18:02:25 -0700686 Ostream &Str = Func->getContext()->getStrEmit();
687 assert(getSrcSize() == 1);
688 Str << "\t" << Opcode << "\t";
Jan Voung8acded02014-09-22 18:02:25 -0700689 getSrc(0)->emit(Func);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700690 Str << ", ";
691 getDest()->emit(Func);
Jan Voung8acded02014-09-22 18:02:25 -0700692 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700693 void emitIAS(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700694 Type Ty = getDest()->getType();
695 assert(getSrcSize() == 1);
Jan Vounge4dc61b2014-10-06 08:53:52 -0700696 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(0), Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700697 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700698 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800699 if (!ALLOW_DUMP)
700 return;
Jan Voung8acded02014-09-22 18:02:25 -0700701 Ostream &Str = Func->getContext()->getStrDump();
702 dumpDest(Func);
703 Str << " = " << Opcode << "." << getDest()->getType() << " ";
704 dumpSources(Func);
705 }
706 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
707
708private:
709 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
710 : InstX8632(Func, K, 1, Dest) {
711 addSource(Src);
712 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700713 ~InstX8632UnaryopXmm() override {}
Jan Voung8acded02014-09-22 18:02:25 -0700714 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700715 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
Jan Voung8acded02014-09-22 18:02:25 -0700716};
717
Jan Voung8bcca042014-10-03 21:58:02 -0700718template <InstX8632::InstKindX8632 K>
719class InstX8632BinopGPRShift : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800720 InstX8632BinopGPRShift() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700721 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
722 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
723
Jan Voung8bcca042014-10-03 21:58:02 -0700724public:
725 // Create a binary-op GPR shift instruction.
726 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest,
727 Operand *Source) {
728 return new (Func->allocate<InstX8632BinopGPRShift>())
729 InstX8632BinopGPRShift(Func, Dest, Source);
730 }
731 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800732 if (!ALLOW_DUMP)
733 return;
Jan Voung8bcca042014-10-03 21:58:02 -0700734 const bool ShiftHack = true;
735 emitTwoAddress(Opcode, this, Func, ShiftHack);
736 }
737 void emitIAS(const Cfg *Func) const override {
738 Type Ty = getDest()->getType();
739 assert(getSrcSize() == 2);
740 emitIASGPRShift(Func, Ty, getDest(), getSrc(1), Emitter);
741 }
742 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800743 if (!ALLOW_DUMP)
744 return;
Jan Voung8bcca042014-10-03 21:58:02 -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 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
754 : InstX8632(Func, K, 2, Dest) {
755 addSource(Dest);
756 addSource(Source);
757 }
Jan Voung8bcca042014-10-03 21:58:02 -0700758 ~InstX8632BinopGPRShift() override {}
759 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700760 static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
Jan Voung8bcca042014-10-03 21:58:02 -0700761};
762
Jan Voungaf2780c2014-09-26 11:14:30 -0700763template <InstX8632::InstKindX8632 K>
764class InstX8632BinopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800765 InstX8632BinopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700766 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
767 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
768
Jan Voungaf2780c2014-09-26 11:14:30 -0700769public:
770 // Create an ordinary binary-op instruction like add or sub.
771 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) {
772 return new (Func->allocate<InstX8632BinopGPR>())
773 InstX8632BinopGPR(Func, Dest, Source);
774 }
775 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800776 if (!ALLOW_DUMP)
777 return;
Jan Voungaf2780c2014-09-26 11:14:30 -0700778 const bool ShiftHack = false;
779 emitTwoAddress(Opcode, this, Func, ShiftHack);
780 }
781 void emitIAS(const Cfg *Func) const override {
782 Type Ty = getDest()->getType();
783 assert(getSrcSize() == 2);
784 emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter);
785 }
786 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800787 if (!ALLOW_DUMP)
788 return;
Jan Voungaf2780c2014-09-26 11:14:30 -0700789 Ostream &Str = Func->getContext()->getStrDump();
790 dumpDest(Func);
791 Str << " = " << Opcode << "." << getDest()->getType() << " ";
792 dumpSources(Func);
793 }
794 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
795
796private:
797 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
798 : InstX8632(Func, K, 2, Dest) {
799 addSource(Dest);
800 addSource(Source);
801 }
Jan Voungaf2780c2014-09-26 11:14:30 -0700802 ~InstX8632BinopGPR() override {}
803 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700804 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
Jan Voungaf2780c2014-09-26 11:14:30 -0700805};
806
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700807template <InstX8632::InstKindX8632 K>
808class InstX8632BinopRMW : public InstX8632 {
809 InstX8632BinopRMW() = delete;
810 InstX8632BinopRMW(const InstX8632BinopRMW &) = delete;
811 InstX8632BinopRMW &operator=(const InstX8632BinopRMW &) = delete;
812
813public:
814 // Create an ordinary binary-op instruction like add or sub.
815 static InstX8632BinopRMW *create(Cfg *Func, OperandX8632Mem *DestSrc0,
816 Operand *Src1) {
817 return new (Func->allocate<InstX8632BinopRMW>())
818 InstX8632BinopRMW(Func, DestSrc0, Src1);
819 }
820 void emit(const Cfg *Func) const override {
821 if (!ALLOW_DUMP)
822 return;
823 const bool ShiftHack = false;
824 emitTwoAddress(Opcode, this, Func, ShiftHack);
825 }
826 void emitIAS(const Cfg *Func) const override {
827 Type Ty = getSrc(0)->getType();
828 assert(getSrcSize() == 2);
829 emitIASAsAddrOpTyGPR(Func, Ty, getSrc(0), getSrc(1), Emitter);
830 }
831 void dump(const Cfg *Func) const override {
832 if (!ALLOW_DUMP)
833 return;
834 Ostream &Str = Func->getContext()->getStrDump();
835 Str << Opcode << "." << getSrc(0)->getType() << " ";
836 dumpSources(Func);
837 }
838 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
839
840private:
841 InstX8632BinopRMW(Cfg *Func, OperandX8632Mem *DestSrc0, Operand *Src1)
842 : InstX8632(Func, K, 2, nullptr) {
843 addSource(DestSrc0);
844 addSource(Src1);
845 }
846 ~InstX8632BinopRMW() override {}
847 static const char *Opcode;
848 static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter;
849};
850
Jan Voung8acded02014-09-22 18:02:25 -0700851template <InstX8632::InstKindX8632 K, bool NeedsElementType>
852class InstX8632BinopXmm : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800853 InstX8632BinopXmm() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700854 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
855 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
856
Jan Voung8acded02014-09-22 18:02:25 -0700857public:
858 // Create an XMM binary-op instruction like addss or addps.
859 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
860 return new (Func->allocate<InstX8632BinopXmm>())
861 InstX8632BinopXmm(Func, Dest, Source);
862 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700863 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800864 if (!ALLOW_DUMP)
865 return;
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700866 validateVectorAddrMode();
Jan Voung8acded02014-09-22 18:02:25 -0700867 const bool ShiftHack = false;
868 emitTwoAddress(Opcode, this, Func, ShiftHack);
869 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700870 void emitIAS(const Cfg *Func) const override {
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700871 validateVectorAddrMode();
Jan Voung8acded02014-09-22 18:02:25 -0700872 Type Ty = getDest()->getType();
873 if (NeedsElementType)
874 Ty = typeElementType(Ty);
875 assert(getSrcSize() == 2);
Jan Vounge4dc61b2014-10-06 08:53:52 -0700876 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700877 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700878 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800879 if (!ALLOW_DUMP)
880 return;
Jan Voung8acded02014-09-22 18:02:25 -0700881 Ostream &Str = Func->getContext()->getStrDump();
882 dumpDest(Func);
883 Str << " = " << Opcode << "." << getDest()->getType() << " ";
884 dumpSources(Func);
885 }
886 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
887
888private:
889 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
890 : InstX8632(Func, K, 2, Dest) {
891 addSource(Dest);
892 addSource(Source);
893 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700894 ~InstX8632BinopXmm() override {}
Jan Voung8acded02014-09-22 18:02:25 -0700895 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700896 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
Jan Voung8acded02014-09-22 18:02:25 -0700897};
898
Jan Voung8bcca042014-10-03 21:58:02 -0700899void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
900 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700901 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter);
Jan Voung8bcca042014-10-03 21:58:02 -0700902
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700903template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false>
Jan Voung8bcca042014-10-03 21:58:02 -0700904class InstX8632BinopXmmShift : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800905 InstX8632BinopXmmShift() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700906 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
907 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
908
Jan Voung8bcca042014-10-03 21:58:02 -0700909public:
910 // Create an XMM binary-op shift operation.
911 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest,
912 Operand *Source) {
913 return new (Func->allocate<InstX8632BinopXmmShift>())
914 InstX8632BinopXmmShift(Func, Dest, Source);
915 }
916 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800917 if (!ALLOW_DUMP)
918 return;
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700919 validateVectorAddrMode();
Jan Voung8bcca042014-10-03 21:58:02 -0700920 const bool ShiftHack = false;
921 emitTwoAddress(Opcode, this, Func, ShiftHack);
922 }
923 void emitIAS(const Cfg *Func) const override {
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700924 validateVectorAddrMode();
Jan Voung8bcca042014-10-03 21:58:02 -0700925 Type Ty = getDest()->getType();
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700926 assert(AllowAllTypes || isVectorType(Ty));
Jan Voung8bcca042014-10-03 21:58:02 -0700927 Type ElementTy = typeElementType(Ty);
928 assert(getSrcSize() == 2);
929 emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter);
930 }
931 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800932 if (!ALLOW_DUMP)
933 return;
Jan Voung8bcca042014-10-03 21:58:02 -0700934 Ostream &Str = Func->getContext()->getStrDump();
935 dumpDest(Func);
936 Str << " = " << Opcode << "." << getDest()->getType() << " ";
937 dumpSources(Func);
938 }
939 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
940
941private:
942 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
943 : InstX8632(Func, K, 2, Dest) {
944 addSource(Dest);
945 addSource(Source);
946 }
Jan Voung8bcca042014-10-03 21:58:02 -0700947 ~InstX8632BinopXmmShift() override {}
948 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700949 static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
Jan Voung8bcca042014-10-03 21:58:02 -0700950};
951
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700952template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800953 InstX8632Ternop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700954 InstX8632Ternop(const InstX8632Ternop &) = delete;
955 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
956
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700957public:
958 // Create a ternary-op instruction like div or idiv.
959 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
960 Operand *Source2) {
961 return new (Func->allocate<InstX8632Ternop>())
962 InstX8632Ternop(Func, Dest, Source1, Source2);
963 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700964 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800965 if (!ALLOW_DUMP)
966 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700967 Ostream &Str = Func->getContext()->getStrEmit();
968 assert(getSrcSize() == 3);
969 Str << "\t" << Opcode << "\t";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700970 getSrc(2)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700971 Str << ", ";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700972 getSrc(1)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700973 Str << ", ";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700974 getDest()->emit(Func);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700975 }
Jan Voung962befa2014-10-15 09:32:58 -0700976 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700977 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800978 if (!ALLOW_DUMP)
979 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700980 Ostream &Str = Func->getContext()->getStrDump();
981 dumpDest(Func);
982 Str << " = " << Opcode << "." << getDest()->getType() << " ";
983 dumpSources(Func);
984 }
985 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
986
987private:
988 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
989 : InstX8632(Func, K, 3, Dest) {
990 addSource(Dest);
991 addSource(Source1);
992 addSource(Source2);
993 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700994 ~InstX8632Ternop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700995 static const char *Opcode;
996};
997
Matt Wala49889232014-07-18 12:45:09 -0700998// Instructions of the form x := y op z
999template <InstX8632::InstKindX8632 K>
1000class InstX8632ThreeAddressop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001001 InstX8632ThreeAddressop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001002 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
1003 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
1004
Matt Wala49889232014-07-18 12:45:09 -07001005public:
1006 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
1007 Operand *Source0, Operand *Source1) {
1008 return new (Func->allocate<InstX8632ThreeAddressop>())
1009 InstX8632ThreeAddressop(Func, Dest, Source0, Source1);
1010 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001011 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001012 if (!ALLOW_DUMP)
1013 return;
Matt Wala49889232014-07-18 12:45:09 -07001014 Ostream &Str = Func->getContext()->getStrEmit();
1015 assert(getSrcSize() == 2);
1016 Str << "\t" << Opcode << "\t";
Jim Stichnothbca2f652014-11-01 10:13:54 -07001017 getSrc(1)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -07001018 Str << ", ";
1019 getSrc(0)->emit(Func);
1020 Str << ", ";
Jim Stichnothbca2f652014-11-01 10:13:54 -07001021 getDest()->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -07001022 }
Jan Voung962befa2014-10-15 09:32:58 -07001023 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001024 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001025 if (!ALLOW_DUMP)
1026 return;
Matt Wala49889232014-07-18 12:45:09 -07001027 Ostream &Str = Func->getContext()->getStrDump();
1028 dumpDest(Func);
1029 Str << " = " << Opcode << "." << getDest()->getType() << " ";
1030 dumpSources(Func);
1031 }
1032 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
1033
1034private:
1035 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
1036 Operand *Source1)
1037 : InstX8632(Func, K, 2, Dest) {
1038 addSource(Source0);
1039 addSource(Source1);
1040 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001041 ~InstX8632ThreeAddressop() override {}
Matt Wala49889232014-07-18 12:45:09 -07001042 static const char *Opcode;
1043};
1044
Matt Walae58178a2014-08-12 13:15:04 -07001045// Base class for assignment instructions
1046template <InstX8632::InstKindX8632 K>
1047class InstX8632Movlike : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001048 InstX8632Movlike() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001049 InstX8632Movlike(const InstX8632Movlike &) = delete;
1050 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
1051
Matt Walae58178a2014-08-12 13:15:04 -07001052public:
1053 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
1054 return new (Func->allocate<InstX8632Movlike>())
1055 InstX8632Movlike(Func, Dest, Source);
1056 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001057 bool isRedundantAssign() const override {
Matt Walae58178a2014-08-12 13:15:04 -07001058 return checkForRedundantAssign(getDest(), getSrc(0));
1059 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001060 bool isSimpleAssign() const override { return true; }
1061 void emit(const Cfg *Func) const override;
Jan Voungfe14fb82014-10-13 15:56:32 -07001062 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001063 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001064 if (!ALLOW_DUMP)
1065 return;
Matt Walae58178a2014-08-12 13:15:04 -07001066 Ostream &Str = Func->getContext()->getStrDump();
1067 Str << Opcode << "." << getDest()->getType() << " ";
1068 dumpDest(Func);
1069 Str << ", ";
1070 dumpSources(Func);
1071 }
1072 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
1073
1074private:
1075 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source)
1076 : InstX8632(Func, K, 1, Dest) {
1077 addSource(Source);
1078 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001079 ~InstX8632Movlike() override {}
Matt Walae58178a2014-08-12 13:15:04 -07001080
1081 static const char *Opcode;
1082};
1083
Jan Voung3b43b892014-09-24 13:32:39 -07001084typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap;
1085typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg;
1086typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf;
1087typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr;
1088typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea;
Matt Wala51e8cfb2014-08-08 08:39:40 -07001089// Cbwdq instruction - wrapper for cbw, cwd, and cdq
Jan Voung3b43b892014-09-24 13:32:39 -07001090typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq;
Jan Voung39d4aca2014-10-15 15:16:54 -07001091typedef InstX8632UnaryopGPR<InstX8632::Movsx> InstX8632Movsx;
1092typedef InstX8632UnaryopGPR<InstX8632::Movzx> InstX8632Movzx;
Jan Voung3b43b892014-09-24 13:32:39 -07001093typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd;
1094typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss;
Matt Walae58178a2014-08-12 13:15:04 -07001095// Move/assignment instruction - wrapper for mov/movss/movsd.
1096typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov;
1097// Move packed - copy 128 bit values between XMM registers, or mem128
1098// and XMM registers.
1099typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp;
1100// Movq - copy between XMM registers, or mem64 and XMM registers.
1101typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq;
Jan Voungaf2780c2014-09-26 11:14:30 -07001102typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add;
Jim Stichnothe4f65d82015-06-17 22:16:02 -07001103typedef InstX8632BinopRMW<InstX8632::AddRMW> InstX8632AddRMW;
Jan Voung8acded02014-09-22 18:02:25 -07001104typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps;
Jan Voungaf2780c2014-09-26 11:14:30 -07001105typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc;
Jan Voung8acded02014-09-22 18:02:25 -07001106typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss;
1107typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd;
Jan Voungaf2780c2014-09-26 11:14:30 -07001108typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub;
Jan Voung8acded02014-09-22 18:02:25 -07001109typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps;
1110typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss;
Jan Voungaf2780c2014-09-26 11:14:30 -07001111typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb;
Jan Voung8acded02014-09-22 18:02:25 -07001112typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub;
Jan Voungaf2780c2014-09-26 11:14:30 -07001113typedef InstX8632BinopGPR<InstX8632::And> InstX8632And;
Jan Voung8acded02014-09-22 18:02:25 -07001114typedef InstX8632BinopXmm<InstX8632::Pand, false> InstX8632Pand;
1115typedef InstX8632BinopXmm<InstX8632::Pandn, false> InstX8632Pandn;
Jan Voungaf2780c2014-09-26 11:14:30 -07001116typedef InstX8632BinopGPR<InstX8632::Or> InstX8632Or;
Jan Voung8acded02014-09-22 18:02:25 -07001117typedef InstX8632BinopXmm<InstX8632::Por, false> InstX8632Por;
Jan Voungaf2780c2014-09-26 11:14:30 -07001118typedef InstX8632BinopGPR<InstX8632::Xor> InstX8632Xor;
Jan Voung8acded02014-09-22 18:02:25 -07001119typedef InstX8632BinopXmm<InstX8632::Pxor, false> InstX8632Pxor;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001120typedef InstX8632BinopGPR<InstX8632::Imul> InstX8632Imul;
Jan Voung8acded02014-09-22 18:02:25 -07001121typedef InstX8632BinopXmm<InstX8632::Mulps, true> InstX8632Mulps;
1122typedef InstX8632BinopXmm<InstX8632::Mulss, false> InstX8632Mulss;
Jan Voung8bcca042014-10-03 21:58:02 -07001123typedef InstX8632BinopXmm<InstX8632::Pmull, true> InstX8632Pmull;
Jan Voung8acded02014-09-22 18:02:25 -07001124typedef InstX8632BinopXmm<InstX8632::Pmuludq, false> InstX8632Pmuludq;
1125typedef InstX8632BinopXmm<InstX8632::Divps, true> InstX8632Divps;
1126typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss;
Jan Voung8bcca042014-10-03 21:58:02 -07001127typedef InstX8632BinopGPRShift<InstX8632::Rol> InstX8632Rol;
1128typedef InstX8632BinopGPRShift<InstX8632::Shl> InstX8632Shl;
1129typedef InstX8632BinopXmmShift<InstX8632::Psll> InstX8632Psll;
Jim Stichnoth8c980d02015-03-19 13:01:50 -07001130typedef InstX8632BinopXmmShift<InstX8632::Psrl, true> InstX8632Psrl;
Jan Voung8bcca042014-10-03 21:58:02 -07001131typedef InstX8632BinopGPRShift<InstX8632::Shr> InstX8632Shr;
1132typedef InstX8632BinopGPRShift<InstX8632::Sar> InstX8632Sar;
1133typedef InstX8632BinopXmmShift<InstX8632::Psra> InstX8632Psra;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001134typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq;
1135typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001136// movss is only a binary operation when the source and dest
1137// operands are both registers (the high bits of dest are left untouched).
1138// In other cases, it behaves like a copy (mov-like) operation (and the
1139// high bits of dest are cleared).
1140// InstX8632Movss will assert that both its source and dest operands are
1141// registers, so the lowering code should use _mov instead of _movss
1142// in cases where a copy operation is intended.
1143typedef InstX8632BinopXmm<InstX8632::MovssRegs, false> InstX8632MovssRegs;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001144typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv;
1145typedef InstX8632Ternop<InstX8632::Div> InstX8632Div;
Matt Wala0a450512014-07-30 12:44:39 -07001146typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
1147typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
Matt Wala49889232014-07-18 12:45:09 -07001148typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
Matt Wala0a450512014-07-30 12:44:39 -07001149typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
1150typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
1151typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
Matt Wala49889232014-07-18 12:45:09 -07001152typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001153
Jan Vounga3a01a22014-07-14 10:32:41 -07001154// Base class for a lockable x86-32 instruction (emits a locked prefix).
1155class InstX8632Lockable : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001156 InstX8632Lockable() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001157 InstX8632Lockable(const InstX8632Lockable &) = delete;
1158 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
1159
Jan Vounga3a01a22014-07-14 10:32:41 -07001160protected:
1161 bool Locked;
1162
1163 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
1164 Variable *Dest, bool Locked)
1165 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
1166 // Assume that such instructions are used for Atomics and be careful
1167 // with optimizations.
1168 HasSideEffects = Locked;
1169 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001170 ~InstX8632Lockable() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001171};
1172
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001173// Mul instruction - unsigned multiply.
1174class InstX8632Mul : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001175 InstX8632Mul() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001176 InstX8632Mul(const InstX8632Mul &) = delete;
1177 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
1178
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001179public:
1180 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
1181 Operand *Source2) {
1182 return new (Func->allocate<InstX8632Mul>())
1183 InstX8632Mul(Func, Dest, Source1, Source2);
1184 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001185 void emit(const Cfg *Func) const override;
Jan Voungaf2780c2014-09-26 11:14:30 -07001186 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001187 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001188 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
1189
1190private:
1191 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001192 ~InstX8632Mul() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001193};
1194
Jan Voung88355762014-11-01 09:40:20 -07001195// Shld instruction - shift across a pair of operands.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001196class InstX8632Shld : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001197 InstX8632Shld() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001198 InstX8632Shld(const InstX8632Shld &) = delete;
1199 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
1200
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001201public:
1202 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
1203 Variable *Source2) {
1204 return new (Func->allocate<InstX8632Shld>())
1205 InstX8632Shld(Func, Dest, Source1, Source2);
1206 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001207 void emit(const Cfg *Func) const override;
Jan Voung962befa2014-10-15 09:32:58 -07001208 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001209 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001210 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
1211
1212private:
1213 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
1214 Variable *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001215 ~InstX8632Shld() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001216};
1217
Jan Voung88355762014-11-01 09:40:20 -07001218// Shrd instruction - shift across a pair of operands.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001219class InstX8632Shrd : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001220 InstX8632Shrd() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001221 InstX8632Shrd(const InstX8632Shrd &) = delete;
1222 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
1223
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001224public:
1225 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
1226 Variable *Source2) {
1227 return new (Func->allocate<InstX8632Shrd>())
1228 InstX8632Shrd(Func, Dest, Source1, Source2);
1229 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001230 void emit(const Cfg *Func) const override;
Jan Voung962befa2014-10-15 09:32:58 -07001231 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001232 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001233 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
1234
1235private:
1236 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
1237 Variable *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001238 ~InstX8632Shrd() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001239};
1240
Jan Vounge4da26f2014-07-15 17:52:39 -07001241// Conditional move instruction.
1242class InstX8632Cmov : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001243 InstX8632Cmov() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001244 InstX8632Cmov(const InstX8632Cmov &) = delete;
1245 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
1246
Jan Vounge4da26f2014-07-15 17:52:39 -07001247public:
1248 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voungbd385e42014-09-18 18:18:10 -07001249 CondX86::BrCond Cond) {
Jan Vounge4da26f2014-07-15 17:52:39 -07001250 return new (Func->allocate<InstX8632Cmov>())
1251 InstX8632Cmov(Func, Dest, Source, Cond);
1252 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001253 void emit(const Cfg *Func) const override;
1254 void emitIAS(const Cfg *Func) const override;
1255 void dump(const Cfg *Func) const override;
Jan Vounge4da26f2014-07-15 17:52:39 -07001256 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
1257
1258private:
Jan Voungbd385e42014-09-18 18:18:10 -07001259 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
1260 CondX86::BrCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001261 ~InstX8632Cmov() override {}
Jan Vounge4da26f2014-07-15 17:52:39 -07001262
Jan Voungbd385e42014-09-18 18:18:10 -07001263 CondX86::BrCond Condition;
Jan Vounge4da26f2014-07-15 17:52:39 -07001264};
1265
Matt Walace0ca8f2014-07-24 12:34:20 -07001266// Cmpps instruction - compare packed singled-precision floating point
1267// values
1268class InstX8632Cmpps : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001269 InstX8632Cmpps() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001270 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
1271 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
1272
Matt Walace0ca8f2014-07-24 12:34:20 -07001273public:
Matt Walace0ca8f2014-07-24 12:34:20 -07001274 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voungbd385e42014-09-18 18:18:10 -07001275 CondX86::CmppsCond Condition) {
Matt Walace0ca8f2014-07-24 12:34:20 -07001276 return new (Func->allocate<InstX8632Cmpps>())
1277 InstX8632Cmpps(Func, Dest, Source, Condition);
1278 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001279 void emit(const Cfg *Func) const override;
1280 void emitIAS(const Cfg *Func) const override;
1281 void dump(const Cfg *Func) const override;
Matt Walace0ca8f2014-07-24 12:34:20 -07001282 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
1283
1284private:
Jan Voungbd385e42014-09-18 18:18:10 -07001285 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
1286 CondX86::CmppsCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001287 ~InstX8632Cmpps() override {}
Matt Walace0ca8f2014-07-24 12:34:20 -07001288
Jan Voungbd385e42014-09-18 18:18:10 -07001289 CondX86::CmppsCond Condition;
Matt Walace0ca8f2014-07-24 12:34:20 -07001290};
1291
Jan Vounga3a01a22014-07-14 10:32:41 -07001292// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
1293// equals eax. If so, the ZF is set and <desired> is stored in <dest>.
1294// If not, ZF is cleared and <dest> is copied to eax (or subregister).
1295// <dest> can be a register or memory, while <desired> must be a register.
1296// It is the user's responsiblity to mark eax with a FakeDef.
1297class InstX8632Cmpxchg : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001298 InstX8632Cmpxchg() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001299 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1300 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
1301
Jan Vounga3a01a22014-07-14 10:32:41 -07001302public:
1303 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1304 Variable *Desired, bool Locked) {
1305 return new (Func->allocate<InstX8632Cmpxchg>())
1306 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
1307 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001308 void emit(const Cfg *Func) const override;
1309 void emitIAS(const Cfg *Func) const override;
1310 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001311 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
1312
1313private:
1314 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1315 Variable *Desired, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001316 ~InstX8632Cmpxchg() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001317};
1318
1319// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
1320// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
1321// If not, ZF is cleared and <m64> is copied to edx:eax.
1322// The caller is responsible for inserting FakeDefs to mark edx
1323// and eax as modified.
1324// <m64> must be a memory operand.
1325class InstX8632Cmpxchg8b : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001326 InstX8632Cmpxchg8b() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001327 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1328 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
1329
Jan Vounga3a01a22014-07-14 10:32:41 -07001330public:
Jan Voung03532e52014-09-23 13:32:18 -07001331 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
Jan Vounga3a01a22014-07-14 10:32:41 -07001332 Variable *Edx, Variable *Eax, Variable *Ecx,
1333 Variable *Ebx, bool Locked) {
1334 return new (Func->allocate<InstX8632Cmpxchg8b>())
1335 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
1336 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001337 void emit(const Cfg *Func) const override;
1338 void emitIAS(const Cfg *Func) const override;
1339 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001340 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
1341
1342private:
Jan Voung03532e52014-09-23 13:32:18 -07001343 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
Jan Vounga3a01a22014-07-14 10:32:41 -07001344 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001345 ~InstX8632Cmpxchg8b() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001346};
1347
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001348// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
1349// as appropriate. s=float, d=double, i=int. X and Y are determined
1350// from dest/src types. Sign and zero extension on the integer
1351// operand needs to be done separately.
1352class InstX8632Cvt : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001353 InstX8632Cvt() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001354 InstX8632Cvt(const InstX8632Cvt &) = delete;
1355 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
1356
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001357public:
Jan Voung699bf022014-10-08 13:52:10 -07001358 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
Jim Stichnothb63cd882014-09-08 10:47:23 -07001359 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voung699bf022014-10-08 13:52:10 -07001360 CvtVariant Variant) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001361 return new (Func->allocate<InstX8632Cvt>())
Jan Voung699bf022014-10-08 13:52:10 -07001362 InstX8632Cvt(Func, Dest, Source, Variant);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001363 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001364 void emit(const Cfg *Func) const override;
Jan Voung699bf022014-10-08 13:52:10 -07001365 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001366 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001367 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
Jan Voung699bf022014-10-08 13:52:10 -07001368 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001369
1370private:
Jan Voung699bf022014-10-08 13:52:10 -07001371 CvtVariant Variant;
1372 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001373 ~InstX8632Cvt() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001374};
1375
1376// cmp - Integer compare instruction.
1377class InstX8632Icmp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001378 InstX8632Icmp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001379 InstX8632Icmp(const InstX8632Icmp &) = delete;
1380 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
1381
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001382public:
1383 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1384 return new (Func->allocate<InstX8632Icmp>())
1385 InstX8632Icmp(Func, Src1, Src2);
1386 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001387 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001388 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001389 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001390 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
1391
1392private:
1393 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001394 ~InstX8632Icmp() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001395};
1396
1397// ucomiss/ucomisd - floating-point compare instruction.
1398class InstX8632Ucomiss : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001399 InstX8632Ucomiss() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001400 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1401 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
1402
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001403public:
1404 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1405 return new (Func->allocate<InstX8632Ucomiss>())
1406 InstX8632Ucomiss(Func, Src1, Src2);
1407 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001408 void emit(const Cfg *Func) const override;
1409 void emitIAS(const Cfg *Func) const override;
1410 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001411 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
1412
1413private:
1414 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001415 ~InstX8632Ucomiss() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001416};
1417
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001418// UD2 instruction.
1419class InstX8632UD2 : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001420 InstX8632UD2() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001421 InstX8632UD2(const InstX8632UD2 &) = delete;
1422 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
1423
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001424public:
1425 static InstX8632UD2 *create(Cfg *Func) {
1426 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
1427 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001428 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001429 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001430 void dump(const Cfg *Func) const override;
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001431 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
1432
1433private:
Jim Stichnothc6ead202015-02-24 09:30:30 -08001434 explicit InstX8632UD2(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001435 ~InstX8632UD2() override {}
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001436};
1437
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001438// Test instruction.
1439class InstX8632Test : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001440 InstX8632Test() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001441 InstX8632Test(const InstX8632Test &) = delete;
1442 InstX8632Test &operator=(const InstX8632Test &) = delete;
1443
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001444public:
1445 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
1446 return new (Func->allocate<InstX8632Test>())
1447 InstX8632Test(Func, Source1, Source2);
1448 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001449 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001450 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001451 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001452 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
1453
1454private:
1455 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001456 ~InstX8632Test() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001457};
1458
Jan Voung5cd240d2014-06-25 10:36:46 -07001459// Mfence instruction.
1460class InstX8632Mfence : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001461 InstX8632Mfence() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001462 InstX8632Mfence(const InstX8632Mfence &) = delete;
1463 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
1464
Jan Voung5cd240d2014-06-25 10:36:46 -07001465public:
1466 static InstX8632Mfence *create(Cfg *Func) {
1467 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
1468 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001469 void emit(const Cfg *Func) const override;
Jan Voungaf2780c2014-09-26 11:14:30 -07001470 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001471 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001472 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
1473
1474private:
Jim Stichnothc6ead202015-02-24 09:30:30 -08001475 explicit InstX8632Mfence(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001476 ~InstX8632Mfence() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001477};
1478
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001479// This is essentially a "mov" instruction with an OperandX8632Mem
1480// operand instead of Variable as the destination. It's important
1481// for liveness that there is no Dest operand.
1482class InstX8632Store : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001483 InstX8632Store() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001484 InstX8632Store(const InstX8632Store &) = delete;
1485 InstX8632Store &operator=(const InstX8632Store &) = delete;
1486
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001487public:
1488 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1489 return new (Func->allocate<InstX8632Store>())
1490 InstX8632Store(Func, Value, Mem);
1491 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001492 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -07001493 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001494 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001495 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
1496
1497private:
1498 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001499 ~InstX8632Store() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001500};
1501
Jan Vounge4dc61b2014-10-06 08:53:52 -07001502// This is essentially a vector "mov" instruction with an OperandX8632Mem
1503// operand instead of Variable as the destination. It's important
1504// for liveness that there is no Dest operand. The source must be an
1505// Xmm register, since Dest is mem.
Matt Wala105b7042014-08-11 19:56:19 -07001506class InstX8632StoreP : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001507 InstX8632StoreP() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001508 InstX8632StoreP(const InstX8632StoreP &) = delete;
1509 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
1510
Matt Wala105b7042014-08-11 19:56:19 -07001511public:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001512 static InstX8632StoreP *create(Cfg *Func, Variable *Value,
1513 OperandX8632Mem *Mem) {
Matt Wala105b7042014-08-11 19:56:19 -07001514 return new (Func->allocate<InstX8632StoreP>())
1515 InstX8632StoreP(Func, Value, Mem);
1516 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001517 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001518 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001519 void dump(const Cfg *Func) const override;
Matt Wala105b7042014-08-11 19:56:19 -07001520 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
1521
1522private:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001523 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001524 ~InstX8632StoreP() override {}
Matt Wala105b7042014-08-11 19:56:19 -07001525};
1526
Jan Voung5cd240d2014-06-25 10:36:46 -07001527class InstX8632StoreQ : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001528 InstX8632StoreQ() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001529 InstX8632StoreQ(const InstX8632StoreQ &) = delete;
1530 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
1531
Jan Voung5cd240d2014-06-25 10:36:46 -07001532public:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001533 static InstX8632StoreQ *create(Cfg *Func, Variable *Value,
1534 OperandX8632Mem *Mem) {
Jan Voung5cd240d2014-06-25 10:36:46 -07001535 return new (Func->allocate<InstX8632StoreQ>())
1536 InstX8632StoreQ(Func, Value, Mem);
1537 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001538 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001539 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001540 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001541 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1542
1543private:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001544 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001545 ~InstX8632StoreQ() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001546};
1547
Matt Walac3302742014-08-15 16:21:56 -07001548// Nop instructions of varying length
1549class InstX8632Nop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001550 InstX8632Nop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001551 InstX8632Nop(const InstX8632Nop &) = delete;
1552 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
1553
Matt Walac3302742014-08-15 16:21:56 -07001554public:
1555 // TODO: Replace with enum.
1556 typedef unsigned NopVariant;
1557
1558 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1559 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1560 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001561 void emit(const Cfg *Func) const override;
1562 void emitIAS(const Cfg *Func) const override;
1563 void dump(const Cfg *Func) const override;
Matt Walac3302742014-08-15 16:21:56 -07001564 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1565
1566private:
1567 InstX8632Nop(Cfg *Func, SizeT Length);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001568 ~InstX8632Nop() override {}
Matt Walac3302742014-08-15 16:21:56 -07001569
1570 NopVariant Variant;
1571};
1572
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001573// Fld - load a value onto the x87 FP stack.
1574class InstX8632Fld : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001575 InstX8632Fld() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001576 InstX8632Fld(const InstX8632Fld &) = delete;
1577 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
1578
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001579public:
1580 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1581 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1582 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001583 void emit(const Cfg *Func) const override;
Jan Voung479e5632014-10-08 21:05:27 -07001584 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001585 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001586 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1587
1588private:
1589 InstX8632Fld(Cfg *Func, Operand *Src);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001590 ~InstX8632Fld() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001591};
1592
1593// Fstp - store x87 st(0) into memory and pop st(0).
1594class InstX8632Fstp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001595 InstX8632Fstp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001596 InstX8632Fstp(const InstX8632Fstp &) = delete;
1597 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
1598
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001599public:
1600 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1601 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1602 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001603 void emit(const Cfg *Func) const override;
Jan Voung479e5632014-10-08 21:05:27 -07001604 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001605 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001606 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
1607
1608private:
1609 InstX8632Fstp(Cfg *Func, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001610 ~InstX8632Fstp() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001611};
1612
1613class InstX8632Pop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001614 InstX8632Pop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001615 InstX8632Pop(const InstX8632Pop &) = delete;
1616 InstX8632Pop &operator=(const InstX8632Pop &) = delete;
1617
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001618public:
1619 static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
1620 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
1621 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001622 void emit(const Cfg *Func) const override;
1623 void emitIAS(const Cfg *Func) const override;
1624 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001625 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1626
1627private:
1628 InstX8632Pop(Cfg *Func, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001629 ~InstX8632Pop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001630};
1631
1632class InstX8632Push : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001633 InstX8632Push() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001634 InstX8632Push(const InstX8632Push &) = delete;
1635 InstX8632Push &operator=(const InstX8632Push &) = delete;
1636
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001637public:
Jan Voung0b9eee52014-10-07 11:20:10 -07001638 static InstX8632Push *create(Cfg *Func, Variable *Source) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001639 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001640 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001641 void emit(const Cfg *Func) const override;
Jan Voung0b9eee52014-10-07 11:20:10 -07001642 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001643 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001644 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1645
1646private:
Jan Voung0b9eee52014-10-07 11:20:10 -07001647 InstX8632Push(Cfg *Func, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001648 ~InstX8632Push() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001649};
1650
1651// Ret instruction. Currently only supports the "ret" version that
1652// does not pop arguments. This instruction takes a Source operand
1653// (for non-void returning functions) for liveness analysis, though
1654// a FakeUse before the ret would do just as well.
1655class InstX8632Ret : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001656 InstX8632Ret() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001657 InstX8632Ret(const InstX8632Ret &) = delete;
1658 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
1659
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001660public:
Jim Stichnothae953202014-12-20 06:17:49 -08001661 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001662 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1663 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001664 void emit(const Cfg *Func) const override;
1665 void emitIAS(const Cfg *Func) const override;
1666 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001667 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1668
1669private:
1670 InstX8632Ret(Cfg *Func, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001671 ~InstX8632Ret() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001672};
1673
Jim Stichnothf48b3202015-05-04 10:22:17 -07001674// Conditional set-byte instruction.
1675class InstX8632Setcc : public InstX8632 {
1676 InstX8632Setcc() = delete;
1677 InstX8632Setcc(const InstX8632Cmov &) = delete;
1678 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete;
1679
1680public:
1681 static InstX8632Setcc *create(Cfg *Func, Variable *Dest,
1682 CondX86::BrCond Cond) {
1683 return new (Func->allocate<InstX8632Setcc>())
1684 InstX8632Setcc(Func, Dest, Cond);
1685 }
1686 void emit(const Cfg *Func) const override;
1687 void emitIAS(const Cfg *Func) const override;
1688 void dump(const Cfg *Func) const override;
1689 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); }
1690
1691private:
1692 InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond);
1693 ~InstX8632Setcc() override {}
1694
1695 const CondX86::BrCond Condition;
1696};
1697
Jan Voung5cd240d2014-06-25 10:36:46 -07001698// Exchanging Add instruction. Exchanges the first operand (destination
1699// operand) with the second operand (source operand), then loads the sum
1700// of the two values into the destination operand. The destination may be
1701// a register or memory, while the source must be a register.
1702//
1703// Both the dest and source are updated. The caller should then insert a
1704// FakeDef to reflect the second udpate.
Jan Vounga3a01a22014-07-14 10:32:41 -07001705class InstX8632Xadd : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001706 InstX8632Xadd() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001707 InstX8632Xadd(const InstX8632Xadd &) = delete;
1708 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
1709
Jan Voung5cd240d2014-06-25 10:36:46 -07001710public:
1711 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1712 bool Locked) {
1713 return new (Func->allocate<InstX8632Xadd>())
1714 InstX8632Xadd(Func, Dest, Source, Locked);
1715 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001716 void emit(const Cfg *Func) const override;
1717 void emitIAS(const Cfg *Func) const override;
1718 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001719 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1720
1721private:
Jan Voung5cd240d2014-06-25 10:36:46 -07001722 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001723 ~InstX8632Xadd() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001724};
1725
Jan Vounga3a01a22014-07-14 10:32:41 -07001726// Exchange instruction. Exchanges the first operand (destination
1727// operand) with the second operand (source operand). At least one of
1728// the operands must be a register (and the other can be reg or mem).
1729// Both the Dest and Source are updated. If there is a memory operand,
1730// then the instruction is automatically "locked" without the need for
1731// a lock prefix.
1732class InstX8632Xchg : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001733 InstX8632Xchg() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001734 InstX8632Xchg(const InstX8632Xchg &) = delete;
1735 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
1736
Jan Vounga3a01a22014-07-14 10:32:41 -07001737public:
1738 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1739 return new (Func->allocate<InstX8632Xchg>())
1740 InstX8632Xchg(Func, Dest, Source);
1741 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001742 void emit(const Cfg *Func) const override;
1743 void emitIAS(const Cfg *Func) const override;
1744 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001745 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
1746
1747private:
1748 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001749 ~InstX8632Xchg() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001750};
1751
Jim Stichnoth6e992142014-07-30 14:45:20 -07001752// Declare partial template specializations of emit() methods that
1753// already have default implementations. Without this, there is the
1754// possibility of ODR violations and link errors.
1755template <> void InstX8632Addss::emit(const Cfg *Func) const;
1756template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
Matt Wala51e8cfb2014-08-08 08:39:40 -07001757template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
Jim Stichnoth6e992142014-07-30 14:45:20 -07001758template <> void InstX8632Div::emit(const Cfg *Func) const;
1759template <> void InstX8632Divss::emit(const Cfg *Func) const;
1760template <> void InstX8632Idiv::emit(const Cfg *Func) const;
1761template <> void InstX8632Imul::emit(const Cfg *Func) const;
1762template <> void InstX8632Lea::emit(const Cfg *Func) const;
1763template <> void InstX8632Mulss::emit(const Cfg *Func) const;
1764template <> void InstX8632Padd::emit(const Cfg *Func) const;
1765template <> void InstX8632Pblendvb::emit(const Cfg *Func) const;
1766template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const;
1767template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const;
1768template <> void InstX8632Pextr::emit(const Cfg *Func) const;
1769template <> void InstX8632Pinsr::emit(const Cfg *Func) const;
1770template <> void InstX8632Pmull::emit(const Cfg *Func) const;
1771template <> void InstX8632Pmuludq::emit(const Cfg *Func) const;
1772template <> void InstX8632Psll::emit(const Cfg *Func) const;
1773template <> void InstX8632Psra::emit(const Cfg *Func) const;
Jim Stichnoth8c980d02015-03-19 13:01:50 -07001774template <> void InstX8632Psrl::emit(const Cfg *Func) const;
Jim Stichnoth6e992142014-07-30 14:45:20 -07001775template <> void InstX8632Psub::emit(const Cfg *Func) const;
1776template <> void InstX8632Sqrtss::emit(const Cfg *Func) const;
1777template <> void InstX8632Subss::emit(const Cfg *Func) const;
1778
Jan Voungd026c442014-10-13 14:06:50 -07001779template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001780template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const;
Jan Voungaf2780c2014-09-26 11:14:30 -07001781template <> void InstX8632Div::emitIAS(const Cfg *Func) const;
1782template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001783template <> void InstX8632Imul::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001784template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const;
Jan Voung3b43b892014-09-24 13:32:39 -07001785template <> void InstX8632Movd::emitIAS(const Cfg *Func) const;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001786template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const;
Jan Voungd026c442014-10-13 14:06:50 -07001787template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001788template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const;
1789template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const;
Jan Voung39d4aca2014-10-15 15:16:54 -07001790template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const;
1791template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const;
Jan Voung8bcca042014-10-03 21:58:02 -07001792template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001793template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const;
1794template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const;
Jan Voung03532e52014-09-23 13:32:18 -07001795
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001796} // end of namespace Ice
1797
1798#endif // SUBZERO_SRC_ICEINSTX8632_H