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() = delete; |
33 OperandX8632(const OperandX8632 &) = delete; | 34 OperandX8632(const OperandX8632 &) = delete; |
34 OperandX8632 &operator=(const OperandX8632 &) = delete; | 35 OperandX8632 &operator=(const OperandX8632 &) = delete; |
35 | 36 |
36 public: | 37 public: |
37 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit }; | 38 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit }; |
38 using Operand::dump; | 39 using Operand::dump; |
39 void dump(const Cfg *, Ostream &Str) const override { | 40 void dump(const Cfg *, Ostream &Str) const override { |
40 if (ALLOW_DUMP) | 41 if (ALLOW_DUMP) |
41 Str << "<OperandX8632>"; | 42 Str << "<OperandX8632>"; |
42 } | 43 } |
43 | 44 |
44 protected: | 45 protected: |
45 OperandX8632(OperandKindX8632 Kind, Type Ty) | 46 OperandX8632(OperandKindX8632 Kind, Type Ty) |
46 : Operand(static_cast<OperandKind>(Kind), Ty) {} | 47 : Operand(static_cast<OperandKind>(Kind), Ty) {} |
47 ~OperandX8632() override {} | 48 ~OperandX8632() override {} |
48 }; | 49 }; |
49 | 50 |
50 // OperandX8632Mem represents the m32 addressing mode, with optional | 51 // OperandX8632Mem represents the m32 addressing mode, with optional |
51 // base and index registers, a constant offset, and a fixed shift | 52 // base and index registers, a constant offset, and a fixed shift |
52 // value for the index register. | 53 // value for the index register. |
53 class OperandX8632Mem : public OperandX8632 { | 54 class OperandX8632Mem : public OperandX8632 { |
| 55 OperandX8632Mem() = delete; |
54 OperandX8632Mem(const OperandX8632Mem &) = delete; | 56 OperandX8632Mem(const OperandX8632Mem &) = delete; |
55 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete; | 57 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete; |
56 | 58 |
57 public: | 59 public: |
58 enum SegmentRegisters { | 60 enum SegmentRegisters { |
59 DefaultSegment = -1, | 61 DefaultSegment = -1, |
60 #define X(val, name, prefix) val, | 62 #define X(val, name, prefix) val, |
61 SEG_REGX8632_TABLE | 63 SEG_REGX8632_TABLE |
62 #undef X | 64 #undef X |
63 SegReg_NUM | 65 SegReg_NUM |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 SegmentRegisters SegmentReg : 16; | 97 SegmentRegisters SegmentReg : 16; |
96 }; | 98 }; |
97 | 99 |
98 // VariableSplit is a way to treat an f64 memory location as a pair | 100 // VariableSplit is a way to treat an f64 memory location as a pair |
99 // of i32 locations (Low and High). This is needed for some cases | 101 // of i32 locations (Low and High). This is needed for some cases |
100 // of the Bitcast instruction. Since it's not possible for integer | 102 // of the Bitcast instruction. Since it's not possible for integer |
101 // registers to access the XMM registers and vice versa, the | 103 // registers to access the XMM registers and vice versa, the |
102 // lowering forces the f64 to be spilled to the stack and then | 104 // lowering forces the f64 to be spilled to the stack and then |
103 // accesses through the VariableSplit. | 105 // accesses through the VariableSplit. |
104 class VariableSplit : public OperandX8632 { | 106 class VariableSplit : public OperandX8632 { |
| 107 VariableSplit() = delete; |
105 VariableSplit(const VariableSplit &) = delete; | 108 VariableSplit(const VariableSplit &) = delete; |
106 VariableSplit &operator=(const VariableSplit &) = delete; | 109 VariableSplit &operator=(const VariableSplit &) = delete; |
107 | 110 |
108 public: | 111 public: |
109 enum Portion { Low, High }; | 112 enum Portion { Low, High }; |
110 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { | 113 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { |
111 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); | 114 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); |
112 } | 115 } |
113 int32_t getOffset() const { return Part == High ? 4 : 0; } | 116 int32_t getOffset() const { return Part == High ? 4 : 0; } |
114 | 117 |
(...skipping 19 matching lines...) Expand all Loading... |
134 Variable *Var; | 137 Variable *Var; |
135 Portion Part; | 138 Portion Part; |
136 }; | 139 }; |
137 | 140 |
138 // SpillVariable decorates a Variable by linking it to another | 141 // SpillVariable decorates a Variable by linking it to another |
139 // Variable. When stack frame offsets are computed, the SpillVariable | 142 // Variable. When stack frame offsets are computed, the SpillVariable |
140 // is given a distinct stack slot only if its linked Variable has a | 143 // is given a distinct stack slot only if its linked Variable has a |
141 // register. If the linked Variable has a stack slot, then the | 144 // register. If the linked Variable has a stack slot, then the |
142 // Variable and SpillVariable share that slot. | 145 // Variable and SpillVariable share that slot. |
143 class SpillVariable : public Variable { | 146 class SpillVariable : public Variable { |
| 147 SpillVariable() = delete; |
144 SpillVariable(const SpillVariable &) = delete; | 148 SpillVariable(const SpillVariable &) = delete; |
145 SpillVariable &operator=(const SpillVariable &) = delete; | 149 SpillVariable &operator=(const SpillVariable &) = delete; |
146 | 150 |
147 public: | 151 public: |
148 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) { | 152 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) { |
149 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index); | 153 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index); |
150 } | 154 } |
151 const static OperandKind SpillVariableKind = | 155 const static OperandKind SpillVariableKind = |
152 static_cast<OperandKind>(kVariable_Target); | 156 static_cast<OperandKind>(kVariable_Target); |
153 static bool classof(const Operand *Operand) { | 157 static bool classof(const Operand *Operand) { |
154 return Operand->getKind() == SpillVariableKind; | 158 return Operand->getKind() == SpillVariableKind; |
155 } | 159 } |
156 void setLinkedTo(Variable *Var) { LinkedTo = Var; } | 160 void setLinkedTo(Variable *Var) { LinkedTo = Var; } |
157 Variable *getLinkedTo() const { return LinkedTo; } | 161 Variable *getLinkedTo() const { return LinkedTo; } |
158 // Inherit dump() and emit() from Variable. | 162 // Inherit dump() and emit() from Variable. |
159 private: | 163 private: |
160 SpillVariable(Type Ty, SizeT Index) | 164 SpillVariable(Type Ty, SizeT Index) |
161 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {} | 165 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {} |
162 Variable *LinkedTo; | 166 Variable *LinkedTo; |
163 }; | 167 }; |
164 | 168 |
165 class InstX8632 : public InstTarget { | 169 class InstX8632 : public InstTarget { |
| 170 InstX8632() = delete; |
166 InstX8632(const InstX8632 &) = delete; | 171 InstX8632(const InstX8632 &) = delete; |
167 InstX8632 &operator=(const InstX8632 &) = delete; | 172 InstX8632 &operator=(const InstX8632 &) = delete; |
168 | 173 |
169 public: | 174 public: |
170 enum InstKindX8632 { | 175 enum InstKindX8632 { |
171 k__Start = Inst::Target, | 176 k__Start = Inst::Target, |
172 Adc, | 177 Adc, |
173 Add, | 178 Add, |
174 Addps, | 179 Addps, |
175 Addss, | 180 Addss, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 // FakeUse(c) | 306 // FakeUse(c) |
302 // L1: | 307 // L1: |
303 // mov c, y | 308 // mov c, y |
304 // L2: | 309 // L2: |
305 // | 310 // |
306 // The down-side is that "mov c, x" can never be dead-code eliminated | 311 // The down-side is that "mov c, x" can never be dead-code eliminated |
307 // even if there are no uses of c. As unlikely as this situation is, | 312 // even if there are no uses of c. As unlikely as this situation is, |
308 // it may be prevented by running dead code elimination before | 313 // it may be prevented by running dead code elimination before |
309 // lowering. | 314 // lowering. |
310 class InstX8632Label : public InstX8632 { | 315 class InstX8632Label : public InstX8632 { |
| 316 InstX8632Label() = delete; |
311 InstX8632Label(const InstX8632Label &) = delete; | 317 InstX8632Label(const InstX8632Label &) = delete; |
312 InstX8632Label &operator=(const InstX8632Label &) = delete; | 318 InstX8632Label &operator=(const InstX8632Label &) = delete; |
313 | 319 |
314 public: | 320 public: |
315 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) { | 321 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) { |
316 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target); | 322 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target); |
317 } | 323 } |
318 uint32_t getEmitInstCount() const override { return 0; } | 324 uint32_t getEmitInstCount() const override { return 0; } |
319 IceString getName(const Cfg *Func) const; | 325 IceString getName(const Cfg *Func) const; |
320 SizeT getNumber() const { return Number; } | 326 SizeT getNumber() const { return Number; } |
321 void emit(const Cfg *Func) const override; | 327 void emit(const Cfg *Func) const override; |
322 void emitIAS(const Cfg *Func) const override; | 328 void emitIAS(const Cfg *Func) const override; |
323 void dump(const Cfg *Func) const override; | 329 void dump(const Cfg *Func) const override; |
324 | 330 |
325 private: | 331 private: |
326 InstX8632Label(Cfg *Func, TargetX8632 *Target); | 332 InstX8632Label(Cfg *Func, TargetX8632 *Target); |
327 ~InstX8632Label() override {} | 333 ~InstX8632Label() override {} |
328 SizeT Number; // used for unique label generation. | 334 SizeT Number; // used for unique label generation. |
329 }; | 335 }; |
330 | 336 |
331 // Conditional and unconditional branch instruction. | 337 // Conditional and unconditional branch instruction. |
332 class InstX8632Br : public InstX8632 { | 338 class InstX8632Br : public InstX8632 { |
| 339 InstX8632Br() = delete; |
333 InstX8632Br(const InstX8632Br &) = delete; | 340 InstX8632Br(const InstX8632Br &) = delete; |
334 InstX8632Br &operator=(const InstX8632Br &) = delete; | 341 InstX8632Br &operator=(const InstX8632Br &) = delete; |
335 | 342 |
336 public: | 343 public: |
337 // Create a conditional branch to a node. | 344 // Create a conditional branch to a node. |
338 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, | 345 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, |
339 CfgNode *TargetFalse, CondX86::BrCond Condition) { | 346 CfgNode *TargetFalse, CondX86::BrCond Condition) { |
340 assert(Condition != CondX86::Br_None); | 347 assert(Condition != CondX86::Br_None); |
341 const InstX8632Label *NoLabel = nullptr; | 348 const InstX8632Label *NoLabel = nullptr; |
342 return new (Func->allocate<InstX8632Br>()) | 349 return new (Func->allocate<InstX8632Br>()) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 CondX86::BrCond Condition; | 405 CondX86::BrCond Condition; |
399 const CfgNode *TargetTrue; | 406 const CfgNode *TargetTrue; |
400 const CfgNode *TargetFalse; | 407 const CfgNode *TargetFalse; |
401 const InstX8632Label *Label; // Intra-block branch target | 408 const InstX8632Label *Label; // Intra-block branch target |
402 }; | 409 }; |
403 | 410 |
404 // Jump to a target outside this function, such as tailcall, nacljump, | 411 // Jump to a target outside this function, such as tailcall, nacljump, |
405 // naclret, unreachable. This is different from a Branch instruction | 412 // naclret, unreachable. This is different from a Branch instruction |
406 // in that there is no intra-function control flow to represent. | 413 // in that there is no intra-function control flow to represent. |
407 class InstX8632Jmp : public InstX8632 { | 414 class InstX8632Jmp : public InstX8632 { |
| 415 InstX8632Jmp() = delete; |
408 InstX8632Jmp(const InstX8632Jmp &) = delete; | 416 InstX8632Jmp(const InstX8632Jmp &) = delete; |
409 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete; | 417 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete; |
410 | 418 |
411 public: | 419 public: |
412 static InstX8632Jmp *create(Cfg *Func, Operand *Target) { | 420 static InstX8632Jmp *create(Cfg *Func, Operand *Target) { |
413 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target); | 421 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target); |
414 } | 422 } |
415 Operand *getJmpTarget() const { return getSrc(0); } | 423 Operand *getJmpTarget() const { return getSrc(0); } |
416 void emit(const Cfg *Func) const override; | 424 void emit(const Cfg *Func) const override; |
417 void emitIAS(const Cfg *Func) const override; | 425 void emitIAS(const Cfg *Func) const override; |
418 void dump(const Cfg *Func) const override; | 426 void dump(const Cfg *Func) const override; |
419 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); } | 427 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); } |
420 | 428 |
421 private: | 429 private: |
422 InstX8632Jmp(Cfg *Func, Operand *Target); | 430 InstX8632Jmp(Cfg *Func, Operand *Target); |
423 }; | 431 }; |
424 | 432 |
425 // AdjustStack instruction - subtracts esp by the given amount and | 433 // AdjustStack instruction - subtracts esp by the given amount and |
426 // updates the stack offset during code emission. | 434 // updates the stack offset during code emission. |
427 class InstX8632AdjustStack : public InstX8632 { | 435 class InstX8632AdjustStack : public InstX8632 { |
| 436 InstX8632AdjustStack() = delete; |
428 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete; | 437 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete; |
429 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete; | 438 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete; |
430 | 439 |
431 public: | 440 public: |
432 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) { | 441 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) { |
433 return new (Func->allocate<InstX8632AdjustStack>()) | 442 return new (Func->allocate<InstX8632AdjustStack>()) |
434 InstX8632AdjustStack(Func, Amount, Esp); | 443 InstX8632AdjustStack(Func, Amount, Esp); |
435 } | 444 } |
436 void emit(const Cfg *Func) const override; | 445 void emit(const Cfg *Func) const override; |
437 void emitIAS(const Cfg *Func) const override; | 446 void emitIAS(const Cfg *Func) const override; |
438 void dump(const Cfg *Func) const override; | 447 void dump(const Cfg *Func) const override; |
439 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); } | 448 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); } |
440 | 449 |
441 private: | 450 private: |
442 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp); | 451 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp); |
443 SizeT Amount; | 452 SizeT Amount; |
444 }; | 453 }; |
445 | 454 |
446 // Call instruction. Arguments should have already been pushed. | 455 // Call instruction. Arguments should have already been pushed. |
447 class InstX8632Call : public InstX8632 { | 456 class InstX8632Call : public InstX8632 { |
| 457 InstX8632Call() = delete; |
448 InstX8632Call(const InstX8632Call &) = delete; | 458 InstX8632Call(const InstX8632Call &) = delete; |
449 InstX8632Call &operator=(const InstX8632Call &) = delete; | 459 InstX8632Call &operator=(const InstX8632Call &) = delete; |
450 | 460 |
451 public: | 461 public: |
452 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { | 462 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { |
453 return new (Func->allocate<InstX8632Call>()) | 463 return new (Func->allocate<InstX8632Call>()) |
454 InstX8632Call(Func, Dest, CallTarget); | 464 InstX8632Call(Func, Dest, CallTarget); |
455 } | 465 } |
456 Operand *getCallTarget() const { return getSrc(0); } | 466 Operand *getCallTarget() const { return getSrc(0); } |
457 void emit(const Cfg *Func) const override; | 467 void emit(const Cfg *Func) const override; |
458 void emitIAS(const Cfg *Func) const override; | 468 void emitIAS(const Cfg *Func) const override; |
459 void dump(const Cfg *Func) const override; | 469 void dump(const Cfg *Func) const override; |
460 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 470 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
461 | 471 |
462 private: | 472 private: |
463 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 473 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
464 ~InstX8632Call() override {} | 474 ~InstX8632Call() override {} |
465 }; | 475 }; |
466 | 476 |
467 // Emit a one-operand (GPR) instruction. | 477 // Emit a one-operand (GPR) instruction. |
468 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, | 478 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, |
469 const x86::AssemblerX86::GPREmitterOneOp &Emitter); | 479 const x86::AssemblerX86::GPREmitterOneOp &Emitter); |
470 | 480 |
471 // Instructions of the form x := op(x). | 481 // Instructions of the form x := op(x). |
472 template <InstX8632::InstKindX8632 K> | 482 template <InstX8632::InstKindX8632 K> |
473 class InstX8632InplaceopGPR : public InstX8632 { | 483 class InstX8632InplaceopGPR : public InstX8632 { |
| 484 InstX8632InplaceopGPR() = delete; |
474 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; | 485 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; |
475 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; | 486 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; |
476 | 487 |
477 public: | 488 public: |
478 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { | 489 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { |
479 return new (Func->allocate<InstX8632InplaceopGPR>()) | 490 return new (Func->allocate<InstX8632InplaceopGPR>()) |
480 InstX8632InplaceopGPR(Func, SrcDest); | 491 InstX8632InplaceopGPR(Func, SrcDest); |
481 } | 492 } |
482 void emit(const Cfg *Func) const override { | 493 void emit(const Cfg *Func) const override { |
483 if (!ALLOW_DUMP) | 494 if (!ALLOW_DUMP) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 // Emit a two-operand (GPR) instruction, where the dest operand is a | 527 // Emit a two-operand (GPR) instruction, where the dest operand is a |
517 // Variable that's guaranteed to be a register. | 528 // Variable that's guaranteed to be a register. |
518 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> | 529 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> |
519 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, | 530 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, |
520 const Operand *Src, | 531 const Operand *Src, |
521 const x86::AssemblerX86::GPREmitterRegOp &Emitter); | 532 const x86::AssemblerX86::GPREmitterRegOp &Emitter); |
522 | 533 |
523 // Instructions of the form x := op(y). | 534 // Instructions of the form x := op(y). |
524 template <InstX8632::InstKindX8632 K> | 535 template <InstX8632::InstKindX8632 K> |
525 class InstX8632UnaryopGPR : public InstX8632 { | 536 class InstX8632UnaryopGPR : public InstX8632 { |
| 537 InstX8632UnaryopGPR() = delete; |
526 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete; | 538 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete; |
527 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete; | 539 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete; |
528 | 540 |
529 public: | 541 public: |
530 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { | 542 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { |
531 return new (Func->allocate<InstX8632UnaryopGPR>()) | 543 return new (Func->allocate<InstX8632UnaryopGPR>()) |
532 InstX8632UnaryopGPR(Func, Dest, Src); | 544 InstX8632UnaryopGPR(Func, Dest, Src); |
533 } | 545 } |
534 void emit(const Cfg *Func) const override { | 546 void emit(const Cfg *Func) const override { |
535 if (!ALLOW_DUMP) | 547 if (!ALLOW_DUMP) |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 static const char *Opcode; | 587 static const char *Opcode; |
576 static const x86::AssemblerX86::GPREmitterRegOp Emitter; | 588 static const x86::AssemblerX86::GPREmitterRegOp Emitter; |
577 }; | 589 }; |
578 | 590 |
579 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 591 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
580 const Operand *Src, | 592 const Operand *Src, |
581 const x86::AssemblerX86::XmmEmitterRegOp &Emitter); | 593 const x86::AssemblerX86::XmmEmitterRegOp &Emitter); |
582 | 594 |
583 template <InstX8632::InstKindX8632 K> | 595 template <InstX8632::InstKindX8632 K> |
584 class InstX8632UnaryopXmm : public InstX8632 { | 596 class InstX8632UnaryopXmm : public InstX8632 { |
| 597 InstX8632UnaryopXmm() = delete; |
585 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete; | 598 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete; |
586 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete; | 599 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete; |
587 | 600 |
588 public: | 601 public: |
589 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { | 602 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { |
590 return new (Func->allocate<InstX8632UnaryopXmm>()) | 603 return new (Func->allocate<InstX8632UnaryopXmm>()) |
591 InstX8632UnaryopXmm(Func, Dest, Src); | 604 InstX8632UnaryopXmm(Func, Dest, Src); |
592 } | 605 } |
593 void emit(const Cfg *Func) const override { | 606 void emit(const Cfg *Func) const override { |
594 if (!ALLOW_DUMP) | 607 if (!ALLOW_DUMP) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 // ShiftHack. | 642 // ShiftHack. |
630 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, | 643 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
631 bool ShiftHack = false); | 644 bool ShiftHack = false); |
632 | 645 |
633 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, | 646 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
634 const Operand *Src, | 647 const Operand *Src, |
635 const x86::AssemblerX86::GPREmitterShiftOp &Emitter); | 648 const x86::AssemblerX86::GPREmitterShiftOp &Emitter); |
636 | 649 |
637 template <InstX8632::InstKindX8632 K> | 650 template <InstX8632::InstKindX8632 K> |
638 class InstX8632BinopGPRShift : public InstX8632 { | 651 class InstX8632BinopGPRShift : public InstX8632 { |
| 652 InstX8632BinopGPRShift() = delete; |
639 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete; | 653 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete; |
640 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete; | 654 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete; |
641 | 655 |
642 public: | 656 public: |
643 // Create a binary-op GPR shift instruction. | 657 // Create a binary-op GPR shift instruction. |
644 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest, | 658 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest, |
645 Operand *Source) { | 659 Operand *Source) { |
646 return new (Func->allocate<InstX8632BinopGPRShift>()) | 660 return new (Func->allocate<InstX8632BinopGPRShift>()) |
647 InstX8632BinopGPRShift(Func, Dest, Source); | 661 InstX8632BinopGPRShift(Func, Dest, Source); |
648 } | 662 } |
(...skipping 24 matching lines...) Expand all Loading... |
673 addSource(Dest); | 687 addSource(Dest); |
674 addSource(Source); | 688 addSource(Source); |
675 } | 689 } |
676 ~InstX8632BinopGPRShift() override {} | 690 ~InstX8632BinopGPRShift() override {} |
677 static const char *Opcode; | 691 static const char *Opcode; |
678 static const x86::AssemblerX86::GPREmitterShiftOp Emitter; | 692 static const x86::AssemblerX86::GPREmitterShiftOp Emitter; |
679 }; | 693 }; |
680 | 694 |
681 template <InstX8632::InstKindX8632 K> | 695 template <InstX8632::InstKindX8632 K> |
682 class InstX8632BinopGPR : public InstX8632 { | 696 class InstX8632BinopGPR : public InstX8632 { |
| 697 InstX8632BinopGPR() = delete; |
683 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete; | 698 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete; |
684 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete; | 699 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete; |
685 | 700 |
686 public: | 701 public: |
687 // Create an ordinary binary-op instruction like add or sub. | 702 // Create an ordinary binary-op instruction like add or sub. |
688 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { | 703 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { |
689 return new (Func->allocate<InstX8632BinopGPR>()) | 704 return new (Func->allocate<InstX8632BinopGPR>()) |
690 InstX8632BinopGPR(Func, Dest, Source); | 705 InstX8632BinopGPR(Func, Dest, Source); |
691 } | 706 } |
692 void emit(const Cfg *Func) const override { | 707 void emit(const Cfg *Func) const override { |
(...skipping 23 matching lines...) Expand all Loading... |
716 addSource(Dest); | 731 addSource(Dest); |
717 addSource(Source); | 732 addSource(Source); |
718 } | 733 } |
719 ~InstX8632BinopGPR() override {} | 734 ~InstX8632BinopGPR() override {} |
720 static const char *Opcode; | 735 static const char *Opcode; |
721 static const x86::AssemblerX86::GPREmitterRegOp Emitter; | 736 static const x86::AssemblerX86::GPREmitterRegOp Emitter; |
722 }; | 737 }; |
723 | 738 |
724 template <InstX8632::InstKindX8632 K, bool NeedsElementType> | 739 template <InstX8632::InstKindX8632 K, bool NeedsElementType> |
725 class InstX8632BinopXmm : public InstX8632 { | 740 class InstX8632BinopXmm : public InstX8632 { |
| 741 InstX8632BinopXmm() = delete; |
726 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; | 742 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; |
727 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; | 743 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; |
728 | 744 |
729 public: | 745 public: |
730 // Create an XMM binary-op instruction like addss or addps. | 746 // Create an XMM binary-op instruction like addss or addps. |
731 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { | 747 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { |
732 return new (Func->allocate<InstX8632BinopXmm>()) | 748 return new (Func->allocate<InstX8632BinopXmm>()) |
733 InstX8632BinopXmm(Func, Dest, Source); | 749 InstX8632BinopXmm(Func, Dest, Source); |
734 } | 750 } |
735 void emit(const Cfg *Func) const override { | 751 void emit(const Cfg *Func) const override { |
(...skipping 29 matching lines...) Expand all Loading... |
765 static const char *Opcode; | 781 static const char *Opcode; |
766 static const x86::AssemblerX86::XmmEmitterRegOp Emitter; | 782 static const x86::AssemblerX86::XmmEmitterRegOp Emitter; |
767 }; | 783 }; |
768 | 784 |
769 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, | 785 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
770 const Operand *Src, | 786 const Operand *Src, |
771 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter); | 787 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter); |
772 | 788 |
773 template <InstX8632::InstKindX8632 K> | 789 template <InstX8632::InstKindX8632 K> |
774 class InstX8632BinopXmmShift : public InstX8632 { | 790 class InstX8632BinopXmmShift : public InstX8632 { |
| 791 InstX8632BinopXmmShift() = delete; |
775 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete; | 792 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete; |
776 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete; | 793 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete; |
777 | 794 |
778 public: | 795 public: |
779 // Create an XMM binary-op shift operation. | 796 // Create an XMM binary-op shift operation. |
780 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, | 797 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, |
781 Operand *Source) { | 798 Operand *Source) { |
782 return new (Func->allocate<InstX8632BinopXmmShift>()) | 799 return new (Func->allocate<InstX8632BinopXmmShift>()) |
783 InstX8632BinopXmmShift(Func, Dest, Source); | 800 InstX8632BinopXmmShift(Func, Dest, Source); |
784 } | 801 } |
(...skipping 26 matching lines...) Expand all Loading... |
811 : InstX8632(Func, K, 2, Dest) { | 828 : InstX8632(Func, K, 2, Dest) { |
812 addSource(Dest); | 829 addSource(Dest); |
813 addSource(Source); | 830 addSource(Source); |
814 } | 831 } |
815 ~InstX8632BinopXmmShift() override {} | 832 ~InstX8632BinopXmmShift() override {} |
816 static const char *Opcode; | 833 static const char *Opcode; |
817 static const x86::AssemblerX86::XmmEmitterShiftOp Emitter; | 834 static const x86::AssemblerX86::XmmEmitterShiftOp Emitter; |
818 }; | 835 }; |
819 | 836 |
820 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { | 837 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { |
| 838 InstX8632Ternop() = delete; |
821 InstX8632Ternop(const InstX8632Ternop &) = delete; | 839 InstX8632Ternop(const InstX8632Ternop &) = delete; |
822 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete; | 840 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete; |
823 | 841 |
824 public: | 842 public: |
825 // Create a ternary-op instruction like div or idiv. | 843 // Create a ternary-op instruction like div or idiv. |
826 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, | 844 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, |
827 Operand *Source2) { | 845 Operand *Source2) { |
828 return new (Func->allocate<InstX8632Ternop>()) | 846 return new (Func->allocate<InstX8632Ternop>()) |
829 InstX8632Ternop(Func, Dest, Source1, Source2); | 847 InstX8632Ternop(Func, Dest, Source1, Source2); |
830 } | 848 } |
(...skipping 27 matching lines...) Expand all Loading... |
858 addSource(Source1); | 876 addSource(Source1); |
859 addSource(Source2); | 877 addSource(Source2); |
860 } | 878 } |
861 ~InstX8632Ternop() override {} | 879 ~InstX8632Ternop() override {} |
862 static const char *Opcode; | 880 static const char *Opcode; |
863 }; | 881 }; |
864 | 882 |
865 // Instructions of the form x := y op z | 883 // Instructions of the form x := y op z |
866 template <InstX8632::InstKindX8632 K> | 884 template <InstX8632::InstKindX8632 K> |
867 class InstX8632ThreeAddressop : public InstX8632 { | 885 class InstX8632ThreeAddressop : public InstX8632 { |
| 886 InstX8632ThreeAddressop() = delete; |
868 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete; | 887 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete; |
869 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete; | 888 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete; |
870 | 889 |
871 public: | 890 public: |
872 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, | 891 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, |
873 Operand *Source0, Operand *Source1) { | 892 Operand *Source0, Operand *Source1) { |
874 return new (Func->allocate<InstX8632ThreeAddressop>()) | 893 return new (Func->allocate<InstX8632ThreeAddressop>()) |
875 InstX8632ThreeAddressop(Func, Dest, Source0, Source1); | 894 InstX8632ThreeAddressop(Func, Dest, Source0, Source1); |
876 } | 895 } |
877 void emit(const Cfg *Func) const override { | 896 void emit(const Cfg *Func) const override { |
(...skipping 28 matching lines...) Expand all Loading... |
906 } | 925 } |
907 ~InstX8632ThreeAddressop() override {} | 926 ~InstX8632ThreeAddressop() override {} |
908 static const char *Opcode; | 927 static const char *Opcode; |
909 }; | 928 }; |
910 | 929 |
911 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); | 930 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); |
912 | 931 |
913 // Base class for assignment instructions | 932 // Base class for assignment instructions |
914 template <InstX8632::InstKindX8632 K> | 933 template <InstX8632::InstKindX8632 K> |
915 class InstX8632Movlike : public InstX8632 { | 934 class InstX8632Movlike : public InstX8632 { |
| 935 InstX8632Movlike() = delete; |
916 InstX8632Movlike(const InstX8632Movlike &) = delete; | 936 InstX8632Movlike(const InstX8632Movlike &) = delete; |
917 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete; | 937 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete; |
918 | 938 |
919 public: | 939 public: |
920 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) { | 940 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) { |
921 return new (Func->allocate<InstX8632Movlike>()) | 941 return new (Func->allocate<InstX8632Movlike>()) |
922 InstX8632Movlike(Func, Dest, Source); | 942 InstX8632Movlike(Func, Dest, Source); |
923 } | 943 } |
924 bool isRedundantAssign() const override { | 944 bool isRedundantAssign() const override { |
925 return checkForRedundantAssign(getDest(), getSrc(0)); | 945 return checkForRedundantAssign(getDest(), getSrc(0)); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps; | 1031 typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps; |
1012 typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr; | 1032 typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr; |
1013 typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps; | 1033 typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps; |
1014 typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps; | 1034 typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps; |
1015 typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb; | 1035 typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb; |
1016 typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr; | 1036 typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr; |
1017 typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd; | 1037 typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd; |
1018 | 1038 |
1019 // Base class for a lockable x86-32 instruction (emits a locked prefix). | 1039 // Base class for a lockable x86-32 instruction (emits a locked prefix). |
1020 class InstX8632Lockable : public InstX8632 { | 1040 class InstX8632Lockable : public InstX8632 { |
| 1041 InstX8632Lockable() = delete; |
1021 InstX8632Lockable(const InstX8632Lockable &) = delete; | 1042 InstX8632Lockable(const InstX8632Lockable &) = delete; |
1022 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete; | 1043 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete; |
1023 | 1044 |
1024 protected: | 1045 protected: |
1025 bool Locked; | 1046 bool Locked; |
1026 | 1047 |
1027 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, | 1048 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, |
1028 Variable *Dest, bool Locked) | 1049 Variable *Dest, bool Locked) |
1029 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { | 1050 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { |
1030 // Assume that such instructions are used for Atomics and be careful | 1051 // Assume that such instructions are used for Atomics and be careful |
1031 // with optimizations. | 1052 // with optimizations. |
1032 HasSideEffects = Locked; | 1053 HasSideEffects = Locked; |
1033 } | 1054 } |
1034 ~InstX8632Lockable() override {} | 1055 ~InstX8632Lockable() override {} |
1035 }; | 1056 }; |
1036 | 1057 |
1037 // Mul instruction - unsigned multiply. | 1058 // Mul instruction - unsigned multiply. |
1038 class InstX8632Mul : public InstX8632 { | 1059 class InstX8632Mul : public InstX8632 { |
| 1060 InstX8632Mul() = delete; |
1039 InstX8632Mul(const InstX8632Mul &) = delete; | 1061 InstX8632Mul(const InstX8632Mul &) = delete; |
1040 InstX8632Mul &operator=(const InstX8632Mul &) = delete; | 1062 InstX8632Mul &operator=(const InstX8632Mul &) = delete; |
1041 | 1063 |
1042 public: | 1064 public: |
1043 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, | 1065 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, |
1044 Operand *Source2) { | 1066 Operand *Source2) { |
1045 return new (Func->allocate<InstX8632Mul>()) | 1067 return new (Func->allocate<InstX8632Mul>()) |
1046 InstX8632Mul(Func, Dest, Source1, Source2); | 1068 InstX8632Mul(Func, Dest, Source1, Source2); |
1047 } | 1069 } |
1048 void emit(const Cfg *Func) const override; | 1070 void emit(const Cfg *Func) const override; |
1049 void emitIAS(const Cfg *Func) const override; | 1071 void emitIAS(const Cfg *Func) const override; |
1050 void dump(const Cfg *Func) const override; | 1072 void dump(const Cfg *Func) const override; |
1051 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); } | 1073 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); } |
1052 | 1074 |
1053 private: | 1075 private: |
1054 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); | 1076 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); |
1055 ~InstX8632Mul() override {} | 1077 ~InstX8632Mul() override {} |
1056 }; | 1078 }; |
1057 | 1079 |
1058 // Shld instruction - shift across a pair of operands. | 1080 // Shld instruction - shift across a pair of operands. |
1059 class InstX8632Shld : public InstX8632 { | 1081 class InstX8632Shld : public InstX8632 { |
| 1082 InstX8632Shld() = delete; |
1060 InstX8632Shld(const InstX8632Shld &) = delete; | 1083 InstX8632Shld(const InstX8632Shld &) = delete; |
1061 InstX8632Shld &operator=(const InstX8632Shld &) = delete; | 1084 InstX8632Shld &operator=(const InstX8632Shld &) = delete; |
1062 | 1085 |
1063 public: | 1086 public: |
1064 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, | 1087 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, |
1065 Variable *Source2) { | 1088 Variable *Source2) { |
1066 return new (Func->allocate<InstX8632Shld>()) | 1089 return new (Func->allocate<InstX8632Shld>()) |
1067 InstX8632Shld(Func, Dest, Source1, Source2); | 1090 InstX8632Shld(Func, Dest, Source1, Source2); |
1068 } | 1091 } |
1069 void emit(const Cfg *Func) const override; | 1092 void emit(const Cfg *Func) const override; |
1070 void emitIAS(const Cfg *Func) const override; | 1093 void emitIAS(const Cfg *Func) const override; |
1071 void dump(const Cfg *Func) const override; | 1094 void dump(const Cfg *Func) const override; |
1072 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); } | 1095 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); } |
1073 | 1096 |
1074 private: | 1097 private: |
1075 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, | 1098 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, |
1076 Variable *Source2); | 1099 Variable *Source2); |
1077 ~InstX8632Shld() override {} | 1100 ~InstX8632Shld() override {} |
1078 }; | 1101 }; |
1079 | 1102 |
1080 // Shrd instruction - shift across a pair of operands. | 1103 // Shrd instruction - shift across a pair of operands. |
1081 class InstX8632Shrd : public InstX8632 { | 1104 class InstX8632Shrd : public InstX8632 { |
| 1105 InstX8632Shrd() = delete; |
1082 InstX8632Shrd(const InstX8632Shrd &) = delete; | 1106 InstX8632Shrd(const InstX8632Shrd &) = delete; |
1083 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete; | 1107 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete; |
1084 | 1108 |
1085 public: | 1109 public: |
1086 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, | 1110 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, |
1087 Variable *Source2) { | 1111 Variable *Source2) { |
1088 return new (Func->allocate<InstX8632Shrd>()) | 1112 return new (Func->allocate<InstX8632Shrd>()) |
1089 InstX8632Shrd(Func, Dest, Source1, Source2); | 1113 InstX8632Shrd(Func, Dest, Source1, Source2); |
1090 } | 1114 } |
1091 void emit(const Cfg *Func) const override; | 1115 void emit(const Cfg *Func) const override; |
1092 void emitIAS(const Cfg *Func) const override; | 1116 void emitIAS(const Cfg *Func) const override; |
1093 void dump(const Cfg *Func) const override; | 1117 void dump(const Cfg *Func) const override; |
1094 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); } | 1118 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); } |
1095 | 1119 |
1096 private: | 1120 private: |
1097 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, | 1121 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, |
1098 Variable *Source2); | 1122 Variable *Source2); |
1099 ~InstX8632Shrd() override {} | 1123 ~InstX8632Shrd() override {} |
1100 }; | 1124 }; |
1101 | 1125 |
1102 // Conditional move instruction. | 1126 // Conditional move instruction. |
1103 class InstX8632Cmov : public InstX8632 { | 1127 class InstX8632Cmov : public InstX8632 { |
| 1128 InstX8632Cmov() = delete; |
1104 InstX8632Cmov(const InstX8632Cmov &) = delete; | 1129 InstX8632Cmov(const InstX8632Cmov &) = delete; |
1105 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete; | 1130 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete; |
1106 | 1131 |
1107 public: | 1132 public: |
1108 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, | 1133 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, |
1109 CondX86::BrCond Cond) { | 1134 CondX86::BrCond Cond) { |
1110 return new (Func->allocate<InstX8632Cmov>()) | 1135 return new (Func->allocate<InstX8632Cmov>()) |
1111 InstX8632Cmov(Func, Dest, Source, Cond); | 1136 InstX8632Cmov(Func, Dest, Source, Cond); |
1112 } | 1137 } |
1113 void emit(const Cfg *Func) const override; | 1138 void emit(const Cfg *Func) const override; |
1114 void emitIAS(const Cfg *Func) const override; | 1139 void emitIAS(const Cfg *Func) const override; |
1115 void dump(const Cfg *Func) const override; | 1140 void dump(const Cfg *Func) const override; |
1116 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } | 1141 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } |
1117 | 1142 |
1118 private: | 1143 private: |
1119 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, | 1144 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, |
1120 CondX86::BrCond Cond); | 1145 CondX86::BrCond Cond); |
1121 ~InstX8632Cmov() override {} | 1146 ~InstX8632Cmov() override {} |
1122 | 1147 |
1123 CondX86::BrCond Condition; | 1148 CondX86::BrCond Condition; |
1124 }; | 1149 }; |
1125 | 1150 |
1126 // Cmpps instruction - compare packed singled-precision floating point | 1151 // Cmpps instruction - compare packed singled-precision floating point |
1127 // values | 1152 // values |
1128 class InstX8632Cmpps : public InstX8632 { | 1153 class InstX8632Cmpps : public InstX8632 { |
| 1154 InstX8632Cmpps() = delete; |
1129 InstX8632Cmpps(const InstX8632Cmpps &) = delete; | 1155 InstX8632Cmpps(const InstX8632Cmpps &) = delete; |
1130 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete; | 1156 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete; |
1131 | 1157 |
1132 public: | 1158 public: |
1133 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, | 1159 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, |
1134 CondX86::CmppsCond Condition) { | 1160 CondX86::CmppsCond Condition) { |
1135 return new (Func->allocate<InstX8632Cmpps>()) | 1161 return new (Func->allocate<InstX8632Cmpps>()) |
1136 InstX8632Cmpps(Func, Dest, Source, Condition); | 1162 InstX8632Cmpps(Func, Dest, Source, Condition); |
1137 } | 1163 } |
1138 void emit(const Cfg *Func) const override; | 1164 void emit(const Cfg *Func) const override; |
1139 void emitIAS(const Cfg *Func) const override; | 1165 void emitIAS(const Cfg *Func) const override; |
1140 void dump(const Cfg *Func) const override; | 1166 void dump(const Cfg *Func) const override; |
1141 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } | 1167 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } |
1142 | 1168 |
1143 private: | 1169 private: |
1144 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, | 1170 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, |
1145 CondX86::CmppsCond Cond); | 1171 CondX86::CmppsCond Cond); |
1146 ~InstX8632Cmpps() override {} | 1172 ~InstX8632Cmpps() override {} |
1147 | 1173 |
1148 CondX86::CmppsCond Condition; | 1174 CondX86::CmppsCond Condition; |
1149 }; | 1175 }; |
1150 | 1176 |
1151 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> | 1177 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> |
1152 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. | 1178 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. |
1153 // If not, ZF is cleared and <dest> is copied to eax (or subregister). | 1179 // If not, ZF is cleared and <dest> is copied to eax (or subregister). |
1154 // <dest> can be a register or memory, while <desired> must be a register. | 1180 // <dest> can be a register or memory, while <desired> must be a register. |
1155 // It is the user's responsiblity to mark eax with a FakeDef. | 1181 // It is the user's responsiblity to mark eax with a FakeDef. |
1156 class InstX8632Cmpxchg : public InstX8632Lockable { | 1182 class InstX8632Cmpxchg : public InstX8632Lockable { |
| 1183 InstX8632Cmpxchg() = delete; |
1157 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete; | 1184 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete; |
1158 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete; | 1185 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete; |
1159 | 1186 |
1160 public: | 1187 public: |
1161 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, | 1188 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, |
1162 Variable *Desired, bool Locked) { | 1189 Variable *Desired, bool Locked) { |
1163 return new (Func->allocate<InstX8632Cmpxchg>()) | 1190 return new (Func->allocate<InstX8632Cmpxchg>()) |
1164 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); | 1191 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); |
1165 } | 1192 } |
1166 void emit(const Cfg *Func) const override; | 1193 void emit(const Cfg *Func) const override; |
1167 void emitIAS(const Cfg *Func) const override; | 1194 void emitIAS(const Cfg *Func) const override; |
1168 void dump(const Cfg *Func) const override; | 1195 void dump(const Cfg *Func) const override; |
1169 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } | 1196 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } |
1170 | 1197 |
1171 private: | 1198 private: |
1172 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, | 1199 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, |
1173 Variable *Desired, bool Locked); | 1200 Variable *Desired, bool Locked); |
1174 ~InstX8632Cmpxchg() override {} | 1201 ~InstX8632Cmpxchg() override {} |
1175 }; | 1202 }; |
1176 | 1203 |
1177 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> | 1204 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> |
1178 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. | 1205 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. |
1179 // If not, ZF is cleared and <m64> is copied to edx:eax. | 1206 // If not, ZF is cleared and <m64> is copied to edx:eax. |
1180 // The caller is responsible for inserting FakeDefs to mark edx | 1207 // The caller is responsible for inserting FakeDefs to mark edx |
1181 // and eax as modified. | 1208 // and eax as modified. |
1182 // <m64> must be a memory operand. | 1209 // <m64> must be a memory operand. |
1183 class InstX8632Cmpxchg8b : public InstX8632Lockable { | 1210 class InstX8632Cmpxchg8b : public InstX8632Lockable { |
| 1211 InstX8632Cmpxchg8b() = delete; |
1184 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete; | 1212 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete; |
1185 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete; | 1213 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete; |
1186 | 1214 |
1187 public: | 1215 public: |
1188 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest, | 1216 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest, |
1189 Variable *Edx, Variable *Eax, Variable *Ecx, | 1217 Variable *Edx, Variable *Eax, Variable *Ecx, |
1190 Variable *Ebx, bool Locked) { | 1218 Variable *Ebx, bool Locked) { |
1191 return new (Func->allocate<InstX8632Cmpxchg8b>()) | 1219 return new (Func->allocate<InstX8632Cmpxchg8b>()) |
1192 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); | 1220 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); |
1193 } | 1221 } |
1194 void emit(const Cfg *Func) const override; | 1222 void emit(const Cfg *Func) const override; |
1195 void emitIAS(const Cfg *Func) const override; | 1223 void emitIAS(const Cfg *Func) const override; |
1196 void dump(const Cfg *Func) const override; | 1224 void dump(const Cfg *Func) const override; |
1197 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } | 1225 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } |
1198 | 1226 |
1199 private: | 1227 private: |
1200 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx, | 1228 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx, |
1201 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); | 1229 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); |
1202 ~InstX8632Cmpxchg8b() override {} | 1230 ~InstX8632Cmpxchg8b() override {} |
1203 }; | 1231 }; |
1204 | 1232 |
1205 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} | 1233 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} |
1206 // as appropriate. s=float, d=double, i=int. X and Y are determined | 1234 // as appropriate. s=float, d=double, i=int. X and Y are determined |
1207 // from dest/src types. Sign and zero extension on the integer | 1235 // from dest/src types. Sign and zero extension on the integer |
1208 // operand needs to be done separately. | 1236 // operand needs to be done separately. |
1209 class InstX8632Cvt : public InstX8632 { | 1237 class InstX8632Cvt : public InstX8632 { |
| 1238 InstX8632Cvt() = delete; |
1210 InstX8632Cvt(const InstX8632Cvt &) = delete; | 1239 InstX8632Cvt(const InstX8632Cvt &) = delete; |
1211 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete; | 1240 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete; |
1212 | 1241 |
1213 public: | 1242 public: |
1214 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; | 1243 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; |
1215 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, | 1244 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, |
1216 CvtVariant Variant) { | 1245 CvtVariant Variant) { |
1217 return new (Func->allocate<InstX8632Cvt>()) | 1246 return new (Func->allocate<InstX8632Cvt>()) |
1218 InstX8632Cvt(Func, Dest, Source, Variant); | 1247 InstX8632Cvt(Func, Dest, Source, Variant); |
1219 } | 1248 } |
1220 void emit(const Cfg *Func) const override; | 1249 void emit(const Cfg *Func) const override; |
1221 void emitIAS(const Cfg *Func) const override; | 1250 void emitIAS(const Cfg *Func) const override; |
1222 void dump(const Cfg *Func) const override; | 1251 void dump(const Cfg *Func) const override; |
1223 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); } | 1252 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); } |
1224 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } | 1253 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } |
1225 | 1254 |
1226 private: | 1255 private: |
1227 CvtVariant Variant; | 1256 CvtVariant Variant; |
1228 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); | 1257 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); |
1229 ~InstX8632Cvt() override {} | 1258 ~InstX8632Cvt() override {} |
1230 }; | 1259 }; |
1231 | 1260 |
1232 // cmp - Integer compare instruction. | 1261 // cmp - Integer compare instruction. |
1233 class InstX8632Icmp : public InstX8632 { | 1262 class InstX8632Icmp : public InstX8632 { |
| 1263 InstX8632Icmp() = delete; |
1234 InstX8632Icmp(const InstX8632Icmp &) = delete; | 1264 InstX8632Icmp(const InstX8632Icmp &) = delete; |
1235 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete; | 1265 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete; |
1236 | 1266 |
1237 public: | 1267 public: |
1238 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { | 1268 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { |
1239 return new (Func->allocate<InstX8632Icmp>()) | 1269 return new (Func->allocate<InstX8632Icmp>()) |
1240 InstX8632Icmp(Func, Src1, Src2); | 1270 InstX8632Icmp(Func, Src1, Src2); |
1241 } | 1271 } |
1242 void emit(const Cfg *Func) const override; | 1272 void emit(const Cfg *Func) const override; |
1243 void emitIAS(const Cfg *Func) const override; | 1273 void emitIAS(const Cfg *Func) const override; |
1244 void dump(const Cfg *Func) const override; | 1274 void dump(const Cfg *Func) const override; |
1245 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } | 1275 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } |
1246 | 1276 |
1247 private: | 1277 private: |
1248 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2); | 1278 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2); |
1249 ~InstX8632Icmp() override {} | 1279 ~InstX8632Icmp() override {} |
1250 }; | 1280 }; |
1251 | 1281 |
1252 // ucomiss/ucomisd - floating-point compare instruction. | 1282 // ucomiss/ucomisd - floating-point compare instruction. |
1253 class InstX8632Ucomiss : public InstX8632 { | 1283 class InstX8632Ucomiss : public InstX8632 { |
| 1284 InstX8632Ucomiss() = delete; |
1254 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete; | 1285 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete; |
1255 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete; | 1286 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete; |
1256 | 1287 |
1257 public: | 1288 public: |
1258 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { | 1289 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { |
1259 return new (Func->allocate<InstX8632Ucomiss>()) | 1290 return new (Func->allocate<InstX8632Ucomiss>()) |
1260 InstX8632Ucomiss(Func, Src1, Src2); | 1291 InstX8632Ucomiss(Func, Src1, Src2); |
1261 } | 1292 } |
1262 void emit(const Cfg *Func) const override; | 1293 void emit(const Cfg *Func) const override; |
1263 void emitIAS(const Cfg *Func) const override; | 1294 void emitIAS(const Cfg *Func) const override; |
1264 void dump(const Cfg *Func) const override; | 1295 void dump(const Cfg *Func) const override; |
1265 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); } | 1296 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); } |
1266 | 1297 |
1267 private: | 1298 private: |
1268 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); | 1299 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); |
1269 ~InstX8632Ucomiss() override {} | 1300 ~InstX8632Ucomiss() override {} |
1270 }; | 1301 }; |
1271 | 1302 |
1272 // UD2 instruction. | 1303 // UD2 instruction. |
1273 class InstX8632UD2 : public InstX8632 { | 1304 class InstX8632UD2 : public InstX8632 { |
| 1305 InstX8632UD2() = delete; |
1274 InstX8632UD2(const InstX8632UD2 &) = delete; | 1306 InstX8632UD2(const InstX8632UD2 &) = delete; |
1275 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete; | 1307 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete; |
1276 | 1308 |
1277 public: | 1309 public: |
1278 static InstX8632UD2 *create(Cfg *Func) { | 1310 static InstX8632UD2 *create(Cfg *Func) { |
1279 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); | 1311 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); |
1280 } | 1312 } |
1281 void emit(const Cfg *Func) const override; | 1313 void emit(const Cfg *Func) const override; |
1282 void emitIAS(const Cfg *Func) const override; | 1314 void emitIAS(const Cfg *Func) const override; |
1283 void dump(const Cfg *Func) const override; | 1315 void dump(const Cfg *Func) const override; |
1284 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } | 1316 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } |
1285 | 1317 |
1286 private: | 1318 private: |
1287 InstX8632UD2(Cfg *Func); | 1319 explicit InstX8632UD2(Cfg *Func); |
1288 ~InstX8632UD2() override {} | 1320 ~InstX8632UD2() override {} |
1289 }; | 1321 }; |
1290 | 1322 |
1291 // Test instruction. | 1323 // Test instruction. |
1292 class InstX8632Test : public InstX8632 { | 1324 class InstX8632Test : public InstX8632 { |
| 1325 InstX8632Test() = delete; |
1293 InstX8632Test(const InstX8632Test &) = delete; | 1326 InstX8632Test(const InstX8632Test &) = delete; |
1294 InstX8632Test &operator=(const InstX8632Test &) = delete; | 1327 InstX8632Test &operator=(const InstX8632Test &) = delete; |
1295 | 1328 |
1296 public: | 1329 public: |
1297 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { | 1330 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { |
1298 return new (Func->allocate<InstX8632Test>()) | 1331 return new (Func->allocate<InstX8632Test>()) |
1299 InstX8632Test(Func, Source1, Source2); | 1332 InstX8632Test(Func, Source1, Source2); |
1300 } | 1333 } |
1301 void emit(const Cfg *Func) const override; | 1334 void emit(const Cfg *Func) const override; |
1302 void emitIAS(const Cfg *Func) const override; | 1335 void emitIAS(const Cfg *Func) const override; |
1303 void dump(const Cfg *Func) const override; | 1336 void dump(const Cfg *Func) const override; |
1304 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } | 1337 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } |
1305 | 1338 |
1306 private: | 1339 private: |
1307 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2); | 1340 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2); |
1308 ~InstX8632Test() override {} | 1341 ~InstX8632Test() override {} |
1309 }; | 1342 }; |
1310 | 1343 |
1311 // Mfence instruction. | 1344 // Mfence instruction. |
1312 class InstX8632Mfence : public InstX8632 { | 1345 class InstX8632Mfence : public InstX8632 { |
| 1346 InstX8632Mfence() = delete; |
1313 InstX8632Mfence(const InstX8632Mfence &) = delete; | 1347 InstX8632Mfence(const InstX8632Mfence &) = delete; |
1314 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete; | 1348 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete; |
1315 | 1349 |
1316 public: | 1350 public: |
1317 static InstX8632Mfence *create(Cfg *Func) { | 1351 static InstX8632Mfence *create(Cfg *Func) { |
1318 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func); | 1352 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func); |
1319 } | 1353 } |
1320 void emit(const Cfg *Func) const override; | 1354 void emit(const Cfg *Func) const override; |
1321 void emitIAS(const Cfg *Func) const override; | 1355 void emitIAS(const Cfg *Func) const override; |
1322 void dump(const Cfg *Func) const override; | 1356 void dump(const Cfg *Func) const override; |
1323 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); } | 1357 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); } |
1324 | 1358 |
1325 private: | 1359 private: |
1326 InstX8632Mfence(Cfg *Func); | 1360 explicit InstX8632Mfence(Cfg *Func); |
1327 ~InstX8632Mfence() override {} | 1361 ~InstX8632Mfence() override {} |
1328 }; | 1362 }; |
1329 | 1363 |
1330 // This is essentially a "mov" instruction with an OperandX8632Mem | 1364 // This is essentially a "mov" instruction with an OperandX8632Mem |
1331 // operand instead of Variable as the destination. It's important | 1365 // operand instead of Variable as the destination. It's important |
1332 // for liveness that there is no Dest operand. | 1366 // for liveness that there is no Dest operand. |
1333 class InstX8632Store : public InstX8632 { | 1367 class InstX8632Store : public InstX8632 { |
| 1368 InstX8632Store() = delete; |
1334 InstX8632Store(const InstX8632Store &) = delete; | 1369 InstX8632Store(const InstX8632Store &) = delete; |
1335 InstX8632Store &operator=(const InstX8632Store &) = delete; | 1370 InstX8632Store &operator=(const InstX8632Store &) = delete; |
1336 | 1371 |
1337 public: | 1372 public: |
1338 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { | 1373 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { |
1339 return new (Func->allocate<InstX8632Store>()) | 1374 return new (Func->allocate<InstX8632Store>()) |
1340 InstX8632Store(Func, Value, Mem); | 1375 InstX8632Store(Func, Value, Mem); |
1341 } | 1376 } |
1342 void emit(const Cfg *Func) const override; | 1377 void emit(const Cfg *Func) const override; |
1343 void emitIAS(const Cfg *Func) const override; | 1378 void emitIAS(const Cfg *Func) const override; |
1344 void dump(const Cfg *Func) const override; | 1379 void dump(const Cfg *Func) const override; |
1345 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); } | 1380 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); } |
1346 | 1381 |
1347 private: | 1382 private: |
1348 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem); | 1383 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem); |
1349 ~InstX8632Store() override {} | 1384 ~InstX8632Store() override {} |
1350 }; | 1385 }; |
1351 | 1386 |
1352 // This is essentially a vector "mov" instruction with an OperandX8632Mem | 1387 // This is essentially a vector "mov" instruction with an OperandX8632Mem |
1353 // operand instead of Variable as the destination. It's important | 1388 // operand instead of Variable as the destination. It's important |
1354 // for liveness that there is no Dest operand. The source must be an | 1389 // for liveness that there is no Dest operand. The source must be an |
1355 // Xmm register, since Dest is mem. | 1390 // Xmm register, since Dest is mem. |
1356 class InstX8632StoreP : public InstX8632 { | 1391 class InstX8632StoreP : public InstX8632 { |
| 1392 InstX8632StoreP() = delete; |
1357 InstX8632StoreP(const InstX8632StoreP &) = delete; | 1393 InstX8632StoreP(const InstX8632StoreP &) = delete; |
1358 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete; | 1394 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete; |
1359 | 1395 |
1360 public: | 1396 public: |
1361 static InstX8632StoreP *create(Cfg *Func, Variable *Value, | 1397 static InstX8632StoreP *create(Cfg *Func, Variable *Value, |
1362 OperandX8632Mem *Mem) { | 1398 OperandX8632Mem *Mem) { |
1363 return new (Func->allocate<InstX8632StoreP>()) | 1399 return new (Func->allocate<InstX8632StoreP>()) |
1364 InstX8632StoreP(Func, Value, Mem); | 1400 InstX8632StoreP(Func, Value, Mem); |
1365 } | 1401 } |
1366 void emit(const Cfg *Func) const override; | 1402 void emit(const Cfg *Func) const override; |
1367 void emitIAS(const Cfg *Func) const override; | 1403 void emitIAS(const Cfg *Func) const override; |
1368 void dump(const Cfg *Func) const override; | 1404 void dump(const Cfg *Func) const override; |
1369 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); } | 1405 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); } |
1370 | 1406 |
1371 private: | 1407 private: |
1372 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); | 1408 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); |
1373 ~InstX8632StoreP() override {} | 1409 ~InstX8632StoreP() override {} |
1374 }; | 1410 }; |
1375 | 1411 |
1376 class InstX8632StoreQ : public InstX8632 { | 1412 class InstX8632StoreQ : public InstX8632 { |
| 1413 InstX8632StoreQ() = delete; |
1377 InstX8632StoreQ(const InstX8632StoreQ &) = delete; | 1414 InstX8632StoreQ(const InstX8632StoreQ &) = delete; |
1378 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete; | 1415 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete; |
1379 | 1416 |
1380 public: | 1417 public: |
1381 static InstX8632StoreQ *create(Cfg *Func, Variable *Value, | 1418 static InstX8632StoreQ *create(Cfg *Func, Variable *Value, |
1382 OperandX8632Mem *Mem) { | 1419 OperandX8632Mem *Mem) { |
1383 return new (Func->allocate<InstX8632StoreQ>()) | 1420 return new (Func->allocate<InstX8632StoreQ>()) |
1384 InstX8632StoreQ(Func, Value, Mem); | 1421 InstX8632StoreQ(Func, Value, Mem); |
1385 } | 1422 } |
1386 void emit(const Cfg *Func) const override; | 1423 void emit(const Cfg *Func) const override; |
1387 void emitIAS(const Cfg *Func) const override; | 1424 void emitIAS(const Cfg *Func) const override; |
1388 void dump(const Cfg *Func) const override; | 1425 void dump(const Cfg *Func) const override; |
1389 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } | 1426 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } |
1390 | 1427 |
1391 private: | 1428 private: |
1392 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); | 1429 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); |
1393 ~InstX8632StoreQ() override {} | 1430 ~InstX8632StoreQ() override {} |
1394 }; | 1431 }; |
1395 | 1432 |
1396 // Nop instructions of varying length | 1433 // Nop instructions of varying length |
1397 class InstX8632Nop : public InstX8632 { | 1434 class InstX8632Nop : public InstX8632 { |
| 1435 InstX8632Nop() = delete; |
1398 InstX8632Nop(const InstX8632Nop &) = delete; | 1436 InstX8632Nop(const InstX8632Nop &) = delete; |
1399 InstX8632Nop &operator=(const InstX8632Nop &) = delete; | 1437 InstX8632Nop &operator=(const InstX8632Nop &) = delete; |
1400 | 1438 |
1401 public: | 1439 public: |
1402 // TODO: Replace with enum. | 1440 // TODO: Replace with enum. |
1403 typedef unsigned NopVariant; | 1441 typedef unsigned NopVariant; |
1404 | 1442 |
1405 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) { | 1443 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) { |
1406 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant); | 1444 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant); |
1407 } | 1445 } |
1408 void emit(const Cfg *Func) const override; | 1446 void emit(const Cfg *Func) const override; |
1409 void emitIAS(const Cfg *Func) const override; | 1447 void emitIAS(const Cfg *Func) const override; |
1410 void dump(const Cfg *Func) const override; | 1448 void dump(const Cfg *Func) const override; |
1411 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); } | 1449 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); } |
1412 | 1450 |
1413 private: | 1451 private: |
1414 InstX8632Nop(Cfg *Func, SizeT Length); | 1452 InstX8632Nop(Cfg *Func, SizeT Length); |
1415 ~InstX8632Nop() override {} | 1453 ~InstX8632Nop() override {} |
1416 | 1454 |
1417 NopVariant Variant; | 1455 NopVariant Variant; |
1418 }; | 1456 }; |
1419 | 1457 |
1420 // Fld - load a value onto the x87 FP stack. | 1458 // Fld - load a value onto the x87 FP stack. |
1421 class InstX8632Fld : public InstX8632 { | 1459 class InstX8632Fld : public InstX8632 { |
| 1460 InstX8632Fld() = delete; |
1422 InstX8632Fld(const InstX8632Fld &) = delete; | 1461 InstX8632Fld(const InstX8632Fld &) = delete; |
1423 InstX8632Fld &operator=(const InstX8632Fld &) = delete; | 1462 InstX8632Fld &operator=(const InstX8632Fld &) = delete; |
1424 | 1463 |
1425 public: | 1464 public: |
1426 static InstX8632Fld *create(Cfg *Func, Operand *Src) { | 1465 static InstX8632Fld *create(Cfg *Func, Operand *Src) { |
1427 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src); | 1466 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src); |
1428 } | 1467 } |
1429 void emit(const Cfg *Func) const override; | 1468 void emit(const Cfg *Func) const override; |
1430 void emitIAS(const Cfg *Func) const override; | 1469 void emitIAS(const Cfg *Func) const override; |
1431 void dump(const Cfg *Func) const override; | 1470 void dump(const Cfg *Func) const override; |
1432 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); } | 1471 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); } |
1433 | 1472 |
1434 private: | 1473 private: |
1435 InstX8632Fld(Cfg *Func, Operand *Src); | 1474 InstX8632Fld(Cfg *Func, Operand *Src); |
1436 ~InstX8632Fld() override {} | 1475 ~InstX8632Fld() override {} |
1437 }; | 1476 }; |
1438 | 1477 |
1439 // Fstp - store x87 st(0) into memory and pop st(0). | 1478 // Fstp - store x87 st(0) into memory and pop st(0). |
1440 class InstX8632Fstp : public InstX8632 { | 1479 class InstX8632Fstp : public InstX8632 { |
| 1480 InstX8632Fstp() = delete; |
1441 InstX8632Fstp(const InstX8632Fstp &) = delete; | 1481 InstX8632Fstp(const InstX8632Fstp &) = delete; |
1442 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete; | 1482 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete; |
1443 | 1483 |
1444 public: | 1484 public: |
1445 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) { | 1485 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) { |
1446 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest); | 1486 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest); |
1447 } | 1487 } |
1448 void emit(const Cfg *Func) const override; | 1488 void emit(const Cfg *Func) const override; |
1449 void emitIAS(const Cfg *Func) const override; | 1489 void emitIAS(const Cfg *Func) const override; |
1450 void dump(const Cfg *Func) const override; | 1490 void dump(const Cfg *Func) const override; |
1451 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); } | 1491 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); } |
1452 | 1492 |
1453 private: | 1493 private: |
1454 InstX8632Fstp(Cfg *Func, Variable *Dest); | 1494 InstX8632Fstp(Cfg *Func, Variable *Dest); |
1455 ~InstX8632Fstp() override {} | 1495 ~InstX8632Fstp() override {} |
1456 }; | 1496 }; |
1457 | 1497 |
1458 class InstX8632Pop : public InstX8632 { | 1498 class InstX8632Pop : public InstX8632 { |
| 1499 InstX8632Pop() = delete; |
1459 InstX8632Pop(const InstX8632Pop &) = delete; | 1500 InstX8632Pop(const InstX8632Pop &) = delete; |
1460 InstX8632Pop &operator=(const InstX8632Pop &) = delete; | 1501 InstX8632Pop &operator=(const InstX8632Pop &) = delete; |
1461 | 1502 |
1462 public: | 1503 public: |
1463 static InstX8632Pop *create(Cfg *Func, Variable *Dest) { | 1504 static InstX8632Pop *create(Cfg *Func, Variable *Dest) { |
1464 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest); | 1505 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest); |
1465 } | 1506 } |
1466 void emit(const Cfg *Func) const override; | 1507 void emit(const Cfg *Func) const override; |
1467 void emitIAS(const Cfg *Func) const override; | 1508 void emitIAS(const Cfg *Func) const override; |
1468 void dump(const Cfg *Func) const override; | 1509 void dump(const Cfg *Func) const override; |
1469 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } | 1510 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } |
1470 | 1511 |
1471 private: | 1512 private: |
1472 InstX8632Pop(Cfg *Func, Variable *Dest); | 1513 InstX8632Pop(Cfg *Func, Variable *Dest); |
1473 ~InstX8632Pop() override {} | 1514 ~InstX8632Pop() override {} |
1474 }; | 1515 }; |
1475 | 1516 |
1476 class InstX8632Push : public InstX8632 { | 1517 class InstX8632Push : public InstX8632 { |
| 1518 InstX8632Push() = delete; |
1477 InstX8632Push(const InstX8632Push &) = delete; | 1519 InstX8632Push(const InstX8632Push &) = delete; |
1478 InstX8632Push &operator=(const InstX8632Push &) = delete; | 1520 InstX8632Push &operator=(const InstX8632Push &) = delete; |
1479 | 1521 |
1480 public: | 1522 public: |
1481 static InstX8632Push *create(Cfg *Func, Variable *Source) { | 1523 static InstX8632Push *create(Cfg *Func, Variable *Source) { |
1482 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source); | 1524 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source); |
1483 } | 1525 } |
1484 void emit(const Cfg *Func) const override; | 1526 void emit(const Cfg *Func) const override; |
1485 void emitIAS(const Cfg *Func) const override; | 1527 void emitIAS(const Cfg *Func) const override; |
1486 void dump(const Cfg *Func) const override; | 1528 void dump(const Cfg *Func) const override; |
1487 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } | 1529 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } |
1488 | 1530 |
1489 private: | 1531 private: |
1490 InstX8632Push(Cfg *Func, Variable *Source); | 1532 InstX8632Push(Cfg *Func, Variable *Source); |
1491 ~InstX8632Push() override {} | 1533 ~InstX8632Push() override {} |
1492 }; | 1534 }; |
1493 | 1535 |
1494 // Ret instruction. Currently only supports the "ret" version that | 1536 // Ret instruction. Currently only supports the "ret" version that |
1495 // does not pop arguments. This instruction takes a Source operand | 1537 // does not pop arguments. This instruction takes a Source operand |
1496 // (for non-void returning functions) for liveness analysis, though | 1538 // (for non-void returning functions) for liveness analysis, though |
1497 // a FakeUse before the ret would do just as well. | 1539 // a FakeUse before the ret would do just as well. |
1498 class InstX8632Ret : public InstX8632 { | 1540 class InstX8632Ret : public InstX8632 { |
| 1541 InstX8632Ret() = delete; |
1499 InstX8632Ret(const InstX8632Ret &) = delete; | 1542 InstX8632Ret(const InstX8632Ret &) = delete; |
1500 InstX8632Ret &operator=(const InstX8632Ret &) = delete; | 1543 InstX8632Ret &operator=(const InstX8632Ret &) = delete; |
1501 | 1544 |
1502 public: | 1545 public: |
1503 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) { | 1546 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) { |
1504 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source); | 1547 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source); |
1505 } | 1548 } |
1506 void emit(const Cfg *Func) const override; | 1549 void emit(const Cfg *Func) const override; |
1507 void emitIAS(const Cfg *Func) const override; | 1550 void emitIAS(const Cfg *Func) const override; |
1508 void dump(const Cfg *Func) const override; | 1551 void dump(const Cfg *Func) const override; |
1509 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } | 1552 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } |
1510 | 1553 |
1511 private: | 1554 private: |
1512 InstX8632Ret(Cfg *Func, Variable *Source); | 1555 InstX8632Ret(Cfg *Func, Variable *Source); |
1513 ~InstX8632Ret() override {} | 1556 ~InstX8632Ret() override {} |
1514 }; | 1557 }; |
1515 | 1558 |
1516 // Exchanging Add instruction. Exchanges the first operand (destination | 1559 // Exchanging Add instruction. Exchanges the first operand (destination |
1517 // operand) with the second operand (source operand), then loads the sum | 1560 // operand) with the second operand (source operand), then loads the sum |
1518 // of the two values into the destination operand. The destination may be | 1561 // of the two values into the destination operand. The destination may be |
1519 // a register or memory, while the source must be a register. | 1562 // a register or memory, while the source must be a register. |
1520 // | 1563 // |
1521 // Both the dest and source are updated. The caller should then insert a | 1564 // Both the dest and source are updated. The caller should then insert a |
1522 // FakeDef to reflect the second udpate. | 1565 // FakeDef to reflect the second udpate. |
1523 class InstX8632Xadd : public InstX8632Lockable { | 1566 class InstX8632Xadd : public InstX8632Lockable { |
| 1567 InstX8632Xadd() = delete; |
1524 InstX8632Xadd(const InstX8632Xadd &) = delete; | 1568 InstX8632Xadd(const InstX8632Xadd &) = delete; |
1525 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete; | 1569 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete; |
1526 | 1570 |
1527 public: | 1571 public: |
1528 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, | 1572 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, |
1529 bool Locked) { | 1573 bool Locked) { |
1530 return new (Func->allocate<InstX8632Xadd>()) | 1574 return new (Func->allocate<InstX8632Xadd>()) |
1531 InstX8632Xadd(Func, Dest, Source, Locked); | 1575 InstX8632Xadd(Func, Dest, Source, Locked); |
1532 } | 1576 } |
1533 void emit(const Cfg *Func) const override; | 1577 void emit(const Cfg *Func) const override; |
1534 void emitIAS(const Cfg *Func) const override; | 1578 void emitIAS(const Cfg *Func) const override; |
1535 void dump(const Cfg *Func) const override; | 1579 void dump(const Cfg *Func) const override; |
1536 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } | 1580 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } |
1537 | 1581 |
1538 private: | 1582 private: |
1539 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); | 1583 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); |
1540 ~InstX8632Xadd() override {} | 1584 ~InstX8632Xadd() override {} |
1541 }; | 1585 }; |
1542 | 1586 |
1543 // Exchange instruction. Exchanges the first operand (destination | 1587 // Exchange instruction. Exchanges the first operand (destination |
1544 // operand) with the second operand (source operand). At least one of | 1588 // operand) with the second operand (source operand). At least one of |
1545 // the operands must be a register (and the other can be reg or mem). | 1589 // the operands must be a register (and the other can be reg or mem). |
1546 // Both the Dest and Source are updated. If there is a memory operand, | 1590 // Both the Dest and Source are updated. If there is a memory operand, |
1547 // then the instruction is automatically "locked" without the need for | 1591 // then the instruction is automatically "locked" without the need for |
1548 // a lock prefix. | 1592 // a lock prefix. |
1549 class InstX8632Xchg : public InstX8632 { | 1593 class InstX8632Xchg : public InstX8632 { |
| 1594 InstX8632Xchg() = delete; |
1550 InstX8632Xchg(const InstX8632Xchg &) = delete; | 1595 InstX8632Xchg(const InstX8632Xchg &) = delete; |
1551 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete; | 1596 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete; |
1552 | 1597 |
1553 public: | 1598 public: |
1554 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { | 1599 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { |
1555 return new (Func->allocate<InstX8632Xchg>()) | 1600 return new (Func->allocate<InstX8632Xchg>()) |
1556 InstX8632Xchg(Func, Dest, Source); | 1601 InstX8632Xchg(Func, Dest, Source); |
1557 } | 1602 } |
1558 void emit(const Cfg *Func) const override; | 1603 void emit(const Cfg *Func) const override; |
1559 void emitIAS(const Cfg *Func) const override; | 1604 void emitIAS(const Cfg *Func) const override; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; | 1649 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; |
1605 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; | 1650 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; |
1606 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; | 1651 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; |
1607 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; | 1652 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; |
1608 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; | 1653 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; |
1609 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; | 1654 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; |
1610 | 1655 |
1611 } // end of namespace Ice | 1656 } // end of namespace Ice |
1612 | 1657 |
1613 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1658 #endif // SUBZERO_SRC_ICEINSTX8632_H |
OLD | NEW |