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