| 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 |