| 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 18 matching lines...) Expand all Loading... |
| 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 public: | 33 public: |
| 34 enum OperandKindX8632 { | 34 enum OperandKindX8632 { |
| 35 k__Start = Operand::kTarget, | 35 k__Start = Operand::kTarget, |
| 36 kMem, | 36 kMem, |
| 37 kSplit | 37 kSplit |
| 38 }; | 38 }; |
| 39 virtual void emit(const Cfg *Func) const = 0; | 39 void emit(const Cfg *Func) const override = 0; |
| 40 using Operand::dump; | 40 using Operand::dump; |
| 41 virtual void dump(const Cfg *, Ostream &Str) const { | 41 void dump(const Cfg *, Ostream &Str) const override { |
| 42 Str << "<OperandX8632>"; | 42 Str << "<OperandX8632>"; |
| 43 } | 43 } |
| 44 | 44 |
| 45 protected: | 45 protected: |
| 46 OperandX8632(OperandKindX8632 Kind, Type Ty) | 46 OperandX8632(OperandKindX8632 Kind, Type Ty) |
| 47 : Operand(static_cast<OperandKind>(Kind), Ty) {} | 47 : Operand(static_cast<OperandKind>(Kind), Ty) {} |
| 48 virtual ~OperandX8632() {} | 48 ~OperandX8632() override {} |
| 49 | 49 |
| 50 private: | 50 private: |
| 51 OperandX8632(const OperandX8632 &) LLVM_DELETED_FUNCTION; | 51 OperandX8632(const OperandX8632 &) LLVM_DELETED_FUNCTION; |
| 52 OperandX8632 &operator=(const OperandX8632 &) LLVM_DELETED_FUNCTION; | 52 OperandX8632 &operator=(const OperandX8632 &) LLVM_DELETED_FUNCTION; |
| 53 }; | 53 }; |
| 54 | 54 |
| 55 // OperandX8632Mem represents the m32 addressing mode, with optional | 55 // OperandX8632Mem represents the m32 addressing mode, with optional |
| 56 // base and index registers, a constant offset, and a fixed shift | 56 // base and index registers, a constant offset, and a fixed shift |
| 57 // value for the index register. | 57 // value for the index register. |
| 58 class OperandX8632Mem : public OperandX8632 { | 58 class OperandX8632Mem : public OperandX8632 { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 70 SegmentRegisters SegmentReg = DefaultSegment) { | 70 SegmentRegisters SegmentReg = DefaultSegment) { |
| 71 return new (Func->allocate<OperandX8632Mem>()) | 71 return new (Func->allocate<OperandX8632Mem>()) |
| 72 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); | 72 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); |
| 73 } | 73 } |
| 74 Variable *getBase() const { return Base; } | 74 Variable *getBase() const { return Base; } |
| 75 Constant *getOffset() const { return Offset; } | 75 Constant *getOffset() const { return Offset; } |
| 76 Variable *getIndex() const { return Index; } | 76 Variable *getIndex() const { return Index; } |
| 77 uint16_t getShift() const { return Shift; } | 77 uint16_t getShift() const { return Shift; } |
| 78 SegmentRegisters getSegmentRegister() const { return SegmentReg; } | 78 SegmentRegisters getSegmentRegister() const { return SegmentReg; } |
| 79 x86::Address toAsmAddress(Assembler *Asm) const; | 79 x86::Address toAsmAddress(Assembler *Asm) const; |
| 80 virtual void emit(const Cfg *Func) const; | 80 void emit(const Cfg *Func) const override; |
| 81 using OperandX8632::dump; | 81 using OperandX8632::dump; |
| 82 virtual void dump(const Cfg *Func, Ostream &Str) const; | 82 void dump(const Cfg *Func, Ostream &Str) const override; |
| 83 | 83 |
| 84 static bool classof(const Operand *Operand) { | 84 static bool classof(const Operand *Operand) { |
| 85 return Operand->getKind() == static_cast<OperandKind>(kMem); | 85 return Operand->getKind() == static_cast<OperandKind>(kMem); |
| 86 } | 86 } |
| 87 | 87 |
| 88 private: | 88 private: |
| 89 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, | 89 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, |
| 90 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg); | 90 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg); |
| 91 OperandX8632Mem(const OperandX8632Mem &) LLVM_DELETED_FUNCTION; | 91 OperandX8632Mem(const OperandX8632Mem &) LLVM_DELETED_FUNCTION; |
| 92 OperandX8632Mem &operator=(const OperandX8632Mem &) LLVM_DELETED_FUNCTION; | 92 OperandX8632Mem &operator=(const OperandX8632Mem &) LLVM_DELETED_FUNCTION; |
| 93 virtual ~OperandX8632Mem() {} | 93 ~OperandX8632Mem() override {} |
| 94 Variable *Base; | 94 Variable *Base; |
| 95 Constant *Offset; | 95 Constant *Offset; |
| 96 Variable *Index; | 96 Variable *Index; |
| 97 uint16_t Shift; | 97 uint16_t Shift; |
| 98 SegmentRegisters SegmentReg : 16; | 98 SegmentRegisters SegmentReg : 16; |
| 99 }; | 99 }; |
| 100 | 100 |
| 101 // VariableSplit is a way to treat an f64 memory location as a pair | 101 // VariableSplit is a way to treat an f64 memory location as a pair |
| 102 // of i32 locations (Low and High). This is needed for some cases | 102 // of i32 locations (Low and High). This is needed for some cases |
| 103 // of the Bitcast instruction. Since it's not possible for integer | 103 // of the Bitcast instruction. Since it's not possible for integer |
| 104 // registers to access the XMM registers and vice versa, the | 104 // registers to access the XMM registers and vice versa, the |
| 105 // lowering forces the f64 to be spilled to the stack and then | 105 // lowering forces the f64 to be spilled to the stack and then |
| 106 // accesses through the VariableSplit. | 106 // accesses through the VariableSplit. |
| 107 class VariableSplit : public OperandX8632 { | 107 class VariableSplit : public OperandX8632 { |
| 108 public: | 108 public: |
| 109 enum Portion { | 109 enum Portion { |
| 110 Low, | 110 Low, |
| 111 High | 111 High |
| 112 }; | 112 }; |
| 113 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { | 113 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { |
| 114 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); | 114 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); |
| 115 } | 115 } |
| 116 virtual void emit(const Cfg *Func) const; | 116 void emit(const Cfg *Func) const override; |
| 117 using OperandX8632::dump; | 117 using OperandX8632::dump; |
| 118 virtual void dump(const Cfg *Func, Ostream &Str) const; | 118 void dump(const Cfg *Func, Ostream &Str) const override; |
| 119 | 119 |
| 120 static bool classof(const Operand *Operand) { | 120 static bool classof(const Operand *Operand) { |
| 121 return Operand->getKind() == static_cast<OperandKind>(kSplit); | 121 return Operand->getKind() == static_cast<OperandKind>(kSplit); |
| 122 } | 122 } |
| 123 | 123 |
| 124 private: | 124 private: |
| 125 VariableSplit(Cfg *Func, Variable *Var, Portion Part) | 125 VariableSplit(Cfg *Func, Variable *Var, Portion Part) |
| 126 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) { | 126 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) { |
| 127 assert(Var->getType() == IceType_f64); | 127 assert(Var->getType() == IceType_f64); |
| 128 Vars = Func->allocateArrayOf<Variable *>(1); | 128 Vars = Func->allocateArrayOf<Variable *>(1); |
| 129 Vars[0] = Var; | 129 Vars[0] = Var; |
| 130 NumVars = 1; | 130 NumVars = 1; |
| 131 } | 131 } |
| 132 VariableSplit(const VariableSplit &) LLVM_DELETED_FUNCTION; | 132 VariableSplit(const VariableSplit &) LLVM_DELETED_FUNCTION; |
| 133 VariableSplit &operator=(const VariableSplit &) LLVM_DELETED_FUNCTION; | 133 VariableSplit &operator=(const VariableSplit &) LLVM_DELETED_FUNCTION; |
| 134 virtual ~VariableSplit() { Func->deallocateArrayOf<Variable *>(Vars); } | 134 ~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); } |
| 135 Cfg *Func; // Held only for the destructor. | 135 Cfg *Func; // Held only for the destructor. |
| 136 Variable *Var; | 136 Variable *Var; |
| 137 Portion Part; | 137 Portion Part; |
| 138 }; | 138 }; |
| 139 | 139 |
| 140 // SpillVariable decorates a Variable by linking it to another | 140 // SpillVariable decorates a Variable by linking it to another |
| 141 // Variable. When stack frame offsets are computed, the SpillVariable | 141 // Variable. When stack frame offsets are computed, the SpillVariable |
| 142 // is given a distinct stack slot only if its linked Variable has a | 142 // is given a distinct stack slot only if its linked Variable has a |
| 143 // register. If the linked Variable has a stack slot, then the | 143 // register. If the linked Variable has a stack slot, then the |
| 144 // Variable and SpillVariable share that slot. | 144 // Variable and SpillVariable share that slot. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 Subss, | 246 Subss, |
| 247 Test, | 247 Test, |
| 248 Ucomiss, | 248 Ucomiss, |
| 249 UD2, | 249 UD2, |
| 250 Xadd, | 250 Xadd, |
| 251 Xchg, | 251 Xchg, |
| 252 Xor | 252 Xor |
| 253 }; | 253 }; |
| 254 | 254 |
| 255 static const char *getWidthString(Type Ty); | 255 static const char *getWidthString(Type Ty); |
| 256 virtual void emit(const Cfg *Func) const = 0; | 256 void emit(const Cfg *Func) const override = 0; |
| 257 virtual void dump(const Cfg *Func) const; | 257 void dump(const Cfg *Func) const override; |
| 258 | 258 |
| 259 protected: | 259 protected: |
| 260 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) | 260 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) |
| 261 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} | 261 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} |
| 262 virtual ~InstX8632() {} | 262 ~InstX8632() override {} |
| 263 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) { | 263 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) { |
| 264 return Inst->getKind() == static_cast<InstKind>(MyKind); | 264 return Inst->getKind() == static_cast<InstKind>(MyKind); |
| 265 } | 265 } |
| 266 | 266 |
| 267 private: | 267 private: |
| 268 InstX8632(const InstX8632 &) LLVM_DELETED_FUNCTION; | 268 InstX8632(const InstX8632 &) LLVM_DELETED_FUNCTION; |
| 269 InstX8632 &operator=(const InstX8632 &) LLVM_DELETED_FUNCTION; | 269 InstX8632 &operator=(const InstX8632 &) LLVM_DELETED_FUNCTION; |
| 270 }; | 270 }; |
| 271 | 271 |
| 272 // InstX8632Label represents an intra-block label that is the | 272 // InstX8632Label represents an intra-block label that is the |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 // | 304 // |
| 305 // The down-side is that "mov c, x" can never be dead-code eliminated | 305 // The down-side is that "mov c, x" can never be dead-code eliminated |
| 306 // even if there are no uses of c. As unlikely as this situation is, | 306 // even if there are no uses of c. As unlikely as this situation is, |
| 307 // it may be prevented by running dead code elimination before | 307 // it may be prevented by running dead code elimination before |
| 308 // lowering. | 308 // lowering. |
| 309 class InstX8632Label : public InstX8632 { | 309 class InstX8632Label : public InstX8632 { |
| 310 public: | 310 public: |
| 311 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) { | 311 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) { |
| 312 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target); | 312 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target); |
| 313 } | 313 } |
| 314 virtual uint32_t getEmitInstCount() const { return 0; } | 314 uint32_t getEmitInstCount() const override { return 0; } |
| 315 IceString getName(const Cfg *Func) const; | 315 IceString getName(const Cfg *Func) const; |
| 316 virtual void emit(const Cfg *Func) const; | 316 void emit(const Cfg *Func) const override; |
| 317 virtual void dump(const Cfg *Func) const; | 317 void dump(const Cfg *Func) const override; |
| 318 | 318 |
| 319 private: | 319 private: |
| 320 InstX8632Label(Cfg *Func, TargetX8632 *Target); | 320 InstX8632Label(Cfg *Func, TargetX8632 *Target); |
| 321 InstX8632Label(const InstX8632Label &) LLVM_DELETED_FUNCTION; | 321 InstX8632Label(const InstX8632Label &) LLVM_DELETED_FUNCTION; |
| 322 InstX8632Label &operator=(const InstX8632Label &) LLVM_DELETED_FUNCTION; | 322 InstX8632Label &operator=(const InstX8632Label &) LLVM_DELETED_FUNCTION; |
| 323 virtual ~InstX8632Label() {} | 323 ~InstX8632Label() override {} |
| 324 SizeT Number; // used only for unique label string generation | 324 SizeT Number; // used only for unique label string generation |
| 325 }; | 325 }; |
| 326 | 326 |
| 327 // Conditional and unconditional branch instruction. | 327 // Conditional and unconditional branch instruction. |
| 328 class InstX8632Br : public InstX8632 { | 328 class InstX8632Br : public InstX8632 { |
| 329 public: | 329 public: |
| 330 // Create a conditional branch to a node. | 330 // Create a conditional branch to a node. |
| 331 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, | 331 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, |
| 332 CfgNode *TargetFalse, CondX86::BrCond Condition) { | 332 CfgNode *TargetFalse, CondX86::BrCond Condition) { |
| 333 const InstX8632Label *NoLabel = NULL; | 333 const InstX8632Label *NoLabel = NULL; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 356 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label, | 356 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label, |
| 357 CondX86::BrCond Condition) { | 357 CondX86::BrCond Condition) { |
| 358 const CfgNode *NoCondTarget = NULL; | 358 const CfgNode *NoCondTarget = NULL; |
| 359 const CfgNode *NoUncondTarget = NULL; | 359 const CfgNode *NoUncondTarget = NULL; |
| 360 return new (Func->allocate<InstX8632Br>()) | 360 return new (Func->allocate<InstX8632Br>()) |
| 361 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition); | 361 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition); |
| 362 } | 362 } |
| 363 const CfgNode *getTargetTrue() const { return TargetTrue; } | 363 const CfgNode *getTargetTrue() const { return TargetTrue; } |
| 364 const CfgNode *getTargetFalse() const { return TargetFalse; } | 364 const CfgNode *getTargetFalse() const { return TargetFalse; } |
| 365 bool optimizeBranch(const CfgNode *NextNode); | 365 bool optimizeBranch(const CfgNode *NextNode); |
| 366 virtual uint32_t getEmitInstCount() const { | 366 uint32_t getEmitInstCount() const override { |
| 367 uint32_t Sum = 0; | 367 uint32_t Sum = 0; |
| 368 if (Label) | 368 if (Label) |
| 369 ++Sum; | 369 ++Sum; |
| 370 if (getTargetTrue()) | 370 if (getTargetTrue()) |
| 371 ++Sum; | 371 ++Sum; |
| 372 if (getTargetFalse()) | 372 if (getTargetFalse()) |
| 373 ++Sum; | 373 ++Sum; |
| 374 return Sum; | 374 return Sum; |
| 375 } | 375 } |
| 376 virtual void emit(const Cfg *Func) const; | 376 void emit(const Cfg *Func) const override; |
| 377 virtual void dump(const Cfg *Func) const; | 377 void dump(const Cfg *Func) const override; |
| 378 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } | 378 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } |
| 379 | 379 |
| 380 private: | 380 private: |
| 381 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, | 381 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, |
| 382 const InstX8632Label *Label, CondX86::BrCond Condition); | 382 const InstX8632Label *Label, CondX86::BrCond Condition); |
| 383 InstX8632Br(const InstX8632Br &) LLVM_DELETED_FUNCTION; | 383 InstX8632Br(const InstX8632Br &) LLVM_DELETED_FUNCTION; |
| 384 InstX8632Br &operator=(const InstX8632Br &) LLVM_DELETED_FUNCTION; | 384 InstX8632Br &operator=(const InstX8632Br &) LLVM_DELETED_FUNCTION; |
| 385 virtual ~InstX8632Br() {} | 385 ~InstX8632Br() override {} |
| 386 CondX86::BrCond Condition; | 386 CondX86::BrCond Condition; |
| 387 const CfgNode *TargetTrue; | 387 const CfgNode *TargetTrue; |
| 388 const CfgNode *TargetFalse; | 388 const CfgNode *TargetFalse; |
| 389 const InstX8632Label *Label; // Intra-block branch target | 389 const InstX8632Label *Label; // Intra-block branch target |
| 390 }; | 390 }; |
| 391 | 391 |
| 392 // AdjustStack instruction - subtracts esp by the given amount and | 392 // AdjustStack instruction - subtracts esp by the given amount and |
| 393 // updates the stack offset during code emission. | 393 // updates the stack offset during code emission. |
| 394 class InstX8632AdjustStack : public InstX8632 { | 394 class InstX8632AdjustStack : public InstX8632 { |
| 395 public: | 395 public: |
| 396 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) { | 396 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) { |
| 397 return new (Func->allocate<InstX8632AdjustStack>()) | 397 return new (Func->allocate<InstX8632AdjustStack>()) |
| 398 InstX8632AdjustStack(Func, Amount, Esp); | 398 InstX8632AdjustStack(Func, Amount, Esp); |
| 399 } | 399 } |
| 400 virtual void emit(const Cfg *Func) const; | 400 void emit(const Cfg *Func) const override; |
| 401 virtual void emitIAS(const Cfg *Func) const; | 401 void emitIAS(const Cfg *Func) const override; |
| 402 virtual void dump(const Cfg *Func) const; | 402 void dump(const Cfg *Func) const override; |
| 403 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); } | 403 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); } |
| 404 | 404 |
| 405 private: | 405 private: |
| 406 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp); | 406 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp); |
| 407 InstX8632AdjustStack(const InstX8632AdjustStack &) LLVM_DELETED_FUNCTION; | 407 InstX8632AdjustStack(const InstX8632AdjustStack &) LLVM_DELETED_FUNCTION; |
| 408 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) | 408 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) |
| 409 LLVM_DELETED_FUNCTION; | 409 LLVM_DELETED_FUNCTION; |
| 410 SizeT Amount; | 410 SizeT Amount; |
| 411 }; | 411 }; |
| 412 | 412 |
| 413 // Call instruction. Arguments should have already been pushed. | 413 // Call instruction. Arguments should have already been pushed. |
| 414 class InstX8632Call : public InstX8632 { | 414 class InstX8632Call : public InstX8632 { |
| 415 public: | 415 public: |
| 416 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { | 416 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { |
| 417 return new (Func->allocate<InstX8632Call>()) | 417 return new (Func->allocate<InstX8632Call>()) |
| 418 InstX8632Call(Func, Dest, CallTarget); | 418 InstX8632Call(Func, Dest, CallTarget); |
| 419 } | 419 } |
| 420 Operand *getCallTarget() const { return getSrc(0); } | 420 Operand *getCallTarget() const { return getSrc(0); } |
| 421 virtual void emit(const Cfg *Func) const; | 421 void emit(const Cfg *Func) const override; |
| 422 virtual void dump(const Cfg *Func) const; | 422 void dump(const Cfg *Func) const override; |
| 423 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 423 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
| 424 | 424 |
| 425 private: | 425 private: |
| 426 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 426 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| 427 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 427 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
| 428 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 428 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
| 429 virtual ~InstX8632Call() {} | 429 ~InstX8632Call() override {} |
| 430 }; | 430 }; |
| 431 | 431 |
| 432 // Emit a one-operand (GPR) instruction. | 432 // Emit a one-operand (GPR) instruction. |
| 433 void emitIASVarTyGPR(const Cfg *Func, Type Ty, const Variable *Var, | 433 void emitIASVarTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
| 434 const x86::AssemblerX86::GPREmitterOneOp &Emitter); | 434 const x86::AssemblerX86::GPREmitterOneOp &Emitter); |
| 435 | 435 |
| 436 // Instructions of the form x := op(x). | 436 // Instructions of the form x := op(x). |
| 437 template <InstX8632::InstKindX8632 K> | 437 template <InstX8632::InstKindX8632 K> |
| 438 class InstX8632InplaceopGPR : public InstX8632 { | 438 class InstX8632InplaceopGPR : public InstX8632 { |
| 439 public: | 439 public: |
| 440 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { | 440 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { |
| 441 return new (Func->allocate<InstX8632InplaceopGPR>()) | 441 return new (Func->allocate<InstX8632InplaceopGPR>()) |
| 442 InstX8632InplaceopGPR(Func, SrcDest); | 442 InstX8632InplaceopGPR(Func, SrcDest); |
| 443 } | 443 } |
| 444 virtual void emit(const Cfg *Func) const { | 444 void emit(const Cfg *Func) const override { |
| 445 Ostream &Str = Func->getContext()->getStrEmit(); | 445 Ostream &Str = Func->getContext()->getStrEmit(); |
| 446 assert(getSrcSize() == 1); | 446 assert(getSrcSize() == 1); |
| 447 Str << "\t" << Opcode << "\t"; | 447 Str << "\t" << Opcode << "\t"; |
| 448 getSrc(0)->emit(Func); | 448 getSrc(0)->emit(Func); |
| 449 Str << "\n"; | 449 Str << "\n"; |
| 450 } | 450 } |
| 451 virtual void emitIAS(const Cfg *Func) const { | 451 void emitIAS(const Cfg *Func) const override { |
| 452 assert(getSrcSize() == 1); | 452 assert(getSrcSize() == 1); |
| 453 const Variable *Var = getDest(); | 453 const Variable *Var = getDest(); |
| 454 Type Ty = Var->getType(); | 454 Type Ty = Var->getType(); |
| 455 emitIASVarTyGPR(Func, Ty, Var, Emitter); | 455 emitIASVarTyGPR(Func, Ty, Var, Emitter); |
| 456 } | 456 } |
| 457 virtual void dump(const Cfg *Func) const { | 457 void dump(const Cfg *Func) const override { |
| 458 Ostream &Str = Func->getContext()->getStrDump(); | 458 Ostream &Str = Func->getContext()->getStrDump(); |
| 459 dumpDest(Func); | 459 dumpDest(Func); |
| 460 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 460 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 461 dumpSources(Func); | 461 dumpSources(Func); |
| 462 } | 462 } |
| 463 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 463 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 464 | 464 |
| 465 private: | 465 private: |
| 466 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) | 466 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) |
| 467 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { | 467 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { |
| 468 addSource(SrcDest); | 468 addSource(SrcDest); |
| 469 } | 469 } |
| 470 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) LLVM_DELETED_FUNCTION; | 470 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) LLVM_DELETED_FUNCTION; |
| 471 InstX8632InplaceopGPR & | 471 InstX8632InplaceopGPR & |
| 472 operator=(const InstX8632InplaceopGPR &) LLVM_DELETED_FUNCTION; | 472 operator=(const InstX8632InplaceopGPR &) LLVM_DELETED_FUNCTION; |
| 473 virtual ~InstX8632InplaceopGPR() {} | 473 ~InstX8632InplaceopGPR() override {} |
| 474 static const char *Opcode; | 474 static const char *Opcode; |
| 475 static const x86::AssemblerX86::GPREmitterOneOp Emitter; | 475 static const x86::AssemblerX86::GPREmitterOneOp Emitter; |
| 476 }; | 476 }; |
| 477 | 477 |
| 478 // Emit a two-operand (GPR) instruction, where the dest operand is a | 478 // Emit a two-operand (GPR) instruction, where the dest operand is a |
| 479 // Variable that's guaranteed to be a register. | 479 // Variable that's guaranteed to be a register. |
| 480 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, | 480 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, |
| 481 const Operand *Src, | 481 const Operand *Src, |
| 482 const x86::AssemblerX86::GPREmitterRegOp &Emitter); | 482 const x86::AssemblerX86::GPREmitterRegOp &Emitter); |
| 483 | 483 |
| 484 // Instructions of the form x := op(y) | 484 // Instructions of the form x := op(y) |
| 485 template <InstX8632::InstKindX8632 K> | 485 template <InstX8632::InstKindX8632 K> |
| 486 class InstX8632UnaryopGPR : public InstX8632 { | 486 class InstX8632UnaryopGPR : public InstX8632 { |
| 487 public: | 487 public: |
| 488 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { | 488 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { |
| 489 return new (Func->allocate<InstX8632UnaryopGPR>()) | 489 return new (Func->allocate<InstX8632UnaryopGPR>()) |
| 490 InstX8632UnaryopGPR(Func, Dest, Src); | 490 InstX8632UnaryopGPR(Func, Dest, Src); |
| 491 } | 491 } |
| 492 virtual void emit(const Cfg *Func) const { | 492 void emit(const Cfg *Func) const override { |
| 493 Ostream &Str = Func->getContext()->getStrEmit(); | 493 Ostream &Str = Func->getContext()->getStrEmit(); |
| 494 assert(getSrcSize() == 1); | 494 assert(getSrcSize() == 1); |
| 495 Str << "\t" << Opcode << "\t"; | 495 Str << "\t" << Opcode << "\t"; |
| 496 getDest()->emit(Func); | 496 getDest()->emit(Func); |
| 497 Str << ", "; | 497 Str << ", "; |
| 498 getSrc(0)->emit(Func); | 498 getSrc(0)->emit(Func); |
| 499 Str << "\n"; | 499 Str << "\n"; |
| 500 } | 500 } |
| 501 virtual void emitIAS(const Cfg *Func) const { | 501 void emitIAS(const Cfg *Func) const override { |
| 502 assert(getSrcSize() == 1); | 502 assert(getSrcSize() == 1); |
| 503 const Variable *Var = getDest(); | 503 const Variable *Var = getDest(); |
| 504 Type Ty = Var->getType(); | 504 Type Ty = Var->getType(); |
| 505 const Operand *Src = getSrc(0); | 505 const Operand *Src = getSrc(0); |
| 506 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); | 506 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); |
| 507 } | 507 } |
| 508 virtual void dump(const Cfg *Func) const { | 508 void dump(const Cfg *Func) const override { |
| 509 Ostream &Str = Func->getContext()->getStrDump(); | 509 Ostream &Str = Func->getContext()->getStrDump(); |
| 510 dumpDest(Func); | 510 dumpDest(Func); |
| 511 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 511 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 512 dumpSources(Func); | 512 dumpSources(Func); |
| 513 } | 513 } |
| 514 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 514 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 515 | 515 |
| 516 private: | 516 private: |
| 517 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) | 517 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) |
| 518 : InstX8632(Func, K, 1, Dest) { | 518 : InstX8632(Func, K, 1, Dest) { |
| 519 addSource(Src); | 519 addSource(Src); |
| 520 } | 520 } |
| 521 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) LLVM_DELETED_FUNCTION; | 521 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) LLVM_DELETED_FUNCTION; |
| 522 InstX8632UnaryopGPR & | 522 InstX8632UnaryopGPR & |
| 523 operator=(const InstX8632UnaryopGPR &) LLVM_DELETED_FUNCTION; | 523 operator=(const InstX8632UnaryopGPR &) LLVM_DELETED_FUNCTION; |
| 524 virtual ~InstX8632UnaryopGPR() {} | 524 ~InstX8632UnaryopGPR() override {} |
| 525 static const char *Opcode; | 525 static const char *Opcode; |
| 526 static const x86::AssemblerX86::GPREmitterRegOp Emitter; | 526 static const x86::AssemblerX86::GPREmitterRegOp Emitter; |
| 527 }; | 527 }; |
| 528 | 528 |
| 529 void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 529 void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
| 530 const Operand *Src, | 530 const Operand *Src, |
| 531 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter); | 531 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter); |
| 532 | 532 |
| 533 template <InstX8632::InstKindX8632 K> | 533 template <InstX8632::InstKindX8632 K> |
| 534 class InstX8632UnaryopXmm : public InstX8632 { | 534 class InstX8632UnaryopXmm : public InstX8632 { |
| 535 public: | 535 public: |
| 536 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { | 536 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { |
| 537 return new (Func->allocate<InstX8632UnaryopXmm>()) | 537 return new (Func->allocate<InstX8632UnaryopXmm>()) |
| 538 InstX8632UnaryopXmm(Func, Dest, Src); | 538 InstX8632UnaryopXmm(Func, Dest, Src); |
| 539 } | 539 } |
| 540 virtual void emit(const Cfg *Func) const { | 540 void emit(const Cfg *Func) const override { |
| 541 Ostream &Str = Func->getContext()->getStrEmit(); | 541 Ostream &Str = Func->getContext()->getStrEmit(); |
| 542 assert(getSrcSize() == 1); | 542 assert(getSrcSize() == 1); |
| 543 Str << "\t" << Opcode << "\t"; | 543 Str << "\t" << Opcode << "\t"; |
| 544 getDest()->emit(Func); | 544 getDest()->emit(Func); |
| 545 Str << ", "; | 545 Str << ", "; |
| 546 getSrc(0)->emit(Func); | 546 getSrc(0)->emit(Func); |
| 547 Str << "\n"; | 547 Str << "\n"; |
| 548 } | 548 } |
| 549 virtual void emitIAS(const Cfg *Func) const { | 549 void emitIAS(const Cfg *Func) const override { |
| 550 Type Ty = getDest()->getType(); | 550 Type Ty = getDest()->getType(); |
| 551 assert(getSrcSize() == 1); | 551 assert(getSrcSize() == 1); |
| 552 emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(0), Emitter); | 552 emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(0), Emitter); |
| 553 } | 553 } |
| 554 virtual void dump(const Cfg *Func) const { | 554 void dump(const Cfg *Func) const override { |
| 555 Ostream &Str = Func->getContext()->getStrDump(); | 555 Ostream &Str = Func->getContext()->getStrDump(); |
| 556 dumpDest(Func); | 556 dumpDest(Func); |
| 557 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 557 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 558 dumpSources(Func); | 558 dumpSources(Func); |
| 559 } | 559 } |
| 560 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 560 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 561 | 561 |
| 562 private: | 562 private: |
| 563 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) | 563 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) |
| 564 : InstX8632(Func, K, 1, Dest) { | 564 : InstX8632(Func, K, 1, Dest) { |
| 565 addSource(Src); | 565 addSource(Src); |
| 566 } | 566 } |
| 567 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; | 567 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; |
| 568 InstX8632UnaryopXmm & | 568 InstX8632UnaryopXmm & |
| 569 operator=(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; | 569 operator=(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; |
| 570 virtual ~InstX8632UnaryopXmm() {} | 570 ~InstX8632UnaryopXmm() override {} |
| 571 static const char *Opcode; | 571 static const char *Opcode; |
| 572 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; | 572 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
| 573 }; | 573 }; |
| 574 | 574 |
| 575 // See the definition of emitTwoAddress() for a description of | 575 // See the definition of emitTwoAddress() for a description of |
| 576 // ShiftHack. | 576 // ShiftHack. |
| 577 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, | 577 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
| 578 bool ShiftHack = false); | 578 bool ShiftHack = false); |
| 579 | 579 |
| 580 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> | 580 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> |
| 581 class InstX8632Binop : public InstX8632 { | 581 class InstX8632Binop : public InstX8632 { |
| 582 public: | 582 public: |
| 583 // Create an ordinary binary-op instruction like add or sub. | 583 // Create an ordinary binary-op instruction like add or sub. |
| 584 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { | 584 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 585 return new (Func->allocate<InstX8632Binop>()) | 585 return new (Func->allocate<InstX8632Binop>()) |
| 586 InstX8632Binop(Func, Dest, Source); | 586 InstX8632Binop(Func, Dest, Source); |
| 587 } | 587 } |
| 588 virtual void emit(const Cfg *Func) const { | 588 void emit(const Cfg *Func) const override { |
| 589 emitTwoAddress(Opcode, this, Func, ShiftHack); | 589 emitTwoAddress(Opcode, this, Func, ShiftHack); |
| 590 } | 590 } |
| 591 virtual void dump(const Cfg *Func) const { | 591 void dump(const Cfg *Func) const override { |
| 592 Ostream &Str = Func->getContext()->getStrDump(); | 592 Ostream &Str = Func->getContext()->getStrDump(); |
| 593 dumpDest(Func); | 593 dumpDest(Func); |
| 594 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 594 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 595 dumpSources(Func); | 595 dumpSources(Func); |
| 596 } | 596 } |
| 597 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 597 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 598 | 598 |
| 599 private: | 599 private: |
| 600 InstX8632Binop(Cfg *Func, Variable *Dest, Operand *Source) | 600 InstX8632Binop(Cfg *Func, Variable *Dest, Operand *Source) |
| 601 : InstX8632(Func, K, 2, Dest) { | 601 : InstX8632(Func, K, 2, Dest) { |
| 602 addSource(Dest); | 602 addSource(Dest); |
| 603 addSource(Source); | 603 addSource(Source); |
| 604 } | 604 } |
| 605 InstX8632Binop(const InstX8632Binop &) LLVM_DELETED_FUNCTION; | 605 InstX8632Binop(const InstX8632Binop &) LLVM_DELETED_FUNCTION; |
| 606 InstX8632Binop &operator=(const InstX8632Binop &) LLVM_DELETED_FUNCTION; | 606 InstX8632Binop &operator=(const InstX8632Binop &) LLVM_DELETED_FUNCTION; |
| 607 virtual ~InstX8632Binop() {} | 607 ~InstX8632Binop() override {} |
| 608 static const char *Opcode; | 608 static const char *Opcode; |
| 609 }; | 609 }; |
| 610 | 610 |
| 611 template <InstX8632::InstKindX8632 K, bool NeedsElementType> | 611 template <InstX8632::InstKindX8632 K, bool NeedsElementType> |
| 612 class InstX8632BinopXmm : public InstX8632 { | 612 class InstX8632BinopXmm : public InstX8632 { |
| 613 public: | 613 public: |
| 614 // Create an XMM binary-op instruction like addss or addps. | 614 // Create an XMM binary-op instruction like addss or addps. |
| 615 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { | 615 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 616 return new (Func->allocate<InstX8632BinopXmm>()) | 616 return new (Func->allocate<InstX8632BinopXmm>()) |
| 617 InstX8632BinopXmm(Func, Dest, Source); | 617 InstX8632BinopXmm(Func, Dest, Source); |
| 618 } | 618 } |
| 619 virtual void emit(const Cfg *Func) const { | 619 void emit(const Cfg *Func) const override { |
| 620 const bool ShiftHack = false; | 620 const bool ShiftHack = false; |
| 621 emitTwoAddress(Opcode, this, Func, ShiftHack); | 621 emitTwoAddress(Opcode, this, Func, ShiftHack); |
| 622 } | 622 } |
| 623 virtual void emitIAS(const Cfg *Func) const { | 623 void emitIAS(const Cfg *Func) const override { |
| 624 Type Ty = getDest()->getType(); | 624 Type Ty = getDest()->getType(); |
| 625 if (NeedsElementType) | 625 if (NeedsElementType) |
| 626 Ty = typeElementType(Ty); | 626 Ty = typeElementType(Ty); |
| 627 assert(getSrcSize() == 2); | 627 assert(getSrcSize() == 2); |
| 628 emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(1), Emitter); | 628 emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(1), Emitter); |
| 629 } | 629 } |
| 630 virtual void dump(const Cfg *Func) const { | 630 void dump(const Cfg *Func) const override { |
| 631 Ostream &Str = Func->getContext()->getStrDump(); | 631 Ostream &Str = Func->getContext()->getStrDump(); |
| 632 dumpDest(Func); | 632 dumpDest(Func); |
| 633 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 633 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 634 dumpSources(Func); | 634 dumpSources(Func); |
| 635 } | 635 } |
| 636 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 636 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 637 | 637 |
| 638 private: | 638 private: |
| 639 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) | 639 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) |
| 640 : InstX8632(Func, K, 2, Dest) { | 640 : InstX8632(Func, K, 2, Dest) { |
| 641 addSource(Dest); | 641 addSource(Dest); |
| 642 addSource(Source); | 642 addSource(Source); |
| 643 } | 643 } |
| 644 InstX8632BinopXmm(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; | 644 InstX8632BinopXmm(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; |
| 645 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; | 645 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; |
| 646 virtual ~InstX8632BinopXmm() {} | 646 ~InstX8632BinopXmm() override {} |
| 647 static const char *Opcode; | 647 static const char *Opcode; |
| 648 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; | 648 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
| 649 }; | 649 }; |
| 650 | 650 |
| 651 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { | 651 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { |
| 652 public: | 652 public: |
| 653 // Create a ternary-op instruction like div or idiv. | 653 // Create a ternary-op instruction like div or idiv. |
| 654 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, | 654 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, |
| 655 Operand *Source2) { | 655 Operand *Source2) { |
| 656 return new (Func->allocate<InstX8632Ternop>()) | 656 return new (Func->allocate<InstX8632Ternop>()) |
| 657 InstX8632Ternop(Func, Dest, Source1, Source2); | 657 InstX8632Ternop(Func, Dest, Source1, Source2); |
| 658 } | 658 } |
| 659 virtual void emit(const Cfg *Func) const { | 659 void emit(const Cfg *Func) const override { |
| 660 Ostream &Str = Func->getContext()->getStrEmit(); | 660 Ostream &Str = Func->getContext()->getStrEmit(); |
| 661 assert(getSrcSize() == 3); | 661 assert(getSrcSize() == 3); |
| 662 Str << "\t" << Opcode << "\t"; | 662 Str << "\t" << Opcode << "\t"; |
| 663 getDest()->emit(Func); | 663 getDest()->emit(Func); |
| 664 Str << ", "; | 664 Str << ", "; |
| 665 getSrc(1)->emit(Func); | 665 getSrc(1)->emit(Func); |
| 666 Str << ", "; | 666 Str << ", "; |
| 667 getSrc(2)->emit(Func); | 667 getSrc(2)->emit(Func); |
| 668 Str << "\n"; | 668 Str << "\n"; |
| 669 } | 669 } |
| 670 virtual void dump(const Cfg *Func) const { | 670 void dump(const Cfg *Func) const override { |
| 671 Ostream &Str = Func->getContext()->getStrDump(); | 671 Ostream &Str = Func->getContext()->getStrDump(); |
| 672 dumpDest(Func); | 672 dumpDest(Func); |
| 673 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 673 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 674 dumpSources(Func); | 674 dumpSources(Func); |
| 675 } | 675 } |
| 676 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 676 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 677 | 677 |
| 678 private: | 678 private: |
| 679 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) | 679 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) |
| 680 : InstX8632(Func, K, 3, Dest) { | 680 : InstX8632(Func, K, 3, Dest) { |
| 681 addSource(Dest); | 681 addSource(Dest); |
| 682 addSource(Source1); | 682 addSource(Source1); |
| 683 addSource(Source2); | 683 addSource(Source2); |
| 684 } | 684 } |
| 685 InstX8632Ternop(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; | 685 InstX8632Ternop(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; |
| 686 InstX8632Ternop &operator=(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; | 686 InstX8632Ternop &operator=(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; |
| 687 virtual ~InstX8632Ternop() {} | 687 ~InstX8632Ternop() override {} |
| 688 static const char *Opcode; | 688 static const char *Opcode; |
| 689 }; | 689 }; |
| 690 | 690 |
| 691 // Instructions of the form x := y op z | 691 // Instructions of the form x := y op z |
| 692 template <InstX8632::InstKindX8632 K> | 692 template <InstX8632::InstKindX8632 K> |
| 693 class InstX8632ThreeAddressop : public InstX8632 { | 693 class InstX8632ThreeAddressop : public InstX8632 { |
| 694 public: | 694 public: |
| 695 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, | 695 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, |
| 696 Operand *Source0, Operand *Source1) { | 696 Operand *Source0, Operand *Source1) { |
| 697 return new (Func->allocate<InstX8632ThreeAddressop>()) | 697 return new (Func->allocate<InstX8632ThreeAddressop>()) |
| 698 InstX8632ThreeAddressop(Func, Dest, Source0, Source1); | 698 InstX8632ThreeAddressop(Func, Dest, Source0, Source1); |
| 699 } | 699 } |
| 700 virtual void emit(const Cfg *Func) const { | 700 void emit(const Cfg *Func) const override { |
| 701 Ostream &Str = Func->getContext()->getStrEmit(); | 701 Ostream &Str = Func->getContext()->getStrEmit(); |
| 702 assert(getSrcSize() == 2); | 702 assert(getSrcSize() == 2); |
| 703 Str << "\t" << Opcode << "\t"; | 703 Str << "\t" << Opcode << "\t"; |
| 704 getDest()->emit(Func); | 704 getDest()->emit(Func); |
| 705 Str << ", "; | 705 Str << ", "; |
| 706 getSrc(0)->emit(Func); | 706 getSrc(0)->emit(Func); |
| 707 Str << ", "; | 707 Str << ", "; |
| 708 getSrc(1)->emit(Func); | 708 getSrc(1)->emit(Func); |
| 709 Str << "\n"; | 709 Str << "\n"; |
| 710 } | 710 } |
| 711 virtual void dump(const Cfg *Func) const { | 711 void dump(const Cfg *Func) const override { |
| 712 Ostream &Str = Func->getContext()->getStrDump(); | 712 Ostream &Str = Func->getContext()->getStrDump(); |
| 713 dumpDest(Func); | 713 dumpDest(Func); |
| 714 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 714 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 715 dumpSources(Func); | 715 dumpSources(Func); |
| 716 } | 716 } |
| 717 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 717 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 718 | 718 |
| 719 private: | 719 private: |
| 720 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, | 720 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, |
| 721 Operand *Source1) | 721 Operand *Source1) |
| 722 : InstX8632(Func, K, 2, Dest) { | 722 : InstX8632(Func, K, 2, Dest) { |
| 723 addSource(Source0); | 723 addSource(Source0); |
| 724 addSource(Source1); | 724 addSource(Source1); |
| 725 } | 725 } |
| 726 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) | 726 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) |
| 727 LLVM_DELETED_FUNCTION; | 727 LLVM_DELETED_FUNCTION; |
| 728 InstX8632ThreeAddressop & | 728 InstX8632ThreeAddressop & |
| 729 operator=(const InstX8632ThreeAddressop &) LLVM_DELETED_FUNCTION; | 729 operator=(const InstX8632ThreeAddressop &) LLVM_DELETED_FUNCTION; |
| 730 virtual ~InstX8632ThreeAddressop() {} | 730 ~InstX8632ThreeAddressop() override {} |
| 731 static const char *Opcode; | 731 static const char *Opcode; |
| 732 }; | 732 }; |
| 733 | 733 |
| 734 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); | 734 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); |
| 735 | 735 |
| 736 // Base class for assignment instructions | 736 // Base class for assignment instructions |
| 737 template <InstX8632::InstKindX8632 K> | 737 template <InstX8632::InstKindX8632 K> |
| 738 class InstX8632Movlike : public InstX8632 { | 738 class InstX8632Movlike : public InstX8632 { |
| 739 public: | 739 public: |
| 740 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) { | 740 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 741 return new (Func->allocate<InstX8632Movlike>()) | 741 return new (Func->allocate<InstX8632Movlike>()) |
| 742 InstX8632Movlike(Func, Dest, Source); | 742 InstX8632Movlike(Func, Dest, Source); |
| 743 } | 743 } |
| 744 virtual bool isRedundantAssign() const { | 744 bool isRedundantAssign() const override { |
| 745 return checkForRedundantAssign(getDest(), getSrc(0)); | 745 return checkForRedundantAssign(getDest(), getSrc(0)); |
| 746 } | 746 } |
| 747 virtual bool isSimpleAssign() const { return true; } | 747 bool isSimpleAssign() const override { return true; } |
| 748 virtual void emit(const Cfg *Func) const; | 748 void emit(const Cfg *Func) const override; |
| 749 virtual void dump(const Cfg *Func) const { | 749 void dump(const Cfg *Func) const override { |
| 750 Ostream &Str = Func->getContext()->getStrDump(); | 750 Ostream &Str = Func->getContext()->getStrDump(); |
| 751 Str << Opcode << "." << getDest()->getType() << " "; | 751 Str << Opcode << "." << getDest()->getType() << " "; |
| 752 dumpDest(Func); | 752 dumpDest(Func); |
| 753 Str << ", "; | 753 Str << ", "; |
| 754 dumpSources(Func); | 754 dumpSources(Func); |
| 755 } | 755 } |
| 756 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 756 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 757 | 757 |
| 758 private: | 758 private: |
| 759 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source) | 759 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source) |
| 760 : InstX8632(Func, K, 1, Dest) { | 760 : InstX8632(Func, K, 1, Dest) { |
| 761 addSource(Source); | 761 addSource(Source); |
| 762 } | 762 } |
| 763 InstX8632Movlike(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; | 763 InstX8632Movlike(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; |
| 764 InstX8632Movlike &operator=(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; | 764 InstX8632Movlike &operator=(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; |
| 765 virtual ~InstX8632Movlike() {} | 765 ~InstX8632Movlike() override {} |
| 766 | 766 |
| 767 static const char *Opcode; | 767 static const char *Opcode; |
| 768 }; | 768 }; |
| 769 | 769 |
| 770 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap; | 770 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap; |
| 771 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg; | 771 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg; |
| 772 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf; | 772 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf; |
| 773 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr; | 773 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr; |
| 774 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea; | 774 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea; |
| 775 // Cbwdq instruction - wrapper for cbw, cwd, and cdq | 775 // Cbwdq instruction - wrapper for cbw, cwd, and cdq |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 protected: | 837 protected: |
| 838 bool Locked; | 838 bool Locked; |
| 839 | 839 |
| 840 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, | 840 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, |
| 841 Variable *Dest, bool Locked) | 841 Variable *Dest, bool Locked) |
| 842 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { | 842 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { |
| 843 // Assume that such instructions are used for Atomics and be careful | 843 // Assume that such instructions are used for Atomics and be careful |
| 844 // with optimizations. | 844 // with optimizations. |
| 845 HasSideEffects = Locked; | 845 HasSideEffects = Locked; |
| 846 } | 846 } |
| 847 virtual ~InstX8632Lockable() {} | 847 ~InstX8632Lockable() override {} |
| 848 | 848 |
| 849 private: | 849 private: |
| 850 InstX8632Lockable(const InstX8632Lockable &) LLVM_DELETED_FUNCTION; | 850 InstX8632Lockable(const InstX8632Lockable &) LLVM_DELETED_FUNCTION; |
| 851 InstX8632Lockable &operator=(const InstX8632Lockable &) LLVM_DELETED_FUNCTION; | 851 InstX8632Lockable &operator=(const InstX8632Lockable &) LLVM_DELETED_FUNCTION; |
| 852 }; | 852 }; |
| 853 | 853 |
| 854 // Mul instruction - unsigned multiply. | 854 // Mul instruction - unsigned multiply. |
| 855 class InstX8632Mul : public InstX8632 { | 855 class InstX8632Mul : public InstX8632 { |
| 856 public: | 856 public: |
| 857 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, | 857 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, |
| 858 Operand *Source2) { | 858 Operand *Source2) { |
| 859 return new (Func->allocate<InstX8632Mul>()) | 859 return new (Func->allocate<InstX8632Mul>()) |
| 860 InstX8632Mul(Func, Dest, Source1, Source2); | 860 InstX8632Mul(Func, Dest, Source1, Source2); |
| 861 } | 861 } |
| 862 virtual void emit(const Cfg *Func) const; | 862 void emit(const Cfg *Func) const override; |
| 863 virtual void dump(const Cfg *Func) const; | 863 void dump(const Cfg *Func) const override; |
| 864 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); } | 864 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); } |
| 865 | 865 |
| 866 private: | 866 private: |
| 867 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); | 867 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); |
| 868 InstX8632Mul(const InstX8632Mul &) LLVM_DELETED_FUNCTION; | 868 InstX8632Mul(const InstX8632Mul &) LLVM_DELETED_FUNCTION; |
| 869 InstX8632Mul &operator=(const InstX8632Mul &) LLVM_DELETED_FUNCTION; | 869 InstX8632Mul &operator=(const InstX8632Mul &) LLVM_DELETED_FUNCTION; |
| 870 virtual ~InstX8632Mul() {} | 870 ~InstX8632Mul() override {} |
| 871 }; | 871 }; |
| 872 | 872 |
| 873 // Shld instruction - shift across a pair of operands. TODO: Verify | 873 // Shld instruction - shift across a pair of operands. TODO: Verify |
| 874 // that the validator accepts the shld instruction. | 874 // that the validator accepts the shld instruction. |
| 875 class InstX8632Shld : public InstX8632 { | 875 class InstX8632Shld : public InstX8632 { |
| 876 public: | 876 public: |
| 877 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, | 877 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, |
| 878 Variable *Source2) { | 878 Variable *Source2) { |
| 879 return new (Func->allocate<InstX8632Shld>()) | 879 return new (Func->allocate<InstX8632Shld>()) |
| 880 InstX8632Shld(Func, Dest, Source1, Source2); | 880 InstX8632Shld(Func, Dest, Source1, Source2); |
| 881 } | 881 } |
| 882 virtual void emit(const Cfg *Func) const; | 882 void emit(const Cfg *Func) const override; |
| 883 virtual void dump(const Cfg *Func) const; | 883 void dump(const Cfg *Func) const override; |
| 884 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); } | 884 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); } |
| 885 | 885 |
| 886 private: | 886 private: |
| 887 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, | 887 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, |
| 888 Variable *Source2); | 888 Variable *Source2); |
| 889 InstX8632Shld(const InstX8632Shld &) LLVM_DELETED_FUNCTION; | 889 InstX8632Shld(const InstX8632Shld &) LLVM_DELETED_FUNCTION; |
| 890 InstX8632Shld &operator=(const InstX8632Shld &) LLVM_DELETED_FUNCTION; | 890 InstX8632Shld &operator=(const InstX8632Shld &) LLVM_DELETED_FUNCTION; |
| 891 virtual ~InstX8632Shld() {} | 891 ~InstX8632Shld() override {} |
| 892 }; | 892 }; |
| 893 | 893 |
| 894 // Shrd instruction - shift across a pair of operands. TODO: Verify | 894 // Shrd instruction - shift across a pair of operands. TODO: Verify |
| 895 // that the validator accepts the shrd instruction. | 895 // that the validator accepts the shrd instruction. |
| 896 class InstX8632Shrd : public InstX8632 { | 896 class InstX8632Shrd : public InstX8632 { |
| 897 public: | 897 public: |
| 898 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, | 898 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, |
| 899 Variable *Source2) { | 899 Variable *Source2) { |
| 900 return new (Func->allocate<InstX8632Shrd>()) | 900 return new (Func->allocate<InstX8632Shrd>()) |
| 901 InstX8632Shrd(Func, Dest, Source1, Source2); | 901 InstX8632Shrd(Func, Dest, Source1, Source2); |
| 902 } | 902 } |
| 903 virtual void emit(const Cfg *Func) const; | 903 void emit(const Cfg *Func) const override; |
| 904 virtual void dump(const Cfg *Func) const; | 904 void dump(const Cfg *Func) const override; |
| 905 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); } | 905 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); } |
| 906 | 906 |
| 907 private: | 907 private: |
| 908 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, | 908 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, |
| 909 Variable *Source2); | 909 Variable *Source2); |
| 910 InstX8632Shrd(const InstX8632Shrd &) LLVM_DELETED_FUNCTION; | 910 InstX8632Shrd(const InstX8632Shrd &) LLVM_DELETED_FUNCTION; |
| 911 InstX8632Shrd &operator=(const InstX8632Shrd &) LLVM_DELETED_FUNCTION; | 911 InstX8632Shrd &operator=(const InstX8632Shrd &) LLVM_DELETED_FUNCTION; |
| 912 virtual ~InstX8632Shrd() {} | 912 ~InstX8632Shrd() override {} |
| 913 }; | 913 }; |
| 914 | 914 |
| 915 // Conditional move instruction. | 915 // Conditional move instruction. |
| 916 class InstX8632Cmov : public InstX8632 { | 916 class InstX8632Cmov : public InstX8632 { |
| 917 public: | 917 public: |
| 918 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, | 918 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 919 CondX86::BrCond Cond) { | 919 CondX86::BrCond Cond) { |
| 920 return new (Func->allocate<InstX8632Cmov>()) | 920 return new (Func->allocate<InstX8632Cmov>()) |
| 921 InstX8632Cmov(Func, Dest, Source, Cond); | 921 InstX8632Cmov(Func, Dest, Source, Cond); |
| 922 } | 922 } |
| 923 virtual void emit(const Cfg *Func) const; | 923 void emit(const Cfg *Func) const override; |
| 924 virtual void emitIAS(const Cfg *Func) const; | 924 void emitIAS(const Cfg *Func) const override; |
| 925 virtual void dump(const Cfg *Func) const; | 925 void dump(const Cfg *Func) const override; |
| 926 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } | 926 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } |
| 927 | 927 |
| 928 private: | 928 private: |
| 929 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, | 929 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, |
| 930 CondX86::BrCond Cond); | 930 CondX86::BrCond Cond); |
| 931 InstX8632Cmov(const InstX8632Cmov &) LLVM_DELETED_FUNCTION; | 931 InstX8632Cmov(const InstX8632Cmov &) LLVM_DELETED_FUNCTION; |
| 932 InstX8632Cmov &operator=(const InstX8632Cmov &) LLVM_DELETED_FUNCTION; | 932 InstX8632Cmov &operator=(const InstX8632Cmov &) LLVM_DELETED_FUNCTION; |
| 933 virtual ~InstX8632Cmov() {} | 933 ~InstX8632Cmov() override {} |
| 934 | 934 |
| 935 CondX86::BrCond Condition; | 935 CondX86::BrCond Condition; |
| 936 }; | 936 }; |
| 937 | 937 |
| 938 // Cmpps instruction - compare packed singled-precision floating point | 938 // Cmpps instruction - compare packed singled-precision floating point |
| 939 // values | 939 // values |
| 940 class InstX8632Cmpps : public InstX8632 { | 940 class InstX8632Cmpps : public InstX8632 { |
| 941 public: | 941 public: |
| 942 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, | 942 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 943 CondX86::CmppsCond Condition) { | 943 CondX86::CmppsCond Condition) { |
| 944 return new (Func->allocate<InstX8632Cmpps>()) | 944 return new (Func->allocate<InstX8632Cmpps>()) |
| 945 InstX8632Cmpps(Func, Dest, Source, Condition); | 945 InstX8632Cmpps(Func, Dest, Source, Condition); |
| 946 } | 946 } |
| 947 virtual void emit(const Cfg *Func) const; | 947 void emit(const Cfg *Func) const override; |
| 948 virtual void emitIAS(const Cfg *Func) const; | 948 void emitIAS(const Cfg *Func) const override; |
| 949 virtual void dump(const Cfg *Func) const; | 949 void dump(const Cfg *Func) const override; |
| 950 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } | 950 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } |
| 951 | 951 |
| 952 private: | 952 private: |
| 953 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, | 953 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, |
| 954 CondX86::CmppsCond Cond); | 954 CondX86::CmppsCond Cond); |
| 955 InstX8632Cmpps(const InstX8632Cmpps &) LLVM_DELETED_FUNCTION; | 955 InstX8632Cmpps(const InstX8632Cmpps &) LLVM_DELETED_FUNCTION; |
| 956 InstX8632Cmpps &operator=(const InstX8632Cmpps &) LLVM_DELETED_FUNCTION; | 956 InstX8632Cmpps &operator=(const InstX8632Cmpps &) LLVM_DELETED_FUNCTION; |
| 957 virtual ~InstX8632Cmpps() {} | 957 ~InstX8632Cmpps() override {} |
| 958 | 958 |
| 959 CondX86::CmppsCond Condition; | 959 CondX86::CmppsCond Condition; |
| 960 }; | 960 }; |
| 961 | 961 |
| 962 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> | 962 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> |
| 963 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. | 963 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. |
| 964 // If not, ZF is cleared and <dest> is copied to eax (or subregister). | 964 // If not, ZF is cleared and <dest> is copied to eax (or subregister). |
| 965 // <dest> can be a register or memory, while <desired> must be a register. | 965 // <dest> can be a register or memory, while <desired> must be a register. |
| 966 // It is the user's responsiblity to mark eax with a FakeDef. | 966 // It is the user's responsiblity to mark eax with a FakeDef. |
| 967 class InstX8632Cmpxchg : public InstX8632Lockable { | 967 class InstX8632Cmpxchg : public InstX8632Lockable { |
| 968 public: | 968 public: |
| 969 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, | 969 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, |
| 970 Variable *Desired, bool Locked) { | 970 Variable *Desired, bool Locked) { |
| 971 return new (Func->allocate<InstX8632Cmpxchg>()) | 971 return new (Func->allocate<InstX8632Cmpxchg>()) |
| 972 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); | 972 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); |
| 973 } | 973 } |
| 974 virtual void emit(const Cfg *Func) const; | 974 void emit(const Cfg *Func) const override; |
| 975 virtual void emitIAS(const Cfg *Func) const; | 975 void emitIAS(const Cfg *Func) const override; |
| 976 virtual void dump(const Cfg *Func) const; | 976 void dump(const Cfg *Func) const override; |
| 977 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } | 977 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } |
| 978 | 978 |
| 979 private: | 979 private: |
| 980 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, | 980 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, |
| 981 Variable *Desired, bool Locked); | 981 Variable *Desired, bool Locked); |
| 982 InstX8632Cmpxchg(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION; | 982 InstX8632Cmpxchg(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION; |
| 983 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION; | 983 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION; |
| 984 virtual ~InstX8632Cmpxchg() {} | 984 ~InstX8632Cmpxchg() override {} |
| 985 }; | 985 }; |
| 986 | 986 |
| 987 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> | 987 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> |
| 988 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. | 988 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. |
| 989 // If not, ZF is cleared and <m64> is copied to edx:eax. | 989 // If not, ZF is cleared and <m64> is copied to edx:eax. |
| 990 // The caller is responsible for inserting FakeDefs to mark edx | 990 // The caller is responsible for inserting FakeDefs to mark edx |
| 991 // and eax as modified. | 991 // and eax as modified. |
| 992 // <m64> must be a memory operand. | 992 // <m64> must be a memory operand. |
| 993 class InstX8632Cmpxchg8b : public InstX8632Lockable { | 993 class InstX8632Cmpxchg8b : public InstX8632Lockable { |
| 994 public: | 994 public: |
| 995 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest, | 995 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest, |
| 996 Variable *Edx, Variable *Eax, Variable *Ecx, | 996 Variable *Edx, Variable *Eax, Variable *Ecx, |
| 997 Variable *Ebx, bool Locked) { | 997 Variable *Ebx, bool Locked) { |
| 998 return new (Func->allocate<InstX8632Cmpxchg8b>()) | 998 return new (Func->allocate<InstX8632Cmpxchg8b>()) |
| 999 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); | 999 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); |
| 1000 } | 1000 } |
| 1001 virtual void emit(const Cfg *Func) const; | 1001 void emit(const Cfg *Func) const override; |
| 1002 virtual void emitIAS(const Cfg *Func) const; | 1002 void emitIAS(const Cfg *Func) const override; |
| 1003 virtual void dump(const Cfg *Func) const; | 1003 void dump(const Cfg *Func) const override; |
| 1004 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } | 1004 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } |
| 1005 | 1005 |
| 1006 private: | 1006 private: |
| 1007 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx, | 1007 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx, |
| 1008 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); | 1008 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); |
| 1009 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION; | 1009 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION; |
| 1010 InstX8632Cmpxchg8b & | 1010 InstX8632Cmpxchg8b & |
| 1011 operator=(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION; | 1011 operator=(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION; |
| 1012 virtual ~InstX8632Cmpxchg8b() {} | 1012 ~InstX8632Cmpxchg8b() override {} |
| 1013 }; | 1013 }; |
| 1014 | 1014 |
| 1015 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} | 1015 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} |
| 1016 // as appropriate. s=float, d=double, i=int. X and Y are determined | 1016 // as appropriate. s=float, d=double, i=int. X and Y are determined |
| 1017 // from dest/src types. Sign and zero extension on the integer | 1017 // from dest/src types. Sign and zero extension on the integer |
| 1018 // operand needs to be done separately. | 1018 // operand needs to be done separately. |
| 1019 class InstX8632Cvt : public InstX8632 { | 1019 class InstX8632Cvt : public InstX8632 { |
| 1020 public: | 1020 public: |
| 1021 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, | 1021 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 1022 bool Trunc) { | 1022 bool Trunc) { |
| 1023 return new (Func->allocate<InstX8632Cvt>()) | 1023 return new (Func->allocate<InstX8632Cvt>()) |
| 1024 InstX8632Cvt(Func, Dest, Source, Trunc); | 1024 InstX8632Cvt(Func, Dest, Source, Trunc); |
| 1025 } | 1025 } |
| 1026 virtual void emit(const Cfg *Func) const; | 1026 void emit(const Cfg *Func) const override; |
| 1027 virtual void dump(const Cfg *Func) const; | 1027 void dump(const Cfg *Func) const override; |
| 1028 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); } | 1028 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); } |
| 1029 | 1029 |
| 1030 private: | 1030 private: |
| 1031 bool Trunc; | 1031 bool Trunc; |
| 1032 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, bool Trunc); | 1032 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, bool Trunc); |
| 1033 InstX8632Cvt(const InstX8632Cvt &) LLVM_DELETED_FUNCTION; | 1033 InstX8632Cvt(const InstX8632Cvt &) LLVM_DELETED_FUNCTION; |
| 1034 InstX8632Cvt &operator=(const InstX8632Cvt &) LLVM_DELETED_FUNCTION; | 1034 InstX8632Cvt &operator=(const InstX8632Cvt &) LLVM_DELETED_FUNCTION; |
| 1035 virtual ~InstX8632Cvt() {} | 1035 ~InstX8632Cvt() override {} |
| 1036 }; | 1036 }; |
| 1037 | 1037 |
| 1038 // cmp - Integer compare instruction. | 1038 // cmp - Integer compare instruction. |
| 1039 class InstX8632Icmp : public InstX8632 { | 1039 class InstX8632Icmp : public InstX8632 { |
| 1040 public: | 1040 public: |
| 1041 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { | 1041 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { |
| 1042 return new (Func->allocate<InstX8632Icmp>()) | 1042 return new (Func->allocate<InstX8632Icmp>()) |
| 1043 InstX8632Icmp(Func, Src1, Src2); | 1043 InstX8632Icmp(Func, Src1, Src2); |
| 1044 } | 1044 } |
| 1045 virtual void emit(const Cfg *Func) const; | 1045 void emit(const Cfg *Func) const override; |
| 1046 virtual void dump(const Cfg *Func) const; | 1046 void dump(const Cfg *Func) const override; |
| 1047 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } | 1047 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } |
| 1048 | 1048 |
| 1049 private: | 1049 private: |
| 1050 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2); | 1050 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2); |
| 1051 InstX8632Icmp(const InstX8632Icmp &) LLVM_DELETED_FUNCTION; | 1051 InstX8632Icmp(const InstX8632Icmp &) LLVM_DELETED_FUNCTION; |
| 1052 InstX8632Icmp &operator=(const InstX8632Icmp &) LLVM_DELETED_FUNCTION; | 1052 InstX8632Icmp &operator=(const InstX8632Icmp &) LLVM_DELETED_FUNCTION; |
| 1053 virtual ~InstX8632Icmp() {} | 1053 ~InstX8632Icmp() override {} |
| 1054 }; | 1054 }; |
| 1055 | 1055 |
| 1056 // ucomiss/ucomisd - floating-point compare instruction. | 1056 // ucomiss/ucomisd - floating-point compare instruction. |
| 1057 class InstX8632Ucomiss : public InstX8632 { | 1057 class InstX8632Ucomiss : public InstX8632 { |
| 1058 public: | 1058 public: |
| 1059 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { | 1059 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { |
| 1060 return new (Func->allocate<InstX8632Ucomiss>()) | 1060 return new (Func->allocate<InstX8632Ucomiss>()) |
| 1061 InstX8632Ucomiss(Func, Src1, Src2); | 1061 InstX8632Ucomiss(Func, Src1, Src2); |
| 1062 } | 1062 } |
| 1063 virtual void emit(const Cfg *Func) const; | 1063 void emit(const Cfg *Func) const override; |
| 1064 virtual void emitIAS(const Cfg *Func) const; | 1064 void emitIAS(const Cfg *Func) const override; |
| 1065 virtual void dump(const Cfg *Func) const; | 1065 void dump(const Cfg *Func) const override; |
| 1066 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); } | 1066 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); } |
| 1067 | 1067 |
| 1068 private: | 1068 private: |
| 1069 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); | 1069 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); |
| 1070 InstX8632Ucomiss(const InstX8632Ucomiss &) LLVM_DELETED_FUNCTION; | 1070 InstX8632Ucomiss(const InstX8632Ucomiss &) LLVM_DELETED_FUNCTION; |
| 1071 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) LLVM_DELETED_FUNCTION; | 1071 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) LLVM_DELETED_FUNCTION; |
| 1072 virtual ~InstX8632Ucomiss() {} | 1072 ~InstX8632Ucomiss() override {} |
| 1073 }; | 1073 }; |
| 1074 | 1074 |
| 1075 // UD2 instruction. | 1075 // UD2 instruction. |
| 1076 class InstX8632UD2 : public InstX8632 { | 1076 class InstX8632UD2 : public InstX8632 { |
| 1077 public: | 1077 public: |
| 1078 static InstX8632UD2 *create(Cfg *Func) { | 1078 static InstX8632UD2 *create(Cfg *Func) { |
| 1079 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); | 1079 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); |
| 1080 } | 1080 } |
| 1081 virtual void emit(const Cfg *Func) const; | 1081 void emit(const Cfg *Func) const override; |
| 1082 virtual void dump(const Cfg *Func) const; | 1082 void dump(const Cfg *Func) const override; |
| 1083 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } | 1083 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } |
| 1084 | 1084 |
| 1085 private: | 1085 private: |
| 1086 InstX8632UD2(Cfg *Func); | 1086 InstX8632UD2(Cfg *Func); |
| 1087 InstX8632UD2(const InstX8632UD2 &) LLVM_DELETED_FUNCTION; | 1087 InstX8632UD2(const InstX8632UD2 &) LLVM_DELETED_FUNCTION; |
| 1088 InstX8632UD2 &operator=(const InstX8632UD2 &) LLVM_DELETED_FUNCTION; | 1088 InstX8632UD2 &operator=(const InstX8632UD2 &) LLVM_DELETED_FUNCTION; |
| 1089 virtual ~InstX8632UD2() {} | 1089 ~InstX8632UD2() override {} |
| 1090 }; | 1090 }; |
| 1091 | 1091 |
| 1092 // Test instruction. | 1092 // Test instruction. |
| 1093 class InstX8632Test : public InstX8632 { | 1093 class InstX8632Test : public InstX8632 { |
| 1094 public: | 1094 public: |
| 1095 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { | 1095 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { |
| 1096 return new (Func->allocate<InstX8632Test>()) | 1096 return new (Func->allocate<InstX8632Test>()) |
| 1097 InstX8632Test(Func, Source1, Source2); | 1097 InstX8632Test(Func, Source1, Source2); |
| 1098 } | 1098 } |
| 1099 virtual void emit(const Cfg *Func) const; | 1099 void emit(const Cfg *Func) const override; |
| 1100 virtual void dump(const Cfg *Func) const; | 1100 void dump(const Cfg *Func) const override; |
| 1101 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } | 1101 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } |
| 1102 | 1102 |
| 1103 private: | 1103 private: |
| 1104 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2); | 1104 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2); |
| 1105 InstX8632Test(const InstX8632Test &) LLVM_DELETED_FUNCTION; | 1105 InstX8632Test(const InstX8632Test &) LLVM_DELETED_FUNCTION; |
| 1106 InstX8632Test &operator=(const InstX8632Test &) LLVM_DELETED_FUNCTION; | 1106 InstX8632Test &operator=(const InstX8632Test &) LLVM_DELETED_FUNCTION; |
| 1107 virtual ~InstX8632Test() {} | 1107 ~InstX8632Test() override {} |
| 1108 }; | 1108 }; |
| 1109 | 1109 |
| 1110 // Mfence instruction. | 1110 // Mfence instruction. |
| 1111 class InstX8632Mfence : public InstX8632 { | 1111 class InstX8632Mfence : public InstX8632 { |
| 1112 public: | 1112 public: |
| 1113 static InstX8632Mfence *create(Cfg *Func) { | 1113 static InstX8632Mfence *create(Cfg *Func) { |
| 1114 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func); | 1114 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func); |
| 1115 } | 1115 } |
| 1116 virtual void emit(const Cfg *Func) const; | 1116 void emit(const Cfg *Func) const override; |
| 1117 virtual void dump(const Cfg *Func) const; | 1117 void dump(const Cfg *Func) const override; |
| 1118 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); } | 1118 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); } |
| 1119 | 1119 |
| 1120 private: | 1120 private: |
| 1121 InstX8632Mfence(Cfg *Func); | 1121 InstX8632Mfence(Cfg *Func); |
| 1122 InstX8632Mfence(const InstX8632Mfence &) LLVM_DELETED_FUNCTION; | 1122 InstX8632Mfence(const InstX8632Mfence &) LLVM_DELETED_FUNCTION; |
| 1123 InstX8632Mfence &operator=(const InstX8632Mfence &) LLVM_DELETED_FUNCTION; | 1123 InstX8632Mfence &operator=(const InstX8632Mfence &) LLVM_DELETED_FUNCTION; |
| 1124 virtual ~InstX8632Mfence() {} | 1124 ~InstX8632Mfence() override {} |
| 1125 }; | 1125 }; |
| 1126 | 1126 |
| 1127 // This is essentially a "mov" instruction with an OperandX8632Mem | 1127 // This is essentially a "mov" instruction with an OperandX8632Mem |
| 1128 // operand instead of Variable as the destination. It's important | 1128 // operand instead of Variable as the destination. It's important |
| 1129 // for liveness that there is no Dest operand. | 1129 // for liveness that there is no Dest operand. |
| 1130 class InstX8632Store : public InstX8632 { | 1130 class InstX8632Store : public InstX8632 { |
| 1131 public: | 1131 public: |
| 1132 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { | 1132 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { |
| 1133 return new (Func->allocate<InstX8632Store>()) | 1133 return new (Func->allocate<InstX8632Store>()) |
| 1134 InstX8632Store(Func, Value, Mem); | 1134 InstX8632Store(Func, Value, Mem); |
| 1135 } | 1135 } |
| 1136 virtual void emit(const Cfg *Func) const; | 1136 void emit(const Cfg *Func) const override; |
| 1137 virtual void dump(const Cfg *Func) const; | 1137 void dump(const Cfg *Func) const override; |
| 1138 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); } | 1138 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); } |
| 1139 | 1139 |
| 1140 private: | 1140 private: |
| 1141 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem); | 1141 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem); |
| 1142 InstX8632Store(const InstX8632Store &) LLVM_DELETED_FUNCTION; | 1142 InstX8632Store(const InstX8632Store &) LLVM_DELETED_FUNCTION; |
| 1143 InstX8632Store &operator=(const InstX8632Store &) LLVM_DELETED_FUNCTION; | 1143 InstX8632Store &operator=(const InstX8632Store &) LLVM_DELETED_FUNCTION; |
| 1144 virtual ~InstX8632Store() {} | 1144 ~InstX8632Store() override {} |
| 1145 }; | 1145 }; |
| 1146 | 1146 |
| 1147 class InstX8632StoreP : public InstX8632 { | 1147 class InstX8632StoreP : public InstX8632 { |
| 1148 public: | 1148 public: |
| 1149 static InstX8632StoreP *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { | 1149 static InstX8632StoreP *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { |
| 1150 return new (Func->allocate<InstX8632StoreP>()) | 1150 return new (Func->allocate<InstX8632StoreP>()) |
| 1151 InstX8632StoreP(Func, Value, Mem); | 1151 InstX8632StoreP(Func, Value, Mem); |
| 1152 } | 1152 } |
| 1153 virtual void emit(const Cfg *Func) const; | 1153 void emit(const Cfg *Func) const override; |
| 1154 virtual void dump(const Cfg *Func) const; | 1154 void dump(const Cfg *Func) const override; |
| 1155 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); } | 1155 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); } |
| 1156 | 1156 |
| 1157 private: | 1157 private: |
| 1158 InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem); | 1158 InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem); |
| 1159 InstX8632StoreP(const InstX8632StoreP &) LLVM_DELETED_FUNCTION; | 1159 InstX8632StoreP(const InstX8632StoreP &) LLVM_DELETED_FUNCTION; |
| 1160 InstX8632StoreP &operator=(const InstX8632StoreP &) LLVM_DELETED_FUNCTION; | 1160 InstX8632StoreP &operator=(const InstX8632StoreP &) LLVM_DELETED_FUNCTION; |
| 1161 virtual ~InstX8632StoreP() {} | 1161 ~InstX8632StoreP() override {} |
| 1162 }; | 1162 }; |
| 1163 | 1163 |
| 1164 // This is essentially a "movq" instruction with an OperandX8632Mem | 1164 // This is essentially a "movq" instruction with an OperandX8632Mem |
| 1165 // operand instead of Variable as the destination. It's important | 1165 // operand instead of Variable as the destination. It's important |
| 1166 // for liveness that there is no Dest operand. | 1166 // for liveness that there is no Dest operand. |
| 1167 class InstX8632StoreQ : public InstX8632 { | 1167 class InstX8632StoreQ : public InstX8632 { |
| 1168 public: | 1168 public: |
| 1169 static InstX8632StoreQ *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { | 1169 static InstX8632StoreQ *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { |
| 1170 return new (Func->allocate<InstX8632StoreQ>()) | 1170 return new (Func->allocate<InstX8632StoreQ>()) |
| 1171 InstX8632StoreQ(Func, Value, Mem); | 1171 InstX8632StoreQ(Func, Value, Mem); |
| 1172 } | 1172 } |
| 1173 virtual void emit(const Cfg *Func) const; | 1173 void emit(const Cfg *Func) const override; |
| 1174 virtual void dump(const Cfg *Func) const; | 1174 void dump(const Cfg *Func) const override; |
| 1175 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } | 1175 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } |
| 1176 | 1176 |
| 1177 private: | 1177 private: |
| 1178 InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem); | 1178 InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem); |
| 1179 InstX8632StoreQ(const InstX8632StoreQ &) LLVM_DELETED_FUNCTION; | 1179 InstX8632StoreQ(const InstX8632StoreQ &) LLVM_DELETED_FUNCTION; |
| 1180 InstX8632StoreQ &operator=(const InstX8632StoreQ &) LLVM_DELETED_FUNCTION; | 1180 InstX8632StoreQ &operator=(const InstX8632StoreQ &) LLVM_DELETED_FUNCTION; |
| 1181 virtual ~InstX8632StoreQ() {} | 1181 ~InstX8632StoreQ() override {} |
| 1182 }; | 1182 }; |
| 1183 | 1183 |
| 1184 // Movsx - copy from a narrower integer type to a wider integer | 1184 // Movsx - copy from a narrower integer type to a wider integer |
| 1185 // type, with sign extension. | 1185 // type, with sign extension. |
| 1186 class InstX8632Movsx : public InstX8632 { | 1186 class InstX8632Movsx : public InstX8632 { |
| 1187 public: | 1187 public: |
| 1188 static InstX8632Movsx *create(Cfg *Func, Variable *Dest, Operand *Source) { | 1188 static InstX8632Movsx *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 1189 return new (Func->allocate<InstX8632Movsx>()) | 1189 return new (Func->allocate<InstX8632Movsx>()) |
| 1190 InstX8632Movsx(Func, Dest, Source); | 1190 InstX8632Movsx(Func, Dest, Source); |
| 1191 } | 1191 } |
| 1192 virtual void emit(const Cfg *Func) const; | 1192 void emit(const Cfg *Func) const override; |
| 1193 virtual void dump(const Cfg *Func) const; | 1193 void dump(const Cfg *Func) const override; |
| 1194 static bool classof(const Inst *Inst) { return isClassof(Inst, Movsx); } | 1194 static bool classof(const Inst *Inst) { return isClassof(Inst, Movsx); } |
| 1195 | 1195 |
| 1196 private: | 1196 private: |
| 1197 InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source); | 1197 InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source); |
| 1198 InstX8632Movsx(const InstX8632Movsx &) LLVM_DELETED_FUNCTION; | 1198 InstX8632Movsx(const InstX8632Movsx &) LLVM_DELETED_FUNCTION; |
| 1199 InstX8632Movsx &operator=(const InstX8632Movsx &) LLVM_DELETED_FUNCTION; | 1199 InstX8632Movsx &operator=(const InstX8632Movsx &) LLVM_DELETED_FUNCTION; |
| 1200 virtual ~InstX8632Movsx() {} | 1200 ~InstX8632Movsx() override {} |
| 1201 }; | 1201 }; |
| 1202 | 1202 |
| 1203 // Movzx - copy from a narrower integer type to a wider integer | 1203 // Movzx - copy from a narrower integer type to a wider integer |
| 1204 // type, with zero extension. | 1204 // type, with zero extension. |
| 1205 class InstX8632Movzx : public InstX8632 { | 1205 class InstX8632Movzx : public InstX8632 { |
| 1206 public: | 1206 public: |
| 1207 static InstX8632Movzx *create(Cfg *Func, Variable *Dest, Operand *Source) { | 1207 static InstX8632Movzx *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 1208 return new (Func->allocate<InstX8632Movzx>()) | 1208 return new (Func->allocate<InstX8632Movzx>()) |
| 1209 InstX8632Movzx(Func, Dest, Source); | 1209 InstX8632Movzx(Func, Dest, Source); |
| 1210 } | 1210 } |
| 1211 virtual void emit(const Cfg *Func) const; | 1211 void emit(const Cfg *Func) const override; |
| 1212 virtual void dump(const Cfg *Func) const; | 1212 void dump(const Cfg *Func) const override; |
| 1213 static bool classof(const Inst *Inst) { return isClassof(Inst, Movzx); } | 1213 static bool classof(const Inst *Inst) { return isClassof(Inst, Movzx); } |
| 1214 | 1214 |
| 1215 private: | 1215 private: |
| 1216 InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source); | 1216 InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source); |
| 1217 InstX8632Movzx(const InstX8632Movzx &) LLVM_DELETED_FUNCTION; | 1217 InstX8632Movzx(const InstX8632Movzx &) LLVM_DELETED_FUNCTION; |
| 1218 InstX8632Movzx &operator=(const InstX8632Movzx &) LLVM_DELETED_FUNCTION; | 1218 InstX8632Movzx &operator=(const InstX8632Movzx &) LLVM_DELETED_FUNCTION; |
| 1219 virtual ~InstX8632Movzx() {} | 1219 ~InstX8632Movzx() override {} |
| 1220 }; | 1220 }; |
| 1221 | 1221 |
| 1222 // Nop instructions of varying length | 1222 // Nop instructions of varying length |
| 1223 class InstX8632Nop : public InstX8632 { | 1223 class InstX8632Nop : public InstX8632 { |
| 1224 public: | 1224 public: |
| 1225 // TODO: Replace with enum. | 1225 // TODO: Replace with enum. |
| 1226 typedef unsigned NopVariant; | 1226 typedef unsigned NopVariant; |
| 1227 | 1227 |
| 1228 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) { | 1228 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) { |
| 1229 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant); | 1229 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant); |
| 1230 } | 1230 } |
| 1231 virtual void emit(const Cfg *Func) const; | 1231 void emit(const Cfg *Func) const override; |
| 1232 virtual void emitIAS(const Cfg *Func) const; | 1232 void emitIAS(const Cfg *Func) const override; |
| 1233 virtual void dump(const Cfg *Func) const; | 1233 void dump(const Cfg *Func) const override; |
| 1234 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); } | 1234 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); } |
| 1235 | 1235 |
| 1236 private: | 1236 private: |
| 1237 InstX8632Nop(Cfg *Func, SizeT Length); | 1237 InstX8632Nop(Cfg *Func, SizeT Length); |
| 1238 InstX8632Nop(const InstX8632Nop &) LLVM_DELETED_FUNCTION; | 1238 InstX8632Nop(const InstX8632Nop &) LLVM_DELETED_FUNCTION; |
| 1239 InstX8632Nop &operator=(const InstX8632Nop &) LLVM_DELETED_FUNCTION; | 1239 InstX8632Nop &operator=(const InstX8632Nop &) LLVM_DELETED_FUNCTION; |
| 1240 virtual ~InstX8632Nop() {} | 1240 ~InstX8632Nop() override {} |
| 1241 | 1241 |
| 1242 NopVariant Variant; | 1242 NopVariant Variant; |
| 1243 }; | 1243 }; |
| 1244 | 1244 |
| 1245 // Fld - load a value onto the x87 FP stack. | 1245 // Fld - load a value onto the x87 FP stack. |
| 1246 class InstX8632Fld : public InstX8632 { | 1246 class InstX8632Fld : public InstX8632 { |
| 1247 public: | 1247 public: |
| 1248 static InstX8632Fld *create(Cfg *Func, Operand *Src) { | 1248 static InstX8632Fld *create(Cfg *Func, Operand *Src) { |
| 1249 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src); | 1249 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src); |
| 1250 } | 1250 } |
| 1251 virtual void emit(const Cfg *Func) const; | 1251 void emit(const Cfg *Func) const override; |
| 1252 virtual void dump(const Cfg *Func) const; | 1252 void dump(const Cfg *Func) const override; |
| 1253 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); } | 1253 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); } |
| 1254 | 1254 |
| 1255 private: | 1255 private: |
| 1256 InstX8632Fld(Cfg *Func, Operand *Src); | 1256 InstX8632Fld(Cfg *Func, Operand *Src); |
| 1257 InstX8632Fld(const InstX8632Fld &) LLVM_DELETED_FUNCTION; | 1257 InstX8632Fld(const InstX8632Fld &) LLVM_DELETED_FUNCTION; |
| 1258 InstX8632Fld &operator=(const InstX8632Fld &) LLVM_DELETED_FUNCTION; | 1258 InstX8632Fld &operator=(const InstX8632Fld &) LLVM_DELETED_FUNCTION; |
| 1259 virtual ~InstX8632Fld() {} | 1259 ~InstX8632Fld() override {} |
| 1260 }; | 1260 }; |
| 1261 | 1261 |
| 1262 // Fstp - store x87 st(0) into memory and pop st(0). | 1262 // Fstp - store x87 st(0) into memory and pop st(0). |
| 1263 class InstX8632Fstp : public InstX8632 { | 1263 class InstX8632Fstp : public InstX8632 { |
| 1264 public: | 1264 public: |
| 1265 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) { | 1265 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) { |
| 1266 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest); | 1266 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest); |
| 1267 } | 1267 } |
| 1268 virtual void emit(const Cfg *Func) const; | 1268 void emit(const Cfg *Func) const override; |
| 1269 virtual void dump(const Cfg *Func) const; | 1269 void dump(const Cfg *Func) const override; |
| 1270 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); } | 1270 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); } |
| 1271 | 1271 |
| 1272 private: | 1272 private: |
| 1273 InstX8632Fstp(Cfg *Func, Variable *Dest); | 1273 InstX8632Fstp(Cfg *Func, Variable *Dest); |
| 1274 InstX8632Fstp(const InstX8632Fstp &) LLVM_DELETED_FUNCTION; | 1274 InstX8632Fstp(const InstX8632Fstp &) LLVM_DELETED_FUNCTION; |
| 1275 InstX8632Fstp &operator=(const InstX8632Fstp &) LLVM_DELETED_FUNCTION; | 1275 InstX8632Fstp &operator=(const InstX8632Fstp &) LLVM_DELETED_FUNCTION; |
| 1276 virtual ~InstX8632Fstp() {} | 1276 ~InstX8632Fstp() override {} |
| 1277 }; | 1277 }; |
| 1278 | 1278 |
| 1279 class InstX8632Pop : public InstX8632 { | 1279 class InstX8632Pop : public InstX8632 { |
| 1280 public: | 1280 public: |
| 1281 static InstX8632Pop *create(Cfg *Func, Variable *Dest) { | 1281 static InstX8632Pop *create(Cfg *Func, Variable *Dest) { |
| 1282 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest); | 1282 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest); |
| 1283 } | 1283 } |
| 1284 virtual void emit(const Cfg *Func) const; | 1284 void emit(const Cfg *Func) const override; |
| 1285 virtual void emitIAS(const Cfg *Func) const; | 1285 void emitIAS(const Cfg *Func) const override; |
| 1286 virtual void dump(const Cfg *Func) const; | 1286 void dump(const Cfg *Func) const override; |
| 1287 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } | 1287 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } |
| 1288 | 1288 |
| 1289 private: | 1289 private: |
| 1290 InstX8632Pop(Cfg *Func, Variable *Dest); | 1290 InstX8632Pop(Cfg *Func, Variable *Dest); |
| 1291 InstX8632Pop(const InstX8632Pop &) LLVM_DELETED_FUNCTION; | 1291 InstX8632Pop(const InstX8632Pop &) LLVM_DELETED_FUNCTION; |
| 1292 InstX8632Pop &operator=(const InstX8632Pop &) LLVM_DELETED_FUNCTION; | 1292 InstX8632Pop &operator=(const InstX8632Pop &) LLVM_DELETED_FUNCTION; |
| 1293 virtual ~InstX8632Pop() {} | 1293 ~InstX8632Pop() override {} |
| 1294 }; | 1294 }; |
| 1295 | 1295 |
| 1296 class InstX8632Push : public InstX8632 { | 1296 class InstX8632Push : public InstX8632 { |
| 1297 public: | 1297 public: |
| 1298 static InstX8632Push *create(Cfg *Func, Operand *Source, | 1298 static InstX8632Push *create(Cfg *Func, Operand *Source, |
| 1299 bool SuppressStackAdjustment) { | 1299 bool SuppressStackAdjustment) { |
| 1300 return new (Func->allocate<InstX8632Push>()) | 1300 return new (Func->allocate<InstX8632Push>()) |
| 1301 InstX8632Push(Func, Source, SuppressStackAdjustment); | 1301 InstX8632Push(Func, Source, SuppressStackAdjustment); |
| 1302 } | 1302 } |
| 1303 virtual void emit(const Cfg *Func) const; | 1303 void emit(const Cfg *Func) const override; |
| 1304 virtual void dump(const Cfg *Func) const; | 1304 void dump(const Cfg *Func) const override; |
| 1305 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } | 1305 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } |
| 1306 | 1306 |
| 1307 private: | 1307 private: |
| 1308 InstX8632Push(Cfg *Func, Operand *Source, bool SuppressStackAdjustment); | 1308 InstX8632Push(Cfg *Func, Operand *Source, bool SuppressStackAdjustment); |
| 1309 InstX8632Push(const InstX8632Push &) LLVM_DELETED_FUNCTION; | 1309 InstX8632Push(const InstX8632Push &) LLVM_DELETED_FUNCTION; |
| 1310 InstX8632Push &operator=(const InstX8632Push &) LLVM_DELETED_FUNCTION; | 1310 InstX8632Push &operator=(const InstX8632Push &) LLVM_DELETED_FUNCTION; |
| 1311 bool SuppressStackAdjustment; | 1311 bool SuppressStackAdjustment; |
| 1312 virtual ~InstX8632Push() {} | 1312 ~InstX8632Push() override {} |
| 1313 }; | 1313 }; |
| 1314 | 1314 |
| 1315 // Ret instruction. Currently only supports the "ret" version that | 1315 // Ret instruction. Currently only supports the "ret" version that |
| 1316 // does not pop arguments. This instruction takes a Source operand | 1316 // does not pop arguments. This instruction takes a Source operand |
| 1317 // (for non-void returning functions) for liveness analysis, though | 1317 // (for non-void returning functions) for liveness analysis, though |
| 1318 // a FakeUse before the ret would do just as well. | 1318 // a FakeUse before the ret would do just as well. |
| 1319 class InstX8632Ret : public InstX8632 { | 1319 class InstX8632Ret : public InstX8632 { |
| 1320 public: | 1320 public: |
| 1321 static InstX8632Ret *create(Cfg *Func, Variable *Source = NULL) { | 1321 static InstX8632Ret *create(Cfg *Func, Variable *Source = NULL) { |
| 1322 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source); | 1322 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source); |
| 1323 } | 1323 } |
| 1324 virtual void emit(const Cfg *Func) const; | 1324 void emit(const Cfg *Func) const override; |
| 1325 virtual void emitIAS(const Cfg *Func) const; | 1325 void emitIAS(const Cfg *Func) const override; |
| 1326 virtual void dump(const Cfg *Func) const; | 1326 void dump(const Cfg *Func) const override; |
| 1327 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } | 1327 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } |
| 1328 | 1328 |
| 1329 private: | 1329 private: |
| 1330 InstX8632Ret(Cfg *Func, Variable *Source); | 1330 InstX8632Ret(Cfg *Func, Variable *Source); |
| 1331 InstX8632Ret(const InstX8632Ret &) LLVM_DELETED_FUNCTION; | 1331 InstX8632Ret(const InstX8632Ret &) LLVM_DELETED_FUNCTION; |
| 1332 InstX8632Ret &operator=(const InstX8632Ret &) LLVM_DELETED_FUNCTION; | 1332 InstX8632Ret &operator=(const InstX8632Ret &) LLVM_DELETED_FUNCTION; |
| 1333 virtual ~InstX8632Ret() {} | 1333 ~InstX8632Ret() override {} |
| 1334 }; | 1334 }; |
| 1335 | 1335 |
| 1336 // Exchanging Add instruction. Exchanges the first operand (destination | 1336 // Exchanging Add instruction. Exchanges the first operand (destination |
| 1337 // operand) with the second operand (source operand), then loads the sum | 1337 // operand) with the second operand (source operand), then loads the sum |
| 1338 // of the two values into the destination operand. The destination may be | 1338 // of the two values into the destination operand. The destination may be |
| 1339 // a register or memory, while the source must be a register. | 1339 // a register or memory, while the source must be a register. |
| 1340 // | 1340 // |
| 1341 // Both the dest and source are updated. The caller should then insert a | 1341 // Both the dest and source are updated. The caller should then insert a |
| 1342 // FakeDef to reflect the second udpate. | 1342 // FakeDef to reflect the second udpate. |
| 1343 class InstX8632Xadd : public InstX8632Lockable { | 1343 class InstX8632Xadd : public InstX8632Lockable { |
| 1344 public: | 1344 public: |
| 1345 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, | 1345 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, |
| 1346 bool Locked) { | 1346 bool Locked) { |
| 1347 return new (Func->allocate<InstX8632Xadd>()) | 1347 return new (Func->allocate<InstX8632Xadd>()) |
| 1348 InstX8632Xadd(Func, Dest, Source, Locked); | 1348 InstX8632Xadd(Func, Dest, Source, Locked); |
| 1349 } | 1349 } |
| 1350 virtual void emit(const Cfg *Func) const; | 1350 void emit(const Cfg *Func) const override; |
| 1351 virtual void emitIAS(const Cfg *Func) const; | 1351 void emitIAS(const Cfg *Func) const override; |
| 1352 virtual void dump(const Cfg *Func) const; | 1352 void dump(const Cfg *Func) const override; |
| 1353 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } | 1353 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } |
| 1354 | 1354 |
| 1355 private: | 1355 private: |
| 1356 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); | 1356 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); |
| 1357 InstX8632Xadd(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; | 1357 InstX8632Xadd(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; |
| 1358 InstX8632Xadd &operator=(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; | 1358 InstX8632Xadd &operator=(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; |
| 1359 virtual ~InstX8632Xadd() {} | 1359 ~InstX8632Xadd() override {} |
| 1360 }; | 1360 }; |
| 1361 | 1361 |
| 1362 // Exchange instruction. Exchanges the first operand (destination | 1362 // Exchange instruction. Exchanges the first operand (destination |
| 1363 // operand) with the second operand (source operand). At least one of | 1363 // operand) with the second operand (source operand). At least one of |
| 1364 // the operands must be a register (and the other can be reg or mem). | 1364 // the operands must be a register (and the other can be reg or mem). |
| 1365 // Both the Dest and Source are updated. If there is a memory operand, | 1365 // Both the Dest and Source are updated. If there is a memory operand, |
| 1366 // then the instruction is automatically "locked" without the need for | 1366 // then the instruction is automatically "locked" without the need for |
| 1367 // a lock prefix. | 1367 // a lock prefix. |
| 1368 class InstX8632Xchg : public InstX8632 { | 1368 class InstX8632Xchg : public InstX8632 { |
| 1369 public: | 1369 public: |
| 1370 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { | 1370 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { |
| 1371 return new (Func->allocate<InstX8632Xchg>()) | 1371 return new (Func->allocate<InstX8632Xchg>()) |
| 1372 InstX8632Xchg(Func, Dest, Source); | 1372 InstX8632Xchg(Func, Dest, Source); |
| 1373 } | 1373 } |
| 1374 virtual void emit(const Cfg *Func) const; | 1374 void emit(const Cfg *Func) const override; |
| 1375 virtual void emitIAS(const Cfg *Func) const; | 1375 void emitIAS(const Cfg *Func) const override; |
| 1376 virtual void dump(const Cfg *Func) const; | 1376 void dump(const Cfg *Func) const override; |
| 1377 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); } | 1377 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); } |
| 1378 | 1378 |
| 1379 private: | 1379 private: |
| 1380 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source); | 1380 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source); |
| 1381 InstX8632Xchg(const InstX8632Xchg &) LLVM_DELETED_FUNCTION; | 1381 InstX8632Xchg(const InstX8632Xchg &) LLVM_DELETED_FUNCTION; |
| 1382 InstX8632Xchg &operator=(const InstX8632Xchg &) LLVM_DELETED_FUNCTION; | 1382 InstX8632Xchg &operator=(const InstX8632Xchg &) LLVM_DELETED_FUNCTION; |
| 1383 virtual ~InstX8632Xchg() {} | 1383 ~InstX8632Xchg() override {} |
| 1384 }; | 1384 }; |
| 1385 | 1385 |
| 1386 // Declare partial template specializations of emit() methods that | 1386 // Declare partial template specializations of emit() methods that |
| 1387 // already have default implementations. Without this, there is the | 1387 // already have default implementations. Without this, there is the |
| 1388 // possibility of ODR violations and link errors. | 1388 // possibility of ODR violations and link errors. |
| 1389 template <> void InstX8632Addss::emit(const Cfg *Func) const; | 1389 template <> void InstX8632Addss::emit(const Cfg *Func) const; |
| 1390 template <> void InstX8632Blendvps::emit(const Cfg *Func) const; | 1390 template <> void InstX8632Blendvps::emit(const Cfg *Func) const; |
| 1391 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const; | 1391 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const; |
| 1392 template <> void InstX8632Div::emit(const Cfg *Func) const; | 1392 template <> void InstX8632Div::emit(const Cfg *Func) const; |
| 1393 template <> void InstX8632Divss::emit(const Cfg *Func) const; | 1393 template <> void InstX8632Divss::emit(const Cfg *Func) const; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1408 template <> void InstX8632Psub::emit(const Cfg *Func) const; | 1408 template <> void InstX8632Psub::emit(const Cfg *Func) const; |
| 1409 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const; | 1409 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const; |
| 1410 template <> void InstX8632Subss::emit(const Cfg *Func) const; | 1410 template <> void InstX8632Subss::emit(const Cfg *Func) const; |
| 1411 | 1411 |
| 1412 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; | 1412 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; |
| 1413 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const; | 1413 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const; |
| 1414 | 1414 |
| 1415 } // end of namespace Ice | 1415 } // end of namespace Ice |
| 1416 | 1416 |
| 1417 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1417 #endif // SUBZERO_SRC_ICEINSTX8632_H |
| OLD | NEW |