blob: 2e82052e821f72ba00f964e37fb44048679e966d [file] [log] [blame]
Jan Voungb36ad9b2015-04-21 17:01:49 -07001//===- subzero/src/IceInstX8632.h - x86-32 machine instructions -*- C++ -*-===//
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07002//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the InstX8632 and OperandX8632 classes and
11// their subclasses. This represents the machine instructions and
12// operands used for x86-32 code selection.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICEINSTX8632_H
17#define SUBZERO_SRC_ICEINSTX8632_H
18
Jan Voung8acded02014-09-22 18:02:25 -070019#include "assembler_ia32.h"
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,
Matt Wala8d1072e2014-07-11 15:43:51 -0700179 Addps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700180 Addss,
Matt Wala105b7042014-08-11 19:56:19 -0700181 Adjuststack,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700182 And,
Matt Wala0a450512014-07-30 12:44:39 -0700183 Blendvps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700184 Br,
Jan Vounge4da26f2014-07-15 17:52:39 -0700185 Bsf,
186 Bsr,
Jan Voung7fa813b2014-07-18 13:01:08 -0700187 Bswap,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700188 Call,
Matt Walaafeaee42014-08-07 13:47:30 -0700189 Cbwdq,
Jan Vounge4da26f2014-07-15 17:52:39 -0700190 Cmov,
Matt Walace0ca8f2014-07-24 12:34:20 -0700191 Cmpps,
Jan Vounga3a01a22014-07-14 10:32:41 -0700192 Cmpxchg,
193 Cmpxchg8b,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700194 Cvt,
195 Div,
Matt Wala8d1072e2014-07-11 15:43:51 -0700196 Divps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700197 Divss,
198 Fld,
199 Fstp,
200 Icmp,
201 Idiv,
202 Imul,
Matt Wala0a450512014-07-30 12:44:39 -0700203 Insertps,
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800204 Jmp,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700205 Label,
Matt Wala49889232014-07-18 12:45:09 -0700206 Lea,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700207 Load,
Jan Voung5cd240d2014-06-25 10:36:46 -0700208 Mfence,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700209 Mov,
Matt Wala49889232014-07-18 12:45:09 -0700210 Movd,
Matt Wala928f1292014-07-07 16:50:46 -0700211 Movp,
Jan Voung5cd240d2014-06-25 10:36:46 -0700212 Movq,
Jan Vounge4dc61b2014-10-06 08:53:52 -0700213 MovssRegs,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700214 Movsx,
215 Movzx,
216 Mul,
Matt Wala8d1072e2014-07-11 15:43:51 -0700217 Mulps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700218 Mulss,
Jan Vounga3a01a22014-07-14 10:32:41 -0700219 Neg,
Matt Walac3302742014-08-15 16:21:56 -0700220 Nop,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700221 Or,
Matt Wala7fa22d82014-07-17 12:41:31 -0700222 Padd,
Matt Wala83b80362014-07-16 10:21:30 -0700223 Pand,
Matt Wala9cb61e22014-07-24 09:44:42 -0700224 Pandn,
Matt Wala0a450512014-07-30 12:44:39 -0700225 Pblendvb,
Matt Wala83b80362014-07-16 10:21:30 -0700226 Pcmpeq,
227 Pcmpgt,
Matt Wala0a450512014-07-30 12:44:39 -0700228 Pextr,
229 Pinsr,
230 Pmull,
Matt Wala7fa22d82014-07-17 12:41:31 -0700231 Pmuludq,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700232 Pop,
Matt Wala7fa22d82014-07-17 12:41:31 -0700233 Por,
234 Pshufd,
Matt Wala83b80362014-07-16 10:21:30 -0700235 Psll,
236 Psra,
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700237 Psrl,
Matt Wala83b80362014-07-16 10:21:30 -0700238 Psub,
Matt Wala7fa22d82014-07-17 12:41:31 -0700239 Push,
Matt Wala928f1292014-07-07 16:50:46 -0700240 Pxor,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700241 Ret,
Jan Voung7fa813b2014-07-18 13:01:08 -0700242 Rol,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700243 Sar,
244 Sbb,
Jim Stichnothf48b3202015-05-04 10:22:17 -0700245 Setcc,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700246 Shl,
247 Shld,
248 Shr,
249 Shrd,
Matt Wala7fa22d82014-07-17 12:41:31 -0700250 Shufps,
Jan Voungf37fbbe2014-07-09 16:13:13 -0700251 Sqrtss,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700252 Store,
Matt Wala105b7042014-08-11 19:56:19 -0700253 StoreP,
Jan Voung5cd240d2014-06-25 10:36:46 -0700254 StoreQ,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700255 Sub,
Matt Wala8d1072e2014-07-11 15:43:51 -0700256 Subps,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700257 Subss,
258 Test,
259 Ucomiss,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700260 UD2,
Jan Voung5cd240d2014-06-25 10:36:46 -0700261 Xadd,
Jan Vounga3a01a22014-07-14 10:32:41 -0700262 Xchg,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700263 Xor
264 };
Jan Vounge4da26f2014-07-15 17:52:39 -0700265
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700266 static const char *getWidthString(Type Ty);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700267 static const char *getFldString(Type Ty);
Jim Stichnoth537b5ba2015-05-19 09:48:44 -0700268 static CondX86::BrCond getOppositeCondition(CondX86::BrCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700269 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700270
Jan Voung3bfd99a2015-05-22 16:35:25 -0700271 // Shared emit routines for common forms of instructions.
272 // See the definition of emitTwoAddress() for a description of
273 // ShiftHack.
274 static void emitTwoAddress(const char *Opcode, const Inst *Inst,
275 const Cfg *Func, bool ShiftHack = false);
276
277 static void
278 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
279 const Operand *Src,
280 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter);
281
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700282protected:
283 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
284 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700285 ~InstX8632() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700286 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
287 return Inst->getKind() == static_cast<InstKind>(MyKind);
288 }
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700289 // Most instructions that operate on vector arguments require vector
290 // memory operands to be fully aligned (16-byte alignment for PNaCl
291 // vector types). The stack frame layout and call ABI ensure proper
292 // alignment for stack operands, but memory operands (originating
293 // from load/store bitcode instructions) only have element-size
294 // alignment guarantees. This function validates that none of the
295 // operands is a memory operand of vector type, calling
296 // report_fatal_error() if one is found. This function should be
297 // called during emission, and maybe also in the ctor (as long as
298 // that fits the lowering style).
299 void validateVectorAddrMode() const {
300 if (getDest())
301 validateVectorAddrModeOpnd(getDest());
302 for (SizeT i = 0; i < getSrcSize(); ++i) {
303 validateVectorAddrModeOpnd(getSrc(i));
304 }
305 }
Jan Voung44c3a802015-03-27 16:29:08 -0700306
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700307private:
308 static void validateVectorAddrModeOpnd(const Operand *Opnd) {
309 if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) {
310 llvm::report_fatal_error("Possible misaligned vector memory operation");
311 }
312 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700313};
314
Jan Voung7e1e4852014-10-24 10:29:30 -0700315// InstX8632Label represents an intra-block label that is the target
316// of an intra-block branch. The offset between the label and the
317// branch must be fit into one byte (considered "near"). These are
318// used for lowering i1 calculations, Select instructions, and 64-bit
319// compares on a 32-bit architecture, without basic block splitting.
320// Basic block splitting is not so desirable for several reasons, one
321// of which is the impact on decisions based on whether a variable's
322// live range spans multiple basic blocks.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700323//
324// Intra-block control flow must be used with caution. Consider the
325// sequence for "c = (a >= b ? x : y)".
326// cmp a, b
327// br lt, L1
328// mov c, x
329// jmp L2
330// L1:
331// mov c, y
332// L2:
333//
334// Labels L1 and L2 are intra-block labels. Without knowledge of the
335// intra-block control flow, liveness analysis will determine the "mov
336// c, x" instruction to be dead. One way to prevent this is to insert
337// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
338// instructions, e.g.:
339//
340// cmp a, b
341// br lt, L1
342// mov c, x
343// jmp L2
344// FakeUse(c)
345// L1:
346// mov c, y
347// L2:
348//
349// The down-side is that "mov c, x" can never be dead-code eliminated
350// even if there are no uses of c. As unlikely as this situation is,
351// it may be prevented by running dead code elimination before
352// lowering.
353class InstX8632Label : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800354 InstX8632Label() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700355 InstX8632Label(const InstX8632Label &) = delete;
356 InstX8632Label &operator=(const InstX8632Label &) = delete;
357
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700358public:
359 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
360 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
361 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700362 uint32_t getEmitInstCount() const override { return 0; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700363 IceString getName(const Cfg *Func) const;
Jan Voung7e1e4852014-10-24 10:29:30 -0700364 SizeT getNumber() const { return Number; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700365 void emit(const Cfg *Func) const override;
Jan Voung7e1e4852014-10-24 10:29:30 -0700366 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700367 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700368
369private:
370 InstX8632Label(Cfg *Func, TargetX8632 *Target);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700371 ~InstX8632Label() override {}
Jan Voung7e1e4852014-10-24 10:29:30 -0700372 SizeT Number; // used for unique label generation.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700373};
374
375// Conditional and unconditional branch instruction.
376class InstX8632Br : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800377 InstX8632Br() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700378 InstX8632Br(const InstX8632Br &) = delete;
379 InstX8632Br &operator=(const InstX8632Br &) = delete;
380
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700381public:
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700382 // Create a conditional branch to a node.
383 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
Jan Voungbd385e42014-09-18 18:18:10 -0700384 CfgNode *TargetFalse, CondX86::BrCond Condition) {
Jim Stichnoth98712a32014-10-24 10:59:02 -0700385 assert(Condition != CondX86::Br_None);
Jim Stichnothae953202014-12-20 06:17:49 -0800386 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700387 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700388 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700389 }
390 // Create an unconditional branch to a node.
391 static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
Jim Stichnothae953202014-12-20 06:17:49 -0800392 const CfgNode *NoCondTarget = nullptr;
393 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700394 return new (Func->allocate<InstX8632Br>())
Jan Voungbd385e42014-09-18 18:18:10 -0700395 InstX8632Br(Func, NoCondTarget, Target, NoLabel, CondX86::Br_None);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700396 }
397 // Create a non-terminator conditional branch to a node, with a
398 // fallthrough to the next instruction in the current node. This is
399 // used for switch lowering.
Jan Voungbd385e42014-09-18 18:18:10 -0700400 static InstX8632Br *create(Cfg *Func, CfgNode *Target,
401 CondX86::BrCond Condition) {
Jim Stichnoth98712a32014-10-24 10:59:02 -0700402 assert(Condition != CondX86::Br_None);
Jim Stichnothae953202014-12-20 06:17:49 -0800403 const CfgNode *NoUncondTarget = nullptr;
404 const InstX8632Label *NoLabel = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700405 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700406 InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700407 }
408 // Create a conditional intra-block branch (or unconditional, if
Jim Stichnoth18735602014-09-16 19:59:35 -0700409 // Condition==Br_None) to a label in the current block.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700410 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
Jan Voungbd385e42014-09-18 18:18:10 -0700411 CondX86::BrCond Condition) {
Jim Stichnothae953202014-12-20 06:17:49 -0800412 const CfgNode *NoCondTarget = nullptr;
413 const CfgNode *NoUncondTarget = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700414 return new (Func->allocate<InstX8632Br>())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700415 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700416 }
Jim Stichnothff9c7062014-09-18 04:50:49 -0700417 const CfgNode *getTargetTrue() const { return TargetTrue; }
418 const CfgNode *getTargetFalse() const { return TargetFalse; }
419 bool optimizeBranch(const CfgNode *NextNode);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700420 uint32_t getEmitInstCount() const override {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700421 uint32_t Sum = 0;
Jim Stichnoth18735602014-09-16 19:59:35 -0700422 if (Label)
Jim Stichnothff9c7062014-09-18 04:50:49 -0700423 ++Sum;
424 if (getTargetTrue())
425 ++Sum;
Jim Stichnoth18735602014-09-16 19:59:35 -0700426 if (getTargetFalse())
Jim Stichnothff9c7062014-09-18 04:50:49 -0700427 ++Sum;
428 return Sum;
Jim Stichnoth18735602014-09-16 19:59:35 -0700429 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700430 bool isUnconditionalBranch() const override {
431 return !Label && Condition == CondX86::Br_None;
432 }
433 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700434 void emit(const Cfg *Func) const override;
Jan Voung7e1e4852014-10-24 10:29:30 -0700435 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700436 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700437 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
438
439private:
Jim Stichnothff9c7062014-09-18 04:50:49 -0700440 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
Jan Voungbd385e42014-09-18 18:18:10 -0700441 const InstX8632Label *Label, CondX86::BrCond Condition);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700442 ~InstX8632Br() override {}
Jan Voungbd385e42014-09-18 18:18:10 -0700443 CondX86::BrCond Condition;
Jim Stichnothff9c7062014-09-18 04:50:49 -0700444 const CfgNode *TargetTrue;
445 const CfgNode *TargetFalse;
446 const InstX8632Label *Label; // Intra-block branch target
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700447};
448
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800449// Jump to a target outside this function, such as tailcall, nacljump,
450// naclret, unreachable. This is different from a Branch instruction
451// in that there is no intra-function control flow to represent.
452class InstX8632Jmp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800453 InstX8632Jmp() = delete;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800454 InstX8632Jmp(const InstX8632Jmp &) = delete;
455 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete;
456
457public:
458 static InstX8632Jmp *create(Cfg *Func, Operand *Target) {
459 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target);
460 }
461 Operand *getJmpTarget() const { return getSrc(0); }
462 void emit(const Cfg *Func) const override;
463 void emitIAS(const Cfg *Func) const override;
464 void dump(const Cfg *Func) const override;
465 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); }
466
467private:
468 InstX8632Jmp(Cfg *Func, Operand *Target);
469};
470
Matt Wala105b7042014-08-11 19:56:19 -0700471// AdjustStack instruction - subtracts esp by the given amount and
472// updates the stack offset during code emission.
473class InstX8632AdjustStack : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800474 InstX8632AdjustStack() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700475 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
476 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
477
Matt Wala105b7042014-08-11 19:56:19 -0700478public:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700479 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
Matt Wala105b7042014-08-11 19:56:19 -0700480 return new (Func->allocate<InstX8632AdjustStack>())
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700481 InstX8632AdjustStack(Func, Amount, Esp);
Matt Wala105b7042014-08-11 19:56:19 -0700482 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700483 void emit(const Cfg *Func) const override;
484 void emitIAS(const Cfg *Func) const override;
485 void dump(const Cfg *Func) const override;
Matt Wala105b7042014-08-11 19:56:19 -0700486 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
487
488private:
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700489 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
Matt Wala105b7042014-08-11 19:56:19 -0700490 SizeT Amount;
491};
492
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700493// Call instruction. Arguments should have already been pushed.
494class InstX8632Call : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800495 InstX8632Call() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700496 InstX8632Call(const InstX8632Call &) = delete;
497 InstX8632Call &operator=(const InstX8632Call &) = delete;
498
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700499public:
500 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
501 return new (Func->allocate<InstX8632Call>())
502 InstX8632Call(Func, Dest, CallTarget);
503 }
504 Operand *getCallTarget() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700505 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700506 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700507 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700508 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
509
510private:
511 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700512 ~InstX8632Call() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700513};
514
Jan Voung3b43b892014-09-24 13:32:39 -0700515// Emit a one-operand (GPR) instruction.
Jan Voungaf2780c2014-09-26 11:14:30 -0700516void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700517 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700518
Jan Voung7fa813b2014-07-18 13:01:08 -0700519// Instructions of the form x := op(x).
520template <InstX8632::InstKindX8632 K>
Jan Voung3b43b892014-09-24 13:32:39 -0700521class InstX8632InplaceopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800522 InstX8632InplaceopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700523 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
524 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
525
Jan Voung7fa813b2014-07-18 13:01:08 -0700526public:
Jan Voung3b43b892014-09-24 13:32:39 -0700527 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) {
528 return new (Func->allocate<InstX8632InplaceopGPR>())
529 InstX8632InplaceopGPR(Func, SrcDest);
Jan Voung7fa813b2014-07-18 13:01:08 -0700530 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700531 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800532 if (!ALLOW_DUMP)
533 return;
Jan Voung7fa813b2014-07-18 13:01:08 -0700534 Ostream &Str = Func->getContext()->getStrEmit();
535 assert(getSrcSize() == 1);
536 Str << "\t" << Opcode << "\t";
537 getSrc(0)->emit(Func);
Jan Voung7fa813b2014-07-18 13:01:08 -0700538 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700539 void emitIAS(const Cfg *Func) const override {
Jan Voung3b43b892014-09-24 13:32:39 -0700540 assert(getSrcSize() == 1);
541 const Variable *Var = getDest();
542 Type Ty = Var->getType();
Jan Voungaf2780c2014-09-26 11:14:30 -0700543 emitIASOpTyGPR(Func, Ty, Var, Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700544 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700545 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800546 if (!ALLOW_DUMP)
547 return;
Jan Voung7fa813b2014-07-18 13:01:08 -0700548 Ostream &Str = Func->getContext()->getStrDump();
549 dumpDest(Func);
550 Str << " = " << Opcode << "." << getDest()->getType() << " ";
551 dumpSources(Func);
552 }
553 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
554
555private:
Jan Voung3b43b892014-09-24 13:32:39 -0700556 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest)
Jan Voung7fa813b2014-07-18 13:01:08 -0700557 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
558 addSource(SrcDest);
559 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700560 ~InstX8632InplaceopGPR() override {}
Jan Voung7fa813b2014-07-18 13:01:08 -0700561 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700562 static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
Jan Voung7fa813b2014-07-18 13:01:08 -0700563};
564
Jan Voung3b43b892014-09-24 13:32:39 -0700565// Emit a two-operand (GPR) instruction, where the dest operand is a
566// Variable that's guaranteed to be a register.
Jan Voung39d4aca2014-10-15 15:16:54 -0700567template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
Jan Voung3b43b892014-09-24 13:32:39 -0700568void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
569 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700570 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter);
Jan Voung3b43b892014-09-24 13:32:39 -0700571
Jan Voung39d4aca2014-10-15 15:16:54 -0700572// Instructions of the form x := op(y).
Jan Vounga3a01a22014-07-14 10:32:41 -0700573template <InstX8632::InstKindX8632 K>
Jan Voung3b43b892014-09-24 13:32:39 -0700574class InstX8632UnaryopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800575 InstX8632UnaryopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700576 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
577 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
578
Jan Vounga3a01a22014-07-14 10:32:41 -0700579public:
Jan Voung3b43b892014-09-24 13:32:39 -0700580 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
581 return new (Func->allocate<InstX8632UnaryopGPR>())
582 InstX8632UnaryopGPR(Func, Dest, Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700583 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700584 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800585 if (!ALLOW_DUMP)
586 return;
Jan Vounga3a01a22014-07-14 10:32:41 -0700587 Ostream &Str = Func->getContext()->getStrEmit();
588 assert(getSrcSize() == 1);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700589 Type SrcTy = getSrc(0)->getType();
590 Type DestTy = getDest()->getType();
591 Str << "\t" << Opcode << getWidthString(SrcTy);
592 // Movsx and movzx need both the source and dest type width letter
593 // to define the operation. The other unary operations have the
594 // same source and dest type and as a result need only one letter.
595 if (SrcTy != DestTy)
596 Str << getWidthString(DestTy);
597 Str << "\t";
Jan Vounga3a01a22014-07-14 10:32:41 -0700598 getSrc(0)->emit(Func);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700599 Str << ", ";
600 getDest()->emit(Func);
Jan Vounga3a01a22014-07-14 10:32:41 -0700601 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700602 void emitIAS(const Cfg *Func) const override {
Jan Voung3b43b892014-09-24 13:32:39 -0700603 assert(getSrcSize() == 1);
604 const Variable *Var = getDest();
605 Type Ty = Var->getType();
606 const Operand *Src = getSrc(0);
607 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter);
608 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700609 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800610 if (!ALLOW_DUMP)
611 return;
Jan Vounga3a01a22014-07-14 10:32:41 -0700612 Ostream &Str = Func->getContext()->getStrDump();
613 dumpDest(Func);
Jan Voung39d4aca2014-10-15 15:16:54 -0700614 Str << " = " << Opcode << "." << getSrc(0)->getType() << " ";
Jan Vounga3a01a22014-07-14 10:32:41 -0700615 dumpSources(Func);
616 }
617 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
618
619private:
Jan Voung3b43b892014-09-24 13:32:39 -0700620 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
Jan Vounge4da26f2014-07-15 17:52:39 -0700621 : InstX8632(Func, K, 1, Dest) {
622 addSource(Src);
Jan Vounga3a01a22014-07-14 10:32:41 -0700623 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700624 ~InstX8632UnaryopGPR() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -0700625 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700626 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
Jan Vounga3a01a22014-07-14 10:32:41 -0700627};
628
Jan Vounge4dc61b2014-10-06 08:53:52 -0700629void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
630 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700631 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700632
633template <InstX8632::InstKindX8632 K>
634class InstX8632UnaryopXmm : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800635 InstX8632UnaryopXmm() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700636 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
637 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
638
Jan Voung8acded02014-09-22 18:02:25 -0700639public:
640 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) {
641 return new (Func->allocate<InstX8632UnaryopXmm>())
642 InstX8632UnaryopXmm(Func, Dest, Src);
643 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700644 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800645 if (!ALLOW_DUMP)
646 return;
Jan Voung8acded02014-09-22 18:02:25 -0700647 Ostream &Str = Func->getContext()->getStrEmit();
648 assert(getSrcSize() == 1);
649 Str << "\t" << Opcode << "\t";
Jan Voung8acded02014-09-22 18:02:25 -0700650 getSrc(0)->emit(Func);
Jim Stichnothbca2f652014-11-01 10:13:54 -0700651 Str << ", ";
652 getDest()->emit(Func);
Jan Voung8acded02014-09-22 18:02:25 -0700653 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700654 void emitIAS(const Cfg *Func) const override {
Jan Voung8acded02014-09-22 18:02:25 -0700655 Type Ty = getDest()->getType();
656 assert(getSrcSize() == 1);
Jan Vounge4dc61b2014-10-06 08:53:52 -0700657 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(0), Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700658 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700659 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800660 if (!ALLOW_DUMP)
661 return;
Jan Voung8acded02014-09-22 18:02:25 -0700662 Ostream &Str = Func->getContext()->getStrDump();
663 dumpDest(Func);
664 Str << " = " << Opcode << "." << getDest()->getType() << " ";
665 dumpSources(Func);
666 }
667 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
668
669private:
670 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
671 : InstX8632(Func, K, 1, Dest) {
672 addSource(Src);
673 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700674 ~InstX8632UnaryopXmm() override {}
Jan Voung8acded02014-09-22 18:02:25 -0700675 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700676 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
Jan Voung8acded02014-09-22 18:02:25 -0700677};
678
Jan Voung8bcca042014-10-03 21:58:02 -0700679template <InstX8632::InstKindX8632 K>
680class InstX8632BinopGPRShift : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800681 InstX8632BinopGPRShift() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700682 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
683 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
684
Jan Voung8bcca042014-10-03 21:58:02 -0700685public:
686 // Create a binary-op GPR shift instruction.
687 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest,
688 Operand *Source) {
689 return new (Func->allocate<InstX8632BinopGPRShift>())
690 InstX8632BinopGPRShift(Func, Dest, Source);
691 }
692 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800693 if (!ALLOW_DUMP)
694 return;
Jan Voung8bcca042014-10-03 21:58:02 -0700695 const bool ShiftHack = true;
696 emitTwoAddress(Opcode, this, Func, ShiftHack);
697 }
698 void emitIAS(const Cfg *Func) const override {
699 Type Ty = getDest()->getType();
700 assert(getSrcSize() == 2);
701 emitIASGPRShift(Func, Ty, getDest(), getSrc(1), Emitter);
702 }
703 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800704 if (!ALLOW_DUMP)
705 return;
Jan Voung8bcca042014-10-03 21:58:02 -0700706 Ostream &Str = Func->getContext()->getStrDump();
707 dumpDest(Func);
708 Str << " = " << Opcode << "." << getDest()->getType() << " ";
709 dumpSources(Func);
710 }
711 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
712
713private:
714 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
715 : InstX8632(Func, K, 2, Dest) {
716 addSource(Dest);
717 addSource(Source);
718 }
Jan Voung8bcca042014-10-03 21:58:02 -0700719 ~InstX8632BinopGPRShift() override {}
720 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700721 static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
Jan Voung8bcca042014-10-03 21:58:02 -0700722};
723
Jan Voungaf2780c2014-09-26 11:14:30 -0700724template <InstX8632::InstKindX8632 K>
725class InstX8632BinopGPR : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800726 InstX8632BinopGPR() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700727 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
728 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
729
Jan Voungaf2780c2014-09-26 11:14:30 -0700730public:
731 // Create an ordinary binary-op instruction like add or sub.
732 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) {
733 return new (Func->allocate<InstX8632BinopGPR>())
734 InstX8632BinopGPR(Func, Dest, Source);
735 }
736 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800737 if (!ALLOW_DUMP)
738 return;
Jan Voungaf2780c2014-09-26 11:14:30 -0700739 const bool ShiftHack = false;
740 emitTwoAddress(Opcode, this, Func, ShiftHack);
741 }
742 void emitIAS(const Cfg *Func) const override {
743 Type Ty = getDest()->getType();
744 assert(getSrcSize() == 2);
745 emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter);
746 }
747 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800748 if (!ALLOW_DUMP)
749 return;
Jan Voungaf2780c2014-09-26 11:14:30 -0700750 Ostream &Str = Func->getContext()->getStrDump();
751 dumpDest(Func);
752 Str << " = " << Opcode << "." << getDest()->getType() << " ";
753 dumpSources(Func);
754 }
755 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
756
757private:
758 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
759 : InstX8632(Func, K, 2, Dest) {
760 addSource(Dest);
761 addSource(Source);
762 }
Jan Voungaf2780c2014-09-26 11:14:30 -0700763 ~InstX8632BinopGPR() override {}
764 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700765 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
Jan Voungaf2780c2014-09-26 11:14:30 -0700766};
767
Jan Voung8acded02014-09-22 18:02:25 -0700768template <InstX8632::InstKindX8632 K, bool NeedsElementType>
769class InstX8632BinopXmm : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800770 InstX8632BinopXmm() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700771 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
772 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
773
Jan Voung8acded02014-09-22 18:02:25 -0700774public:
775 // Create an XMM binary-op instruction like addss or addps.
776 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
777 return new (Func->allocate<InstX8632BinopXmm>())
778 InstX8632BinopXmm(Func, Dest, Source);
779 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700780 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800781 if (!ALLOW_DUMP)
782 return;
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700783 validateVectorAddrMode();
Jan Voung8acded02014-09-22 18:02:25 -0700784 const bool ShiftHack = false;
785 emitTwoAddress(Opcode, this, Func, ShiftHack);
786 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700787 void emitIAS(const Cfg *Func) const override {
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700788 validateVectorAddrMode();
Jan Voung8acded02014-09-22 18:02:25 -0700789 Type Ty = getDest()->getType();
790 if (NeedsElementType)
791 Ty = typeElementType(Ty);
792 assert(getSrcSize() == 2);
Jan Vounge4dc61b2014-10-06 08:53:52 -0700793 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter);
Jan Voung8acded02014-09-22 18:02:25 -0700794 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700795 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800796 if (!ALLOW_DUMP)
797 return;
Jan Voung8acded02014-09-22 18:02:25 -0700798 Ostream &Str = Func->getContext()->getStrDump();
799 dumpDest(Func);
800 Str << " = " << Opcode << "." << getDest()->getType() << " ";
801 dumpSources(Func);
802 }
803 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
804
805private:
806 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
807 : InstX8632(Func, K, 2, Dest) {
808 addSource(Dest);
809 addSource(Source);
810 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700811 ~InstX8632BinopXmm() override {}
Jan Voung8acded02014-09-22 18:02:25 -0700812 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700813 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
Jan Voung8acded02014-09-22 18:02:25 -0700814};
815
Jan Voung8bcca042014-10-03 21:58:02 -0700816void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
817 const Operand *Src,
Jan Voung90ccc3f2015-04-30 14:15:10 -0700818 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter);
Jan Voung8bcca042014-10-03 21:58:02 -0700819
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700820template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false>
Jan Voung8bcca042014-10-03 21:58:02 -0700821class InstX8632BinopXmmShift : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800822 InstX8632BinopXmmShift() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700823 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
824 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
825
Jan Voung8bcca042014-10-03 21:58:02 -0700826public:
827 // Create an XMM binary-op shift operation.
828 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest,
829 Operand *Source) {
830 return new (Func->allocate<InstX8632BinopXmmShift>())
831 InstX8632BinopXmmShift(Func, Dest, Source);
832 }
833 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800834 if (!ALLOW_DUMP)
835 return;
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700836 validateVectorAddrMode();
Jan Voung8bcca042014-10-03 21:58:02 -0700837 const bool ShiftHack = false;
838 emitTwoAddress(Opcode, this, Func, ShiftHack);
839 }
840 void emitIAS(const Cfg *Func) const override {
Jim Stichnothf79d2cb2015-03-23 15:10:54 -0700841 validateVectorAddrMode();
Jan Voung8bcca042014-10-03 21:58:02 -0700842 Type Ty = getDest()->getType();
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700843 assert(AllowAllTypes || isVectorType(Ty));
Jan Voung8bcca042014-10-03 21:58:02 -0700844 Type ElementTy = typeElementType(Ty);
845 assert(getSrcSize() == 2);
846 emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter);
847 }
848 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800849 if (!ALLOW_DUMP)
850 return;
Jan Voung8bcca042014-10-03 21:58:02 -0700851 Ostream &Str = Func->getContext()->getStrDump();
852 dumpDest(Func);
853 Str << " = " << Opcode << "." << getDest()->getType() << " ";
854 dumpSources(Func);
855 }
856 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
857
858private:
859 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
860 : InstX8632(Func, K, 2, Dest) {
861 addSource(Dest);
862 addSource(Source);
863 }
Jan Voung8bcca042014-10-03 21:58:02 -0700864 ~InstX8632BinopXmmShift() override {}
865 static const char *Opcode;
Jan Voung90ccc3f2015-04-30 14:15:10 -0700866 static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
Jan Voung8bcca042014-10-03 21:58:02 -0700867};
868
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700869template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800870 InstX8632Ternop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700871 InstX8632Ternop(const InstX8632Ternop &) = delete;
872 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
873
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700874public:
875 // Create a ternary-op instruction like div or idiv.
876 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
877 Operand *Source2) {
878 return new (Func->allocate<InstX8632Ternop>())
879 InstX8632Ternop(Func, Dest, Source1, Source2);
880 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700881 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800882 if (!ALLOW_DUMP)
883 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700884 Ostream &Str = Func->getContext()->getStrEmit();
885 assert(getSrcSize() == 3);
886 Str << "\t" << Opcode << "\t";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700887 getSrc(2)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700888 Str << ", ";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700889 getSrc(1)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700890 Str << ", ";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700891 getDest()->emit(Func);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700892 }
Jan Voung962befa2014-10-15 09:32:58 -0700893 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700894 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800895 if (!ALLOW_DUMP)
896 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700897 Ostream &Str = Func->getContext()->getStrDump();
898 dumpDest(Func);
899 Str << " = " << Opcode << "." << getDest()->getType() << " ";
900 dumpSources(Func);
901 }
902 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
903
904private:
905 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
906 : InstX8632(Func, K, 3, Dest) {
907 addSource(Dest);
908 addSource(Source1);
909 addSource(Source2);
910 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700911 ~InstX8632Ternop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700912 static const char *Opcode;
913};
914
Matt Wala49889232014-07-18 12:45:09 -0700915// Instructions of the form x := y op z
916template <InstX8632::InstKindX8632 K>
917class InstX8632ThreeAddressop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800918 InstX8632ThreeAddressop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700919 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
920 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
921
Matt Wala49889232014-07-18 12:45:09 -0700922public:
923 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
924 Operand *Source0, Operand *Source1) {
925 return new (Func->allocate<InstX8632ThreeAddressop>())
926 InstX8632ThreeAddressop(Func, Dest, Source0, Source1);
927 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700928 void emit(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800929 if (!ALLOW_DUMP)
930 return;
Matt Wala49889232014-07-18 12:45:09 -0700931 Ostream &Str = Func->getContext()->getStrEmit();
932 assert(getSrcSize() == 2);
933 Str << "\t" << Opcode << "\t";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700934 getSrc(1)->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700935 Str << ", ";
936 getSrc(0)->emit(Func);
937 Str << ", ";
Jim Stichnothbca2f652014-11-01 10:13:54 -0700938 getDest()->emit(Func);
Matt Wala49889232014-07-18 12:45:09 -0700939 }
Jan Voung962befa2014-10-15 09:32:58 -0700940 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700941 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800942 if (!ALLOW_DUMP)
943 return;
Matt Wala49889232014-07-18 12:45:09 -0700944 Ostream &Str = Func->getContext()->getStrDump();
945 dumpDest(Func);
946 Str << " = " << Opcode << "." << getDest()->getType() << " ";
947 dumpSources(Func);
948 }
949 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
950
951private:
952 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
953 Operand *Source1)
954 : InstX8632(Func, K, 2, Dest) {
955 addSource(Source0);
956 addSource(Source1);
957 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700958 ~InstX8632ThreeAddressop() override {}
Matt Wala49889232014-07-18 12:45:09 -0700959 static const char *Opcode;
960};
961
Matt Walae58178a2014-08-12 13:15:04 -0700962// Base class for assignment instructions
963template <InstX8632::InstKindX8632 K>
964class InstX8632Movlike : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800965 InstX8632Movlike() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700966 InstX8632Movlike(const InstX8632Movlike &) = delete;
967 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
968
Matt Walae58178a2014-08-12 13:15:04 -0700969public:
970 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
971 return new (Func->allocate<InstX8632Movlike>())
972 InstX8632Movlike(Func, Dest, Source);
973 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700974 bool isRedundantAssign() const override {
Matt Walae58178a2014-08-12 13:15:04 -0700975 return checkForRedundantAssign(getDest(), getSrc(0));
976 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700977 bool isSimpleAssign() const override { return true; }
978 void emit(const Cfg *Func) const override;
Jan Voungfe14fb82014-10-13 15:56:32 -0700979 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700980 void dump(const Cfg *Func) const override {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800981 if (!ALLOW_DUMP)
982 return;
Matt Walae58178a2014-08-12 13:15:04 -0700983 Ostream &Str = Func->getContext()->getStrDump();
984 Str << Opcode << "." << getDest()->getType() << " ";
985 dumpDest(Func);
986 Str << ", ";
987 dumpSources(Func);
988 }
989 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
990
991private:
992 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source)
993 : InstX8632(Func, K, 1, Dest) {
994 addSource(Source);
995 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700996 ~InstX8632Movlike() override {}
Matt Walae58178a2014-08-12 13:15:04 -0700997
998 static const char *Opcode;
999};
1000
Jan Voung3b43b892014-09-24 13:32:39 -07001001typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap;
1002typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg;
1003typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf;
1004typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr;
1005typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea;
Matt Wala51e8cfb2014-08-08 08:39:40 -07001006// Cbwdq instruction - wrapper for cbw, cwd, and cdq
Jan Voung3b43b892014-09-24 13:32:39 -07001007typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq;
Jan Voung39d4aca2014-10-15 15:16:54 -07001008typedef InstX8632UnaryopGPR<InstX8632::Movsx> InstX8632Movsx;
1009typedef InstX8632UnaryopGPR<InstX8632::Movzx> InstX8632Movzx;
Jan Voung3b43b892014-09-24 13:32:39 -07001010typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd;
1011typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss;
Matt Walae58178a2014-08-12 13:15:04 -07001012// Move/assignment instruction - wrapper for mov/movss/movsd.
1013typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov;
1014// Move packed - copy 128 bit values between XMM registers, or mem128
1015// and XMM registers.
1016typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp;
1017// Movq - copy between XMM registers, or mem64 and XMM registers.
1018typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq;
Jan Voungaf2780c2014-09-26 11:14:30 -07001019typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add;
Jan Voung8acded02014-09-22 18:02:25 -07001020typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps;
Jan Voungaf2780c2014-09-26 11:14:30 -07001021typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc;
Jan Voung8acded02014-09-22 18:02:25 -07001022typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss;
1023typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd;
Jan Voungaf2780c2014-09-26 11:14:30 -07001024typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub;
Jan Voung8acded02014-09-22 18:02:25 -07001025typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps;
1026typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss;
Jan Voungaf2780c2014-09-26 11:14:30 -07001027typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb;
Jan Voung8acded02014-09-22 18:02:25 -07001028typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub;
Jan Voungaf2780c2014-09-26 11:14:30 -07001029typedef InstX8632BinopGPR<InstX8632::And> InstX8632And;
Jan Voung8acded02014-09-22 18:02:25 -07001030typedef InstX8632BinopXmm<InstX8632::Pand, false> InstX8632Pand;
1031typedef InstX8632BinopXmm<InstX8632::Pandn, false> InstX8632Pandn;
Jan Voungaf2780c2014-09-26 11:14:30 -07001032typedef InstX8632BinopGPR<InstX8632::Or> InstX8632Or;
Jan Voung8acded02014-09-22 18:02:25 -07001033typedef InstX8632BinopXmm<InstX8632::Por, false> InstX8632Por;
Jan Voungaf2780c2014-09-26 11:14:30 -07001034typedef InstX8632BinopGPR<InstX8632::Xor> InstX8632Xor;
Jan Voung8acded02014-09-22 18:02:25 -07001035typedef InstX8632BinopXmm<InstX8632::Pxor, false> InstX8632Pxor;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001036typedef InstX8632BinopGPR<InstX8632::Imul> InstX8632Imul;
Jan Voung8acded02014-09-22 18:02:25 -07001037typedef InstX8632BinopXmm<InstX8632::Mulps, true> InstX8632Mulps;
1038typedef InstX8632BinopXmm<InstX8632::Mulss, false> InstX8632Mulss;
Jan Voung8bcca042014-10-03 21:58:02 -07001039typedef InstX8632BinopXmm<InstX8632::Pmull, true> InstX8632Pmull;
Jan Voung8acded02014-09-22 18:02:25 -07001040typedef InstX8632BinopXmm<InstX8632::Pmuludq, false> InstX8632Pmuludq;
1041typedef InstX8632BinopXmm<InstX8632::Divps, true> InstX8632Divps;
1042typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss;
Jan Voung8bcca042014-10-03 21:58:02 -07001043typedef InstX8632BinopGPRShift<InstX8632::Rol> InstX8632Rol;
1044typedef InstX8632BinopGPRShift<InstX8632::Shl> InstX8632Shl;
1045typedef InstX8632BinopXmmShift<InstX8632::Psll> InstX8632Psll;
Jim Stichnoth8c980d02015-03-19 13:01:50 -07001046typedef InstX8632BinopXmmShift<InstX8632::Psrl, true> InstX8632Psrl;
Jan Voung8bcca042014-10-03 21:58:02 -07001047typedef InstX8632BinopGPRShift<InstX8632::Shr> InstX8632Shr;
1048typedef InstX8632BinopGPRShift<InstX8632::Sar> InstX8632Sar;
1049typedef InstX8632BinopXmmShift<InstX8632::Psra> InstX8632Psra;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001050typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq;
1051typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001052// movss is only a binary operation when the source and dest
1053// operands are both registers (the high bits of dest are left untouched).
1054// In other cases, it behaves like a copy (mov-like) operation (and the
1055// high bits of dest are cleared).
1056// InstX8632Movss will assert that both its source and dest operands are
1057// registers, so the lowering code should use _mov instead of _movss
1058// in cases where a copy operation is intended.
1059typedef InstX8632BinopXmm<InstX8632::MovssRegs, false> InstX8632MovssRegs;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001060typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv;
1061typedef InstX8632Ternop<InstX8632::Div> InstX8632Div;
Matt Wala0a450512014-07-30 12:44:39 -07001062typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
1063typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
Matt Wala49889232014-07-18 12:45:09 -07001064typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
Matt Wala0a450512014-07-30 12:44:39 -07001065typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
1066typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
1067typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
Matt Wala49889232014-07-18 12:45:09 -07001068typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001069
Jan Vounga3a01a22014-07-14 10:32:41 -07001070// Base class for a lockable x86-32 instruction (emits a locked prefix).
1071class InstX8632Lockable : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001072 InstX8632Lockable() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001073 InstX8632Lockable(const InstX8632Lockable &) = delete;
1074 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
1075
Jan Vounga3a01a22014-07-14 10:32:41 -07001076protected:
1077 bool Locked;
1078
1079 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
1080 Variable *Dest, bool Locked)
1081 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
1082 // Assume that such instructions are used for Atomics and be careful
1083 // with optimizations.
1084 HasSideEffects = Locked;
1085 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001086 ~InstX8632Lockable() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001087};
1088
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001089// Mul instruction - unsigned multiply.
1090class InstX8632Mul : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001091 InstX8632Mul() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001092 InstX8632Mul(const InstX8632Mul &) = delete;
1093 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
1094
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001095public:
1096 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
1097 Operand *Source2) {
1098 return new (Func->allocate<InstX8632Mul>())
1099 InstX8632Mul(Func, Dest, Source1, Source2);
1100 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001101 void emit(const Cfg *Func) const override;
Jan Voungaf2780c2014-09-26 11:14:30 -07001102 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001103 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001104 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
1105
1106private:
1107 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001108 ~InstX8632Mul() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001109};
1110
Jan Voung88355762014-11-01 09:40:20 -07001111// Shld instruction - shift across a pair of operands.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001112class InstX8632Shld : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001113 InstX8632Shld() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001114 InstX8632Shld(const InstX8632Shld &) = delete;
1115 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
1116
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001117public:
1118 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
1119 Variable *Source2) {
1120 return new (Func->allocate<InstX8632Shld>())
1121 InstX8632Shld(Func, Dest, Source1, Source2);
1122 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001123 void emit(const Cfg *Func) const override;
Jan Voung962befa2014-10-15 09:32:58 -07001124 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001125 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001126 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
1127
1128private:
1129 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
1130 Variable *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001131 ~InstX8632Shld() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001132};
1133
Jan Voung88355762014-11-01 09:40:20 -07001134// Shrd instruction - shift across a pair of operands.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001135class InstX8632Shrd : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001136 InstX8632Shrd() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001137 InstX8632Shrd(const InstX8632Shrd &) = delete;
1138 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
1139
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001140public:
1141 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
1142 Variable *Source2) {
1143 return new (Func->allocate<InstX8632Shrd>())
1144 InstX8632Shrd(Func, Dest, Source1, Source2);
1145 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001146 void emit(const Cfg *Func) const override;
Jan Voung962befa2014-10-15 09:32:58 -07001147 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001148 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001149 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
1150
1151private:
1152 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
1153 Variable *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001154 ~InstX8632Shrd() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001155};
1156
Jan Vounge4da26f2014-07-15 17:52:39 -07001157// Conditional move instruction.
1158class InstX8632Cmov : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001159 InstX8632Cmov() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001160 InstX8632Cmov(const InstX8632Cmov &) = delete;
1161 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
1162
Jan Vounge4da26f2014-07-15 17:52:39 -07001163public:
1164 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voungbd385e42014-09-18 18:18:10 -07001165 CondX86::BrCond Cond) {
Jan Vounge4da26f2014-07-15 17:52:39 -07001166 return new (Func->allocate<InstX8632Cmov>())
1167 InstX8632Cmov(Func, Dest, Source, Cond);
1168 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001169 void emit(const Cfg *Func) const override;
1170 void emitIAS(const Cfg *Func) const override;
1171 void dump(const Cfg *Func) const override;
Jan Vounge4da26f2014-07-15 17:52:39 -07001172 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
1173
1174private:
Jan Voungbd385e42014-09-18 18:18:10 -07001175 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
1176 CondX86::BrCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001177 ~InstX8632Cmov() override {}
Jan Vounge4da26f2014-07-15 17:52:39 -07001178
Jan Voungbd385e42014-09-18 18:18:10 -07001179 CondX86::BrCond Condition;
Jan Vounge4da26f2014-07-15 17:52:39 -07001180};
1181
Matt Walace0ca8f2014-07-24 12:34:20 -07001182// Cmpps instruction - compare packed singled-precision floating point
1183// values
1184class InstX8632Cmpps : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001185 InstX8632Cmpps() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001186 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
1187 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
1188
Matt Walace0ca8f2014-07-24 12:34:20 -07001189public:
Matt Walace0ca8f2014-07-24 12:34:20 -07001190 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voungbd385e42014-09-18 18:18:10 -07001191 CondX86::CmppsCond Condition) {
Matt Walace0ca8f2014-07-24 12:34:20 -07001192 return new (Func->allocate<InstX8632Cmpps>())
1193 InstX8632Cmpps(Func, Dest, Source, Condition);
1194 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001195 void emit(const Cfg *Func) const override;
1196 void emitIAS(const Cfg *Func) const override;
1197 void dump(const Cfg *Func) const override;
Matt Walace0ca8f2014-07-24 12:34:20 -07001198 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
1199
1200private:
Jan Voungbd385e42014-09-18 18:18:10 -07001201 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
1202 CondX86::CmppsCond Cond);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001203 ~InstX8632Cmpps() override {}
Matt Walace0ca8f2014-07-24 12:34:20 -07001204
Jan Voungbd385e42014-09-18 18:18:10 -07001205 CondX86::CmppsCond Condition;
Matt Walace0ca8f2014-07-24 12:34:20 -07001206};
1207
Jan Vounga3a01a22014-07-14 10:32:41 -07001208// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
1209// equals eax. If so, the ZF is set and <desired> is stored in <dest>.
1210// If not, ZF is cleared and <dest> is copied to eax (or subregister).
1211// <dest> can be a register or memory, while <desired> must be a register.
1212// It is the user's responsiblity to mark eax with a FakeDef.
1213class InstX8632Cmpxchg : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001214 InstX8632Cmpxchg() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001215 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1216 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
1217
Jan Vounga3a01a22014-07-14 10:32:41 -07001218public:
1219 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1220 Variable *Desired, bool Locked) {
1221 return new (Func->allocate<InstX8632Cmpxchg>())
1222 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
1223 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001224 void emit(const Cfg *Func) const override;
1225 void emitIAS(const Cfg *Func) const override;
1226 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001227 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
1228
1229private:
1230 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1231 Variable *Desired, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001232 ~InstX8632Cmpxchg() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001233};
1234
1235// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
1236// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
1237// If not, ZF is cleared and <m64> is copied to edx:eax.
1238// The caller is responsible for inserting FakeDefs to mark edx
1239// and eax as modified.
1240// <m64> must be a memory operand.
1241class InstX8632Cmpxchg8b : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001242 InstX8632Cmpxchg8b() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001243 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1244 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
1245
Jan Vounga3a01a22014-07-14 10:32:41 -07001246public:
Jan Voung03532e52014-09-23 13:32:18 -07001247 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
Jan Vounga3a01a22014-07-14 10:32:41 -07001248 Variable *Edx, Variable *Eax, Variable *Ecx,
1249 Variable *Ebx, bool Locked) {
1250 return new (Func->allocate<InstX8632Cmpxchg8b>())
1251 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
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 Vounga3a01a22014-07-14 10:32:41 -07001256 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
1257
1258private:
Jan Voung03532e52014-09-23 13:32:18 -07001259 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
Jan Vounga3a01a22014-07-14 10:32:41 -07001260 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001261 ~InstX8632Cmpxchg8b() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001262};
1263
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001264// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
1265// as appropriate. s=float, d=double, i=int. X and Y are determined
1266// from dest/src types. Sign and zero extension on the integer
1267// operand needs to be done separately.
1268class InstX8632Cvt : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001269 InstX8632Cvt() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001270 InstX8632Cvt(const InstX8632Cvt &) = delete;
1271 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
1272
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001273public:
Jan Voung699bf022014-10-08 13:52:10 -07001274 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
Jim Stichnothb63cd882014-09-08 10:47:23 -07001275 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
Jan Voung699bf022014-10-08 13:52:10 -07001276 CvtVariant Variant) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001277 return new (Func->allocate<InstX8632Cvt>())
Jan Voung699bf022014-10-08 13:52:10 -07001278 InstX8632Cvt(Func, Dest, Source, Variant);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001279 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001280 void emit(const Cfg *Func) const override;
Jan Voung699bf022014-10-08 13:52:10 -07001281 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001282 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001283 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
Jan Voung699bf022014-10-08 13:52:10 -07001284 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001285
1286private:
Jan Voung699bf022014-10-08 13:52:10 -07001287 CvtVariant Variant;
1288 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001289 ~InstX8632Cvt() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001290};
1291
1292// cmp - Integer compare instruction.
1293class InstX8632Icmp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001294 InstX8632Icmp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001295 InstX8632Icmp(const InstX8632Icmp &) = delete;
1296 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
1297
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001298public:
1299 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1300 return new (Func->allocate<InstX8632Icmp>())
1301 InstX8632Icmp(Func, Src1, Src2);
1302 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001303 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001304 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001305 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001306 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
1307
1308private:
1309 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001310 ~InstX8632Icmp() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001311};
1312
1313// ucomiss/ucomisd - floating-point compare instruction.
1314class InstX8632Ucomiss : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001315 InstX8632Ucomiss() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001316 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1317 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
1318
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001319public:
1320 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1321 return new (Func->allocate<InstX8632Ucomiss>())
1322 InstX8632Ucomiss(Func, Src1, Src2);
1323 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001324 void emit(const Cfg *Func) const override;
1325 void emitIAS(const Cfg *Func) const override;
1326 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001327 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
1328
1329private:
1330 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001331 ~InstX8632Ucomiss() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001332};
1333
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001334// UD2 instruction.
1335class InstX8632UD2 : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001336 InstX8632UD2() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001337 InstX8632UD2(const InstX8632UD2 &) = delete;
1338 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
1339
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001340public:
1341 static InstX8632UD2 *create(Cfg *Func) {
1342 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
1343 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001344 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001345 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001346 void dump(const Cfg *Func) const override;
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001347 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
1348
1349private:
Jim Stichnothc6ead202015-02-24 09:30:30 -08001350 explicit InstX8632UD2(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001351 ~InstX8632UD2() override {}
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001352};
1353
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001354// Test instruction.
1355class InstX8632Test : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001356 InstX8632Test() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001357 InstX8632Test(const InstX8632Test &) = delete;
1358 InstX8632Test &operator=(const InstX8632Test &) = delete;
1359
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001360public:
1361 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
1362 return new (Func->allocate<InstX8632Test>())
1363 InstX8632Test(Func, Source1, Source2);
1364 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001365 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001366 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001367 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001368 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
1369
1370private:
1371 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001372 ~InstX8632Test() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001373};
1374
Jan Voung5cd240d2014-06-25 10:36:46 -07001375// Mfence instruction.
1376class InstX8632Mfence : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001377 InstX8632Mfence() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001378 InstX8632Mfence(const InstX8632Mfence &) = delete;
1379 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
1380
Jan Voung5cd240d2014-06-25 10:36:46 -07001381public:
1382 static InstX8632Mfence *create(Cfg *Func) {
1383 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
1384 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001385 void emit(const Cfg *Func) const override;
Jan Voungaf2780c2014-09-26 11:14:30 -07001386 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001387 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001388 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
1389
1390private:
Jim Stichnothc6ead202015-02-24 09:30:30 -08001391 explicit InstX8632Mfence(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001392 ~InstX8632Mfence() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001393};
1394
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001395// This is essentially a "mov" instruction with an OperandX8632Mem
1396// operand instead of Variable as the destination. It's important
1397// for liveness that there is no Dest operand.
1398class InstX8632Store : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001399 InstX8632Store() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001400 InstX8632Store(const InstX8632Store &) = delete;
1401 InstX8632Store &operator=(const InstX8632Store &) = delete;
1402
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001403public:
1404 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1405 return new (Func->allocate<InstX8632Store>())
1406 InstX8632Store(Func, Value, Mem);
1407 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001408 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -07001409 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001410 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001411 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
1412
1413private:
1414 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001415 ~InstX8632Store() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001416};
1417
Jan Vounge4dc61b2014-10-06 08:53:52 -07001418// This is essentially a vector "mov" instruction with an OperandX8632Mem
1419// operand instead of Variable as the destination. It's important
1420// for liveness that there is no Dest operand. The source must be an
1421// Xmm register, since Dest is mem.
Matt Wala105b7042014-08-11 19:56:19 -07001422class InstX8632StoreP : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001423 InstX8632StoreP() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001424 InstX8632StoreP(const InstX8632StoreP &) = delete;
1425 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
1426
Matt Wala105b7042014-08-11 19:56:19 -07001427public:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001428 static InstX8632StoreP *create(Cfg *Func, Variable *Value,
1429 OperandX8632Mem *Mem) {
Matt Wala105b7042014-08-11 19:56:19 -07001430 return new (Func->allocate<InstX8632StoreP>())
1431 InstX8632StoreP(Func, Value, Mem);
1432 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001433 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001434 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001435 void dump(const Cfg *Func) const override;
Matt Wala105b7042014-08-11 19:56:19 -07001436 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
1437
1438private:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001439 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001440 ~InstX8632StoreP() override {}
Matt Wala105b7042014-08-11 19:56:19 -07001441};
1442
Jan Voung5cd240d2014-06-25 10:36:46 -07001443class InstX8632StoreQ : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001444 InstX8632StoreQ() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001445 InstX8632StoreQ(const InstX8632StoreQ &) = delete;
1446 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
1447
Jan Voung5cd240d2014-06-25 10:36:46 -07001448public:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001449 static InstX8632StoreQ *create(Cfg *Func, Variable *Value,
1450 OperandX8632Mem *Mem) {
Jan Voung5cd240d2014-06-25 10:36:46 -07001451 return new (Func->allocate<InstX8632StoreQ>())
1452 InstX8632StoreQ(Func, Value, Mem);
1453 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001454 void emit(const Cfg *Func) const override;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001455 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001456 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001457 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1458
1459private:
Jan Vounge4dc61b2014-10-06 08:53:52 -07001460 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001461 ~InstX8632StoreQ() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001462};
1463
Matt Walac3302742014-08-15 16:21:56 -07001464// Nop instructions of varying length
1465class InstX8632Nop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001466 InstX8632Nop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001467 InstX8632Nop(const InstX8632Nop &) = delete;
1468 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
1469
Matt Walac3302742014-08-15 16:21:56 -07001470public:
1471 // TODO: Replace with enum.
1472 typedef unsigned NopVariant;
1473
1474 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1475 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1476 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001477 void emit(const Cfg *Func) const override;
1478 void emitIAS(const Cfg *Func) const override;
1479 void dump(const Cfg *Func) const override;
Matt Walac3302742014-08-15 16:21:56 -07001480 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1481
1482private:
1483 InstX8632Nop(Cfg *Func, SizeT Length);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001484 ~InstX8632Nop() override {}
Matt Walac3302742014-08-15 16:21:56 -07001485
1486 NopVariant Variant;
1487};
1488
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001489// Fld - load a value onto the x87 FP stack.
1490class InstX8632Fld : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001491 InstX8632Fld() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001492 InstX8632Fld(const InstX8632Fld &) = delete;
1493 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
1494
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001495public:
1496 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1497 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1498 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001499 void emit(const Cfg *Func) const override;
Jan Voung479e5632014-10-08 21:05:27 -07001500 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001501 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001502 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1503
1504private:
1505 InstX8632Fld(Cfg *Func, Operand *Src);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001506 ~InstX8632Fld() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001507};
1508
1509// Fstp - store x87 st(0) into memory and pop st(0).
1510class InstX8632Fstp : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001511 InstX8632Fstp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001512 InstX8632Fstp(const InstX8632Fstp &) = delete;
1513 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
1514
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001515public:
1516 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1517 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1518 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001519 void emit(const Cfg *Func) const override;
Jan Voung479e5632014-10-08 21:05:27 -07001520 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001521 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001522 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
1523
1524private:
1525 InstX8632Fstp(Cfg *Func, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001526 ~InstX8632Fstp() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001527};
1528
1529class InstX8632Pop : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001530 InstX8632Pop() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001531 InstX8632Pop(const InstX8632Pop &) = delete;
1532 InstX8632Pop &operator=(const InstX8632Pop &) = delete;
1533
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001534public:
1535 static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
1536 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
1537 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001538 void emit(const Cfg *Func) const override;
1539 void emitIAS(const Cfg *Func) const override;
1540 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001541 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1542
1543private:
1544 InstX8632Pop(Cfg *Func, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001545 ~InstX8632Pop() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001546};
1547
1548class InstX8632Push : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001549 InstX8632Push() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001550 InstX8632Push(const InstX8632Push &) = delete;
1551 InstX8632Push &operator=(const InstX8632Push &) = delete;
1552
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001553public:
Jan Voung0b9eee52014-10-07 11:20:10 -07001554 static InstX8632Push *create(Cfg *Func, Variable *Source) {
Jim Stichnothdd842db2015-01-27 12:53:53 -08001555 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001556 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001557 void emit(const Cfg *Func) const override;
Jan Voung0b9eee52014-10-07 11:20:10 -07001558 void emitIAS(const Cfg *Func) const override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001559 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001560 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1561
1562private:
Jan Voung0b9eee52014-10-07 11:20:10 -07001563 InstX8632Push(Cfg *Func, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001564 ~InstX8632Push() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001565};
1566
1567// Ret instruction. Currently only supports the "ret" version that
1568// does not pop arguments. This instruction takes a Source operand
1569// (for non-void returning functions) for liveness analysis, though
1570// a FakeUse before the ret would do just as well.
1571class InstX8632Ret : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001572 InstX8632Ret() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001573 InstX8632Ret(const InstX8632Ret &) = delete;
1574 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
1575
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001576public:
Jim Stichnothae953202014-12-20 06:17:49 -08001577 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001578 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1579 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001580 void emit(const Cfg *Func) const override;
1581 void emitIAS(const Cfg *Func) const override;
1582 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001583 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1584
1585private:
1586 InstX8632Ret(Cfg *Func, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001587 ~InstX8632Ret() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001588};
1589
Jim Stichnothf48b3202015-05-04 10:22:17 -07001590// Conditional set-byte instruction.
1591class InstX8632Setcc : public InstX8632 {
1592 InstX8632Setcc() = delete;
1593 InstX8632Setcc(const InstX8632Cmov &) = delete;
1594 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete;
1595
1596public:
1597 static InstX8632Setcc *create(Cfg *Func, Variable *Dest,
1598 CondX86::BrCond Cond) {
1599 return new (Func->allocate<InstX8632Setcc>())
1600 InstX8632Setcc(Func, Dest, Cond);
1601 }
1602 void emit(const Cfg *Func) const override;
1603 void emitIAS(const Cfg *Func) const override;
1604 void dump(const Cfg *Func) const override;
1605 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); }
1606
1607private:
1608 InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond);
1609 ~InstX8632Setcc() override {}
1610
1611 const CondX86::BrCond Condition;
1612};
1613
Jan Voung5cd240d2014-06-25 10:36:46 -07001614// Exchanging Add instruction. Exchanges the first operand (destination
1615// operand) with the second operand (source operand), then loads the sum
1616// of the two values into the destination operand. The destination may be
1617// a register or memory, while the source must be a register.
1618//
1619// Both the dest and source are updated. The caller should then insert a
1620// FakeDef to reflect the second udpate.
Jan Vounga3a01a22014-07-14 10:32:41 -07001621class InstX8632Xadd : public InstX8632Lockable {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001622 InstX8632Xadd() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001623 InstX8632Xadd(const InstX8632Xadd &) = delete;
1624 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
1625
Jan Voung5cd240d2014-06-25 10:36:46 -07001626public:
1627 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1628 bool Locked) {
1629 return new (Func->allocate<InstX8632Xadd>())
1630 InstX8632Xadd(Func, Dest, Source, Locked);
1631 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001632 void emit(const Cfg *Func) const override;
1633 void emitIAS(const Cfg *Func) const override;
1634 void dump(const Cfg *Func) const override;
Jan Voung5cd240d2014-06-25 10:36:46 -07001635 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1636
1637private:
Jan Voung5cd240d2014-06-25 10:36:46 -07001638 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001639 ~InstX8632Xadd() override {}
Jan Voung5cd240d2014-06-25 10:36:46 -07001640};
1641
Jan Vounga3a01a22014-07-14 10:32:41 -07001642// Exchange instruction. Exchanges the first operand (destination
1643// operand) with the second operand (source operand). At least one of
1644// the operands must be a register (and the other can be reg or mem).
1645// Both the Dest and Source are updated. If there is a memory operand,
1646// then the instruction is automatically "locked" without the need for
1647// a lock prefix.
1648class InstX8632Xchg : public InstX8632 {
Jim Stichnothc6ead202015-02-24 09:30:30 -08001649 InstX8632Xchg() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -07001650 InstX8632Xchg(const InstX8632Xchg &) = delete;
1651 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
1652
Jan Vounga3a01a22014-07-14 10:32:41 -07001653public:
1654 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1655 return new (Func->allocate<InstX8632Xchg>())
1656 InstX8632Xchg(Func, Dest, Source);
1657 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001658 void emit(const Cfg *Func) const override;
1659 void emitIAS(const Cfg *Func) const override;
1660 void dump(const Cfg *Func) const override;
Jan Vounga3a01a22014-07-14 10:32:41 -07001661 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
1662
1663private:
1664 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -07001665 ~InstX8632Xchg() override {}
Jan Vounga3a01a22014-07-14 10:32:41 -07001666};
1667
Jim Stichnoth6e992142014-07-30 14:45:20 -07001668// Declare partial template specializations of emit() methods that
1669// already have default implementations. Without this, there is the
1670// possibility of ODR violations and link errors.
1671template <> void InstX8632Addss::emit(const Cfg *Func) const;
1672template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
Matt Wala51e8cfb2014-08-08 08:39:40 -07001673template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
Jim Stichnoth6e992142014-07-30 14:45:20 -07001674template <> void InstX8632Div::emit(const Cfg *Func) const;
1675template <> void InstX8632Divss::emit(const Cfg *Func) const;
1676template <> void InstX8632Idiv::emit(const Cfg *Func) const;
1677template <> void InstX8632Imul::emit(const Cfg *Func) const;
1678template <> void InstX8632Lea::emit(const Cfg *Func) const;
1679template <> void InstX8632Mulss::emit(const Cfg *Func) const;
1680template <> void InstX8632Padd::emit(const Cfg *Func) const;
1681template <> void InstX8632Pblendvb::emit(const Cfg *Func) const;
1682template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const;
1683template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const;
1684template <> void InstX8632Pextr::emit(const Cfg *Func) const;
1685template <> void InstX8632Pinsr::emit(const Cfg *Func) const;
1686template <> void InstX8632Pmull::emit(const Cfg *Func) const;
1687template <> void InstX8632Pmuludq::emit(const Cfg *Func) const;
1688template <> void InstX8632Psll::emit(const Cfg *Func) const;
1689template <> void InstX8632Psra::emit(const Cfg *Func) const;
Jim Stichnoth8c980d02015-03-19 13:01:50 -07001690template <> void InstX8632Psrl::emit(const Cfg *Func) const;
Jim Stichnoth6e992142014-07-30 14:45:20 -07001691template <> void InstX8632Psub::emit(const Cfg *Func) const;
1692template <> void InstX8632Sqrtss::emit(const Cfg *Func) const;
1693template <> void InstX8632Subss::emit(const Cfg *Func) const;
1694
Jan Voungd026c442014-10-13 14:06:50 -07001695template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001696template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const;
Jan Voungaf2780c2014-09-26 11:14:30 -07001697template <> void InstX8632Div::emitIAS(const Cfg *Func) const;
1698template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const;
Jan Voung0ac50dc2014-09-30 08:36:06 -07001699template <> void InstX8632Imul::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001700template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const;
Jan Voung3b43b892014-09-24 13:32:39 -07001701template <> void InstX8632Movd::emitIAS(const Cfg *Func) const;
Jan Vounge4dc61b2014-10-06 08:53:52 -07001702template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const;
Jan Voungd026c442014-10-13 14:06:50 -07001703template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001704template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const;
1705template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const;
Jan Voung39d4aca2014-10-15 15:16:54 -07001706template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const;
1707template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const;
Jan Voung8bcca042014-10-03 21:58:02 -07001708template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const;
Jan Voung962befa2014-10-15 09:32:58 -07001709template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const;
1710template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const;
Jan Voung03532e52014-09-23 13:32:18 -07001711
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001712} // end of namespace Ice
1713
1714#endif // SUBZERO_SRC_ICEINSTX8632_H