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