| OLD | NEW |
| 1 //===- subzero/src/IceInstX8632.h - x86-32 machine instructions -*- C++ -*-===// | 1 //===- subzero/src/IceInstX8632.h - x86-32 machine 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 |
| 11 // their subclasses. This represents the machine instructions and | 11 // their subclasses. This represents the machine instructions and |
| 12 // operands used for x86-32 code selection. | 12 // operands used for x86-32 code selection. |
| 13 // | 13 // |
| 14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 15 | 15 |
| 16 #ifndef SUBZERO_SRC_ICEINSTX8632_H | 16 #ifndef SUBZERO_SRC_ICEINSTX8632_H |
| 17 #define SUBZERO_SRC_ICEINSTX8632_H | 17 #define SUBZERO_SRC_ICEINSTX8632_H |
| 18 | 18 |
| 19 #include "IceAssemblerX8632.h" | 19 #include "IceAssemblerX8632.h" |
| 20 #include "IceConditionCodesX8632.h" | 20 #include "IceConditionCodesX8632.h" |
| 21 #include "IceDefs.h" | 21 #include "IceDefs.h" |
| 22 #include "IceInst.h" | 22 #include "IceInst.h" |
| 23 #include "IceInstX8632.def" | 23 #include "IceInstX8632.def" |
| 24 #include "IceOperand.h" | 24 #include "IceOperand.h" |
| 25 #include "IceTargetLoweringX8632Traits.h" |
| 25 | 26 |
| 26 namespace Ice { | 27 namespace Ice { |
| 27 | 28 |
| 28 class TargetX8632; | 29 class TargetX8632; |
| 29 | 30 |
| 30 // OperandX8632 extends the Operand hierarchy. Its subclasses are | 31 // OperandX8632 extends the Operand hierarchy. Its subclasses are |
| 31 // OperandX8632Mem and VariableSplit. | 32 // OperandX8632Mem and VariableSplit. |
| 32 class OperandX8632 : public Operand { | 33 class OperandX8632 : public Operand { |
| 33 OperandX8632() = delete; | 34 OperandX8632() = delete; |
| 34 OperandX8632(const OperandX8632 &) = delete; | 35 OperandX8632(const OperandX8632 &) = delete; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 SegmentRegisters SegmentReg = DefaultSegment) { | 70 SegmentRegisters SegmentReg = DefaultSegment) { |
| 70 return new (Func->allocate<OperandX8632Mem>()) | 71 return new (Func->allocate<OperandX8632Mem>()) |
| 71 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); | 72 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); |
| 72 } | 73 } |
| 73 Variable *getBase() const { return Base; } | 74 Variable *getBase() const { return Base; } |
| 74 Constant *getOffset() const { return Offset; } | 75 Constant *getOffset() const { return Offset; } |
| 75 Variable *getIndex() const { return Index; } | 76 Variable *getIndex() const { return Index; } |
| 76 uint16_t getShift() const { return Shift; } | 77 uint16_t getShift() const { return Shift; } |
| 77 SegmentRegisters getSegmentRegister() const { return SegmentReg; } | 78 SegmentRegisters getSegmentRegister() const { return SegmentReg; } |
| 78 void emitSegmentOverride(X8632::AssemblerX8632 *Asm) const; | 79 void emitSegmentOverride(X8632::AssemblerX8632 *Asm) const; |
| 79 X8632::Address toAsmAddress(Assembler *Asm) const; | 80 X8632::Traits::Address toAsmAddress(Assembler *Asm) const; |
| 80 void emit(const Cfg *Func) const override; | 81 void emit(const Cfg *Func) const override; |
| 81 using OperandX8632::dump; | 82 using OperandX8632::dump; |
| 82 void dump(const Cfg *Func, Ostream &Str) const override; | 83 void dump(const Cfg *Func, Ostream &Str) const override; |
| 83 | 84 |
| 84 static bool classof(const Operand *Operand) { | 85 static bool classof(const Operand *Operand) { |
| 85 return Operand->getKind() == static_cast<OperandKind>(kMem); | 86 return Operand->getKind() == static_cast<OperandKind>(kMem); |
| 86 } | 87 } |
| 87 | 88 |
| 88 void setRandomized(bool R) { Randomized = R; } | 89 void setRandomized(bool R) { Randomized = R; } |
| 89 | 90 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 115 VariableSplit(const VariableSplit &) = delete; | 116 VariableSplit(const VariableSplit &) = delete; |
| 116 VariableSplit &operator=(const VariableSplit &) = delete; | 117 VariableSplit &operator=(const VariableSplit &) = delete; |
| 117 | 118 |
| 118 public: | 119 public: |
| 119 enum Portion { Low, High }; | 120 enum Portion { Low, High }; |
| 120 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { | 121 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { |
| 121 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); | 122 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); |
| 122 } | 123 } |
| 123 int32_t getOffset() const { return Part == High ? 4 : 0; } | 124 int32_t getOffset() const { return Part == High ? 4 : 0; } |
| 124 | 125 |
| 125 X8632::Address toAsmAddress(const Cfg *Func) const; | 126 X8632::Traits::Address toAsmAddress(const Cfg *Func) const; |
| 126 void emit(const Cfg *Func) const override; | 127 void emit(const Cfg *Func) const override; |
| 127 using OperandX8632::dump; | 128 using OperandX8632::dump; |
| 128 void dump(const Cfg *Func, Ostream &Str) const override; | 129 void dump(const Cfg *Func, Ostream &Str) const override; |
| 129 | 130 |
| 130 static bool classof(const Operand *Operand) { | 131 static bool classof(const Operand *Operand) { |
| 131 return Operand->getKind() == static_cast<OperandKind>(kSplit); | 132 return Operand->getKind() == static_cast<OperandKind>(kSplit); |
| 132 } | 133 } |
| 133 | 134 |
| 134 private: | 135 private: |
| 135 VariableSplit(Cfg *Func, Variable *Var, Portion Part) | 136 VariableSplit(Cfg *Func, Variable *Var, Portion Part) |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 Ucomiss, | 273 Ucomiss, |
| 273 UD2, | 274 UD2, |
| 274 Xadd, | 275 Xadd, |
| 275 Xchg, | 276 Xchg, |
| 276 Xor, | 277 Xor, |
| 277 XorRMW | 278 XorRMW |
| 278 }; | 279 }; |
| 279 | 280 |
| 280 static const char *getWidthString(Type Ty); | 281 static const char *getWidthString(Type Ty); |
| 281 static const char *getFldString(Type Ty); | 282 static const char *getFldString(Type Ty); |
| 282 static CondX86::BrCond getOppositeCondition(CondX86::BrCond Cond); | 283 static X8632::Traits::Cond::BrCond |
| 284 getOppositeCondition(X8632::Traits::Cond::BrCond Cond); |
| 283 void dump(const Cfg *Func) const override; | 285 void dump(const Cfg *Func) const override; |
| 284 | 286 |
| 285 // Shared emit routines for common forms of instructions. | 287 // Shared emit routines for common forms of instructions. |
| 286 // See the definition of emitTwoAddress() for a description of | 288 // See the definition of emitTwoAddress() for a description of |
| 287 // ShiftHack. | 289 // ShiftHack. |
| 288 static void emitTwoAddress(const char *Opcode, const Inst *Inst, | 290 static void emitTwoAddress(const char *Opcode, const Inst *Inst, |
| 289 const Cfg *Func, bool ShiftHack = false); | 291 const Cfg *Func, bool ShiftHack = false); |
| 290 | 292 |
| 291 static void | 293 static void |
| 292 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, | 294 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 | 423 |
| 422 // Conditional and unconditional branch instruction. | 424 // Conditional and unconditional branch instruction. |
| 423 class InstX8632Br : public InstX8632 { | 425 class InstX8632Br : public InstX8632 { |
| 424 InstX8632Br() = delete; | 426 InstX8632Br() = delete; |
| 425 InstX8632Br(const InstX8632Br &) = delete; | 427 InstX8632Br(const InstX8632Br &) = delete; |
| 426 InstX8632Br &operator=(const InstX8632Br &) = delete; | 428 InstX8632Br &operator=(const InstX8632Br &) = delete; |
| 427 | 429 |
| 428 public: | 430 public: |
| 429 // Create a conditional branch to a node. | 431 // Create a conditional branch to a node. |
| 430 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, | 432 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, |
| 431 CfgNode *TargetFalse, CondX86::BrCond Condition) { | 433 CfgNode *TargetFalse, |
| 432 assert(Condition != CondX86::Br_None); | 434 X8632::Traits::Cond::BrCond Condition) { |
| 435 assert(Condition != X8632::Traits::Cond::Br_None); |
| 433 const InstX8632Label *NoLabel = nullptr; | 436 const InstX8632Label *NoLabel = nullptr; |
| 434 return new (Func->allocate<InstX8632Br>()) | 437 return new (Func->allocate<InstX8632Br>()) |
| 435 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition); | 438 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition); |
| 436 } | 439 } |
| 437 // Create an unconditional branch to a node. | 440 // Create an unconditional branch to a node. |
| 438 static InstX8632Br *create(Cfg *Func, CfgNode *Target) { | 441 static InstX8632Br *create(Cfg *Func, CfgNode *Target) { |
| 439 const CfgNode *NoCondTarget = nullptr; | 442 const CfgNode *NoCondTarget = nullptr; |
| 440 const InstX8632Label *NoLabel = nullptr; | 443 const InstX8632Label *NoLabel = nullptr; |
| 441 return new (Func->allocate<InstX8632Br>()) | 444 return new (Func->allocate<InstX8632Br>()) InstX8632Br( |
| 442 InstX8632Br(Func, NoCondTarget, Target, NoLabel, CondX86::Br_None); | 445 Func, NoCondTarget, Target, NoLabel, X8632::Traits::Cond::Br_None); |
| 443 } | 446 } |
| 444 // Create a non-terminator conditional branch to a node, with a | 447 // Create a non-terminator conditional branch to a node, with a |
| 445 // fallthrough to the next instruction in the current node. This is | 448 // fallthrough to the next instruction in the current node. This is |
| 446 // used for switch lowering. | 449 // used for switch lowering. |
| 447 static InstX8632Br *create(Cfg *Func, CfgNode *Target, | 450 static InstX8632Br *create(Cfg *Func, CfgNode *Target, |
| 448 CondX86::BrCond Condition) { | 451 X8632::Traits::Cond::BrCond Condition) { |
| 449 assert(Condition != CondX86::Br_None); | 452 assert(Condition != X8632::Traits::Cond::Br_None); |
| 450 const CfgNode *NoUncondTarget = nullptr; | 453 const CfgNode *NoUncondTarget = nullptr; |
| 451 const InstX8632Label *NoLabel = nullptr; | 454 const InstX8632Label *NoLabel = nullptr; |
| 452 return new (Func->allocate<InstX8632Br>()) | 455 return new (Func->allocate<InstX8632Br>()) |
| 453 InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition); | 456 InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition); |
| 454 } | 457 } |
| 455 // Create a conditional intra-block branch (or unconditional, if | 458 // Create a conditional intra-block branch (or unconditional, if |
| 456 // Condition==Br_None) to a label in the current block. | 459 // Condition==Br_None) to a label in the current block. |
| 457 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label, | 460 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label, |
| 458 CondX86::BrCond Condition) { | 461 X8632::Traits::Cond::BrCond Condition) { |
| 459 const CfgNode *NoCondTarget = nullptr; | 462 const CfgNode *NoCondTarget = nullptr; |
| 460 const CfgNode *NoUncondTarget = nullptr; | 463 const CfgNode *NoUncondTarget = nullptr; |
| 461 return new (Func->allocate<InstX8632Br>()) | 464 return new (Func->allocate<InstX8632Br>()) |
| 462 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition); | 465 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition); |
| 463 } | 466 } |
| 464 const CfgNode *getTargetTrue() const { return TargetTrue; } | 467 const CfgNode *getTargetTrue() const { return TargetTrue; } |
| 465 const CfgNode *getTargetFalse() const { return TargetFalse; } | 468 const CfgNode *getTargetFalse() const { return TargetFalse; } |
| 466 bool optimizeBranch(const CfgNode *NextNode); | 469 bool optimizeBranch(const CfgNode *NextNode); |
| 467 uint32_t getEmitInstCount() const override { | 470 uint32_t getEmitInstCount() const override { |
| 468 uint32_t Sum = 0; | 471 uint32_t Sum = 0; |
| 469 if (Label) | 472 if (Label) |
| 470 ++Sum; | 473 ++Sum; |
| 471 if (getTargetTrue()) | 474 if (getTargetTrue()) |
| 472 ++Sum; | 475 ++Sum; |
| 473 if (getTargetFalse()) | 476 if (getTargetFalse()) |
| 474 ++Sum; | 477 ++Sum; |
| 475 return Sum; | 478 return Sum; |
| 476 } | 479 } |
| 477 bool isUnconditionalBranch() const override { | 480 bool isUnconditionalBranch() const override { |
| 478 return !Label && Condition == CondX86::Br_None; | 481 return !Label && Condition == X8632::Traits::Cond::Br_None; |
| 479 } | 482 } |
| 480 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; | 483 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; |
| 481 void emit(const Cfg *Func) const override; | 484 void emit(const Cfg *Func) const override; |
| 482 void emitIAS(const Cfg *Func) const override; | 485 void emitIAS(const Cfg *Func) const override; |
| 483 void dump(const Cfg *Func) const override; | 486 void dump(const Cfg *Func) const override; |
| 484 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } | 487 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } |
| 485 | 488 |
| 486 private: | 489 private: |
| 487 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, | 490 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, |
| 488 const InstX8632Label *Label, CondX86::BrCond Condition); | 491 const InstX8632Label *Label, |
| 492 X8632::Traits::Cond::BrCond Condition); |
| 489 | 493 |
| 490 CondX86::BrCond Condition; | 494 X8632::Traits::Cond::BrCond Condition; |
| 491 const CfgNode *TargetTrue; | 495 const CfgNode *TargetTrue; |
| 492 const CfgNode *TargetFalse; | 496 const CfgNode *TargetFalse; |
| 493 const InstX8632Label *Label; // Intra-block branch target | 497 const InstX8632Label *Label; // Intra-block branch target |
| 494 }; | 498 }; |
| 495 | 499 |
| 496 // Jump to a target outside this function, such as tailcall, nacljump, | 500 // Jump to a target outside this function, such as tailcall, nacljump, |
| 497 // naclret, unreachable. This is different from a Branch instruction | 501 // naclret, unreachable. This is different from a Branch instruction |
| 498 // in that there is no intra-function control flow to represent. | 502 // in that there is no intra-function control flow to represent. |
| 499 class InstX8632Jmp : public InstX8632 { | 503 class InstX8632Jmp : public InstX8632 { |
| 500 InstX8632Jmp() = delete; | 504 InstX8632Jmp() = delete; |
| (...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 }; | 1253 }; |
| 1250 | 1254 |
| 1251 // Conditional move instruction. | 1255 // Conditional move instruction. |
| 1252 class InstX8632Cmov : public InstX8632 { | 1256 class InstX8632Cmov : public InstX8632 { |
| 1253 InstX8632Cmov() = delete; | 1257 InstX8632Cmov() = delete; |
| 1254 InstX8632Cmov(const InstX8632Cmov &) = delete; | 1258 InstX8632Cmov(const InstX8632Cmov &) = delete; |
| 1255 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete; | 1259 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete; |
| 1256 | 1260 |
| 1257 public: | 1261 public: |
| 1258 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, | 1262 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 1259 CondX86::BrCond Cond) { | 1263 X8632::Traits::Cond::BrCond Cond) { |
| 1260 return new (Func->allocate<InstX8632Cmov>()) | 1264 return new (Func->allocate<InstX8632Cmov>()) |
| 1261 InstX8632Cmov(Func, Dest, Source, Cond); | 1265 InstX8632Cmov(Func, Dest, Source, Cond); |
| 1262 } | 1266 } |
| 1263 void emit(const Cfg *Func) const override; | 1267 void emit(const Cfg *Func) const override; |
| 1264 void emitIAS(const Cfg *Func) const override; | 1268 void emitIAS(const Cfg *Func) const override; |
| 1265 void dump(const Cfg *Func) const override; | 1269 void dump(const Cfg *Func) const override; |
| 1266 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } | 1270 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } |
| 1267 | 1271 |
| 1268 private: | 1272 private: |
| 1269 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, | 1273 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, |
| 1270 CondX86::BrCond Cond); | 1274 X8632::Traits::Cond::BrCond Cond); |
| 1271 | 1275 |
| 1272 CondX86::BrCond Condition; | 1276 X8632::Traits::Cond::BrCond Condition; |
| 1273 }; | 1277 }; |
| 1274 | 1278 |
| 1275 // Cmpps instruction - compare packed singled-precision floating point | 1279 // Cmpps instruction - compare packed singled-precision floating point |
| 1276 // values | 1280 // values |
| 1277 class InstX8632Cmpps : public InstX8632 { | 1281 class InstX8632Cmpps : public InstX8632 { |
| 1278 InstX8632Cmpps() = delete; | 1282 InstX8632Cmpps() = delete; |
| 1279 InstX8632Cmpps(const InstX8632Cmpps &) = delete; | 1283 InstX8632Cmpps(const InstX8632Cmpps &) = delete; |
| 1280 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete; | 1284 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete; |
| 1281 | 1285 |
| 1282 public: | 1286 public: |
| 1283 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, | 1287 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 1284 CondX86::CmppsCond Condition) { | 1288 X8632::Traits::Cond::CmppsCond Condition) { |
| 1285 return new (Func->allocate<InstX8632Cmpps>()) | 1289 return new (Func->allocate<InstX8632Cmpps>()) |
| 1286 InstX8632Cmpps(Func, Dest, Source, Condition); | 1290 InstX8632Cmpps(Func, Dest, Source, Condition); |
| 1287 } | 1291 } |
| 1288 void emit(const Cfg *Func) const override; | 1292 void emit(const Cfg *Func) const override; |
| 1289 void emitIAS(const Cfg *Func) const override; | 1293 void emitIAS(const Cfg *Func) const override; |
| 1290 void dump(const Cfg *Func) const override; | 1294 void dump(const Cfg *Func) const override; |
| 1291 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } | 1295 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } |
| 1292 | 1296 |
| 1293 private: | 1297 private: |
| 1294 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, | 1298 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, |
| 1295 CondX86::CmppsCond Cond); | 1299 X8632::Traits::Cond::CmppsCond Cond); |
| 1296 | 1300 |
| 1297 CondX86::CmppsCond Condition; | 1301 X8632::Traits::Cond::CmppsCond Condition; |
| 1298 }; | 1302 }; |
| 1299 | 1303 |
| 1300 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> | 1304 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> |
| 1301 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. | 1305 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. |
| 1302 // If not, ZF is cleared and <dest> is copied to eax (or subregister). | 1306 // If not, ZF is cleared and <dest> is copied to eax (or subregister). |
| 1303 // <dest> can be a register or memory, while <desired> must be a register. | 1307 // <dest> can be a register or memory, while <desired> must be a register. |
| 1304 // It is the user's responsiblity to mark eax with a FakeDef. | 1308 // It is the user's responsiblity to mark eax with a FakeDef. |
| 1305 class InstX8632Cmpxchg : public InstX8632Lockable { | 1309 class InstX8632Cmpxchg : public InstX8632Lockable { |
| 1306 InstX8632Cmpxchg() = delete; | 1310 InstX8632Cmpxchg() = delete; |
| 1307 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete; | 1311 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete; |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1663 }; | 1667 }; |
| 1664 | 1668 |
| 1665 // Conditional set-byte instruction. | 1669 // Conditional set-byte instruction. |
| 1666 class InstX8632Setcc : public InstX8632 { | 1670 class InstX8632Setcc : public InstX8632 { |
| 1667 InstX8632Setcc() = delete; | 1671 InstX8632Setcc() = delete; |
| 1668 InstX8632Setcc(const InstX8632Cmov &) = delete; | 1672 InstX8632Setcc(const InstX8632Cmov &) = delete; |
| 1669 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete; | 1673 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete; |
| 1670 | 1674 |
| 1671 public: | 1675 public: |
| 1672 static InstX8632Setcc *create(Cfg *Func, Variable *Dest, | 1676 static InstX8632Setcc *create(Cfg *Func, Variable *Dest, |
| 1673 CondX86::BrCond Cond) { | 1677 X8632::Traits::Cond::BrCond Cond) { |
| 1674 return new (Func->allocate<InstX8632Setcc>()) | 1678 return new (Func->allocate<InstX8632Setcc>()) |
| 1675 InstX8632Setcc(Func, Dest, Cond); | 1679 InstX8632Setcc(Func, Dest, Cond); |
| 1676 } | 1680 } |
| 1677 void emit(const Cfg *Func) const override; | 1681 void emit(const Cfg *Func) const override; |
| 1678 void emitIAS(const Cfg *Func) const override; | 1682 void emitIAS(const Cfg *Func) const override; |
| 1679 void dump(const Cfg *Func) const override; | 1683 void dump(const Cfg *Func) const override; |
| 1680 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); } | 1684 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); } |
| 1681 | 1685 |
| 1682 private: | 1686 private: |
| 1683 InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond); | 1687 InstX8632Setcc(Cfg *Func, Variable *Dest, X8632::Traits::Cond::BrCond Cond); |
| 1684 | 1688 |
| 1685 const CondX86::BrCond Condition; | 1689 const X8632::Traits::Cond::BrCond Condition; |
| 1686 }; | 1690 }; |
| 1687 | 1691 |
| 1688 // Exchanging Add instruction. Exchanges the first operand (destination | 1692 // Exchanging Add instruction. Exchanges the first operand (destination |
| 1689 // operand) with the second operand (source operand), then loads the sum | 1693 // operand) with the second operand (source operand), then loads the sum |
| 1690 // of the two values into the destination operand. The destination may be | 1694 // of the two values into the destination operand. The destination may be |
| 1691 // a register or memory, while the source must be a register. | 1695 // a register or memory, while the source must be a register. |
| 1692 // | 1696 // |
| 1693 // Both the dest and source are updated. The caller should then insert a | 1697 // Both the dest and source are updated. The caller should then insert a |
| 1694 // FakeDef to reflect the second udpate. | 1698 // FakeDef to reflect the second udpate. |
| 1695 class InstX8632Xadd : public InstX8632Lockable { | 1699 class InstX8632Xadd : public InstX8632Lockable { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1777 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; | 1781 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; |
| 1778 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; | 1782 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; |
| 1779 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; | 1783 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; |
| 1780 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; | 1784 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; |
| 1781 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; | 1785 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; |
| 1782 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; | 1786 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; |
| 1783 | 1787 |
| 1784 } // end of namespace Ice | 1788 } // end of namespace Ice |
| 1785 | 1789 |
| 1786 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1790 #endif // SUBZERO_SRC_ICEINSTX8632_H |
| OLD | NEW |