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 operation on a |
| 318 // memory location. An InstX8632FakeRMW is a "fake" instruction in that it |
| 319 // still needs to be lowered to some actual RMW instruction. |
| 320 // |
| 321 // If A is some memory address, D is some data value to apply, and OP is an |
| 322 // arithmetic operator, the instruction operates as: (*A) = (*A) OP D |
| 323 class InstX8632FakeRMW : public InstX8632 { |
| 324 InstX8632FakeRMW() = delete; |
| 325 InstX8632FakeRMW(const InstX8632FakeRMW &) = delete; |
| 326 InstX8632FakeRMW &operator=(const InstX8632FakeRMW &) = delete; |
| 327 |
| 328 public: |
| 329 static InstX8632FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr, |
| 330 Variable *Beacon, InstArithmetic::OpKind Op, |
| 331 uint32_t Align = 1) { |
| 332 // TODO(stichnot): Stop ignoring alignment specification. |
| 333 (void)Align; |
| 334 return new (Func->allocate<InstX8632FakeRMW>()) |
| 335 InstX8632FakeRMW(Func, Data, Addr, Op, Beacon); |
| 336 } |
| 337 Operand *getAddr() const { return getSrc(1); } |
| 338 Operand *getData() const { return getSrc(0); } |
| 339 InstArithmetic::OpKind getOp() const { return Op; } |
| 340 Variable *getBeacon() const { return llvm::cast<Variable>(getSrc(2)); } |
| 341 void dump(const Cfg *Func) const override; |
| 342 static bool classof(const Inst *Inst) { return isClassof(Inst, FakeRMW); } |
| 343 |
| 344 private: |
| 345 InstArithmetic::OpKind Op; |
| 346 InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, |
| 347 InstArithmetic::OpKind Op, Variable *Beacon); |
| 348 ~InstX8632FakeRMW() override {} |
| 349 }; |
| 350 |
315 // InstX8632Label represents an intra-block label that is the target | 351 // InstX8632Label represents an intra-block label that is the target |
316 // of an intra-block branch. The offset between the label and the | 352 // of an intra-block branch. The offset between the label and the |
317 // branch must be fit into one byte (considered "near"). These are | 353 // branch must be fit into one byte (considered "near"). These are |
318 // used for lowering i1 calculations, Select instructions, and 64-bit | 354 // used for lowering i1 calculations, Select instructions, and 64-bit |
319 // compares on a 32-bit architecture, without basic block splitting. | 355 // compares on a 32-bit architecture, without basic block splitting. |
320 // Basic block splitting is not so desirable for several reasons, one | 356 // 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 | 357 // of which is the impact on decisions based on whether a variable's |
322 // live range spans multiple basic blocks. | 358 // live range spans multiple basic blocks. |
323 // | 359 // |
324 // Intra-block control flow must be used with caution. Consider the | 360 // 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); } | 544 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
509 | 545 |
510 private: | 546 private: |
511 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 547 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
512 ~InstX8632Call() override {} | 548 ~InstX8632Call() override {} |
513 }; | 549 }; |
514 | 550 |
515 // Emit a one-operand (GPR) instruction. | 551 // Emit a one-operand (GPR) instruction. |
516 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, | 552 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, |
517 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter); | 553 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter); |
| 554 void emitIASAsAddrOpTyGPR( |
| 555 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
| 556 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter); |
518 | 557 |
519 // Instructions of the form x := op(x). | 558 // Instructions of the form x := op(x). |
520 template <InstX8632::InstKindX8632 K> | 559 template <InstX8632::InstKindX8632 K> |
521 class InstX8632InplaceopGPR : public InstX8632 { | 560 class InstX8632InplaceopGPR : public InstX8632 { |
522 InstX8632InplaceopGPR() = delete; | 561 InstX8632InplaceopGPR() = delete; |
523 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; | 562 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; |
524 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; | 563 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; |
525 | 564 |
526 public: | 565 public: |
527 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { | 566 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) | 797 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source) |
759 : InstX8632(Func, K, 2, Dest) { | 798 : InstX8632(Func, K, 2, Dest) { |
760 addSource(Dest); | 799 addSource(Dest); |
761 addSource(Source); | 800 addSource(Source); |
762 } | 801 } |
763 ~InstX8632BinopGPR() override {} | 802 ~InstX8632BinopGPR() override {} |
764 static const char *Opcode; | 803 static const char *Opcode; |
765 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter; | 804 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter; |
766 }; | 805 }; |
767 | 806 |
| 807 template <InstX8632::InstKindX8632 K> |
| 808 class InstX8632BinopRMW : public InstX8632 { |
| 809 InstX8632BinopRMW() = delete; |
| 810 InstX8632BinopRMW(const InstX8632BinopRMW &) = delete; |
| 811 InstX8632BinopRMW &operator=(const InstX8632BinopRMW &) = delete; |
| 812 |
| 813 public: |
| 814 // Create an ordinary binary-op instruction like add or sub. |
| 815 static InstX8632BinopRMW *create(Cfg *Func, OperandX8632Mem *DestSrc0, |
| 816 Operand *Src1) { |
| 817 return new (Func->allocate<InstX8632BinopRMW>()) |
| 818 InstX8632BinopRMW(Func, DestSrc0, Src1); |
| 819 } |
| 820 void emit(const Cfg *Func) const override { |
| 821 if (!ALLOW_DUMP) |
| 822 return; |
| 823 const bool ShiftHack = false; |
| 824 emitTwoAddress(Opcode, this, Func, ShiftHack); |
| 825 } |
| 826 void emitIAS(const Cfg *Func) const override { |
| 827 Type Ty = getSrc(0)->getType(); |
| 828 assert(getSrcSize() == 2); |
| 829 emitIASAsAddrOpTyGPR(Func, Ty, getSrc(0), getSrc(1), Emitter); |
| 830 } |
| 831 void dump(const Cfg *Func) const override { |
| 832 if (!ALLOW_DUMP) |
| 833 return; |
| 834 Ostream &Str = Func->getContext()->getStrDump(); |
| 835 Str << Opcode << "." << getSrc(0)->getType() << " "; |
| 836 dumpSources(Func); |
| 837 } |
| 838 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 839 |
| 840 private: |
| 841 InstX8632BinopRMW(Cfg *Func, OperandX8632Mem *DestSrc0, Operand *Src1) |
| 842 : InstX8632(Func, K, 2, nullptr) { |
| 843 addSource(DestSrc0); |
| 844 addSource(Src1); |
| 845 } |
| 846 ~InstX8632BinopRMW() override {} |
| 847 static const char *Opcode; |
| 848 static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter; |
| 849 }; |
| 850 |
768 template <InstX8632::InstKindX8632 K, bool NeedsElementType> | 851 template <InstX8632::InstKindX8632 K, bool NeedsElementType> |
769 class InstX8632BinopXmm : public InstX8632 { | 852 class InstX8632BinopXmm : public InstX8632 { |
770 InstX8632BinopXmm() = delete; | 853 InstX8632BinopXmm() = delete; |
771 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; | 854 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; |
772 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; | 855 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; |
773 | 856 |
774 public: | 857 public: |
775 // Create an XMM binary-op instruction like addss or addps. | 858 // Create an XMM binary-op instruction like addss or addps. |
776 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { | 859 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { |
777 return new (Func->allocate<InstX8632BinopXmm>()) | 860 return new (Func->allocate<InstX8632BinopXmm>()) |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1010 typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd; | 1093 typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd; |
1011 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; | 1094 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; |
1012 // Move/assignment instruction - wrapper for mov/movss/movsd. | 1095 // Move/assignment instruction - wrapper for mov/movss/movsd. |
1013 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; | 1096 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; |
1014 // Move packed - copy 128 bit values between XMM registers, or mem128 | 1097 // Move packed - copy 128 bit values between XMM registers, or mem128 |
1015 // and XMM registers. | 1098 // and XMM registers. |
1016 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; | 1099 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; |
1017 // Movq - copy between XMM registers, or mem64 and XMM registers. | 1100 // Movq - copy between XMM registers, or mem64 and XMM registers. |
1018 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; | 1101 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; |
1019 typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add; | 1102 typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add; |
| 1103 typedef InstX8632BinopRMW<InstX8632::AddRMW> InstX8632AddRMW; |
1020 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; | 1104 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; |
1021 typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc; | 1105 typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc; |
1022 typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss; | 1106 typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss; |
1023 typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd; | 1107 typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd; |
1024 typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub; | 1108 typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub; |
1025 typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps; | 1109 typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps; |
1026 typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss; | 1110 typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss; |
1027 typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb; | 1111 typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb; |
1028 typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub; | 1112 typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub; |
1029 typedef InstX8632BinopGPR<InstX8632::And> InstX8632And; | 1113 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; | 1789 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; |
1706 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; | 1790 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; |
1707 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; | 1791 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; |
1708 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; | 1792 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; |
1709 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; | 1793 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; |
1710 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; | 1794 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; |
1711 | 1795 |
1712 } // end of namespace Ice | 1796 } // end of namespace Ice |
1713 | 1797 |
1714 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1798 #endif // SUBZERO_SRC_ICEINSTX8632_H |
OLD | NEW |