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