Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/IceInstX8632.h

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

Powered by Google App Engine
This is Rietveld 408576698