OLD | NEW |
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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 static const char *getFldString(Type Ty); | 266 static const char *getFldString(Type Ty); |
267 void dump(const Cfg *Func) const override; | 267 void dump(const Cfg *Func) const override; |
268 | 268 |
269 protected: | 269 protected: |
270 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) | 270 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) |
271 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} | 271 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} |
272 ~InstX8632() override {} | 272 ~InstX8632() override {} |
273 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) { | 273 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) { |
274 return Inst->getKind() == static_cast<InstKind>(MyKind); | 274 return Inst->getKind() == static_cast<InstKind>(MyKind); |
275 } | 275 } |
| 276 // Most instructions that operate on vector arguments require vector |
| 277 // memory operands to be fully aligned (16-byte alignment for PNaCl |
| 278 // vector types). The stack frame layout and call ABI ensure proper |
| 279 // alignment for stack operands, but memory operands (originating |
| 280 // from load/store bitcode instructions) only have element-size |
| 281 // alignment guarantees. This function validates that none of the |
| 282 // operands is a memory operand of vector type, calling |
| 283 // report_fatal_error() if one is found. This function should be |
| 284 // called during emission, and maybe also in the ctor (as long as |
| 285 // that fits the lowering style). |
| 286 void validateVectorAddrMode() const { |
| 287 if (getDest()) |
| 288 validateVectorAddrModeOpnd(getDest()); |
| 289 for (SizeT i = 0; i < getSrcSize(); ++i) { |
| 290 validateVectorAddrModeOpnd(getSrc(i)); |
| 291 } |
| 292 } |
| 293 private: |
| 294 static void validateVectorAddrModeOpnd(const Operand *Opnd) { |
| 295 if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) { |
| 296 llvm::report_fatal_error("Possible misaligned vector memory operation"); |
| 297 } |
| 298 } |
276 }; | 299 }; |
277 | 300 |
278 // InstX8632Label represents an intra-block label that is the target | 301 // InstX8632Label represents an intra-block label that is the target |
279 // of an intra-block branch. The offset between the label and the | 302 // of an intra-block branch. The offset between the label and the |
280 // branch must be fit into one byte (considered "near"). These are | 303 // branch must be fit into one byte (considered "near"). These are |
281 // used for lowering i1 calculations, Select instructions, and 64-bit | 304 // used for lowering i1 calculations, Select instructions, and 64-bit |
282 // compares on a 32-bit architecture, without basic block splitting. | 305 // compares on a 32-bit architecture, without basic block splitting. |
283 // Basic block splitting is not so desirable for several reasons, one | 306 // Basic block splitting is not so desirable for several reasons, one |
284 // of which is the impact on decisions based on whether a variable's | 307 // of which is the impact on decisions based on whether a variable's |
285 // live range spans multiple basic blocks. | 308 // live range spans multiple basic blocks. |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 | 768 |
746 public: | 769 public: |
747 // Create an XMM binary-op instruction like addss or addps. | 770 // Create an XMM binary-op instruction like addss or addps. |
748 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { | 771 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { |
749 return new (Func->allocate<InstX8632BinopXmm>()) | 772 return new (Func->allocate<InstX8632BinopXmm>()) |
750 InstX8632BinopXmm(Func, Dest, Source); | 773 InstX8632BinopXmm(Func, Dest, Source); |
751 } | 774 } |
752 void emit(const Cfg *Func) const override { | 775 void emit(const Cfg *Func) const override { |
753 if (!ALLOW_DUMP) | 776 if (!ALLOW_DUMP) |
754 return; | 777 return; |
| 778 validateVectorAddrMode(); |
755 const bool ShiftHack = false; | 779 const bool ShiftHack = false; |
756 emitTwoAddress(Opcode, this, Func, ShiftHack); | 780 emitTwoAddress(Opcode, this, Func, ShiftHack); |
757 } | 781 } |
758 void emitIAS(const Cfg *Func) const override { | 782 void emitIAS(const Cfg *Func) const override { |
| 783 validateVectorAddrMode(); |
759 Type Ty = getDest()->getType(); | 784 Type Ty = getDest()->getType(); |
760 if (NeedsElementType) | 785 if (NeedsElementType) |
761 Ty = typeElementType(Ty); | 786 Ty = typeElementType(Ty); |
762 assert(getSrcSize() == 2); | 787 assert(getSrcSize() == 2); |
763 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter); | 788 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter); |
764 } | 789 } |
765 void dump(const Cfg *Func) const override { | 790 void dump(const Cfg *Func) const override { |
766 if (!ALLOW_DUMP) | 791 if (!ALLOW_DUMP) |
767 return; | 792 return; |
768 Ostream &Str = Func->getContext()->getStrDump(); | 793 Ostream &Str = Func->getContext()->getStrDump(); |
(...skipping 27 matching lines...) Expand all Loading... |
796 public: | 821 public: |
797 // Create an XMM binary-op shift operation. | 822 // Create an XMM binary-op shift operation. |
798 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, | 823 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, |
799 Operand *Source) { | 824 Operand *Source) { |
800 return new (Func->allocate<InstX8632BinopXmmShift>()) | 825 return new (Func->allocate<InstX8632BinopXmmShift>()) |
801 InstX8632BinopXmmShift(Func, Dest, Source); | 826 InstX8632BinopXmmShift(Func, Dest, Source); |
802 } | 827 } |
803 void emit(const Cfg *Func) const override { | 828 void emit(const Cfg *Func) const override { |
804 if (!ALLOW_DUMP) | 829 if (!ALLOW_DUMP) |
805 return; | 830 return; |
| 831 validateVectorAddrMode(); |
806 const bool ShiftHack = false; | 832 const bool ShiftHack = false; |
807 emitTwoAddress(Opcode, this, Func, ShiftHack); | 833 emitTwoAddress(Opcode, this, Func, ShiftHack); |
808 } | 834 } |
809 void emitIAS(const Cfg *Func) const override { | 835 void emitIAS(const Cfg *Func) const override { |
| 836 validateVectorAddrMode(); |
810 Type Ty = getDest()->getType(); | 837 Type Ty = getDest()->getType(); |
811 assert(AllowAllTypes || isVectorType(Ty)); | 838 assert(AllowAllTypes || isVectorType(Ty)); |
812 Type ElementTy = typeElementType(Ty); | 839 Type ElementTy = typeElementType(Ty); |
813 assert(getSrcSize() == 2); | 840 assert(getSrcSize() == 2); |
814 emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter); | 841 emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter); |
815 } | 842 } |
816 void dump(const Cfg *Func) const override { | 843 void dump(const Cfg *Func) const override { |
817 if (!ALLOW_DUMP) | 844 if (!ALLOW_DUMP) |
818 return; | 845 return; |
819 Ostream &Str = Func->getContext()->getStrDump(); | 846 Ostream &Str = Func->getContext()->getStrDump(); |
(...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1651 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; | 1678 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; |
1652 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; | 1679 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; |
1653 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; | 1680 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; |
1654 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; | 1681 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; |
1655 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; | 1682 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; |
1656 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; | 1683 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; |
1657 | 1684 |
1658 } // end of namespace Ice | 1685 } // end of namespace Ice |
1659 | 1686 |
1660 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1687 #endif // SUBZERO_SRC_ICEINSTX8632_H |
OLD | NEW |