Chromium Code Reviews| 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 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 class InstX8632 : public InstTarget { | 169 class InstX8632 : public InstTarget { |
| 170 InstX8632() = delete; | 170 InstX8632() = delete; |
| 171 InstX8632(const InstX8632 &) = delete; | 171 InstX8632(const InstX8632 &) = delete; |
| 172 InstX8632 &operator=(const InstX8632 &) = delete; | 172 InstX8632 &operator=(const InstX8632 &) = delete; |
| 173 | 173 |
| 174 public: | 174 public: |
| 175 enum InstKindX8632 { | 175 enum InstKindX8632 { |
| 176 k__Start = Inst::Target, | 176 k__Start = Inst::Target, |
| 177 Adc, | 177 Adc, |
| 178 Add, | 178 Add, |
| 179 AddRMW, | |
| 179 Addps, | 180 Addps, |
| 180 Addss, | 181 Addss, |
| 181 Adjuststack, | 182 Adjuststack, |
| 182 And, | 183 And, |
| 183 Blendvps, | 184 Blendvps, |
| 184 Br, | 185 Br, |
| 185 Bsf, | 186 Bsf, |
| 186 Bsr, | 187 Bsr, |
| 187 Bswap, | 188 Bswap, |
| 188 Call, | 189 Call, |
| 189 Cbwdq, | 190 Cbwdq, |
| 190 Cmov, | 191 Cmov, |
| 191 Cmpps, | 192 Cmpps, |
| 192 Cmpxchg, | 193 Cmpxchg, |
| 193 Cmpxchg8b, | 194 Cmpxchg8b, |
| 194 Cvt, | 195 Cvt, |
| 195 Div, | 196 Div, |
| 196 Divps, | 197 Divps, |
| 197 Divss, | 198 Divss, |
| 199 FakeRMW, | |
| 198 Fld, | 200 Fld, |
| 199 Fstp, | 201 Fstp, |
| 200 Icmp, | 202 Icmp, |
| 201 Idiv, | 203 Idiv, |
| 202 Imul, | 204 Imul, |
| 203 Insertps, | 205 Insertps, |
| 204 Jmp, | 206 Jmp, |
| 205 Label, | 207 Label, |
| 206 Lea, | 208 Lea, |
| 207 Load, | 209 Load, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 } | 307 } |
| 306 | 308 |
| 307 private: | 309 private: |
| 308 static void validateVectorAddrModeOpnd(const Operand *Opnd) { | 310 static void validateVectorAddrModeOpnd(const Operand *Opnd) { |
| 309 if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) { | 311 if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) { |
| 310 llvm::report_fatal_error("Possible misaligned vector memory operation"); | 312 llvm::report_fatal_error("Possible misaligned vector memory operation"); |
| 311 } | 313 } |
| 312 } | 314 } |
| 313 }; | 315 }; |
| 314 | 316 |
| 317 // InstX8632FakeRMW represents a non-atomic read-modify-write | |
|
jvoung (off chromium)
2015/06/17 16:40:22
In this case the "Fake" seems a bit different from
Jim Stichnoth
2015/06/18 05:15:12
Done.
| |
| 318 // operation on a memory location. If A is some memory address, D is | |
| 319 // some data value to apply, and OP is an arithmetic operator, the | |
| 320 // instruction operates as: | |
| 321 // (*A) = (*A) OP D | |
| 322 class InstX8632FakeRMW : public InstX8632 { | |
| 323 InstX8632FakeRMW() = delete; | |
| 324 InstX8632FakeRMW(const InstX8632FakeRMW &) = delete; | |
| 325 InstX8632FakeRMW &operator=(const InstX8632FakeRMW &) = delete; | |
| 326 | |
| 327 public: | |
| 328 static InstX8632FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr, | |
| 329 Variable *Beacon, InstArithmetic::OpKind Op, | |
| 330 uint32_t Align = 1) { | |
| 331 // TODO(stichnot): Stop ignoring alignment specification. | |
| 332 (void)Align; | |
| 333 return new (Func->allocate<InstX8632FakeRMW>()) | |
| 334 InstX8632FakeRMW(Func, Data, Addr, Op, Beacon); | |
| 335 } | |
| 336 Operand *getAddr() const { return getSrc(1); } | |
| 337 Operand *getData() const { return getSrc(0); } | |
| 338 InstArithmetic::OpKind getOp() const { return Op; } | |
| 339 Variable *getBeacon() const { return llvm::cast<Variable>(getSrc(2)); } | |
| 340 void dump(const Cfg *Func) const override; | |
| 341 static bool classof(const Inst *Inst) { return isClassof(Inst, FakeRMW); } | |
| 342 | |
| 343 private: | |
| 344 InstArithmetic::OpKind Op; | |
| 345 InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, | |
| 346 InstArithmetic::OpKind Op, Variable *Beacon); | |
| 347 ~InstX8632FakeRMW() override {} | |
| 348 }; | |
| 349 | |
| 315 // InstX8632Label represents an intra-block label that is the target | 350 // InstX8632Label represents an intra-block label that is the target |
| 316 // of an intra-block branch. The offset between the label and the | 351 // of an intra-block branch. The offset between the label and the |
| 317 // branch must be fit into one byte (considered "near"). These are | 352 // branch must be fit into one byte (considered "near"). These are |
| 318 // used for lowering i1 calculations, Select instructions, and 64-bit | 353 // used for lowering i1 calculations, Select instructions, and 64-bit |
| 319 // compares on a 32-bit architecture, without basic block splitting. | 354 // compares on a 32-bit architecture, without basic block splitting. |
| 320 // Basic block splitting is not so desirable for several reasons, one | 355 // Basic block splitting is not so desirable for several reasons, one |
| 321 // of which is the impact on decisions based on whether a variable's | 356 // of which is the impact on decisions based on whether a variable's |
| 322 // live range spans multiple basic blocks. | 357 // live range spans multiple basic blocks. |
| 323 // | 358 // |
| 324 // Intra-block control flow must be used with caution. Consider the | 359 // Intra-block control flow must be used with caution. Consider the |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 543 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
| 509 | 544 |
| 510 private: | 545 private: |
| 511 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 546 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| 512 ~InstX8632Call() override {} | 547 ~InstX8632Call() override {} |
| 513 }; | 548 }; |
| 514 | 549 |
| 515 // Emit a one-operand (GPR) instruction. | 550 // Emit a one-operand (GPR) instruction. |
| 516 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, | 551 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, |
| 517 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter); | 552 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter); |
| 553 void emitIASAsAddrOpTyGPR( | |
| 554 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, | |
| 555 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter); | |
| 518 | 556 |
| 519 // Instructions of the form x := op(x). | 557 // Instructions of the form x := op(x). |
| 520 template <InstX8632::InstKindX8632 K> | 558 template <InstX8632::InstKindX8632 K> |
| 521 class InstX8632InplaceopGPR : public InstX8632 { | 559 class InstX8632InplaceopGPR : public InstX8632 { |
| 522 InstX8632InplaceopGPR() = delete; | 560 InstX8632InplaceopGPR() = delete; |
| 523 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; | 561 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; |
| 524 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; | 562 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; |
| 525 | 563 |
| 526 public: | 564 public: |
| 527 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { | 565 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 758 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source) | 796 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source) |
| 759 : InstX8632(Func, K, 2, Dest) { | 797 : InstX8632(Func, K, 2, Dest) { |
| 760 addSource(Dest); | 798 addSource(Dest); |
| 761 addSource(Source); | 799 addSource(Source); |
| 762 } | 800 } |
| 763 ~InstX8632BinopGPR() override {} | 801 ~InstX8632BinopGPR() override {} |
| 764 static const char *Opcode; | 802 static const char *Opcode; |
| 765 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter; | 803 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter; |
| 766 }; | 804 }; |
| 767 | 805 |
| 806 template <InstX8632::InstKindX8632 K> | |
| 807 class InstX8632BinopRMW : public InstX8632 { | |
| 808 InstX8632BinopRMW() = delete; | |
| 809 InstX8632BinopRMW(const InstX8632BinopRMW &) = delete; | |
| 810 InstX8632BinopRMW &operator=(const InstX8632BinopRMW &) = delete; | |
| 811 | |
| 812 public: | |
| 813 // Create an ordinary binary-op instruction like add or sub. | |
| 814 static InstX8632BinopRMW *create(Cfg *Func, OperandX8632Mem *DestSrc0, | |
| 815 Operand *Src1) { | |
| 816 return new (Func->allocate<InstX8632BinopRMW>()) | |
| 817 InstX8632BinopRMW(Func, DestSrc0, Src1); | |
| 818 } | |
| 819 void emit(const Cfg *Func) const override { | |
| 820 if (!ALLOW_DUMP) | |
| 821 return; | |
| 822 const bool ShiftHack = false; | |
| 823 emitTwoAddress(Opcode, this, Func, ShiftHack); | |
| 824 } | |
| 825 void emitIAS(const Cfg *Func) const override { | |
| 826 Type Ty = getSrc(0)->getType(); | |
| 827 assert(getSrcSize() == 2); | |
| 828 emitIASAsAddrOpTyGPR(Func, Ty, getSrc(0), getSrc(1), Emitter); | |
| 829 } | |
| 830 void dump(const Cfg *Func) const override { | |
| 831 if (!ALLOW_DUMP) | |
| 832 return; | |
| 833 Ostream &Str = Func->getContext()->getStrDump(); | |
| 834 Str << Opcode << "." << getSrc(0)->getType() << " "; | |
| 835 dumpSources(Func); | |
| 836 } | |
| 837 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | |
| 838 | |
| 839 private: | |
| 840 InstX8632BinopRMW(Cfg *Func, Operand *DestSrc0, Operand *Src1) | |
|
jvoung (off chromium)
2015/06/17 16:40:22
OperandX8632Mem *DestSrc0 too?
Jim Stichnoth
2015/06/18 05:15:12
Done.
| |
| 841 : InstX8632(Func, K, 2, nullptr) { | |
| 842 addSource(DestSrc0); | |
| 843 addSource(Src1); | |
| 844 } | |
| 845 ~InstX8632BinopRMW() override {} | |
| 846 static const char *Opcode; | |
| 847 static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter; | |
| 848 }; | |
| 849 | |
| 768 template <InstX8632::InstKindX8632 K, bool NeedsElementType> | 850 template <InstX8632::InstKindX8632 K, bool NeedsElementType> |
| 769 class InstX8632BinopXmm : public InstX8632 { | 851 class InstX8632BinopXmm : public InstX8632 { |
| 770 InstX8632BinopXmm() = delete; | 852 InstX8632BinopXmm() = delete; |
| 771 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; | 853 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; |
| 772 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; | 854 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; |
| 773 | 855 |
| 774 public: | 856 public: |
| 775 // Create an XMM binary-op instruction like addss or addps. | 857 // Create an XMM binary-op instruction like addss or addps. |
| 776 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { | 858 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 777 return new (Func->allocate<InstX8632BinopXmm>()) | 859 return new (Func->allocate<InstX8632BinopXmm>()) |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1010 typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd; | 1092 typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd; |
| 1011 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; | 1093 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; |
| 1012 // Move/assignment instruction - wrapper for mov/movss/movsd. | 1094 // Move/assignment instruction - wrapper for mov/movss/movsd. |
| 1013 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; | 1095 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; |
| 1014 // Move packed - copy 128 bit values between XMM registers, or mem128 | 1096 // Move packed - copy 128 bit values between XMM registers, or mem128 |
| 1015 // and XMM registers. | 1097 // and XMM registers. |
| 1016 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; | 1098 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; |
| 1017 // Movq - copy between XMM registers, or mem64 and XMM registers. | 1099 // Movq - copy between XMM registers, or mem64 and XMM registers. |
| 1018 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; | 1100 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; |
| 1019 typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add; | 1101 typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add; |
| 1102 typedef InstX8632BinopRMW<InstX8632::AddRMW> InstX8632AddRMW; | |
| 1020 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; | 1103 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; |
| 1021 typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc; | 1104 typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc; |
| 1022 typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss; | 1105 typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss; |
| 1023 typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd; | 1106 typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd; |
| 1024 typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub; | 1107 typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub; |
| 1025 typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps; | 1108 typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps; |
| 1026 typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss; | 1109 typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss; |
| 1027 typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb; | 1110 typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb; |
| 1028 typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub; | 1111 typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub; |
| 1029 typedef InstX8632BinopGPR<InstX8632::And> InstX8632And; | 1112 typedef InstX8632BinopGPR<InstX8632::And> InstX8632And; |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1705 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; | 1788 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; |
| 1706 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; | 1789 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; |
| 1707 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; | 1790 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; |
| 1708 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; | 1791 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; |
| 1709 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; | 1792 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; |
| 1710 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; | 1793 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; |
| 1711 | 1794 |
| 1712 } // end of namespace Ice | 1795 } // end of namespace Ice |
| 1713 | 1796 |
| 1714 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1797 #endif // SUBZERO_SRC_ICEINSTX8632_H |
| OLD | NEW |