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 | |
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, Operand *DestSrc0, | |
jvoung (off chromium)
2015/06/16 17:59:21
Can DestSrc0 be type OperandX8632* ? Store uses Op
Jim Stichnoth
2015/06/17 00:15:40
It turns out it can just as well be OperandX8632Me
| |
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) | |
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 |