Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: src/IceInstX8632.h

Issue 656123003: Subzero: Class definition cleanup. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// 1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file declares the InstX8632 and OperandX8632 classes and 10 // This file declares the InstX8632 and OperandX8632 classes and
(...skipping 12 matching lines...) Expand all
23 #include "IceInstX8632.def" 23 #include "IceInstX8632.def"
24 #include "IceOperand.h" 24 #include "IceOperand.h"
25 25
26 namespace Ice { 26 namespace Ice {
27 27
28 class TargetX8632; 28 class TargetX8632;
29 29
30 // OperandX8632 extends the Operand hierarchy. Its subclasses are 30 // OperandX8632 extends the Operand hierarchy. Its subclasses are
31 // OperandX8632Mem and VariableSplit. 31 // OperandX8632Mem and VariableSplit.
32 class OperandX8632 : public Operand { 32 class OperandX8632 : public Operand {
33 OperandX8632(const OperandX8632 &) = delete;
34 OperandX8632 &operator=(const OperandX8632 &) = delete;
35
33 public: 36 public:
34 enum OperandKindX8632 { 37 enum OperandKindX8632 {
35 k__Start = Operand::kTarget, 38 k__Start = Operand::kTarget,
36 kMem, 39 kMem,
37 kSplit 40 kSplit
38 }; 41 };
39 using Operand::dump; 42 using Operand::dump;
40 void dump(const Cfg *, Ostream &Str) const override { 43 void dump(const Cfg *, Ostream &Str) const override {
41 Str << "<OperandX8632>"; 44 Str << "<OperandX8632>";
42 } 45 }
43 46
44 protected: 47 protected:
45 OperandX8632(OperandKindX8632 Kind, Type Ty) 48 OperandX8632(OperandKindX8632 Kind, Type Ty)
46 : Operand(static_cast<OperandKind>(Kind), Ty) {} 49 : Operand(static_cast<OperandKind>(Kind), Ty) {}
47 ~OperandX8632() override {} 50 ~OperandX8632() override {}
48
49 private:
50 OperandX8632(const OperandX8632 &) = delete;
51 OperandX8632 &operator=(const OperandX8632 &) = delete;
52 }; 51 };
53 52
54 // OperandX8632Mem represents the m32 addressing mode, with optional 53 // OperandX8632Mem represents the m32 addressing mode, with optional
55 // base and index registers, a constant offset, and a fixed shift 54 // base and index registers, a constant offset, and a fixed shift
56 // value for the index register. 55 // value for the index register.
57 class OperandX8632Mem : public OperandX8632 { 56 class OperandX8632Mem : public OperandX8632 {
57 OperandX8632Mem(const OperandX8632Mem &) = delete;
58 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
59
58 public: 60 public:
59 enum SegmentRegisters { 61 enum SegmentRegisters {
60 DefaultSegment = -1, 62 DefaultSegment = -1,
61 #define X(val, name, prefix) val, 63 #define X(val, name, prefix) val,
62 SEG_REGX8632_TABLE 64 SEG_REGX8632_TABLE
63 #undef X 65 #undef X
64 SegReg_NUM 66 SegReg_NUM
65 }; 67 };
66 static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base, 68 static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base,
67 Constant *Offset, Variable *Index = NULL, 69 Constant *Offset, Variable *Index = NULL,
(...skipping 13 matching lines...) Expand all
81 using OperandX8632::dump; 83 using OperandX8632::dump;
82 void dump(const Cfg *Func, Ostream &Str) const override; 84 void dump(const Cfg *Func, Ostream &Str) const override;
83 85
84 static bool classof(const Operand *Operand) { 86 static bool classof(const Operand *Operand) {
85 return Operand->getKind() == static_cast<OperandKind>(kMem); 87 return Operand->getKind() == static_cast<OperandKind>(kMem);
86 } 88 }
87 89
88 private: 90 private:
89 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, 91 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
90 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg); 92 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
91 OperandX8632Mem(const OperandX8632Mem &) = delete;
92 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
93 ~OperandX8632Mem() override {} 93 ~OperandX8632Mem() override {}
94 Variable *Base; 94 Variable *Base;
95 Constant *Offset; 95 Constant *Offset;
96 Variable *Index; 96 Variable *Index;
97 uint16_t Shift; 97 uint16_t Shift;
98 SegmentRegisters SegmentReg : 16; 98 SegmentRegisters SegmentReg : 16;
99 }; 99 };
100 100
101 // VariableSplit is a way to treat an f64 memory location as a pair 101 // VariableSplit is a way to treat an f64 memory location as a pair
102 // of i32 locations (Low and High). This is needed for some cases 102 // of i32 locations (Low and High). This is needed for some cases
103 // of the Bitcast instruction. Since it's not possible for integer 103 // of the Bitcast instruction. Since it's not possible for integer
104 // registers to access the XMM registers and vice versa, the 104 // registers to access the XMM registers and vice versa, the
105 // lowering forces the f64 to be spilled to the stack and then 105 // lowering forces the f64 to be spilled to the stack and then
106 // accesses through the VariableSplit. 106 // accesses through the VariableSplit.
107 class VariableSplit : public OperandX8632 { 107 class VariableSplit : public OperandX8632 {
108 VariableSplit(const VariableSplit &) = delete;
109 VariableSplit &operator=(const VariableSplit &) = delete;
110
108 public: 111 public:
109 enum Portion { 112 enum Portion {
110 Low, 113 Low,
111 High 114 High
112 }; 115 };
113 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { 116 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
114 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); 117 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
115 } 118 }
116 int32_t getOffset() const { return Part == High ? 4 : 0; } 119 int32_t getOffset() const { return Part == High ? 4 : 0; }
117 120
118 x86::Address toAsmAddress(const Cfg *Func) const; 121 x86::Address toAsmAddress(const Cfg *Func) const;
119 void emit(const Cfg *Func) const override; 122 void emit(const Cfg *Func) const override;
120 using OperandX8632::dump; 123 using OperandX8632::dump;
121 void dump(const Cfg *Func, Ostream &Str) const override; 124 void dump(const Cfg *Func, Ostream &Str) const override;
122 125
123 static bool classof(const Operand *Operand) { 126 static bool classof(const Operand *Operand) {
124 return Operand->getKind() == static_cast<OperandKind>(kSplit); 127 return Operand->getKind() == static_cast<OperandKind>(kSplit);
125 } 128 }
126 129
127 private: 130 private:
128 VariableSplit(Cfg *Func, Variable *Var, Portion Part) 131 VariableSplit(Cfg *Func, Variable *Var, Portion Part)
129 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) { 132 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) {
130 assert(Var->getType() == IceType_f64); 133 assert(Var->getType() == IceType_f64);
131 Vars = Func->allocateArrayOf<Variable *>(1); 134 Vars = Func->allocateArrayOf<Variable *>(1);
132 Vars[0] = Var; 135 Vars[0] = Var;
133 NumVars = 1; 136 NumVars = 1;
134 } 137 }
135 VariableSplit(const VariableSplit &) = delete;
136 VariableSplit &operator=(const VariableSplit &) = delete;
137 ~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); } 138 ~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); }
138 Cfg *Func; // Held only for the destructor. 139 Cfg *Func; // Held only for the destructor.
139 Variable *Var; 140 Variable *Var;
140 Portion Part; 141 Portion Part;
141 }; 142 };
142 143
143 // SpillVariable decorates a Variable by linking it to another 144 // SpillVariable decorates a Variable by linking it to another
144 // Variable. When stack frame offsets are computed, the SpillVariable 145 // Variable. When stack frame offsets are computed, the SpillVariable
145 // is given a distinct stack slot only if its linked Variable has a 146 // is given a distinct stack slot only if its linked Variable has a
146 // register. If the linked Variable has a stack slot, then the 147 // register. If the linked Variable has a stack slot, then the
147 // Variable and SpillVariable share that slot. 148 // Variable and SpillVariable share that slot.
148 class SpillVariable : public Variable { 149 class SpillVariable : public Variable {
Karl 2014/10/15 19:59:12 What about delete for default constructor/assignme
Jim Stichnoth 2014/10/15 20:23:43 Done.
149 public: 150 public:
150 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index, 151 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index,
151 const IceString &Name) { 152 const IceString &Name) {
152 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index, Name); 153 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index, Name);
153 } 154 }
154 const static OperandKind SpillVariableKind = 155 const static OperandKind SpillVariableKind =
155 static_cast<OperandKind>(kVariable_Target); 156 static_cast<OperandKind>(kVariable_Target);
156 static bool classof(const Operand *Operand) { 157 static bool classof(const Operand *Operand) {
157 return Operand->getKind() == SpillVariableKind; 158 return Operand->getKind() == SpillVariableKind;
158 } 159 }
159 void setLinkedTo(Variable *Var) { LinkedTo = Var; } 160 void setLinkedTo(Variable *Var) { LinkedTo = Var; }
160 Variable *getLinkedTo() const { return LinkedTo; } 161 Variable *getLinkedTo() const { return LinkedTo; }
161 // Inherit dump() and emit() from Variable. 162 // Inherit dump() and emit() from Variable.
162 private: 163 private:
163 SpillVariable(Type Ty, SizeT Index, const IceString &Name) 164 SpillVariable(Type Ty, SizeT Index, const IceString &Name)
164 : Variable(SpillVariableKind, Ty, Index, Name), LinkedTo(NULL) {} 165 : Variable(SpillVariableKind, Ty, Index, Name), LinkedTo(NULL) {}
165 Variable *LinkedTo; 166 Variable *LinkedTo;
166 }; 167 };
167 168
168 class InstX8632 : public InstTarget { 169 class InstX8632 : public InstTarget {
170 InstX8632(const InstX8632 &) = delete;
171 InstX8632 &operator=(const InstX8632 &) = delete;
172
169 public: 173 public:
170 enum InstKindX8632 { 174 enum InstKindX8632 {
171 k__Start = Inst::Target, 175 k__Start = Inst::Target,
172 Adc, 176 Adc,
173 Add, 177 Add,
174 Addps, 178 Addps,
175 Addss, 179 Addss,
176 Adjuststack, 180 Adjuststack,
177 And, 181 And,
178 Blendvps, 182 Blendvps,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 static const char *getWidthString(Type Ty); 262 static const char *getWidthString(Type Ty);
259 void dump(const Cfg *Func) const override; 263 void dump(const Cfg *Func) const override;
260 264
261 protected: 265 protected:
262 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) 266 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
263 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 267 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
264 ~InstX8632() override {} 268 ~InstX8632() override {}
265 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) { 269 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
266 return Inst->getKind() == static_cast<InstKind>(MyKind); 270 return Inst->getKind() == static_cast<InstKind>(MyKind);
267 } 271 }
268
269 private:
270 InstX8632(const InstX8632 &) = delete;
271 InstX8632 &operator=(const InstX8632 &) = delete;
272 }; 272 };
273 273
274 // InstX8632Label represents an intra-block label that is the 274 // InstX8632Label represents an intra-block label that is the
275 // target of an intra-block branch. These are used for lowering i1 275 // target of an intra-block branch. These are used for lowering i1
276 // calculations, Select instructions, and 64-bit compares on a 32-bit 276 // calculations, Select instructions, and 64-bit compares on a 32-bit
277 // architecture, without basic block splitting. Basic block splitting 277 // architecture, without basic block splitting. Basic block splitting
278 // is not so desirable for several reasons, one of which is the impact 278 // is not so desirable for several reasons, one of which is the impact
279 // on decisions based on whether a variable's live range spans 279 // on decisions based on whether a variable's live range spans
280 // multiple basic blocks. 280 // multiple basic blocks.
281 // 281 //
(...skipping 20 matching lines...) Expand all
302 // FakeUse(c) 302 // FakeUse(c)
303 // L1: 303 // L1:
304 // mov c, y 304 // mov c, y
305 // L2: 305 // L2:
306 // 306 //
307 // The down-side is that "mov c, x" can never be dead-code eliminated 307 // The down-side is that "mov c, x" can never be dead-code eliminated
308 // even if there are no uses of c. As unlikely as this situation is, 308 // even if there are no uses of c. As unlikely as this situation is,
309 // it may be prevented by running dead code elimination before 309 // it may be prevented by running dead code elimination before
310 // lowering. 310 // lowering.
311 class InstX8632Label : public InstX8632 { 311 class InstX8632Label : public InstX8632 {
312 InstX8632Label(const InstX8632Label &) = delete;
313 InstX8632Label &operator=(const InstX8632Label &) = delete;
314
312 public: 315 public:
313 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) { 316 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
314 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target); 317 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
315 } 318 }
316 uint32_t getEmitInstCount() const override { return 0; } 319 uint32_t getEmitInstCount() const override { return 0; }
317 IceString getName(const Cfg *Func) const; 320 IceString getName(const Cfg *Func) const;
318 void emit(const Cfg *Func) const override; 321 void emit(const Cfg *Func) const override;
319 void dump(const Cfg *Func) const override; 322 void dump(const Cfg *Func) const override;
320 323
321 private: 324 private:
322 InstX8632Label(Cfg *Func, TargetX8632 *Target); 325 InstX8632Label(Cfg *Func, TargetX8632 *Target);
323 InstX8632Label(const InstX8632Label &) = delete;
324 InstX8632Label &operator=(const InstX8632Label &) = delete;
325 ~InstX8632Label() override {} 326 ~InstX8632Label() override {}
326 SizeT Number; // used only for unique label string generation 327 SizeT Number; // used only for unique label string generation
327 }; 328 };
328 329
329 // Conditional and unconditional branch instruction. 330 // Conditional and unconditional branch instruction.
330 class InstX8632Br : public InstX8632 { 331 class InstX8632Br : public InstX8632 {
332 InstX8632Br(const InstX8632Br &) = delete;
333 InstX8632Br &operator=(const InstX8632Br &) = delete;
334
331 public: 335 public:
332 // Create a conditional branch to a node. 336 // Create a conditional branch to a node.
333 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, 337 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
334 CfgNode *TargetFalse, CondX86::BrCond Condition) { 338 CfgNode *TargetFalse, CondX86::BrCond Condition) {
335 const InstX8632Label *NoLabel = NULL; 339 const InstX8632Label *NoLabel = NULL;
336 return new (Func->allocate<InstX8632Br>()) 340 return new (Func->allocate<InstX8632Br>())
337 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition); 341 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
338 } 342 }
339 // Create an unconditional branch to a node. 343 // Create an unconditional branch to a node.
340 static InstX8632Br *create(Cfg *Func, CfgNode *Target) { 344 static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 ++Sum; 379 ++Sum;
376 return Sum; 380 return Sum;
377 } 381 }
378 void emit(const Cfg *Func) const override; 382 void emit(const Cfg *Func) const override;
379 void dump(const Cfg *Func) const override; 383 void dump(const Cfg *Func) const override;
380 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } 384 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
381 385
382 private: 386 private:
383 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 387 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
384 const InstX8632Label *Label, CondX86::BrCond Condition); 388 const InstX8632Label *Label, CondX86::BrCond Condition);
385 InstX8632Br(const InstX8632Br &) = delete;
386 InstX8632Br &operator=(const InstX8632Br &) = delete;
387 ~InstX8632Br() override {} 389 ~InstX8632Br() override {}
388 CondX86::BrCond Condition; 390 CondX86::BrCond Condition;
389 const CfgNode *TargetTrue; 391 const CfgNode *TargetTrue;
390 const CfgNode *TargetFalse; 392 const CfgNode *TargetFalse;
391 const InstX8632Label *Label; // Intra-block branch target 393 const InstX8632Label *Label; // Intra-block branch target
392 }; 394 };
393 395
394 // AdjustStack instruction - subtracts esp by the given amount and 396 // AdjustStack instruction - subtracts esp by the given amount and
395 // updates the stack offset during code emission. 397 // updates the stack offset during code emission.
396 class InstX8632AdjustStack : public InstX8632 { 398 class InstX8632AdjustStack : public InstX8632 {
399 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
400 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
401
397 public: 402 public:
398 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) { 403 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
399 return new (Func->allocate<InstX8632AdjustStack>()) 404 return new (Func->allocate<InstX8632AdjustStack>())
400 InstX8632AdjustStack(Func, Amount, Esp); 405 InstX8632AdjustStack(Func, Amount, Esp);
401 } 406 }
402 void emit(const Cfg *Func) const override; 407 void emit(const Cfg *Func) const override;
403 void emitIAS(const Cfg *Func) const override; 408 void emitIAS(const Cfg *Func) const override;
404 void dump(const Cfg *Func) const override; 409 void dump(const Cfg *Func) const override;
405 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); } 410 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
406 411
407 private: 412 private:
408 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp); 413 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
409 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
410 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
411 SizeT Amount; 414 SizeT Amount;
412 }; 415 };
413 416
414 // Call instruction. Arguments should have already been pushed. 417 // Call instruction. Arguments should have already been pushed.
415 class InstX8632Call : public InstX8632 { 418 class InstX8632Call : public InstX8632 {
419 InstX8632Call(const InstX8632Call &) = delete;
420 InstX8632Call &operator=(const InstX8632Call &) = delete;
421
416 public: 422 public:
417 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { 423 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
418 return new (Func->allocate<InstX8632Call>()) 424 return new (Func->allocate<InstX8632Call>())
419 InstX8632Call(Func, Dest, CallTarget); 425 InstX8632Call(Func, Dest, CallTarget);
420 } 426 }
421 Operand *getCallTarget() const { return getSrc(0); } 427 Operand *getCallTarget() const { return getSrc(0); }
422 void emit(const Cfg *Func) const override; 428 void emit(const Cfg *Func) const override;
423 void dump(const Cfg *Func) const override; 429 void dump(const Cfg *Func) const override;
424 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 430 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
425 431
426 private: 432 private:
427 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 433 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
428 InstX8632Call(const InstX8632Call &) = delete;
429 InstX8632Call &operator=(const InstX8632Call &) = delete;
430 ~InstX8632Call() override {} 434 ~InstX8632Call() override {}
431 }; 435 };
432 436
433 // Emit a one-operand (GPR) instruction. 437 // Emit a one-operand (GPR) instruction.
434 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, 438 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
435 const x86::AssemblerX86::GPREmitterOneOp &Emitter); 439 const x86::AssemblerX86::GPREmitterOneOp &Emitter);
436 440
437 // Instructions of the form x := op(x). 441 // Instructions of the form x := op(x).
438 template <InstX8632::InstKindX8632 K> 442 template <InstX8632::InstKindX8632 K>
439 class InstX8632InplaceopGPR : public InstX8632 { 443 class InstX8632InplaceopGPR : public InstX8632 {
444 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
445 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
446
440 public: 447 public:
441 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { 448 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) {
442 return new (Func->allocate<InstX8632InplaceopGPR>()) 449 return new (Func->allocate<InstX8632InplaceopGPR>())
443 InstX8632InplaceopGPR(Func, SrcDest); 450 InstX8632InplaceopGPR(Func, SrcDest);
444 } 451 }
445 void emit(const Cfg *Func) const override { 452 void emit(const Cfg *Func) const override {
446 Ostream &Str = Func->getContext()->getStrEmit(); 453 Ostream &Str = Func->getContext()->getStrEmit();
447 assert(getSrcSize() == 1); 454 assert(getSrcSize() == 1);
448 Str << "\t" << Opcode << "\t"; 455 Str << "\t" << Opcode << "\t";
449 getSrc(0)->emit(Func); 456 getSrc(0)->emit(Func);
(...skipping 11 matching lines...) Expand all
461 Str << " = " << Opcode << "." << getDest()->getType() << " "; 468 Str << " = " << Opcode << "." << getDest()->getType() << " ";
462 dumpSources(Func); 469 dumpSources(Func);
463 } 470 }
464 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 471 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
465 472
466 private: 473 private:
467 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) 474 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest)
468 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { 475 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
469 addSource(SrcDest); 476 addSource(SrcDest);
470 } 477 }
471 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
472 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
473 ~InstX8632InplaceopGPR() override {} 478 ~InstX8632InplaceopGPR() override {}
474 static const char *Opcode; 479 static const char *Opcode;
475 static const x86::AssemblerX86::GPREmitterOneOp Emitter; 480 static const x86::AssemblerX86::GPREmitterOneOp Emitter;
476 }; 481 };
477 482
478 // Emit a two-operand (GPR) instruction, where the dest operand is a 483 // Emit a two-operand (GPR) instruction, where the dest operand is a
479 // Variable that's guaranteed to be a register. 484 // Variable that's guaranteed to be a register.
480 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, 485 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
481 const Operand *Src, 486 const Operand *Src,
482 const x86::AssemblerX86::GPREmitterRegOp &Emitter); 487 const x86::AssemblerX86::GPREmitterRegOp &Emitter);
483 488
484 // Instructions of the form x := op(y) 489 // Instructions of the form x := op(y)
485 template <InstX8632::InstKindX8632 K> 490 template <InstX8632::InstKindX8632 K>
486 class InstX8632UnaryopGPR : public InstX8632 { 491 class InstX8632UnaryopGPR : public InstX8632 {
492 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
493 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
494
487 public: 495 public:
488 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { 496 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
489 return new (Func->allocate<InstX8632UnaryopGPR>()) 497 return new (Func->allocate<InstX8632UnaryopGPR>())
490 InstX8632UnaryopGPR(Func, Dest, Src); 498 InstX8632UnaryopGPR(Func, Dest, Src);
491 } 499 }
492 void emit(const Cfg *Func) const override { 500 void emit(const Cfg *Func) const override {
493 Ostream &Str = Func->getContext()->getStrEmit(); 501 Ostream &Str = Func->getContext()->getStrEmit();
494 assert(getSrcSize() == 1); 502 assert(getSrcSize() == 1);
495 Str << "\t" << Opcode << "\t"; 503 Str << "\t" << Opcode << "\t";
496 getDest()->emit(Func); 504 getDest()->emit(Func);
(...skipping 14 matching lines...) Expand all
511 Str << " = " << Opcode << "." << getDest()->getType() << " "; 519 Str << " = " << Opcode << "." << getDest()->getType() << " ";
512 dumpSources(Func); 520 dumpSources(Func);
513 } 521 }
514 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 522 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
515 523
516 private: 524 private:
517 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) 525 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
518 : InstX8632(Func, K, 1, Dest) { 526 : InstX8632(Func, K, 1, Dest) {
519 addSource(Src); 527 addSource(Src);
520 } 528 }
521 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
522 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
523 ~InstX8632UnaryopGPR() override {} 529 ~InstX8632UnaryopGPR() override {}
524 static const char *Opcode; 530 static const char *Opcode;
525 static const x86::AssemblerX86::GPREmitterRegOp Emitter; 531 static const x86::AssemblerX86::GPREmitterRegOp Emitter;
526 }; 532 };
527 533
528 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, 534 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
529 const Operand *Src, 535 const Operand *Src,
530 const x86::AssemblerX86::XmmEmitterRegOp &Emitter); 536 const x86::AssemblerX86::XmmEmitterRegOp &Emitter);
531 537
532 template <InstX8632::InstKindX8632 K> 538 template <InstX8632::InstKindX8632 K>
533 class InstX8632UnaryopXmm : public InstX8632 { 539 class InstX8632UnaryopXmm : public InstX8632 {
540 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
541 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
542
534 public: 543 public:
535 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { 544 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) {
536 return new (Func->allocate<InstX8632UnaryopXmm>()) 545 return new (Func->allocate<InstX8632UnaryopXmm>())
537 InstX8632UnaryopXmm(Func, Dest, Src); 546 InstX8632UnaryopXmm(Func, Dest, Src);
538 } 547 }
539 void emit(const Cfg *Func) const override { 548 void emit(const Cfg *Func) const override {
540 Ostream &Str = Func->getContext()->getStrEmit(); 549 Ostream &Str = Func->getContext()->getStrEmit();
541 assert(getSrcSize() == 1); 550 assert(getSrcSize() == 1);
542 Str << "\t" << Opcode << "\t"; 551 Str << "\t" << Opcode << "\t";
543 getDest()->emit(Func); 552 getDest()->emit(Func);
(...skipping 12 matching lines...) Expand all
556 Str << " = " << Opcode << "." << getDest()->getType() << " "; 565 Str << " = " << Opcode << "." << getDest()->getType() << " ";
557 dumpSources(Func); 566 dumpSources(Func);
558 } 567 }
559 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 568 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
560 569
561 private: 570 private:
562 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) 571 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
563 : InstX8632(Func, K, 1, Dest) { 572 : InstX8632(Func, K, 1, Dest) {
564 addSource(Src); 573 addSource(Src);
565 } 574 }
566 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
567 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
568 ~InstX8632UnaryopXmm() override {} 575 ~InstX8632UnaryopXmm() override {}
569 static const char *Opcode; 576 static const char *Opcode;
570 static const x86::AssemblerX86::XmmEmitterRegOp Emitter; 577 static const x86::AssemblerX86::XmmEmitterRegOp Emitter;
571 }; 578 };
572 579
573 // See the definition of emitTwoAddress() for a description of 580 // See the definition of emitTwoAddress() for a description of
574 // ShiftHack. 581 // ShiftHack.
575 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, 582 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
576 bool ShiftHack = false); 583 bool ShiftHack = false);
577 584
578 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 585 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
579 const Operand *Src, 586 const Operand *Src,
580 const x86::AssemblerX86::GPREmitterShiftOp &Emitter); 587 const x86::AssemblerX86::GPREmitterShiftOp &Emitter);
581 588
582 template <InstX8632::InstKindX8632 K> 589 template <InstX8632::InstKindX8632 K>
583 class InstX8632BinopGPRShift : public InstX8632 { 590 class InstX8632BinopGPRShift : public InstX8632 {
591 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
592 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
593
584 public: 594 public:
585 // Create a binary-op GPR shift instruction. 595 // Create a binary-op GPR shift instruction.
586 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest, 596 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest,
587 Operand *Source) { 597 Operand *Source) {
588 return new (Func->allocate<InstX8632BinopGPRShift>()) 598 return new (Func->allocate<InstX8632BinopGPRShift>())
589 InstX8632BinopGPRShift(Func, Dest, Source); 599 InstX8632BinopGPRShift(Func, Dest, Source);
590 } 600 }
591 void emit(const Cfg *Func) const override { 601 void emit(const Cfg *Func) const override {
592 const bool ShiftHack = true; 602 const bool ShiftHack = true;
593 emitTwoAddress(Opcode, this, Func, ShiftHack); 603 emitTwoAddress(Opcode, this, Func, ShiftHack);
(...skipping 10 matching lines...) Expand all
604 dumpSources(Func); 614 dumpSources(Func);
605 } 615 }
606 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 616 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
607 617
608 private: 618 private:
609 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) 619 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
610 : InstX8632(Func, K, 2, Dest) { 620 : InstX8632(Func, K, 2, Dest) {
611 addSource(Dest); 621 addSource(Dest);
612 addSource(Source); 622 addSource(Source);
613 } 623 }
614 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
615 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
616 ~InstX8632BinopGPRShift() override {} 624 ~InstX8632BinopGPRShift() override {}
617 static const char *Opcode; 625 static const char *Opcode;
618 static const x86::AssemblerX86::GPREmitterShiftOp Emitter; 626 static const x86::AssemblerX86::GPREmitterShiftOp Emitter;
619 }; 627 };
620 628
621 template <InstX8632::InstKindX8632 K> 629 template <InstX8632::InstKindX8632 K>
622 class InstX8632BinopGPR : public InstX8632 { 630 class InstX8632BinopGPR : public InstX8632 {
631 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
632 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
633
623 public: 634 public:
624 // Create an ordinary binary-op instruction like add or sub. 635 // Create an ordinary binary-op instruction like add or sub.
625 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { 636 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) {
626 return new (Func->allocate<InstX8632BinopGPR>()) 637 return new (Func->allocate<InstX8632BinopGPR>())
627 InstX8632BinopGPR(Func, Dest, Source); 638 InstX8632BinopGPR(Func, Dest, Source);
628 } 639 }
629 void emit(const Cfg *Func) const override { 640 void emit(const Cfg *Func) const override {
630 const bool ShiftHack = false; 641 const bool ShiftHack = false;
631 emitTwoAddress(Opcode, this, Func, ShiftHack); 642 emitTwoAddress(Opcode, this, Func, ShiftHack);
632 } 643 }
633 void emitIAS(const Cfg *Func) const override { 644 void emitIAS(const Cfg *Func) const override {
634 Type Ty = getDest()->getType(); 645 Type Ty = getDest()->getType();
635 assert(getSrcSize() == 2); 646 assert(getSrcSize() == 2);
636 emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter); 647 emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter);
637 } 648 }
638 void dump(const Cfg *Func) const override { 649 void dump(const Cfg *Func) const override {
639 Ostream &Str = Func->getContext()->getStrDump(); 650 Ostream &Str = Func->getContext()->getStrDump();
640 dumpDest(Func); 651 dumpDest(Func);
641 Str << " = " << Opcode << "." << getDest()->getType() << " "; 652 Str << " = " << Opcode << "." << getDest()->getType() << " ";
642 dumpSources(Func); 653 dumpSources(Func);
643 } 654 }
644 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 655 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
645 656
646 private: 657 private:
647 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source) 658 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
648 : InstX8632(Func, K, 2, Dest) { 659 : InstX8632(Func, K, 2, Dest) {
649 addSource(Dest); 660 addSource(Dest);
650 addSource(Source); 661 addSource(Source);
651 } 662 }
652 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
653 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
654 ~InstX8632BinopGPR() override {} 663 ~InstX8632BinopGPR() override {}
655 static const char *Opcode; 664 static const char *Opcode;
656 static const x86::AssemblerX86::GPREmitterRegOp Emitter; 665 static const x86::AssemblerX86::GPREmitterRegOp Emitter;
657 }; 666 };
658 667
659 template <InstX8632::InstKindX8632 K, bool NeedsElementType> 668 template <InstX8632::InstKindX8632 K, bool NeedsElementType>
660 class InstX8632BinopXmm : public InstX8632 { 669 class InstX8632BinopXmm : public InstX8632 {
670 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
671 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
672
661 public: 673 public:
662 // Create an XMM binary-op instruction like addss or addps. 674 // Create an XMM binary-op instruction like addss or addps.
663 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { 675 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
664 return new (Func->allocate<InstX8632BinopXmm>()) 676 return new (Func->allocate<InstX8632BinopXmm>())
665 InstX8632BinopXmm(Func, Dest, Source); 677 InstX8632BinopXmm(Func, Dest, Source);
666 } 678 }
667 void emit(const Cfg *Func) const override { 679 void emit(const Cfg *Func) const override {
668 const bool ShiftHack = false; 680 const bool ShiftHack = false;
669 emitTwoAddress(Opcode, this, Func, ShiftHack); 681 emitTwoAddress(Opcode, this, Func, ShiftHack);
670 } 682 }
(...skipping 11 matching lines...) Expand all
682 dumpSources(Func); 694 dumpSources(Func);
683 } 695 }
684 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 696 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
685 697
686 private: 698 private:
687 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) 699 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
688 : InstX8632(Func, K, 2, Dest) { 700 : InstX8632(Func, K, 2, Dest) {
689 addSource(Dest); 701 addSource(Dest);
690 addSource(Source); 702 addSource(Source);
691 } 703 }
692 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
693 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
694 ~InstX8632BinopXmm() override {} 704 ~InstX8632BinopXmm() override {}
695 static const char *Opcode; 705 static const char *Opcode;
696 static const x86::AssemblerX86::XmmEmitterRegOp Emitter; 706 static const x86::AssemblerX86::XmmEmitterRegOp Emitter;
697 }; 707 };
698 708
699 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, 709 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
700 const Operand *Src, 710 const Operand *Src,
701 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter); 711 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter);
702 712
703 template <InstX8632::InstKindX8632 K> 713 template <InstX8632::InstKindX8632 K>
704 class InstX8632BinopXmmShift : public InstX8632 { 714 class InstX8632BinopXmmShift : public InstX8632 {
715 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
716 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
717
705 public: 718 public:
706 // Create an XMM binary-op shift operation. 719 // Create an XMM binary-op shift operation.
707 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, 720 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest,
708 Operand *Source) { 721 Operand *Source) {
709 return new (Func->allocate<InstX8632BinopXmmShift>()) 722 return new (Func->allocate<InstX8632BinopXmmShift>())
710 InstX8632BinopXmmShift(Func, Dest, Source); 723 InstX8632BinopXmmShift(Func, Dest, Source);
711 } 724 }
712 void emit(const Cfg *Func) const override { 725 void emit(const Cfg *Func) const override {
713 const bool ShiftHack = false; 726 const bool ShiftHack = false;
714 emitTwoAddress(Opcode, this, Func, ShiftHack); 727 emitTwoAddress(Opcode, this, Func, ShiftHack);
(...skipping 13 matching lines...) Expand all
728 dumpSources(Func); 741 dumpSources(Func);
729 } 742 }
730 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 743 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
731 744
732 private: 745 private:
733 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) 746 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
734 : InstX8632(Func, K, 2, Dest) { 747 : InstX8632(Func, K, 2, Dest) {
735 addSource(Dest); 748 addSource(Dest);
736 addSource(Source); 749 addSource(Source);
737 } 750 }
738 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
739 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
740 ~InstX8632BinopXmmShift() override {} 751 ~InstX8632BinopXmmShift() override {}
741 static const char *Opcode; 752 static const char *Opcode;
742 static const x86::AssemblerX86::XmmEmitterShiftOp Emitter; 753 static const x86::AssemblerX86::XmmEmitterShiftOp Emitter;
743 }; 754 };
744 755
745 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { 756 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
757 InstX8632Ternop(const InstX8632Ternop &) = delete;
758 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
759
746 public: 760 public:
747 // Create a ternary-op instruction like div or idiv. 761 // Create a ternary-op instruction like div or idiv.
748 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, 762 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
749 Operand *Source2) { 763 Operand *Source2) {
750 return new (Func->allocate<InstX8632Ternop>()) 764 return new (Func->allocate<InstX8632Ternop>())
751 InstX8632Ternop(Func, Dest, Source1, Source2); 765 InstX8632Ternop(Func, Dest, Source1, Source2);
752 } 766 }
753 void emit(const Cfg *Func) const override { 767 void emit(const Cfg *Func) const override {
754 Ostream &Str = Func->getContext()->getStrEmit(); 768 Ostream &Str = Func->getContext()->getStrEmit();
755 assert(getSrcSize() == 3); 769 assert(getSrcSize() == 3);
(...skipping 14 matching lines...) Expand all
770 } 784 }
771 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 785 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
772 786
773 private: 787 private:
774 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 788 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
775 : InstX8632(Func, K, 3, Dest) { 789 : InstX8632(Func, K, 3, Dest) {
776 addSource(Dest); 790 addSource(Dest);
777 addSource(Source1); 791 addSource(Source1);
778 addSource(Source2); 792 addSource(Source2);
779 } 793 }
780 InstX8632Ternop(const InstX8632Ternop &) = delete;
781 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
782 ~InstX8632Ternop() override {} 794 ~InstX8632Ternop() override {}
783 static const char *Opcode; 795 static const char *Opcode;
784 }; 796 };
785 797
786 // Instructions of the form x := y op z 798 // Instructions of the form x := y op z
787 template <InstX8632::InstKindX8632 K> 799 template <InstX8632::InstKindX8632 K>
788 class InstX8632ThreeAddressop : public InstX8632 { 800 class InstX8632ThreeAddressop : public InstX8632 {
801 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
802 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
803
789 public: 804 public:
790 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, 805 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
791 Operand *Source0, Operand *Source1) { 806 Operand *Source0, Operand *Source1) {
792 return new (Func->allocate<InstX8632ThreeAddressop>()) 807 return new (Func->allocate<InstX8632ThreeAddressop>())
793 InstX8632ThreeAddressop(Func, Dest, Source0, Source1); 808 InstX8632ThreeAddressop(Func, Dest, Source0, Source1);
794 } 809 }
795 void emit(const Cfg *Func) const override { 810 void emit(const Cfg *Func) const override {
796 Ostream &Str = Func->getContext()->getStrEmit(); 811 Ostream &Str = Func->getContext()->getStrEmit();
797 assert(getSrcSize() == 2); 812 assert(getSrcSize() == 2);
798 Str << "\t" << Opcode << "\t"; 813 Str << "\t" << Opcode << "\t";
(...skipping 13 matching lines...) Expand all
812 } 827 }
813 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 828 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
814 829
815 private: 830 private:
816 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, 831 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
817 Operand *Source1) 832 Operand *Source1)
818 : InstX8632(Func, K, 2, Dest) { 833 : InstX8632(Func, K, 2, Dest) {
819 addSource(Source0); 834 addSource(Source0);
820 addSource(Source1); 835 addSource(Source1);
821 } 836 }
822 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
823 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
824 ~InstX8632ThreeAddressop() override {} 837 ~InstX8632ThreeAddressop() override {}
825 static const char *Opcode; 838 static const char *Opcode;
826 }; 839 };
827 840
828 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); 841 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
829 842
830 // Base class for assignment instructions 843 // Base class for assignment instructions
831 template <InstX8632::InstKindX8632 K> 844 template <InstX8632::InstKindX8632 K>
832 class InstX8632Movlike : public InstX8632 { 845 class InstX8632Movlike : public InstX8632 {
846 InstX8632Movlike(const InstX8632Movlike &) = delete;
847 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
848
833 public: 849 public:
834 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) { 850 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
835 return new (Func->allocate<InstX8632Movlike>()) 851 return new (Func->allocate<InstX8632Movlike>())
836 InstX8632Movlike(Func, Dest, Source); 852 InstX8632Movlike(Func, Dest, Source);
837 } 853 }
838 bool isRedundantAssign() const override { 854 bool isRedundantAssign() const override {
839 return checkForRedundantAssign(getDest(), getSrc(0)); 855 return checkForRedundantAssign(getDest(), getSrc(0));
840 } 856 }
841 bool isSimpleAssign() const override { return true; } 857 bool isSimpleAssign() const override { return true; }
842 void emit(const Cfg *Func) const override; 858 void emit(const Cfg *Func) const override;
843 void emitIAS(const Cfg *Func) const override; 859 void emitIAS(const Cfg *Func) const override;
844 void dump(const Cfg *Func) const override { 860 void dump(const Cfg *Func) const override {
845 Ostream &Str = Func->getContext()->getStrDump(); 861 Ostream &Str = Func->getContext()->getStrDump();
846 Str << Opcode << "." << getDest()->getType() << " "; 862 Str << Opcode << "." << getDest()->getType() << " ";
847 dumpDest(Func); 863 dumpDest(Func);
848 Str << ", "; 864 Str << ", ";
849 dumpSources(Func); 865 dumpSources(Func);
850 } 866 }
851 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 867 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
852 868
853 private: 869 private:
854 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source) 870 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source)
855 : InstX8632(Func, K, 1, Dest) { 871 : InstX8632(Func, K, 1, Dest) {
856 addSource(Source); 872 addSource(Source);
857 } 873 }
858 InstX8632Movlike(const InstX8632Movlike &) = delete;
859 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
860 ~InstX8632Movlike() override {} 874 ~InstX8632Movlike() override {}
861 875
862 static const char *Opcode; 876 static const char *Opcode;
863 }; 877 };
864 878
865 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap; 879 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap;
866 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg; 880 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg;
867 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf; 881 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf;
868 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr; 882 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr;
869 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea; 883 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps; 937 typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
924 typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr; 938 typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
925 typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps; 939 typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
926 typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps; 940 typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
927 typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb; 941 typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
928 typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr; 942 typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
929 typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd; 943 typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
930 944
931 // Base class for a lockable x86-32 instruction (emits a locked prefix). 945 // Base class for a lockable x86-32 instruction (emits a locked prefix).
932 class InstX8632Lockable : public InstX8632 { 946 class InstX8632Lockable : public InstX8632 {
947 InstX8632Lockable(const InstX8632Lockable &) = delete;
948 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
949
933 protected: 950 protected:
934 bool Locked; 951 bool Locked;
935 952
936 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, 953 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
937 Variable *Dest, bool Locked) 954 Variable *Dest, bool Locked)
938 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { 955 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
939 // Assume that such instructions are used for Atomics and be careful 956 // Assume that such instructions are used for Atomics and be careful
940 // with optimizations. 957 // with optimizations.
941 HasSideEffects = Locked; 958 HasSideEffects = Locked;
942 } 959 }
943 ~InstX8632Lockable() override {} 960 ~InstX8632Lockable() override {}
944
945 private:
946 InstX8632Lockable(const InstX8632Lockable &) = delete;
947 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
948 }; 961 };
949 962
950 // Mul instruction - unsigned multiply. 963 // Mul instruction - unsigned multiply.
951 class InstX8632Mul : public InstX8632 { 964 class InstX8632Mul : public InstX8632 {
965 InstX8632Mul(const InstX8632Mul &) = delete;
966 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
967
952 public: 968 public:
953 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, 969 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
954 Operand *Source2) { 970 Operand *Source2) {
955 return new (Func->allocate<InstX8632Mul>()) 971 return new (Func->allocate<InstX8632Mul>())
956 InstX8632Mul(Func, Dest, Source1, Source2); 972 InstX8632Mul(Func, Dest, Source1, Source2);
957 } 973 }
958 void emit(const Cfg *Func) const override; 974 void emit(const Cfg *Func) const override;
959 void emitIAS(const Cfg *Func) const override; 975 void emitIAS(const Cfg *Func) const override;
960 void dump(const Cfg *Func) const override; 976 void dump(const Cfg *Func) const override;
961 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); } 977 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
962 978
963 private: 979 private:
964 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 980 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
965 InstX8632Mul(const InstX8632Mul &) = delete;
966 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
967 ~InstX8632Mul() override {} 981 ~InstX8632Mul() override {}
968 }; 982 };
969 983
970 // Shld instruction - shift across a pair of operands. TODO: Verify 984 // Shld instruction - shift across a pair of operands. TODO: Verify
971 // that the validator accepts the shld instruction. 985 // that the validator accepts the shld instruction.
972 class InstX8632Shld : public InstX8632 { 986 class InstX8632Shld : public InstX8632 {
987 InstX8632Shld(const InstX8632Shld &) = delete;
988 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
989
973 public: 990 public:
974 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, 991 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
975 Variable *Source2) { 992 Variable *Source2) {
976 return new (Func->allocate<InstX8632Shld>()) 993 return new (Func->allocate<InstX8632Shld>())
977 InstX8632Shld(Func, Dest, Source1, Source2); 994 InstX8632Shld(Func, Dest, Source1, Source2);
978 } 995 }
979 void emit(const Cfg *Func) const override; 996 void emit(const Cfg *Func) const override;
980 void emitIAS(const Cfg *Func) const override; 997 void emitIAS(const Cfg *Func) const override;
981 void dump(const Cfg *Func) const override; 998 void dump(const Cfg *Func) const override;
982 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); } 999 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
983 1000
984 private: 1001 private:
985 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, 1002 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
986 Variable *Source2); 1003 Variable *Source2);
987 InstX8632Shld(const InstX8632Shld &) = delete;
988 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
989 ~InstX8632Shld() override {} 1004 ~InstX8632Shld() override {}
990 }; 1005 };
991 1006
992 // Shrd instruction - shift across a pair of operands. TODO: Verify 1007 // Shrd instruction - shift across a pair of operands. TODO: Verify
993 // that the validator accepts the shrd instruction. 1008 // that the validator accepts the shrd instruction.
994 class InstX8632Shrd : public InstX8632 { 1009 class InstX8632Shrd : public InstX8632 {
1010 InstX8632Shrd(const InstX8632Shrd &) = delete;
1011 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
1012
995 public: 1013 public:
996 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, 1014 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
997 Variable *Source2) { 1015 Variable *Source2) {
998 return new (Func->allocate<InstX8632Shrd>()) 1016 return new (Func->allocate<InstX8632Shrd>())
999 InstX8632Shrd(Func, Dest, Source1, Source2); 1017 InstX8632Shrd(Func, Dest, Source1, Source2);
1000 } 1018 }
1001 void emit(const Cfg *Func) const override; 1019 void emit(const Cfg *Func) const override;
1002 void emitIAS(const Cfg *Func) const override; 1020 void emitIAS(const Cfg *Func) const override;
1003 void dump(const Cfg *Func) const override; 1021 void dump(const Cfg *Func) const override;
1004 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); } 1022 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
1005 1023
1006 private: 1024 private:
1007 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, 1025 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
1008 Variable *Source2); 1026 Variable *Source2);
1009 InstX8632Shrd(const InstX8632Shrd &) = delete;
1010 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
1011 ~InstX8632Shrd() override {} 1027 ~InstX8632Shrd() override {}
1012 }; 1028 };
1013 1029
1014 // Conditional move instruction. 1030 // Conditional move instruction.
1015 class InstX8632Cmov : public InstX8632 { 1031 class InstX8632Cmov : public InstX8632 {
1032 InstX8632Cmov(const InstX8632Cmov &) = delete;
1033 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
1034
1016 public: 1035 public:
1017 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, 1036 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
1018 CondX86::BrCond Cond) { 1037 CondX86::BrCond Cond) {
1019 return new (Func->allocate<InstX8632Cmov>()) 1038 return new (Func->allocate<InstX8632Cmov>())
1020 InstX8632Cmov(Func, Dest, Source, Cond); 1039 InstX8632Cmov(Func, Dest, Source, Cond);
1021 } 1040 }
1022 void emit(const Cfg *Func) const override; 1041 void emit(const Cfg *Func) const override;
1023 void emitIAS(const Cfg *Func) const override; 1042 void emitIAS(const Cfg *Func) const override;
1024 void dump(const Cfg *Func) const override; 1043 void dump(const Cfg *Func) const override;
1025 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } 1044 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
1026 1045
1027 private: 1046 private:
1028 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, 1047 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
1029 CondX86::BrCond Cond); 1048 CondX86::BrCond Cond);
1030 InstX8632Cmov(const InstX8632Cmov &) = delete;
1031 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
1032 ~InstX8632Cmov() override {} 1049 ~InstX8632Cmov() override {}
1033 1050
1034 CondX86::BrCond Condition; 1051 CondX86::BrCond Condition;
1035 }; 1052 };
1036 1053
1037 // Cmpps instruction - compare packed singled-precision floating point 1054 // Cmpps instruction - compare packed singled-precision floating point
1038 // values 1055 // values
1039 class InstX8632Cmpps : public InstX8632 { 1056 class InstX8632Cmpps : public InstX8632 {
1057 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
1058 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
1059
1040 public: 1060 public:
1041 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, 1061 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
1042 CondX86::CmppsCond Condition) { 1062 CondX86::CmppsCond Condition) {
1043 return new (Func->allocate<InstX8632Cmpps>()) 1063 return new (Func->allocate<InstX8632Cmpps>())
1044 InstX8632Cmpps(Func, Dest, Source, Condition); 1064 InstX8632Cmpps(Func, Dest, Source, Condition);
1045 } 1065 }
1046 void emit(const Cfg *Func) const override; 1066 void emit(const Cfg *Func) const override;
1047 void emitIAS(const Cfg *Func) const override; 1067 void emitIAS(const Cfg *Func) const override;
1048 void dump(const Cfg *Func) const override; 1068 void dump(const Cfg *Func) const override;
1049 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } 1069 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
1050 1070
1051 private: 1071 private:
1052 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, 1072 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
1053 CondX86::CmppsCond Cond); 1073 CondX86::CmppsCond Cond);
1054 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
1055 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
1056 ~InstX8632Cmpps() override {} 1074 ~InstX8632Cmpps() override {}
1057 1075
1058 CondX86::CmppsCond Condition; 1076 CondX86::CmppsCond Condition;
1059 }; 1077 };
1060 1078
1061 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> 1079 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
1062 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. 1080 // equals eax. If so, the ZF is set and <desired> is stored in <dest>.
1063 // If not, ZF is cleared and <dest> is copied to eax (or subregister). 1081 // If not, ZF is cleared and <dest> is copied to eax (or subregister).
1064 // <dest> can be a register or memory, while <desired> must be a register. 1082 // <dest> can be a register or memory, while <desired> must be a register.
1065 // It is the user's responsiblity to mark eax with a FakeDef. 1083 // It is the user's responsiblity to mark eax with a FakeDef.
1066 class InstX8632Cmpxchg : public InstX8632Lockable { 1084 class InstX8632Cmpxchg : public InstX8632Lockable {
1085 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1086 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
1087
1067 public: 1088 public:
1068 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 1089 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1069 Variable *Desired, bool Locked) { 1090 Variable *Desired, bool Locked) {
1070 return new (Func->allocate<InstX8632Cmpxchg>()) 1091 return new (Func->allocate<InstX8632Cmpxchg>())
1071 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); 1092 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
1072 } 1093 }
1073 void emit(const Cfg *Func) const override; 1094 void emit(const Cfg *Func) const override;
1074 void emitIAS(const Cfg *Func) const override; 1095 void emitIAS(const Cfg *Func) const override;
1075 void dump(const Cfg *Func) const override; 1096 void dump(const Cfg *Func) const override;
1076 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } 1097 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
1077 1098
1078 private: 1099 private:
1079 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 1100 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1080 Variable *Desired, bool Locked); 1101 Variable *Desired, bool Locked);
1081 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1082 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
1083 ~InstX8632Cmpxchg() override {} 1102 ~InstX8632Cmpxchg() override {}
1084 }; 1103 };
1085 1104
1086 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> 1105 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
1087 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. 1106 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
1088 // If not, ZF is cleared and <m64> is copied to edx:eax. 1107 // If not, ZF is cleared and <m64> is copied to edx:eax.
1089 // The caller is responsible for inserting FakeDefs to mark edx 1108 // The caller is responsible for inserting FakeDefs to mark edx
1090 // and eax as modified. 1109 // and eax as modified.
1091 // <m64> must be a memory operand. 1110 // <m64> must be a memory operand.
1092 class InstX8632Cmpxchg8b : public InstX8632Lockable { 1111 class InstX8632Cmpxchg8b : public InstX8632Lockable {
1112 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1113 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
1114
1093 public: 1115 public:
1094 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest, 1116 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
1095 Variable *Edx, Variable *Eax, Variable *Ecx, 1117 Variable *Edx, Variable *Eax, Variable *Ecx,
1096 Variable *Ebx, bool Locked) { 1118 Variable *Ebx, bool Locked) {
1097 return new (Func->allocate<InstX8632Cmpxchg8b>()) 1119 return new (Func->allocate<InstX8632Cmpxchg8b>())
1098 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); 1120 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
1099 } 1121 }
1100 void emit(const Cfg *Func) const override; 1122 void emit(const Cfg *Func) const override;
1101 void emitIAS(const Cfg *Func) const override; 1123 void emitIAS(const Cfg *Func) const override;
1102 void dump(const Cfg *Func) const override; 1124 void dump(const Cfg *Func) const override;
1103 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } 1125 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
1104 1126
1105 private: 1127 private:
1106 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx, 1128 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
1107 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); 1129 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
1108 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1109 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
1110 ~InstX8632Cmpxchg8b() override {} 1130 ~InstX8632Cmpxchg8b() override {}
1111 }; 1131 };
1112 1132
1113 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} 1133 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
1114 // as appropriate. s=float, d=double, i=int. X and Y are determined 1134 // as appropriate. s=float, d=double, i=int. X and Y are determined
1115 // from dest/src types. Sign and zero extension on the integer 1135 // from dest/src types. Sign and zero extension on the integer
1116 // operand needs to be done separately. 1136 // operand needs to be done separately.
1117 class InstX8632Cvt : public InstX8632 { 1137 class InstX8632Cvt : public InstX8632 {
1138 InstX8632Cvt(const InstX8632Cvt &) = delete;
1139 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
1140
1118 public: 1141 public:
1119 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; 1142 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
1120 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, 1143 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
1121 CvtVariant Variant) { 1144 CvtVariant Variant) {
1122 return new (Func->allocate<InstX8632Cvt>()) 1145 return new (Func->allocate<InstX8632Cvt>())
1123 InstX8632Cvt(Func, Dest, Source, Variant); 1146 InstX8632Cvt(Func, Dest, Source, Variant);
1124 } 1147 }
1125 void emit(const Cfg *Func) const override; 1148 void emit(const Cfg *Func) const override;
1126 void emitIAS(const Cfg *Func) const override; 1149 void emitIAS(const Cfg *Func) const override;
1127 void dump(const Cfg *Func) const override; 1150 void dump(const Cfg *Func) const override;
1128 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); } 1151 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
1129 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } 1152 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
1130 1153
1131 private: 1154 private:
1132 CvtVariant Variant; 1155 CvtVariant Variant;
1133 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); 1156 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
1134 InstX8632Cvt(const InstX8632Cvt &) = delete;
1135 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
1136 ~InstX8632Cvt() override {} 1157 ~InstX8632Cvt() override {}
1137 }; 1158 };
1138 1159
1139 // cmp - Integer compare instruction. 1160 // cmp - Integer compare instruction.
1140 class InstX8632Icmp : public InstX8632 { 1161 class InstX8632Icmp : public InstX8632 {
1162 InstX8632Icmp(const InstX8632Icmp &) = delete;
1163 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
1164
1141 public: 1165 public:
1142 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { 1166 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1143 return new (Func->allocate<InstX8632Icmp>()) 1167 return new (Func->allocate<InstX8632Icmp>())
1144 InstX8632Icmp(Func, Src1, Src2); 1168 InstX8632Icmp(Func, Src1, Src2);
1145 } 1169 }
1146 void emit(const Cfg *Func) const override; 1170 void emit(const Cfg *Func) const override;
1147 void emitIAS(const Cfg *Func) const override; 1171 void emitIAS(const Cfg *Func) const override;
1148 void dump(const Cfg *Func) const override; 1172 void dump(const Cfg *Func) const override;
1149 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } 1173 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
1150 1174
1151 private: 1175 private:
1152 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2); 1176 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
1153 InstX8632Icmp(const InstX8632Icmp &) = delete;
1154 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
1155 ~InstX8632Icmp() override {} 1177 ~InstX8632Icmp() override {}
1156 }; 1178 };
1157 1179
1158 // ucomiss/ucomisd - floating-point compare instruction. 1180 // ucomiss/ucomisd - floating-point compare instruction.
1159 class InstX8632Ucomiss : public InstX8632 { 1181 class InstX8632Ucomiss : public InstX8632 {
1182 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1183 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
1184
1160 public: 1185 public:
1161 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { 1186 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1162 return new (Func->allocate<InstX8632Ucomiss>()) 1187 return new (Func->allocate<InstX8632Ucomiss>())
1163 InstX8632Ucomiss(Func, Src1, Src2); 1188 InstX8632Ucomiss(Func, Src1, Src2);
1164 } 1189 }
1165 void emit(const Cfg *Func) const override; 1190 void emit(const Cfg *Func) const override;
1166 void emitIAS(const Cfg *Func) const override; 1191 void emitIAS(const Cfg *Func) const override;
1167 void dump(const Cfg *Func) const override; 1192 void dump(const Cfg *Func) const override;
1168 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); } 1193 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
1169 1194
1170 private: 1195 private:
1171 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); 1196 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
1172 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1173 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
1174 ~InstX8632Ucomiss() override {} 1197 ~InstX8632Ucomiss() override {}
1175 }; 1198 };
1176 1199
1177 // UD2 instruction. 1200 // UD2 instruction.
1178 class InstX8632UD2 : public InstX8632 { 1201 class InstX8632UD2 : public InstX8632 {
1202 InstX8632UD2(const InstX8632UD2 &) = delete;
1203 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
1204
1179 public: 1205 public:
1180 static InstX8632UD2 *create(Cfg *Func) { 1206 static InstX8632UD2 *create(Cfg *Func) {
1181 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); 1207 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
1182 } 1208 }
1183 void emit(const Cfg *Func) const override; 1209 void emit(const Cfg *Func) const override;
1184 void emitIAS(const Cfg *Func) const override; 1210 void emitIAS(const Cfg *Func) const override;
1185 void dump(const Cfg *Func) const override; 1211 void dump(const Cfg *Func) const override;
1186 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } 1212 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
1187 1213
1188 private: 1214 private:
1189 InstX8632UD2(Cfg *Func); 1215 InstX8632UD2(Cfg *Func);
1190 InstX8632UD2(const InstX8632UD2 &) = delete;
1191 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
1192 ~InstX8632UD2() override {} 1216 ~InstX8632UD2() override {}
1193 }; 1217 };
1194 1218
1195 // Test instruction. 1219 // Test instruction.
1196 class InstX8632Test : public InstX8632 { 1220 class InstX8632Test : public InstX8632 {
1221 InstX8632Test(const InstX8632Test &) = delete;
1222 InstX8632Test &operator=(const InstX8632Test &) = delete;
1223
1197 public: 1224 public:
1198 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { 1225 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
1199 return new (Func->allocate<InstX8632Test>()) 1226 return new (Func->allocate<InstX8632Test>())
1200 InstX8632Test(Func, Source1, Source2); 1227 InstX8632Test(Func, Source1, Source2);
1201 } 1228 }
1202 void emit(const Cfg *Func) const override; 1229 void emit(const Cfg *Func) const override;
1203 void emitIAS(const Cfg *Func) const override; 1230 void emitIAS(const Cfg *Func) const override;
1204 void dump(const Cfg *Func) const override; 1231 void dump(const Cfg *Func) const override;
1205 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } 1232 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
1206 1233
1207 private: 1234 private:
1208 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2); 1235 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
1209 InstX8632Test(const InstX8632Test &) = delete;
1210 InstX8632Test &operator=(const InstX8632Test &) = delete;
1211 ~InstX8632Test() override {} 1236 ~InstX8632Test() override {}
1212 }; 1237 };
1213 1238
1214 // Mfence instruction. 1239 // Mfence instruction.
1215 class InstX8632Mfence : public InstX8632 { 1240 class InstX8632Mfence : public InstX8632 {
1241 InstX8632Mfence(const InstX8632Mfence &) = delete;
1242 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
1243
1216 public: 1244 public:
1217 static InstX8632Mfence *create(Cfg *Func) { 1245 static InstX8632Mfence *create(Cfg *Func) {
1218 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func); 1246 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
1219 } 1247 }
1220 void emit(const Cfg *Func) const override; 1248 void emit(const Cfg *Func) const override;
1221 void emitIAS(const Cfg *Func) const override; 1249 void emitIAS(const Cfg *Func) const override;
1222 void dump(const Cfg *Func) const override; 1250 void dump(const Cfg *Func) const override;
1223 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); } 1251 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
1224 1252
1225 private: 1253 private:
1226 InstX8632Mfence(Cfg *Func); 1254 InstX8632Mfence(Cfg *Func);
1227 InstX8632Mfence(const InstX8632Mfence &) = delete;
1228 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
1229 ~InstX8632Mfence() override {} 1255 ~InstX8632Mfence() override {}
1230 }; 1256 };
1231 1257
1232 // This is essentially a "mov" instruction with an OperandX8632Mem 1258 // This is essentially a "mov" instruction with an OperandX8632Mem
1233 // operand instead of Variable as the destination. It's important 1259 // operand instead of Variable as the destination. It's important
1234 // for liveness that there is no Dest operand. 1260 // for liveness that there is no Dest operand.
1235 class InstX8632Store : public InstX8632 { 1261 class InstX8632Store : public InstX8632 {
1262 InstX8632Store(const InstX8632Store &) = delete;
1263 InstX8632Store &operator=(const InstX8632Store &) = delete;
1264
1236 public: 1265 public:
1237 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { 1266 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1238 return new (Func->allocate<InstX8632Store>()) 1267 return new (Func->allocate<InstX8632Store>())
1239 InstX8632Store(Func, Value, Mem); 1268 InstX8632Store(Func, Value, Mem);
1240 } 1269 }
1241 void emit(const Cfg *Func) const override; 1270 void emit(const Cfg *Func) const override;
1242 void dump(const Cfg *Func) const override; 1271 void dump(const Cfg *Func) const override;
1243 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); } 1272 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
1244 1273
1245 private: 1274 private:
1246 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem); 1275 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
1247 InstX8632Store(const InstX8632Store &) = delete;
1248 InstX8632Store &operator=(const InstX8632Store &) = delete;
1249 ~InstX8632Store() override {} 1276 ~InstX8632Store() override {}
1250 }; 1277 };
1251 1278
1252 // This is essentially a vector "mov" instruction with an OperandX8632Mem 1279 // This is essentially a vector "mov" instruction with an OperandX8632Mem
1253 // operand instead of Variable as the destination. It's important 1280 // operand instead of Variable as the destination. It's important
1254 // for liveness that there is no Dest operand. The source must be an 1281 // for liveness that there is no Dest operand. The source must be an
1255 // Xmm register, since Dest is mem. 1282 // Xmm register, since Dest is mem.
1256 class InstX8632StoreP : public InstX8632 { 1283 class InstX8632StoreP : public InstX8632 {
1284 InstX8632StoreP(const InstX8632StoreP &) = delete;
1285 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
1286
1257 public: 1287 public:
1258 static InstX8632StoreP *create(Cfg *Func, Variable *Value, 1288 static InstX8632StoreP *create(Cfg *Func, Variable *Value,
1259 OperandX8632Mem *Mem) { 1289 OperandX8632Mem *Mem) {
1260 return new (Func->allocate<InstX8632StoreP>()) 1290 return new (Func->allocate<InstX8632StoreP>())
1261 InstX8632StoreP(Func, Value, Mem); 1291 InstX8632StoreP(Func, Value, Mem);
1262 } 1292 }
1263 void emit(const Cfg *Func) const override; 1293 void emit(const Cfg *Func) const override;
1264 void emitIAS(const Cfg *Func) const override; 1294 void emitIAS(const Cfg *Func) const override;
1265 void dump(const Cfg *Func) const override; 1295 void dump(const Cfg *Func) const override;
1266 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); } 1296 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
1267 1297
1268 private: 1298 private:
1269 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); 1299 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
1270 InstX8632StoreP(const InstX8632StoreP &) = delete;
1271 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
1272 ~InstX8632StoreP() override {} 1300 ~InstX8632StoreP() override {}
1273 }; 1301 };
1274 1302
1275 class InstX8632StoreQ : public InstX8632 { 1303 class InstX8632StoreQ : public InstX8632 {
1304 InstX8632StoreQ(const InstX8632StoreQ &) = delete;
1305 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
1306
1276 public: 1307 public:
1277 static InstX8632StoreQ *create(Cfg *Func, Variable *Value, 1308 static InstX8632StoreQ *create(Cfg *Func, Variable *Value,
1278 OperandX8632Mem *Mem) { 1309 OperandX8632Mem *Mem) {
1279 return new (Func->allocate<InstX8632StoreQ>()) 1310 return new (Func->allocate<InstX8632StoreQ>())
1280 InstX8632StoreQ(Func, Value, Mem); 1311 InstX8632StoreQ(Func, Value, Mem);
1281 } 1312 }
1282 void emit(const Cfg *Func) const override; 1313 void emit(const Cfg *Func) const override;
1283 void emitIAS(const Cfg *Func) const override; 1314 void emitIAS(const Cfg *Func) const override;
1284 void dump(const Cfg *Func) const override; 1315 void dump(const Cfg *Func) const override;
1285 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } 1316 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1286 1317
1287 private: 1318 private:
1288 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); 1319 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
1289 InstX8632StoreQ(const InstX8632StoreQ &) = delete;
1290 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
1291 ~InstX8632StoreQ() override {} 1320 ~InstX8632StoreQ() override {}
1292 }; 1321 };
1293 1322
1294 // Movsx - copy from a narrower integer type to a wider integer 1323 // Movsx - copy from a narrower integer type to a wider integer
1295 // type, with sign extension. 1324 // type, with sign extension.
1296 class InstX8632Movsx : public InstX8632 { 1325 class InstX8632Movsx : public InstX8632 {
1326 InstX8632Movsx(const InstX8632Movsx &) = delete;
1327 InstX8632Movsx &operator=(const InstX8632Movsx &) = delete;
1328
1297 public: 1329 public:
1298 static InstX8632Movsx *create(Cfg *Func, Variable *Dest, Operand *Source) { 1330 static InstX8632Movsx *create(Cfg *Func, Variable *Dest, Operand *Source) {
1299 return new (Func->allocate<InstX8632Movsx>()) 1331 return new (Func->allocate<InstX8632Movsx>())
1300 InstX8632Movsx(Func, Dest, Source); 1332 InstX8632Movsx(Func, Dest, Source);
1301 } 1333 }
1302 void emit(const Cfg *Func) const override; 1334 void emit(const Cfg *Func) const override;
1303 void dump(const Cfg *Func) const override; 1335 void dump(const Cfg *Func) const override;
1304 static bool classof(const Inst *Inst) { return isClassof(Inst, Movsx); } 1336 static bool classof(const Inst *Inst) { return isClassof(Inst, Movsx); }
1305 1337
1306 private: 1338 private:
1307 InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source); 1339 InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source);
1308 InstX8632Movsx(const InstX8632Movsx &) = delete;
1309 InstX8632Movsx &operator=(const InstX8632Movsx &) = delete;
1310 ~InstX8632Movsx() override {} 1340 ~InstX8632Movsx() override {}
1311 }; 1341 };
1312 1342
1313 // Movzx - copy from a narrower integer type to a wider integer 1343 // Movzx - copy from a narrower integer type to a wider integer
1314 // type, with zero extension. 1344 // type, with zero extension.
1315 class InstX8632Movzx : public InstX8632 { 1345 class InstX8632Movzx : public InstX8632 {
1346 InstX8632Movzx(const InstX8632Movzx &) = delete;
1347 InstX8632Movzx &operator=(const InstX8632Movzx &) = delete;
1348
1316 public: 1349 public:
1317 static InstX8632Movzx *create(Cfg *Func, Variable *Dest, Operand *Source) { 1350 static InstX8632Movzx *create(Cfg *Func, Variable *Dest, Operand *Source) {
1318 return new (Func->allocate<InstX8632Movzx>()) 1351 return new (Func->allocate<InstX8632Movzx>())
1319 InstX8632Movzx(Func, Dest, Source); 1352 InstX8632Movzx(Func, Dest, Source);
1320 } 1353 }
1321 void emit(const Cfg *Func) const override; 1354 void emit(const Cfg *Func) const override;
1322 void dump(const Cfg *Func) const override; 1355 void dump(const Cfg *Func) const override;
1323 static bool classof(const Inst *Inst) { return isClassof(Inst, Movzx); } 1356 static bool classof(const Inst *Inst) { return isClassof(Inst, Movzx); }
1324 1357
1325 private: 1358 private:
1326 InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source); 1359 InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source);
1327 InstX8632Movzx(const InstX8632Movzx &) = delete;
1328 InstX8632Movzx &operator=(const InstX8632Movzx &) = delete;
1329 ~InstX8632Movzx() override {} 1360 ~InstX8632Movzx() override {}
1330 }; 1361 };
1331 1362
1332 // Nop instructions of varying length 1363 // Nop instructions of varying length
1333 class InstX8632Nop : public InstX8632 { 1364 class InstX8632Nop : public InstX8632 {
1365 InstX8632Nop(const InstX8632Nop &) = delete;
1366 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
1367
1334 public: 1368 public:
1335 // TODO: Replace with enum. 1369 // TODO: Replace with enum.
1336 typedef unsigned NopVariant; 1370 typedef unsigned NopVariant;
1337 1371
1338 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) { 1372 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1339 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant); 1373 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1340 } 1374 }
1341 void emit(const Cfg *Func) const override; 1375 void emit(const Cfg *Func) const override;
1342 void emitIAS(const Cfg *Func) const override; 1376 void emitIAS(const Cfg *Func) const override;
1343 void dump(const Cfg *Func) const override; 1377 void dump(const Cfg *Func) const override;
1344 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); } 1378 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1345 1379
1346 private: 1380 private:
1347 InstX8632Nop(Cfg *Func, SizeT Length); 1381 InstX8632Nop(Cfg *Func, SizeT Length);
1348 InstX8632Nop(const InstX8632Nop &) = delete;
1349 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
1350 ~InstX8632Nop() override {} 1382 ~InstX8632Nop() override {}
1351 1383
1352 NopVariant Variant; 1384 NopVariant Variant;
1353 }; 1385 };
1354 1386
1355 // Fld - load a value onto the x87 FP stack. 1387 // Fld - load a value onto the x87 FP stack.
1356 class InstX8632Fld : public InstX8632 { 1388 class InstX8632Fld : public InstX8632 {
1389 InstX8632Fld(const InstX8632Fld &) = delete;
1390 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
1391
1357 public: 1392 public:
1358 static InstX8632Fld *create(Cfg *Func, Operand *Src) { 1393 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1359 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src); 1394 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1360 } 1395 }
1361 void emit(const Cfg *Func) const override; 1396 void emit(const Cfg *Func) const override;
1362 void emitIAS(const Cfg *Func) const override; 1397 void emitIAS(const Cfg *Func) const override;
1363 void dump(const Cfg *Func) const override; 1398 void dump(const Cfg *Func) const override;
1364 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); } 1399 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1365 1400
1366 private: 1401 private:
1367 InstX8632Fld(Cfg *Func, Operand *Src); 1402 InstX8632Fld(Cfg *Func, Operand *Src);
1368 InstX8632Fld(const InstX8632Fld &) = delete;
1369 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
1370 ~InstX8632Fld() override {} 1403 ~InstX8632Fld() override {}
1371 }; 1404 };
1372 1405
1373 // Fstp - store x87 st(0) into memory and pop st(0). 1406 // Fstp - store x87 st(0) into memory and pop st(0).
1374 class InstX8632Fstp : public InstX8632 { 1407 class InstX8632Fstp : public InstX8632 {
1408 InstX8632Fstp(const InstX8632Fstp &) = delete;
1409 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
1410
1375 public: 1411 public:
1376 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) { 1412 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1377 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest); 1413 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1378 } 1414 }
1379 void emit(const Cfg *Func) const override; 1415 void emit(const Cfg *Func) const override;
1380 void emitIAS(const Cfg *Func) const override; 1416 void emitIAS(const Cfg *Func) const override;
1381 void dump(const Cfg *Func) const override; 1417 void dump(const Cfg *Func) const override;
1382 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); } 1418 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
1383 1419
1384 private: 1420 private:
1385 InstX8632Fstp(Cfg *Func, Variable *Dest); 1421 InstX8632Fstp(Cfg *Func, Variable *Dest);
1386 InstX8632Fstp(const InstX8632Fstp &) = delete;
1387 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
1388 ~InstX8632Fstp() override {} 1422 ~InstX8632Fstp() override {}
1389 }; 1423 };
1390 1424
1391 class InstX8632Pop : public InstX8632 { 1425 class InstX8632Pop : public InstX8632 {
1426 InstX8632Pop(const InstX8632Pop &) = delete;
1427 InstX8632Pop &operator=(const InstX8632Pop &) = delete;
1428
1392 public: 1429 public:
1393 static InstX8632Pop *create(Cfg *Func, Variable *Dest) { 1430 static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
1394 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest); 1431 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
1395 } 1432 }
1396 void emit(const Cfg *Func) const override; 1433 void emit(const Cfg *Func) const override;
1397 void emitIAS(const Cfg *Func) const override; 1434 void emitIAS(const Cfg *Func) const override;
1398 void dump(const Cfg *Func) const override; 1435 void dump(const Cfg *Func) const override;
1399 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } 1436 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1400 1437
1401 private: 1438 private:
1402 InstX8632Pop(Cfg *Func, Variable *Dest); 1439 InstX8632Pop(Cfg *Func, Variable *Dest);
1403 InstX8632Pop(const InstX8632Pop &) = delete;
1404 InstX8632Pop &operator=(const InstX8632Pop &) = delete;
1405 ~InstX8632Pop() override {} 1440 ~InstX8632Pop() override {}
1406 }; 1441 };
1407 1442
1408 class InstX8632Push : public InstX8632 { 1443 class InstX8632Push : public InstX8632 {
1444 InstX8632Push(const InstX8632Push &) = delete;
1445 InstX8632Push &operator=(const InstX8632Push &) = delete;
1446
1409 public: 1447 public:
1410 static InstX8632Push *create(Cfg *Func, Variable *Source) { 1448 static InstX8632Push *create(Cfg *Func, Variable *Source) {
1411 return new (Func->allocate<InstX8632Push>()) 1449 return new (Func->allocate<InstX8632Push>())
1412 InstX8632Push(Func, Source); 1450 InstX8632Push(Func, Source);
1413 } 1451 }
1414 void emit(const Cfg *Func) const override; 1452 void emit(const Cfg *Func) const override;
1415 void emitIAS(const Cfg *Func) const override; 1453 void emitIAS(const Cfg *Func) const override;
1416 void dump(const Cfg *Func) const override; 1454 void dump(const Cfg *Func) const override;
1417 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } 1455 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1418 1456
1419 private: 1457 private:
1420 InstX8632Push(Cfg *Func, Variable *Source); 1458 InstX8632Push(Cfg *Func, Variable *Source);
1421 InstX8632Push(const InstX8632Push &) = delete;
1422 InstX8632Push &operator=(const InstX8632Push &) = delete;
1423 ~InstX8632Push() override {} 1459 ~InstX8632Push() override {}
1424 }; 1460 };
1425 1461
1426 // Ret instruction. Currently only supports the "ret" version that 1462 // Ret instruction. Currently only supports the "ret" version that
1427 // does not pop arguments. This instruction takes a Source operand 1463 // does not pop arguments. This instruction takes a Source operand
1428 // (for non-void returning functions) for liveness analysis, though 1464 // (for non-void returning functions) for liveness analysis, though
1429 // a FakeUse before the ret would do just as well. 1465 // a FakeUse before the ret would do just as well.
1430 class InstX8632Ret : public InstX8632 { 1466 class InstX8632Ret : public InstX8632 {
1467 InstX8632Ret(const InstX8632Ret &) = delete;
1468 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
1469
1431 public: 1470 public:
1432 static InstX8632Ret *create(Cfg *Func, Variable *Source = NULL) { 1471 static InstX8632Ret *create(Cfg *Func, Variable *Source = NULL) {
1433 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source); 1472 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1434 } 1473 }
1435 void emit(const Cfg *Func) const override; 1474 void emit(const Cfg *Func) const override;
1436 void emitIAS(const Cfg *Func) const override; 1475 void emitIAS(const Cfg *Func) const override;
1437 void dump(const Cfg *Func) const override; 1476 void dump(const Cfg *Func) const override;
1438 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } 1477 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1439 1478
1440 private: 1479 private:
1441 InstX8632Ret(Cfg *Func, Variable *Source); 1480 InstX8632Ret(Cfg *Func, Variable *Source);
1442 InstX8632Ret(const InstX8632Ret &) = delete;
1443 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
1444 ~InstX8632Ret() override {} 1481 ~InstX8632Ret() override {}
1445 }; 1482 };
1446 1483
1447 // Exchanging Add instruction. Exchanges the first operand (destination 1484 // Exchanging Add instruction. Exchanges the first operand (destination
1448 // operand) with the second operand (source operand), then loads the sum 1485 // operand) with the second operand (source operand), then loads the sum
1449 // of the two values into the destination operand. The destination may be 1486 // of the two values into the destination operand. The destination may be
1450 // a register or memory, while the source must be a register. 1487 // a register or memory, while the source must be a register.
1451 // 1488 //
1452 // Both the dest and source are updated. The caller should then insert a 1489 // Both the dest and source are updated. The caller should then insert a
1453 // FakeDef to reflect the second udpate. 1490 // FakeDef to reflect the second udpate.
1454 class InstX8632Xadd : public InstX8632Lockable { 1491 class InstX8632Xadd : public InstX8632Lockable {
1492 InstX8632Xadd(const InstX8632Xadd &) = delete;
1493 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
1494
1455 public: 1495 public:
1456 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, 1496 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1457 bool Locked) { 1497 bool Locked) {
1458 return new (Func->allocate<InstX8632Xadd>()) 1498 return new (Func->allocate<InstX8632Xadd>())
1459 InstX8632Xadd(Func, Dest, Source, Locked); 1499 InstX8632Xadd(Func, Dest, Source, Locked);
1460 } 1500 }
1461 void emit(const Cfg *Func) const override; 1501 void emit(const Cfg *Func) const override;
1462 void emitIAS(const Cfg *Func) const override; 1502 void emitIAS(const Cfg *Func) const override;
1463 void dump(const Cfg *Func) const override; 1503 void dump(const Cfg *Func) const override;
1464 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } 1504 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1465 1505
1466 private: 1506 private:
1467 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); 1507 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
1468 InstX8632Xadd(const InstX8632Xadd &) = delete;
1469 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
1470 ~InstX8632Xadd() override {} 1508 ~InstX8632Xadd() override {}
1471 }; 1509 };
1472 1510
1473 // Exchange instruction. Exchanges the first operand (destination 1511 // Exchange instruction. Exchanges the first operand (destination
1474 // operand) with the second operand (source operand). At least one of 1512 // operand) with the second operand (source operand). At least one of
1475 // the operands must be a register (and the other can be reg or mem). 1513 // the operands must be a register (and the other can be reg or mem).
1476 // Both the Dest and Source are updated. If there is a memory operand, 1514 // Both the Dest and Source are updated. If there is a memory operand,
1477 // then the instruction is automatically "locked" without the need for 1515 // then the instruction is automatically "locked" without the need for
1478 // a lock prefix. 1516 // a lock prefix.
1479 class InstX8632Xchg : public InstX8632 { 1517 class InstX8632Xchg : public InstX8632 {
1518 InstX8632Xchg(const InstX8632Xchg &) = delete;
1519 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
1520
1480 public: 1521 public:
1481 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { 1522 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1482 return new (Func->allocate<InstX8632Xchg>()) 1523 return new (Func->allocate<InstX8632Xchg>())
1483 InstX8632Xchg(Func, Dest, Source); 1524 InstX8632Xchg(Func, Dest, Source);
1484 } 1525 }
1485 void emit(const Cfg *Func) const override; 1526 void emit(const Cfg *Func) const override;
1486 void emitIAS(const Cfg *Func) const override; 1527 void emitIAS(const Cfg *Func) const override;
1487 void dump(const Cfg *Func) const override; 1528 void dump(const Cfg *Func) const override;
1488 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); } 1529 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
1489 1530
1490 private: 1531 private:
1491 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source); 1532 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
1492 InstX8632Xchg(const InstX8632Xchg &) = delete;
1493 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
1494 ~InstX8632Xchg() override {} 1533 ~InstX8632Xchg() override {}
1495 }; 1534 };
1496 1535
1497 // Declare partial template specializations of emit() methods that 1536 // Declare partial template specializations of emit() methods that
1498 // already have default implementations. Without this, there is the 1537 // already have default implementations. Without this, there is the
1499 // possibility of ODR violations and link errors. 1538 // possibility of ODR violations and link errors.
1500 template <> void InstX8632Addss::emit(const Cfg *Func) const; 1539 template <> void InstX8632Addss::emit(const Cfg *Func) const;
1501 template <> void InstX8632Blendvps::emit(const Cfg *Func) const; 1540 template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
1502 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const; 1541 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
1503 template <> void InstX8632Div::emit(const Cfg *Func) const; 1542 template <> void InstX8632Div::emit(const Cfg *Func) const;
(...skipping 27 matching lines...) Expand all
1531 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const; 1570 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const;
1532 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const; 1571 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const;
1533 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; 1572 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const;
1534 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; 1573 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const;
1535 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; 1574 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const;
1536 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; 1575 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const;
1537 1576
1538 } // end of namespace Ice 1577 } // end of namespace Ice
1539 1578
1540 #endif // SUBZERO_SRC_ICEINSTX8632_H 1579 #endif // SUBZERO_SRC_ICEINSTX8632_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698