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