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

Side by Side Diff: src/IceInstX8632.h

Issue 952953002: Subzero: Improve class definition hygiene. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix typo Created 5 years, 10 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/IceLiveness.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() = delete;
33 OperandX8632(const OperandX8632 &) = delete; 34 OperandX8632(const OperandX8632 &) = delete;
34 OperandX8632 &operator=(const OperandX8632 &) = delete; 35 OperandX8632 &operator=(const OperandX8632 &) = delete;
35 36
36 public: 37 public:
37 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit }; 38 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit };
38 using Operand::dump; 39 using Operand::dump;
39 void dump(const Cfg *, Ostream &Str) const override { 40 void dump(const Cfg *, Ostream &Str) const override {
40 if (ALLOW_DUMP) 41 if (ALLOW_DUMP)
41 Str << "<OperandX8632>"; 42 Str << "<OperandX8632>";
42 } 43 }
43 44
44 protected: 45 protected:
45 OperandX8632(OperandKindX8632 Kind, Type Ty) 46 OperandX8632(OperandKindX8632 Kind, Type Ty)
46 : Operand(static_cast<OperandKind>(Kind), Ty) {} 47 : Operand(static_cast<OperandKind>(Kind), Ty) {}
47 ~OperandX8632() override {} 48 ~OperandX8632() override {}
48 }; 49 };
49 50
50 // OperandX8632Mem represents the m32 addressing mode, with optional 51 // OperandX8632Mem represents the m32 addressing mode, with optional
51 // base and index registers, a constant offset, and a fixed shift 52 // base and index registers, a constant offset, and a fixed shift
52 // value for the index register. 53 // value for the index register.
53 class OperandX8632Mem : public OperandX8632 { 54 class OperandX8632Mem : public OperandX8632 {
55 OperandX8632Mem() = delete;
54 OperandX8632Mem(const OperandX8632Mem &) = delete; 56 OperandX8632Mem(const OperandX8632Mem &) = delete;
55 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete; 57 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
56 58
57 public: 59 public:
58 enum SegmentRegisters { 60 enum SegmentRegisters {
59 DefaultSegment = -1, 61 DefaultSegment = -1,
60 #define X(val, name, prefix) val, 62 #define X(val, name, prefix) val,
61 SEG_REGX8632_TABLE 63 SEG_REGX8632_TABLE
62 #undef X 64 #undef X
63 SegReg_NUM 65 SegReg_NUM
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 SegmentRegisters SegmentReg : 16; 97 SegmentRegisters SegmentReg : 16;
96 }; 98 };
97 99
98 // VariableSplit is a way to treat an f64 memory location as a pair 100 // VariableSplit is a way to treat an f64 memory location as a pair
99 // of i32 locations (Low and High). This is needed for some cases 101 // of i32 locations (Low and High). This is needed for some cases
100 // of the Bitcast instruction. Since it's not possible for integer 102 // of the Bitcast instruction. Since it's not possible for integer
101 // registers to access the XMM registers and vice versa, the 103 // registers to access the XMM registers and vice versa, the
102 // lowering forces the f64 to be spilled to the stack and then 104 // lowering forces the f64 to be spilled to the stack and then
103 // accesses through the VariableSplit. 105 // accesses through the VariableSplit.
104 class VariableSplit : public OperandX8632 { 106 class VariableSplit : public OperandX8632 {
107 VariableSplit() = delete;
105 VariableSplit(const VariableSplit &) = delete; 108 VariableSplit(const VariableSplit &) = delete;
106 VariableSplit &operator=(const VariableSplit &) = delete; 109 VariableSplit &operator=(const VariableSplit &) = delete;
107 110
108 public: 111 public:
109 enum Portion { Low, High }; 112 enum Portion { Low, High };
110 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { 113 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
111 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); 114 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
112 } 115 }
113 int32_t getOffset() const { return Part == High ? 4 : 0; } 116 int32_t getOffset() const { return Part == High ? 4 : 0; }
114 117
(...skipping 19 matching lines...) Expand all
134 Variable *Var; 137 Variable *Var;
135 Portion Part; 138 Portion Part;
136 }; 139 };
137 140
138 // SpillVariable decorates a Variable by linking it to another 141 // SpillVariable decorates a Variable by linking it to another
139 // Variable. When stack frame offsets are computed, the SpillVariable 142 // Variable. When stack frame offsets are computed, the SpillVariable
140 // is given a distinct stack slot only if its linked Variable has a 143 // is given a distinct stack slot only if its linked Variable has a
141 // register. If the linked Variable has a stack slot, then the 144 // register. If the linked Variable has a stack slot, then the
142 // Variable and SpillVariable share that slot. 145 // Variable and SpillVariable share that slot.
143 class SpillVariable : public Variable { 146 class SpillVariable : public Variable {
147 SpillVariable() = delete;
144 SpillVariable(const SpillVariable &) = delete; 148 SpillVariable(const SpillVariable &) = delete;
145 SpillVariable &operator=(const SpillVariable &) = delete; 149 SpillVariable &operator=(const SpillVariable &) = delete;
146 150
147 public: 151 public:
148 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) { 152 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) {
149 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index); 153 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index);
150 } 154 }
151 const static OperandKind SpillVariableKind = 155 const static OperandKind SpillVariableKind =
152 static_cast<OperandKind>(kVariable_Target); 156 static_cast<OperandKind>(kVariable_Target);
153 static bool classof(const Operand *Operand) { 157 static bool classof(const Operand *Operand) {
154 return Operand->getKind() == SpillVariableKind; 158 return Operand->getKind() == SpillVariableKind;
155 } 159 }
156 void setLinkedTo(Variable *Var) { LinkedTo = Var; } 160 void setLinkedTo(Variable *Var) { LinkedTo = Var; }
157 Variable *getLinkedTo() const { return LinkedTo; } 161 Variable *getLinkedTo() const { return LinkedTo; }
158 // Inherit dump() and emit() from Variable. 162 // Inherit dump() and emit() from Variable.
159 private: 163 private:
160 SpillVariable(Type Ty, SizeT Index) 164 SpillVariable(Type Ty, SizeT Index)
161 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {} 165 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {}
162 Variable *LinkedTo; 166 Variable *LinkedTo;
163 }; 167 };
164 168
165 class InstX8632 : public InstTarget { 169 class InstX8632 : public InstTarget {
170 InstX8632() = delete;
166 InstX8632(const InstX8632 &) = delete; 171 InstX8632(const InstX8632 &) = delete;
167 InstX8632 &operator=(const InstX8632 &) = delete; 172 InstX8632 &operator=(const InstX8632 &) = delete;
168 173
169 public: 174 public:
170 enum InstKindX8632 { 175 enum InstKindX8632 {
171 k__Start = Inst::Target, 176 k__Start = Inst::Target,
172 Adc, 177 Adc,
173 Add, 178 Add,
174 Addps, 179 Addps,
175 Addss, 180 Addss,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 // FakeUse(c) 306 // FakeUse(c)
302 // L1: 307 // L1:
303 // mov c, y 308 // mov c, y
304 // L2: 309 // L2:
305 // 310 //
306 // The down-side is that "mov c, x" can never be dead-code eliminated 311 // The down-side is that "mov c, x" can never be dead-code eliminated
307 // even if there are no uses of c. As unlikely as this situation is, 312 // even if there are no uses of c. As unlikely as this situation is,
308 // it may be prevented by running dead code elimination before 313 // it may be prevented by running dead code elimination before
309 // lowering. 314 // lowering.
310 class InstX8632Label : public InstX8632 { 315 class InstX8632Label : public InstX8632 {
316 InstX8632Label() = delete;
311 InstX8632Label(const InstX8632Label &) = delete; 317 InstX8632Label(const InstX8632Label &) = delete;
312 InstX8632Label &operator=(const InstX8632Label &) = delete; 318 InstX8632Label &operator=(const InstX8632Label &) = delete;
313 319
314 public: 320 public:
315 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) { 321 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
316 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target); 322 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
317 } 323 }
318 uint32_t getEmitInstCount() const override { return 0; } 324 uint32_t getEmitInstCount() const override { return 0; }
319 IceString getName(const Cfg *Func) const; 325 IceString getName(const Cfg *Func) const;
320 SizeT getNumber() const { return Number; } 326 SizeT getNumber() const { return Number; }
321 void emit(const Cfg *Func) const override; 327 void emit(const Cfg *Func) const override;
322 void emitIAS(const Cfg *Func) const override; 328 void emitIAS(const Cfg *Func) const override;
323 void dump(const Cfg *Func) const override; 329 void dump(const Cfg *Func) const override;
324 330
325 private: 331 private:
326 InstX8632Label(Cfg *Func, TargetX8632 *Target); 332 InstX8632Label(Cfg *Func, TargetX8632 *Target);
327 ~InstX8632Label() override {} 333 ~InstX8632Label() override {}
328 SizeT Number; // used for unique label generation. 334 SizeT Number; // used for unique label generation.
329 }; 335 };
330 336
331 // Conditional and unconditional branch instruction. 337 // Conditional and unconditional branch instruction.
332 class InstX8632Br : public InstX8632 { 338 class InstX8632Br : public InstX8632 {
339 InstX8632Br() = delete;
333 InstX8632Br(const InstX8632Br &) = delete; 340 InstX8632Br(const InstX8632Br &) = delete;
334 InstX8632Br &operator=(const InstX8632Br &) = delete; 341 InstX8632Br &operator=(const InstX8632Br &) = delete;
335 342
336 public: 343 public:
337 // Create a conditional branch to a node. 344 // Create a conditional branch to a node.
338 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, 345 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
339 CfgNode *TargetFalse, CondX86::BrCond Condition) { 346 CfgNode *TargetFalse, CondX86::BrCond Condition) {
340 assert(Condition != CondX86::Br_None); 347 assert(Condition != CondX86::Br_None);
341 const InstX8632Label *NoLabel = nullptr; 348 const InstX8632Label *NoLabel = nullptr;
342 return new (Func->allocate<InstX8632Br>()) 349 return new (Func->allocate<InstX8632Br>())
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 CondX86::BrCond Condition; 405 CondX86::BrCond Condition;
399 const CfgNode *TargetTrue; 406 const CfgNode *TargetTrue;
400 const CfgNode *TargetFalse; 407 const CfgNode *TargetFalse;
401 const InstX8632Label *Label; // Intra-block branch target 408 const InstX8632Label *Label; // Intra-block branch target
402 }; 409 };
403 410
404 // Jump to a target outside this function, such as tailcall, nacljump, 411 // Jump to a target outside this function, such as tailcall, nacljump,
405 // naclret, unreachable. This is different from a Branch instruction 412 // naclret, unreachable. This is different from a Branch instruction
406 // in that there is no intra-function control flow to represent. 413 // in that there is no intra-function control flow to represent.
407 class InstX8632Jmp : public InstX8632 { 414 class InstX8632Jmp : public InstX8632 {
415 InstX8632Jmp() = delete;
408 InstX8632Jmp(const InstX8632Jmp &) = delete; 416 InstX8632Jmp(const InstX8632Jmp &) = delete;
409 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete; 417 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete;
410 418
411 public: 419 public:
412 static InstX8632Jmp *create(Cfg *Func, Operand *Target) { 420 static InstX8632Jmp *create(Cfg *Func, Operand *Target) {
413 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target); 421 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target);
414 } 422 }
415 Operand *getJmpTarget() const { return getSrc(0); } 423 Operand *getJmpTarget() const { return getSrc(0); }
416 void emit(const Cfg *Func) const override; 424 void emit(const Cfg *Func) const override;
417 void emitIAS(const Cfg *Func) const override; 425 void emitIAS(const Cfg *Func) const override;
418 void dump(const Cfg *Func) const override; 426 void dump(const Cfg *Func) const override;
419 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); } 427 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); }
420 428
421 private: 429 private:
422 InstX8632Jmp(Cfg *Func, Operand *Target); 430 InstX8632Jmp(Cfg *Func, Operand *Target);
423 }; 431 };
424 432
425 // AdjustStack instruction - subtracts esp by the given amount and 433 // AdjustStack instruction - subtracts esp by the given amount and
426 // updates the stack offset during code emission. 434 // updates the stack offset during code emission.
427 class InstX8632AdjustStack : public InstX8632 { 435 class InstX8632AdjustStack : public InstX8632 {
436 InstX8632AdjustStack() = delete;
428 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete; 437 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
429 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete; 438 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
430 439
431 public: 440 public:
432 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) { 441 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
433 return new (Func->allocate<InstX8632AdjustStack>()) 442 return new (Func->allocate<InstX8632AdjustStack>())
434 InstX8632AdjustStack(Func, Amount, Esp); 443 InstX8632AdjustStack(Func, Amount, Esp);
435 } 444 }
436 void emit(const Cfg *Func) const override; 445 void emit(const Cfg *Func) const override;
437 void emitIAS(const Cfg *Func) const override; 446 void emitIAS(const Cfg *Func) const override;
438 void dump(const Cfg *Func) const override; 447 void dump(const Cfg *Func) const override;
439 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); } 448 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
440 449
441 private: 450 private:
442 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp); 451 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
443 SizeT Amount; 452 SizeT Amount;
444 }; 453 };
445 454
446 // Call instruction. Arguments should have already been pushed. 455 // Call instruction. Arguments should have already been pushed.
447 class InstX8632Call : public InstX8632 { 456 class InstX8632Call : public InstX8632 {
457 InstX8632Call() = delete;
448 InstX8632Call(const InstX8632Call &) = delete; 458 InstX8632Call(const InstX8632Call &) = delete;
449 InstX8632Call &operator=(const InstX8632Call &) = delete; 459 InstX8632Call &operator=(const InstX8632Call &) = delete;
450 460
451 public: 461 public:
452 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { 462 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
453 return new (Func->allocate<InstX8632Call>()) 463 return new (Func->allocate<InstX8632Call>())
454 InstX8632Call(Func, Dest, CallTarget); 464 InstX8632Call(Func, Dest, CallTarget);
455 } 465 }
456 Operand *getCallTarget() const { return getSrc(0); } 466 Operand *getCallTarget() const { return getSrc(0); }
457 void emit(const Cfg *Func) const override; 467 void emit(const Cfg *Func) const override;
458 void emitIAS(const Cfg *Func) const override; 468 void emitIAS(const Cfg *Func) const override;
459 void dump(const Cfg *Func) const override; 469 void dump(const Cfg *Func) const override;
460 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 470 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
461 471
462 private: 472 private:
463 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 473 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
464 ~InstX8632Call() override {} 474 ~InstX8632Call() override {}
465 }; 475 };
466 476
467 // Emit a one-operand (GPR) instruction. 477 // Emit a one-operand (GPR) instruction.
468 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, 478 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
469 const x86::AssemblerX86::GPREmitterOneOp &Emitter); 479 const x86::AssemblerX86::GPREmitterOneOp &Emitter);
470 480
471 // Instructions of the form x := op(x). 481 // Instructions of the form x := op(x).
472 template <InstX8632::InstKindX8632 K> 482 template <InstX8632::InstKindX8632 K>
473 class InstX8632InplaceopGPR : public InstX8632 { 483 class InstX8632InplaceopGPR : public InstX8632 {
484 InstX8632InplaceopGPR() = delete;
474 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; 485 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
475 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; 486 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
476 487
477 public: 488 public:
478 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { 489 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) {
479 return new (Func->allocate<InstX8632InplaceopGPR>()) 490 return new (Func->allocate<InstX8632InplaceopGPR>())
480 InstX8632InplaceopGPR(Func, SrcDest); 491 InstX8632InplaceopGPR(Func, SrcDest);
481 } 492 }
482 void emit(const Cfg *Func) const override { 493 void emit(const Cfg *Func) const override {
483 if (!ALLOW_DUMP) 494 if (!ALLOW_DUMP)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 // Emit a two-operand (GPR) instruction, where the dest operand is a 527 // Emit a two-operand (GPR) instruction, where the dest operand is a
517 // Variable that's guaranteed to be a register. 528 // Variable that's guaranteed to be a register.
518 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> 529 template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
519 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, 530 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
520 const Operand *Src, 531 const Operand *Src,
521 const x86::AssemblerX86::GPREmitterRegOp &Emitter); 532 const x86::AssemblerX86::GPREmitterRegOp &Emitter);
522 533
523 // Instructions of the form x := op(y). 534 // Instructions of the form x := op(y).
524 template <InstX8632::InstKindX8632 K> 535 template <InstX8632::InstKindX8632 K>
525 class InstX8632UnaryopGPR : public InstX8632 { 536 class InstX8632UnaryopGPR : public InstX8632 {
537 InstX8632UnaryopGPR() = delete;
526 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete; 538 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
527 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete; 539 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
528 540
529 public: 541 public:
530 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { 542 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
531 return new (Func->allocate<InstX8632UnaryopGPR>()) 543 return new (Func->allocate<InstX8632UnaryopGPR>())
532 InstX8632UnaryopGPR(Func, Dest, Src); 544 InstX8632UnaryopGPR(Func, Dest, Src);
533 } 545 }
534 void emit(const Cfg *Func) const override { 546 void emit(const Cfg *Func) const override {
535 if (!ALLOW_DUMP) 547 if (!ALLOW_DUMP)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 static const char *Opcode; 587 static const char *Opcode;
576 static const x86::AssemblerX86::GPREmitterRegOp Emitter; 588 static const x86::AssemblerX86::GPREmitterRegOp Emitter;
577 }; 589 };
578 590
579 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, 591 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
580 const Operand *Src, 592 const Operand *Src,
581 const x86::AssemblerX86::XmmEmitterRegOp &Emitter); 593 const x86::AssemblerX86::XmmEmitterRegOp &Emitter);
582 594
583 template <InstX8632::InstKindX8632 K> 595 template <InstX8632::InstKindX8632 K>
584 class InstX8632UnaryopXmm : public InstX8632 { 596 class InstX8632UnaryopXmm : public InstX8632 {
597 InstX8632UnaryopXmm() = delete;
585 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete; 598 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
586 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete; 599 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
587 600
588 public: 601 public:
589 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { 602 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) {
590 return new (Func->allocate<InstX8632UnaryopXmm>()) 603 return new (Func->allocate<InstX8632UnaryopXmm>())
591 InstX8632UnaryopXmm(Func, Dest, Src); 604 InstX8632UnaryopXmm(Func, Dest, Src);
592 } 605 }
593 void emit(const Cfg *Func) const override { 606 void emit(const Cfg *Func) const override {
594 if (!ALLOW_DUMP) 607 if (!ALLOW_DUMP)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 // ShiftHack. 642 // ShiftHack.
630 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, 643 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
631 bool ShiftHack = false); 644 bool ShiftHack = false);
632 645
633 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 646 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
634 const Operand *Src, 647 const Operand *Src,
635 const x86::AssemblerX86::GPREmitterShiftOp &Emitter); 648 const x86::AssemblerX86::GPREmitterShiftOp &Emitter);
636 649
637 template <InstX8632::InstKindX8632 K> 650 template <InstX8632::InstKindX8632 K>
638 class InstX8632BinopGPRShift : public InstX8632 { 651 class InstX8632BinopGPRShift : public InstX8632 {
652 InstX8632BinopGPRShift() = delete;
639 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete; 653 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
640 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete; 654 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
641 655
642 public: 656 public:
643 // Create a binary-op GPR shift instruction. 657 // Create a binary-op GPR shift instruction.
644 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest, 658 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest,
645 Operand *Source) { 659 Operand *Source) {
646 return new (Func->allocate<InstX8632BinopGPRShift>()) 660 return new (Func->allocate<InstX8632BinopGPRShift>())
647 InstX8632BinopGPRShift(Func, Dest, Source); 661 InstX8632BinopGPRShift(Func, Dest, Source);
648 } 662 }
(...skipping 24 matching lines...) Expand all
673 addSource(Dest); 687 addSource(Dest);
674 addSource(Source); 688 addSource(Source);
675 } 689 }
676 ~InstX8632BinopGPRShift() override {} 690 ~InstX8632BinopGPRShift() override {}
677 static const char *Opcode; 691 static const char *Opcode;
678 static const x86::AssemblerX86::GPREmitterShiftOp Emitter; 692 static const x86::AssemblerX86::GPREmitterShiftOp Emitter;
679 }; 693 };
680 694
681 template <InstX8632::InstKindX8632 K> 695 template <InstX8632::InstKindX8632 K>
682 class InstX8632BinopGPR : public InstX8632 { 696 class InstX8632BinopGPR : public InstX8632 {
697 InstX8632BinopGPR() = delete;
683 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete; 698 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
684 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete; 699 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
685 700
686 public: 701 public:
687 // Create an ordinary binary-op instruction like add or sub. 702 // Create an ordinary binary-op instruction like add or sub.
688 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { 703 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) {
689 return new (Func->allocate<InstX8632BinopGPR>()) 704 return new (Func->allocate<InstX8632BinopGPR>())
690 InstX8632BinopGPR(Func, Dest, Source); 705 InstX8632BinopGPR(Func, Dest, Source);
691 } 706 }
692 void emit(const Cfg *Func) const override { 707 void emit(const Cfg *Func) const override {
(...skipping 23 matching lines...) Expand all
716 addSource(Dest); 731 addSource(Dest);
717 addSource(Source); 732 addSource(Source);
718 } 733 }
719 ~InstX8632BinopGPR() override {} 734 ~InstX8632BinopGPR() override {}
720 static const char *Opcode; 735 static const char *Opcode;
721 static const x86::AssemblerX86::GPREmitterRegOp Emitter; 736 static const x86::AssemblerX86::GPREmitterRegOp Emitter;
722 }; 737 };
723 738
724 template <InstX8632::InstKindX8632 K, bool NeedsElementType> 739 template <InstX8632::InstKindX8632 K, bool NeedsElementType>
725 class InstX8632BinopXmm : public InstX8632 { 740 class InstX8632BinopXmm : public InstX8632 {
741 InstX8632BinopXmm() = delete;
726 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; 742 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
727 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; 743 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
728 744
729 public: 745 public:
730 // Create an XMM binary-op instruction like addss or addps. 746 // Create an XMM binary-op instruction like addss or addps.
731 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { 747 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
732 return new (Func->allocate<InstX8632BinopXmm>()) 748 return new (Func->allocate<InstX8632BinopXmm>())
733 InstX8632BinopXmm(Func, Dest, Source); 749 InstX8632BinopXmm(Func, Dest, Source);
734 } 750 }
735 void emit(const Cfg *Func) const override { 751 void emit(const Cfg *Func) const override {
(...skipping 29 matching lines...) Expand all
765 static const char *Opcode; 781 static const char *Opcode;
766 static const x86::AssemblerX86::XmmEmitterRegOp Emitter; 782 static const x86::AssemblerX86::XmmEmitterRegOp Emitter;
767 }; 783 };
768 784
769 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, 785 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
770 const Operand *Src, 786 const Operand *Src,
771 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter); 787 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter);
772 788
773 template <InstX8632::InstKindX8632 K> 789 template <InstX8632::InstKindX8632 K>
774 class InstX8632BinopXmmShift : public InstX8632 { 790 class InstX8632BinopXmmShift : public InstX8632 {
791 InstX8632BinopXmmShift() = delete;
775 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete; 792 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
776 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete; 793 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
777 794
778 public: 795 public:
779 // Create an XMM binary-op shift operation. 796 // Create an XMM binary-op shift operation.
780 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, 797 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest,
781 Operand *Source) { 798 Operand *Source) {
782 return new (Func->allocate<InstX8632BinopXmmShift>()) 799 return new (Func->allocate<InstX8632BinopXmmShift>())
783 InstX8632BinopXmmShift(Func, Dest, Source); 800 InstX8632BinopXmmShift(Func, Dest, Source);
784 } 801 }
(...skipping 26 matching lines...) Expand all
811 : InstX8632(Func, K, 2, Dest) { 828 : InstX8632(Func, K, 2, Dest) {
812 addSource(Dest); 829 addSource(Dest);
813 addSource(Source); 830 addSource(Source);
814 } 831 }
815 ~InstX8632BinopXmmShift() override {} 832 ~InstX8632BinopXmmShift() override {}
816 static const char *Opcode; 833 static const char *Opcode;
817 static const x86::AssemblerX86::XmmEmitterShiftOp Emitter; 834 static const x86::AssemblerX86::XmmEmitterShiftOp Emitter;
818 }; 835 };
819 836
820 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { 837 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
838 InstX8632Ternop() = delete;
821 InstX8632Ternop(const InstX8632Ternop &) = delete; 839 InstX8632Ternop(const InstX8632Ternop &) = delete;
822 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete; 840 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
823 841
824 public: 842 public:
825 // Create a ternary-op instruction like div or idiv. 843 // Create a ternary-op instruction like div or idiv.
826 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, 844 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
827 Operand *Source2) { 845 Operand *Source2) {
828 return new (Func->allocate<InstX8632Ternop>()) 846 return new (Func->allocate<InstX8632Ternop>())
829 InstX8632Ternop(Func, Dest, Source1, Source2); 847 InstX8632Ternop(Func, Dest, Source1, Source2);
830 } 848 }
(...skipping 27 matching lines...) Expand all
858 addSource(Source1); 876 addSource(Source1);
859 addSource(Source2); 877 addSource(Source2);
860 } 878 }
861 ~InstX8632Ternop() override {} 879 ~InstX8632Ternop() override {}
862 static const char *Opcode; 880 static const char *Opcode;
863 }; 881 };
864 882
865 // Instructions of the form x := y op z 883 // Instructions of the form x := y op z
866 template <InstX8632::InstKindX8632 K> 884 template <InstX8632::InstKindX8632 K>
867 class InstX8632ThreeAddressop : public InstX8632 { 885 class InstX8632ThreeAddressop : public InstX8632 {
886 InstX8632ThreeAddressop() = delete;
868 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete; 887 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
869 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete; 888 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
870 889
871 public: 890 public:
872 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, 891 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
873 Operand *Source0, Operand *Source1) { 892 Operand *Source0, Operand *Source1) {
874 return new (Func->allocate<InstX8632ThreeAddressop>()) 893 return new (Func->allocate<InstX8632ThreeAddressop>())
875 InstX8632ThreeAddressop(Func, Dest, Source0, Source1); 894 InstX8632ThreeAddressop(Func, Dest, Source0, Source1);
876 } 895 }
877 void emit(const Cfg *Func) const override { 896 void emit(const Cfg *Func) const override {
(...skipping 28 matching lines...) Expand all
906 } 925 }
907 ~InstX8632ThreeAddressop() override {} 926 ~InstX8632ThreeAddressop() override {}
908 static const char *Opcode; 927 static const char *Opcode;
909 }; 928 };
910 929
911 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); 930 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
912 931
913 // Base class for assignment instructions 932 // Base class for assignment instructions
914 template <InstX8632::InstKindX8632 K> 933 template <InstX8632::InstKindX8632 K>
915 class InstX8632Movlike : public InstX8632 { 934 class InstX8632Movlike : public InstX8632 {
935 InstX8632Movlike() = delete;
916 InstX8632Movlike(const InstX8632Movlike &) = delete; 936 InstX8632Movlike(const InstX8632Movlike &) = delete;
917 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete; 937 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
918 938
919 public: 939 public:
920 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) { 940 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
921 return new (Func->allocate<InstX8632Movlike>()) 941 return new (Func->allocate<InstX8632Movlike>())
922 InstX8632Movlike(Func, Dest, Source); 942 InstX8632Movlike(Func, Dest, Source);
923 } 943 }
924 bool isRedundantAssign() const override { 944 bool isRedundantAssign() const override {
925 return checkForRedundantAssign(getDest(), getSrc(0)); 945 return checkForRedundantAssign(getDest(), getSrc(0));
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps; 1031 typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
1012 typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr; 1032 typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
1013 typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps; 1033 typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
1014 typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps; 1034 typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
1015 typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb; 1035 typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
1016 typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr; 1036 typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
1017 typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd; 1037 typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
1018 1038
1019 // Base class for a lockable x86-32 instruction (emits a locked prefix). 1039 // Base class for a lockable x86-32 instruction (emits a locked prefix).
1020 class InstX8632Lockable : public InstX8632 { 1040 class InstX8632Lockable : public InstX8632 {
1041 InstX8632Lockable() = delete;
1021 InstX8632Lockable(const InstX8632Lockable &) = delete; 1042 InstX8632Lockable(const InstX8632Lockable &) = delete;
1022 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete; 1043 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
1023 1044
1024 protected: 1045 protected:
1025 bool Locked; 1046 bool Locked;
1026 1047
1027 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, 1048 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
1028 Variable *Dest, bool Locked) 1049 Variable *Dest, bool Locked)
1029 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { 1050 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
1030 // Assume that such instructions are used for Atomics and be careful 1051 // Assume that such instructions are used for Atomics and be careful
1031 // with optimizations. 1052 // with optimizations.
1032 HasSideEffects = Locked; 1053 HasSideEffects = Locked;
1033 } 1054 }
1034 ~InstX8632Lockable() override {} 1055 ~InstX8632Lockable() override {}
1035 }; 1056 };
1036 1057
1037 // Mul instruction - unsigned multiply. 1058 // Mul instruction - unsigned multiply.
1038 class InstX8632Mul : public InstX8632 { 1059 class InstX8632Mul : public InstX8632 {
1060 InstX8632Mul() = delete;
1039 InstX8632Mul(const InstX8632Mul &) = delete; 1061 InstX8632Mul(const InstX8632Mul &) = delete;
1040 InstX8632Mul &operator=(const InstX8632Mul &) = delete; 1062 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
1041 1063
1042 public: 1064 public:
1043 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, 1065 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
1044 Operand *Source2) { 1066 Operand *Source2) {
1045 return new (Func->allocate<InstX8632Mul>()) 1067 return new (Func->allocate<InstX8632Mul>())
1046 InstX8632Mul(Func, Dest, Source1, Source2); 1068 InstX8632Mul(Func, Dest, Source1, Source2);
1047 } 1069 }
1048 void emit(const Cfg *Func) const override; 1070 void emit(const Cfg *Func) const override;
1049 void emitIAS(const Cfg *Func) const override; 1071 void emitIAS(const Cfg *Func) const override;
1050 void dump(const Cfg *Func) const override; 1072 void dump(const Cfg *Func) const override;
1051 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); } 1073 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
1052 1074
1053 private: 1075 private:
1054 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 1076 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
1055 ~InstX8632Mul() override {} 1077 ~InstX8632Mul() override {}
1056 }; 1078 };
1057 1079
1058 // Shld instruction - shift across a pair of operands. 1080 // Shld instruction - shift across a pair of operands.
1059 class InstX8632Shld : public InstX8632 { 1081 class InstX8632Shld : public InstX8632 {
1082 InstX8632Shld() = delete;
1060 InstX8632Shld(const InstX8632Shld &) = delete; 1083 InstX8632Shld(const InstX8632Shld &) = delete;
1061 InstX8632Shld &operator=(const InstX8632Shld &) = delete; 1084 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
1062 1085
1063 public: 1086 public:
1064 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, 1087 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
1065 Variable *Source2) { 1088 Variable *Source2) {
1066 return new (Func->allocate<InstX8632Shld>()) 1089 return new (Func->allocate<InstX8632Shld>())
1067 InstX8632Shld(Func, Dest, Source1, Source2); 1090 InstX8632Shld(Func, Dest, Source1, Source2);
1068 } 1091 }
1069 void emit(const Cfg *Func) const override; 1092 void emit(const Cfg *Func) const override;
1070 void emitIAS(const Cfg *Func) const override; 1093 void emitIAS(const Cfg *Func) const override;
1071 void dump(const Cfg *Func) const override; 1094 void dump(const Cfg *Func) const override;
1072 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); } 1095 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
1073 1096
1074 private: 1097 private:
1075 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, 1098 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
1076 Variable *Source2); 1099 Variable *Source2);
1077 ~InstX8632Shld() override {} 1100 ~InstX8632Shld() override {}
1078 }; 1101 };
1079 1102
1080 // Shrd instruction - shift across a pair of operands. 1103 // Shrd instruction - shift across a pair of operands.
1081 class InstX8632Shrd : public InstX8632 { 1104 class InstX8632Shrd : public InstX8632 {
1105 InstX8632Shrd() = delete;
1082 InstX8632Shrd(const InstX8632Shrd &) = delete; 1106 InstX8632Shrd(const InstX8632Shrd &) = delete;
1083 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete; 1107 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
1084 1108
1085 public: 1109 public:
1086 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, 1110 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
1087 Variable *Source2) { 1111 Variable *Source2) {
1088 return new (Func->allocate<InstX8632Shrd>()) 1112 return new (Func->allocate<InstX8632Shrd>())
1089 InstX8632Shrd(Func, Dest, Source1, Source2); 1113 InstX8632Shrd(Func, Dest, Source1, Source2);
1090 } 1114 }
1091 void emit(const Cfg *Func) const override; 1115 void emit(const Cfg *Func) const override;
1092 void emitIAS(const Cfg *Func) const override; 1116 void emitIAS(const Cfg *Func) const override;
1093 void dump(const Cfg *Func) const override; 1117 void dump(const Cfg *Func) const override;
1094 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); } 1118 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
1095 1119
1096 private: 1120 private:
1097 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, 1121 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
1098 Variable *Source2); 1122 Variable *Source2);
1099 ~InstX8632Shrd() override {} 1123 ~InstX8632Shrd() override {}
1100 }; 1124 };
1101 1125
1102 // Conditional move instruction. 1126 // Conditional move instruction.
1103 class InstX8632Cmov : public InstX8632 { 1127 class InstX8632Cmov : public InstX8632 {
1128 InstX8632Cmov() = delete;
1104 InstX8632Cmov(const InstX8632Cmov &) = delete; 1129 InstX8632Cmov(const InstX8632Cmov &) = delete;
1105 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete; 1130 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
1106 1131
1107 public: 1132 public:
1108 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, 1133 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
1109 CondX86::BrCond Cond) { 1134 CondX86::BrCond Cond) {
1110 return new (Func->allocate<InstX8632Cmov>()) 1135 return new (Func->allocate<InstX8632Cmov>())
1111 InstX8632Cmov(Func, Dest, Source, Cond); 1136 InstX8632Cmov(Func, Dest, Source, Cond);
1112 } 1137 }
1113 void emit(const Cfg *Func) const override; 1138 void emit(const Cfg *Func) const override;
1114 void emitIAS(const Cfg *Func) const override; 1139 void emitIAS(const Cfg *Func) const override;
1115 void dump(const Cfg *Func) const override; 1140 void dump(const Cfg *Func) const override;
1116 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } 1141 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
1117 1142
1118 private: 1143 private:
1119 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, 1144 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
1120 CondX86::BrCond Cond); 1145 CondX86::BrCond Cond);
1121 ~InstX8632Cmov() override {} 1146 ~InstX8632Cmov() override {}
1122 1147
1123 CondX86::BrCond Condition; 1148 CondX86::BrCond Condition;
1124 }; 1149 };
1125 1150
1126 // Cmpps instruction - compare packed singled-precision floating point 1151 // Cmpps instruction - compare packed singled-precision floating point
1127 // values 1152 // values
1128 class InstX8632Cmpps : public InstX8632 { 1153 class InstX8632Cmpps : public InstX8632 {
1154 InstX8632Cmpps() = delete;
1129 InstX8632Cmpps(const InstX8632Cmpps &) = delete; 1155 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
1130 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete; 1156 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
1131 1157
1132 public: 1158 public:
1133 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, 1159 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
1134 CondX86::CmppsCond Condition) { 1160 CondX86::CmppsCond Condition) {
1135 return new (Func->allocate<InstX8632Cmpps>()) 1161 return new (Func->allocate<InstX8632Cmpps>())
1136 InstX8632Cmpps(Func, Dest, Source, Condition); 1162 InstX8632Cmpps(Func, Dest, Source, Condition);
1137 } 1163 }
1138 void emit(const Cfg *Func) const override; 1164 void emit(const Cfg *Func) const override;
1139 void emitIAS(const Cfg *Func) const override; 1165 void emitIAS(const Cfg *Func) const override;
1140 void dump(const Cfg *Func) const override; 1166 void dump(const Cfg *Func) const override;
1141 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } 1167 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
1142 1168
1143 private: 1169 private:
1144 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, 1170 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
1145 CondX86::CmppsCond Cond); 1171 CondX86::CmppsCond Cond);
1146 ~InstX8632Cmpps() override {} 1172 ~InstX8632Cmpps() override {}
1147 1173
1148 CondX86::CmppsCond Condition; 1174 CondX86::CmppsCond Condition;
1149 }; 1175 };
1150 1176
1151 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> 1177 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
1152 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. 1178 // equals eax. If so, the ZF is set and <desired> is stored in <dest>.
1153 // If not, ZF is cleared and <dest> is copied to eax (or subregister). 1179 // If not, ZF is cleared and <dest> is copied to eax (or subregister).
1154 // <dest> can be a register or memory, while <desired> must be a register. 1180 // <dest> can be a register or memory, while <desired> must be a register.
1155 // It is the user's responsiblity to mark eax with a FakeDef. 1181 // It is the user's responsiblity to mark eax with a FakeDef.
1156 class InstX8632Cmpxchg : public InstX8632Lockable { 1182 class InstX8632Cmpxchg : public InstX8632Lockable {
1183 InstX8632Cmpxchg() = delete;
1157 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete; 1184 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1158 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete; 1185 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
1159 1186
1160 public: 1187 public:
1161 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 1188 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1162 Variable *Desired, bool Locked) { 1189 Variable *Desired, bool Locked) {
1163 return new (Func->allocate<InstX8632Cmpxchg>()) 1190 return new (Func->allocate<InstX8632Cmpxchg>())
1164 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); 1191 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
1165 } 1192 }
1166 void emit(const Cfg *Func) const override; 1193 void emit(const Cfg *Func) const override;
1167 void emitIAS(const Cfg *Func) const override; 1194 void emitIAS(const Cfg *Func) const override;
1168 void dump(const Cfg *Func) const override; 1195 void dump(const Cfg *Func) const override;
1169 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } 1196 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
1170 1197
1171 private: 1198 private:
1172 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 1199 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1173 Variable *Desired, bool Locked); 1200 Variable *Desired, bool Locked);
1174 ~InstX8632Cmpxchg() override {} 1201 ~InstX8632Cmpxchg() override {}
1175 }; 1202 };
1176 1203
1177 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> 1204 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
1178 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. 1205 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
1179 // If not, ZF is cleared and <m64> is copied to edx:eax. 1206 // If not, ZF is cleared and <m64> is copied to edx:eax.
1180 // The caller is responsible for inserting FakeDefs to mark edx 1207 // The caller is responsible for inserting FakeDefs to mark edx
1181 // and eax as modified. 1208 // and eax as modified.
1182 // <m64> must be a memory operand. 1209 // <m64> must be a memory operand.
1183 class InstX8632Cmpxchg8b : public InstX8632Lockable { 1210 class InstX8632Cmpxchg8b : public InstX8632Lockable {
1211 InstX8632Cmpxchg8b() = delete;
1184 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete; 1212 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1185 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete; 1213 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
1186 1214
1187 public: 1215 public:
1188 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest, 1216 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
1189 Variable *Edx, Variable *Eax, Variable *Ecx, 1217 Variable *Edx, Variable *Eax, Variable *Ecx,
1190 Variable *Ebx, bool Locked) { 1218 Variable *Ebx, bool Locked) {
1191 return new (Func->allocate<InstX8632Cmpxchg8b>()) 1219 return new (Func->allocate<InstX8632Cmpxchg8b>())
1192 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); 1220 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
1193 } 1221 }
1194 void emit(const Cfg *Func) const override; 1222 void emit(const Cfg *Func) const override;
1195 void emitIAS(const Cfg *Func) const override; 1223 void emitIAS(const Cfg *Func) const override;
1196 void dump(const Cfg *Func) const override; 1224 void dump(const Cfg *Func) const override;
1197 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } 1225 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
1198 1226
1199 private: 1227 private:
1200 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx, 1228 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
1201 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); 1229 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
1202 ~InstX8632Cmpxchg8b() override {} 1230 ~InstX8632Cmpxchg8b() override {}
1203 }; 1231 };
1204 1232
1205 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} 1233 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
1206 // as appropriate. s=float, d=double, i=int. X and Y are determined 1234 // as appropriate. s=float, d=double, i=int. X and Y are determined
1207 // from dest/src types. Sign and zero extension on the integer 1235 // from dest/src types. Sign and zero extension on the integer
1208 // operand needs to be done separately. 1236 // operand needs to be done separately.
1209 class InstX8632Cvt : public InstX8632 { 1237 class InstX8632Cvt : public InstX8632 {
1238 InstX8632Cvt() = delete;
1210 InstX8632Cvt(const InstX8632Cvt &) = delete; 1239 InstX8632Cvt(const InstX8632Cvt &) = delete;
1211 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete; 1240 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
1212 1241
1213 public: 1242 public:
1214 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; 1243 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
1215 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, 1244 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
1216 CvtVariant Variant) { 1245 CvtVariant Variant) {
1217 return new (Func->allocate<InstX8632Cvt>()) 1246 return new (Func->allocate<InstX8632Cvt>())
1218 InstX8632Cvt(Func, Dest, Source, Variant); 1247 InstX8632Cvt(Func, Dest, Source, Variant);
1219 } 1248 }
1220 void emit(const Cfg *Func) const override; 1249 void emit(const Cfg *Func) const override;
1221 void emitIAS(const Cfg *Func) const override; 1250 void emitIAS(const Cfg *Func) const override;
1222 void dump(const Cfg *Func) const override; 1251 void dump(const Cfg *Func) const override;
1223 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); } 1252 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
1224 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } 1253 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
1225 1254
1226 private: 1255 private:
1227 CvtVariant Variant; 1256 CvtVariant Variant;
1228 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); 1257 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
1229 ~InstX8632Cvt() override {} 1258 ~InstX8632Cvt() override {}
1230 }; 1259 };
1231 1260
1232 // cmp - Integer compare instruction. 1261 // cmp - Integer compare instruction.
1233 class InstX8632Icmp : public InstX8632 { 1262 class InstX8632Icmp : public InstX8632 {
1263 InstX8632Icmp() = delete;
1234 InstX8632Icmp(const InstX8632Icmp &) = delete; 1264 InstX8632Icmp(const InstX8632Icmp &) = delete;
1235 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete; 1265 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
1236 1266
1237 public: 1267 public:
1238 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { 1268 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1239 return new (Func->allocate<InstX8632Icmp>()) 1269 return new (Func->allocate<InstX8632Icmp>())
1240 InstX8632Icmp(Func, Src1, Src2); 1270 InstX8632Icmp(Func, Src1, Src2);
1241 } 1271 }
1242 void emit(const Cfg *Func) const override; 1272 void emit(const Cfg *Func) const override;
1243 void emitIAS(const Cfg *Func) const override; 1273 void emitIAS(const Cfg *Func) const override;
1244 void dump(const Cfg *Func) const override; 1274 void dump(const Cfg *Func) const override;
1245 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } 1275 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
1246 1276
1247 private: 1277 private:
1248 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2); 1278 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
1249 ~InstX8632Icmp() override {} 1279 ~InstX8632Icmp() override {}
1250 }; 1280 };
1251 1281
1252 // ucomiss/ucomisd - floating-point compare instruction. 1282 // ucomiss/ucomisd - floating-point compare instruction.
1253 class InstX8632Ucomiss : public InstX8632 { 1283 class InstX8632Ucomiss : public InstX8632 {
1284 InstX8632Ucomiss() = delete;
1254 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete; 1285 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1255 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete; 1286 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
1256 1287
1257 public: 1288 public:
1258 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { 1289 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1259 return new (Func->allocate<InstX8632Ucomiss>()) 1290 return new (Func->allocate<InstX8632Ucomiss>())
1260 InstX8632Ucomiss(Func, Src1, Src2); 1291 InstX8632Ucomiss(Func, Src1, Src2);
1261 } 1292 }
1262 void emit(const Cfg *Func) const override; 1293 void emit(const Cfg *Func) const override;
1263 void emitIAS(const Cfg *Func) const override; 1294 void emitIAS(const Cfg *Func) const override;
1264 void dump(const Cfg *Func) const override; 1295 void dump(const Cfg *Func) const override;
1265 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); } 1296 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
1266 1297
1267 private: 1298 private:
1268 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); 1299 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
1269 ~InstX8632Ucomiss() override {} 1300 ~InstX8632Ucomiss() override {}
1270 }; 1301 };
1271 1302
1272 // UD2 instruction. 1303 // UD2 instruction.
1273 class InstX8632UD2 : public InstX8632 { 1304 class InstX8632UD2 : public InstX8632 {
1305 InstX8632UD2() = delete;
1274 InstX8632UD2(const InstX8632UD2 &) = delete; 1306 InstX8632UD2(const InstX8632UD2 &) = delete;
1275 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete; 1307 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
1276 1308
1277 public: 1309 public:
1278 static InstX8632UD2 *create(Cfg *Func) { 1310 static InstX8632UD2 *create(Cfg *Func) {
1279 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); 1311 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
1280 } 1312 }
1281 void emit(const Cfg *Func) const override; 1313 void emit(const Cfg *Func) const override;
1282 void emitIAS(const Cfg *Func) const override; 1314 void emitIAS(const Cfg *Func) const override;
1283 void dump(const Cfg *Func) const override; 1315 void dump(const Cfg *Func) const override;
1284 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } 1316 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
1285 1317
1286 private: 1318 private:
1287 InstX8632UD2(Cfg *Func); 1319 explicit InstX8632UD2(Cfg *Func);
1288 ~InstX8632UD2() override {} 1320 ~InstX8632UD2() override {}
1289 }; 1321 };
1290 1322
1291 // Test instruction. 1323 // Test instruction.
1292 class InstX8632Test : public InstX8632 { 1324 class InstX8632Test : public InstX8632 {
1325 InstX8632Test() = delete;
1293 InstX8632Test(const InstX8632Test &) = delete; 1326 InstX8632Test(const InstX8632Test &) = delete;
1294 InstX8632Test &operator=(const InstX8632Test &) = delete; 1327 InstX8632Test &operator=(const InstX8632Test &) = delete;
1295 1328
1296 public: 1329 public:
1297 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { 1330 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
1298 return new (Func->allocate<InstX8632Test>()) 1331 return new (Func->allocate<InstX8632Test>())
1299 InstX8632Test(Func, Source1, Source2); 1332 InstX8632Test(Func, Source1, Source2);
1300 } 1333 }
1301 void emit(const Cfg *Func) const override; 1334 void emit(const Cfg *Func) const override;
1302 void emitIAS(const Cfg *Func) const override; 1335 void emitIAS(const Cfg *Func) const override;
1303 void dump(const Cfg *Func) const override; 1336 void dump(const Cfg *Func) const override;
1304 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } 1337 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
1305 1338
1306 private: 1339 private:
1307 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2); 1340 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
1308 ~InstX8632Test() override {} 1341 ~InstX8632Test() override {}
1309 }; 1342 };
1310 1343
1311 // Mfence instruction. 1344 // Mfence instruction.
1312 class InstX8632Mfence : public InstX8632 { 1345 class InstX8632Mfence : public InstX8632 {
1346 InstX8632Mfence() = delete;
1313 InstX8632Mfence(const InstX8632Mfence &) = delete; 1347 InstX8632Mfence(const InstX8632Mfence &) = delete;
1314 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete; 1348 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
1315 1349
1316 public: 1350 public:
1317 static InstX8632Mfence *create(Cfg *Func) { 1351 static InstX8632Mfence *create(Cfg *Func) {
1318 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func); 1352 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
1319 } 1353 }
1320 void emit(const Cfg *Func) const override; 1354 void emit(const Cfg *Func) const override;
1321 void emitIAS(const Cfg *Func) const override; 1355 void emitIAS(const Cfg *Func) const override;
1322 void dump(const Cfg *Func) const override; 1356 void dump(const Cfg *Func) const override;
1323 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); } 1357 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
1324 1358
1325 private: 1359 private:
1326 InstX8632Mfence(Cfg *Func); 1360 explicit InstX8632Mfence(Cfg *Func);
1327 ~InstX8632Mfence() override {} 1361 ~InstX8632Mfence() override {}
1328 }; 1362 };
1329 1363
1330 // This is essentially a "mov" instruction with an OperandX8632Mem 1364 // This is essentially a "mov" instruction with an OperandX8632Mem
1331 // operand instead of Variable as the destination. It's important 1365 // operand instead of Variable as the destination. It's important
1332 // for liveness that there is no Dest operand. 1366 // for liveness that there is no Dest operand.
1333 class InstX8632Store : public InstX8632 { 1367 class InstX8632Store : public InstX8632 {
1368 InstX8632Store() = delete;
1334 InstX8632Store(const InstX8632Store &) = delete; 1369 InstX8632Store(const InstX8632Store &) = delete;
1335 InstX8632Store &operator=(const InstX8632Store &) = delete; 1370 InstX8632Store &operator=(const InstX8632Store &) = delete;
1336 1371
1337 public: 1372 public:
1338 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { 1373 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1339 return new (Func->allocate<InstX8632Store>()) 1374 return new (Func->allocate<InstX8632Store>())
1340 InstX8632Store(Func, Value, Mem); 1375 InstX8632Store(Func, Value, Mem);
1341 } 1376 }
1342 void emit(const Cfg *Func) const override; 1377 void emit(const Cfg *Func) const override;
1343 void emitIAS(const Cfg *Func) const override; 1378 void emitIAS(const Cfg *Func) const override;
1344 void dump(const Cfg *Func) const override; 1379 void dump(const Cfg *Func) const override;
1345 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); } 1380 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
1346 1381
1347 private: 1382 private:
1348 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem); 1383 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
1349 ~InstX8632Store() override {} 1384 ~InstX8632Store() override {}
1350 }; 1385 };
1351 1386
1352 // This is essentially a vector "mov" instruction with an OperandX8632Mem 1387 // This is essentially a vector "mov" instruction with an OperandX8632Mem
1353 // operand instead of Variable as the destination. It's important 1388 // operand instead of Variable as the destination. It's important
1354 // for liveness that there is no Dest operand. The source must be an 1389 // for liveness that there is no Dest operand. The source must be an
1355 // Xmm register, since Dest is mem. 1390 // Xmm register, since Dest is mem.
1356 class InstX8632StoreP : public InstX8632 { 1391 class InstX8632StoreP : public InstX8632 {
1392 InstX8632StoreP() = delete;
1357 InstX8632StoreP(const InstX8632StoreP &) = delete; 1393 InstX8632StoreP(const InstX8632StoreP &) = delete;
1358 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete; 1394 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
1359 1395
1360 public: 1396 public:
1361 static InstX8632StoreP *create(Cfg *Func, Variable *Value, 1397 static InstX8632StoreP *create(Cfg *Func, Variable *Value,
1362 OperandX8632Mem *Mem) { 1398 OperandX8632Mem *Mem) {
1363 return new (Func->allocate<InstX8632StoreP>()) 1399 return new (Func->allocate<InstX8632StoreP>())
1364 InstX8632StoreP(Func, Value, Mem); 1400 InstX8632StoreP(Func, Value, Mem);
1365 } 1401 }
1366 void emit(const Cfg *Func) const override; 1402 void emit(const Cfg *Func) const override;
1367 void emitIAS(const Cfg *Func) const override; 1403 void emitIAS(const Cfg *Func) const override;
1368 void dump(const Cfg *Func) const override; 1404 void dump(const Cfg *Func) const override;
1369 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); } 1405 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
1370 1406
1371 private: 1407 private:
1372 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); 1408 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
1373 ~InstX8632StoreP() override {} 1409 ~InstX8632StoreP() override {}
1374 }; 1410 };
1375 1411
1376 class InstX8632StoreQ : public InstX8632 { 1412 class InstX8632StoreQ : public InstX8632 {
1413 InstX8632StoreQ() = delete;
1377 InstX8632StoreQ(const InstX8632StoreQ &) = delete; 1414 InstX8632StoreQ(const InstX8632StoreQ &) = delete;
1378 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete; 1415 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
1379 1416
1380 public: 1417 public:
1381 static InstX8632StoreQ *create(Cfg *Func, Variable *Value, 1418 static InstX8632StoreQ *create(Cfg *Func, Variable *Value,
1382 OperandX8632Mem *Mem) { 1419 OperandX8632Mem *Mem) {
1383 return new (Func->allocate<InstX8632StoreQ>()) 1420 return new (Func->allocate<InstX8632StoreQ>())
1384 InstX8632StoreQ(Func, Value, Mem); 1421 InstX8632StoreQ(Func, Value, Mem);
1385 } 1422 }
1386 void emit(const Cfg *Func) const override; 1423 void emit(const Cfg *Func) const override;
1387 void emitIAS(const Cfg *Func) const override; 1424 void emitIAS(const Cfg *Func) const override;
1388 void dump(const Cfg *Func) const override; 1425 void dump(const Cfg *Func) const override;
1389 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } 1426 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1390 1427
1391 private: 1428 private:
1392 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); 1429 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
1393 ~InstX8632StoreQ() override {} 1430 ~InstX8632StoreQ() override {}
1394 }; 1431 };
1395 1432
1396 // Nop instructions of varying length 1433 // Nop instructions of varying length
1397 class InstX8632Nop : public InstX8632 { 1434 class InstX8632Nop : public InstX8632 {
1435 InstX8632Nop() = delete;
1398 InstX8632Nop(const InstX8632Nop &) = delete; 1436 InstX8632Nop(const InstX8632Nop &) = delete;
1399 InstX8632Nop &operator=(const InstX8632Nop &) = delete; 1437 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
1400 1438
1401 public: 1439 public:
1402 // TODO: Replace with enum. 1440 // TODO: Replace with enum.
1403 typedef unsigned NopVariant; 1441 typedef unsigned NopVariant;
1404 1442
1405 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) { 1443 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1406 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant); 1444 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1407 } 1445 }
1408 void emit(const Cfg *Func) const override; 1446 void emit(const Cfg *Func) const override;
1409 void emitIAS(const Cfg *Func) const override; 1447 void emitIAS(const Cfg *Func) const override;
1410 void dump(const Cfg *Func) const override; 1448 void dump(const Cfg *Func) const override;
1411 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); } 1449 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1412 1450
1413 private: 1451 private:
1414 InstX8632Nop(Cfg *Func, SizeT Length); 1452 InstX8632Nop(Cfg *Func, SizeT Length);
1415 ~InstX8632Nop() override {} 1453 ~InstX8632Nop() override {}
1416 1454
1417 NopVariant Variant; 1455 NopVariant Variant;
1418 }; 1456 };
1419 1457
1420 // Fld - load a value onto the x87 FP stack. 1458 // Fld - load a value onto the x87 FP stack.
1421 class InstX8632Fld : public InstX8632 { 1459 class InstX8632Fld : public InstX8632 {
1460 InstX8632Fld() = delete;
1422 InstX8632Fld(const InstX8632Fld &) = delete; 1461 InstX8632Fld(const InstX8632Fld &) = delete;
1423 InstX8632Fld &operator=(const InstX8632Fld &) = delete; 1462 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
1424 1463
1425 public: 1464 public:
1426 static InstX8632Fld *create(Cfg *Func, Operand *Src) { 1465 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1427 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src); 1466 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1428 } 1467 }
1429 void emit(const Cfg *Func) const override; 1468 void emit(const Cfg *Func) const override;
1430 void emitIAS(const Cfg *Func) const override; 1469 void emitIAS(const Cfg *Func) const override;
1431 void dump(const Cfg *Func) const override; 1470 void dump(const Cfg *Func) const override;
1432 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); } 1471 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1433 1472
1434 private: 1473 private:
1435 InstX8632Fld(Cfg *Func, Operand *Src); 1474 InstX8632Fld(Cfg *Func, Operand *Src);
1436 ~InstX8632Fld() override {} 1475 ~InstX8632Fld() override {}
1437 }; 1476 };
1438 1477
1439 // Fstp - store x87 st(0) into memory and pop st(0). 1478 // Fstp - store x87 st(0) into memory and pop st(0).
1440 class InstX8632Fstp : public InstX8632 { 1479 class InstX8632Fstp : public InstX8632 {
1480 InstX8632Fstp() = delete;
1441 InstX8632Fstp(const InstX8632Fstp &) = delete; 1481 InstX8632Fstp(const InstX8632Fstp &) = delete;
1442 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete; 1482 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
1443 1483
1444 public: 1484 public:
1445 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) { 1485 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1446 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest); 1486 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1447 } 1487 }
1448 void emit(const Cfg *Func) const override; 1488 void emit(const Cfg *Func) const override;
1449 void emitIAS(const Cfg *Func) const override; 1489 void emitIAS(const Cfg *Func) const override;
1450 void dump(const Cfg *Func) const override; 1490 void dump(const Cfg *Func) const override;
1451 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); } 1491 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
1452 1492
1453 private: 1493 private:
1454 InstX8632Fstp(Cfg *Func, Variable *Dest); 1494 InstX8632Fstp(Cfg *Func, Variable *Dest);
1455 ~InstX8632Fstp() override {} 1495 ~InstX8632Fstp() override {}
1456 }; 1496 };
1457 1497
1458 class InstX8632Pop : public InstX8632 { 1498 class InstX8632Pop : public InstX8632 {
1499 InstX8632Pop() = delete;
1459 InstX8632Pop(const InstX8632Pop &) = delete; 1500 InstX8632Pop(const InstX8632Pop &) = delete;
1460 InstX8632Pop &operator=(const InstX8632Pop &) = delete; 1501 InstX8632Pop &operator=(const InstX8632Pop &) = delete;
1461 1502
1462 public: 1503 public:
1463 static InstX8632Pop *create(Cfg *Func, Variable *Dest) { 1504 static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
1464 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest); 1505 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
1465 } 1506 }
1466 void emit(const Cfg *Func) const override; 1507 void emit(const Cfg *Func) const override;
1467 void emitIAS(const Cfg *Func) const override; 1508 void emitIAS(const Cfg *Func) const override;
1468 void dump(const Cfg *Func) const override; 1509 void dump(const Cfg *Func) const override;
1469 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } 1510 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1470 1511
1471 private: 1512 private:
1472 InstX8632Pop(Cfg *Func, Variable *Dest); 1513 InstX8632Pop(Cfg *Func, Variable *Dest);
1473 ~InstX8632Pop() override {} 1514 ~InstX8632Pop() override {}
1474 }; 1515 };
1475 1516
1476 class InstX8632Push : public InstX8632 { 1517 class InstX8632Push : public InstX8632 {
1518 InstX8632Push() = delete;
1477 InstX8632Push(const InstX8632Push &) = delete; 1519 InstX8632Push(const InstX8632Push &) = delete;
1478 InstX8632Push &operator=(const InstX8632Push &) = delete; 1520 InstX8632Push &operator=(const InstX8632Push &) = delete;
1479 1521
1480 public: 1522 public:
1481 static InstX8632Push *create(Cfg *Func, Variable *Source) { 1523 static InstX8632Push *create(Cfg *Func, Variable *Source) {
1482 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source); 1524 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source);
1483 } 1525 }
1484 void emit(const Cfg *Func) const override; 1526 void emit(const Cfg *Func) const override;
1485 void emitIAS(const Cfg *Func) const override; 1527 void emitIAS(const Cfg *Func) const override;
1486 void dump(const Cfg *Func) const override; 1528 void dump(const Cfg *Func) const override;
1487 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } 1529 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1488 1530
1489 private: 1531 private:
1490 InstX8632Push(Cfg *Func, Variable *Source); 1532 InstX8632Push(Cfg *Func, Variable *Source);
1491 ~InstX8632Push() override {} 1533 ~InstX8632Push() override {}
1492 }; 1534 };
1493 1535
1494 // Ret instruction. Currently only supports the "ret" version that 1536 // Ret instruction. Currently only supports the "ret" version that
1495 // does not pop arguments. This instruction takes a Source operand 1537 // does not pop arguments. This instruction takes a Source operand
1496 // (for non-void returning functions) for liveness analysis, though 1538 // (for non-void returning functions) for liveness analysis, though
1497 // a FakeUse before the ret would do just as well. 1539 // a FakeUse before the ret would do just as well.
1498 class InstX8632Ret : public InstX8632 { 1540 class InstX8632Ret : public InstX8632 {
1541 InstX8632Ret() = delete;
1499 InstX8632Ret(const InstX8632Ret &) = delete; 1542 InstX8632Ret(const InstX8632Ret &) = delete;
1500 InstX8632Ret &operator=(const InstX8632Ret &) = delete; 1543 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
1501 1544
1502 public: 1545 public:
1503 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) { 1546 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) {
1504 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source); 1547 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1505 } 1548 }
1506 void emit(const Cfg *Func) const override; 1549 void emit(const Cfg *Func) const override;
1507 void emitIAS(const Cfg *Func) const override; 1550 void emitIAS(const Cfg *Func) const override;
1508 void dump(const Cfg *Func) const override; 1551 void dump(const Cfg *Func) const override;
1509 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } 1552 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1510 1553
1511 private: 1554 private:
1512 InstX8632Ret(Cfg *Func, Variable *Source); 1555 InstX8632Ret(Cfg *Func, Variable *Source);
1513 ~InstX8632Ret() override {} 1556 ~InstX8632Ret() override {}
1514 }; 1557 };
1515 1558
1516 // Exchanging Add instruction. Exchanges the first operand (destination 1559 // Exchanging Add instruction. Exchanges the first operand (destination
1517 // operand) with the second operand (source operand), then loads the sum 1560 // operand) with the second operand (source operand), then loads the sum
1518 // of the two values into the destination operand. The destination may be 1561 // of the two values into the destination operand. The destination may be
1519 // a register or memory, while the source must be a register. 1562 // a register or memory, while the source must be a register.
1520 // 1563 //
1521 // Both the dest and source are updated. The caller should then insert a 1564 // Both the dest and source are updated. The caller should then insert a
1522 // FakeDef to reflect the second udpate. 1565 // FakeDef to reflect the second udpate.
1523 class InstX8632Xadd : public InstX8632Lockable { 1566 class InstX8632Xadd : public InstX8632Lockable {
1567 InstX8632Xadd() = delete;
1524 InstX8632Xadd(const InstX8632Xadd &) = delete; 1568 InstX8632Xadd(const InstX8632Xadd &) = delete;
1525 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete; 1569 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
1526 1570
1527 public: 1571 public:
1528 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, 1572 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1529 bool Locked) { 1573 bool Locked) {
1530 return new (Func->allocate<InstX8632Xadd>()) 1574 return new (Func->allocate<InstX8632Xadd>())
1531 InstX8632Xadd(Func, Dest, Source, Locked); 1575 InstX8632Xadd(Func, Dest, Source, Locked);
1532 } 1576 }
1533 void emit(const Cfg *Func) const override; 1577 void emit(const Cfg *Func) const override;
1534 void emitIAS(const Cfg *Func) const override; 1578 void emitIAS(const Cfg *Func) const override;
1535 void dump(const Cfg *Func) const override; 1579 void dump(const Cfg *Func) const override;
1536 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } 1580 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1537 1581
1538 private: 1582 private:
1539 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); 1583 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
1540 ~InstX8632Xadd() override {} 1584 ~InstX8632Xadd() override {}
1541 }; 1585 };
1542 1586
1543 // Exchange instruction. Exchanges the first operand (destination 1587 // Exchange instruction. Exchanges the first operand (destination
1544 // operand) with the second operand (source operand). At least one of 1588 // operand) with the second operand (source operand). At least one of
1545 // the operands must be a register (and the other can be reg or mem). 1589 // the operands must be a register (and the other can be reg or mem).
1546 // Both the Dest and Source are updated. If there is a memory operand, 1590 // Both the Dest and Source are updated. If there is a memory operand,
1547 // then the instruction is automatically "locked" without the need for 1591 // then the instruction is automatically "locked" without the need for
1548 // a lock prefix. 1592 // a lock prefix.
1549 class InstX8632Xchg : public InstX8632 { 1593 class InstX8632Xchg : public InstX8632 {
1594 InstX8632Xchg() = delete;
1550 InstX8632Xchg(const InstX8632Xchg &) = delete; 1595 InstX8632Xchg(const InstX8632Xchg &) = delete;
1551 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete; 1596 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
1552 1597
1553 public: 1598 public:
1554 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { 1599 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1555 return new (Func->allocate<InstX8632Xchg>()) 1600 return new (Func->allocate<InstX8632Xchg>())
1556 InstX8632Xchg(Func, Dest, Source); 1601 InstX8632Xchg(Func, Dest, Source);
1557 } 1602 }
1558 void emit(const Cfg *Func) const override; 1603 void emit(const Cfg *Func) const override;
1559 void emitIAS(const Cfg *Func) const override; 1604 void emitIAS(const Cfg *Func) const override;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; 1649 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const;
1605 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; 1650 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const;
1606 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; 1651 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const;
1607 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; 1652 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const;
1608 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; 1653 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const;
1609 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; 1654 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const;
1610 1655
1611 } // end of namespace Ice 1656 } // end of namespace Ice
1612 1657
1613 #endif // SUBZERO_SRC_ICEINSTX8632_H 1658 #endif // SUBZERO_SRC_ICEINSTX8632_H
OLDNEW
« no previous file with comments | « src/IceInst.h ('k') | src/IceLiveness.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698