| 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 |