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