OLD | NEW |
1 //===- subzero/src/IceInstARM32.h - ARM32 machine instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstARM32.h - ARM32 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 InstARM32 and OperandARM32 classes and | 10 // This file declares the InstARM32 and OperandARM32 classes and |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 OperandARM32Mem(Func, Ty, Base, Index, ShiftOp, ShiftAmt, Mode); | 106 OperandARM32Mem(Func, Ty, Base, Index, ShiftOp, ShiftAmt, Mode); |
107 } | 107 } |
108 Variable *getBase() const { return Base; } | 108 Variable *getBase() const { return Base; } |
109 ConstantInteger32 *getOffset() const { return ImmOffset; } | 109 ConstantInteger32 *getOffset() const { return ImmOffset; } |
110 Variable *getIndex() const { return Index; } | 110 Variable *getIndex() const { return Index; } |
111 ShiftKind getShiftOp() const { return ShiftOp; } | 111 ShiftKind getShiftOp() const { return ShiftOp; } |
112 uint16_t getShiftAmt() const { return ShiftAmt; } | 112 uint16_t getShiftAmt() const { return ShiftAmt; } |
113 AddrMode getAddrMode() const { return Mode; } | 113 AddrMode getAddrMode() const { return Mode; } |
114 | 114 |
115 bool isRegReg() const { return Index != nullptr; } | 115 bool isRegReg() const { return Index != nullptr; } |
116 bool isNegAddrMode() const { return Mode >= NegOffset; } | 116 bool isNegAddrMode() const { |
| 117 // Positive address modes have the "U" bit set, and negative modes don't. |
| 118 static_assert((PreIndex & (4 << 21)) != 0, |
| 119 "Positive addr modes should have U bit set."); |
| 120 static_assert((NegPreIndex & (4 << 21)) == 0, |
| 121 "Negative addr modes should have U bit clear."); |
| 122 return (Mode & (4 << 21)) == 0; |
| 123 } |
117 | 124 |
118 void emit(const Cfg *Func) const override; | 125 void emit(const Cfg *Func) const override; |
119 using OperandARM32::dump; | 126 using OperandARM32::dump; |
120 void dump(const Cfg *Func, Ostream &Str) const override; | 127 void dump(const Cfg *Func, Ostream &Str) const override; |
121 | 128 |
122 static bool classof(const Operand *Operand) { | 129 static bool classof(const Operand *Operand) { |
123 return Operand->getKind() == static_cast<OperandKind>(kMem); | 130 return Operand->getKind() == static_cast<OperandKind>(kMem); |
124 } | 131 } |
125 | 132 |
126 // Return true if a load/store instruction for an element of type Ty | 133 // Return true if a load/store instruction for an element of type Ty |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 Eor, | 266 Eor, |
260 Ldr, | 267 Ldr, |
261 Lsl, | 268 Lsl, |
262 Mla, | 269 Mla, |
263 Mov, | 270 Mov, |
264 Movt, | 271 Movt, |
265 Movw, | 272 Movw, |
266 Mul, | 273 Mul, |
267 Mvn, | 274 Mvn, |
268 Orr, | 275 Orr, |
| 276 Pop, |
| 277 Push, |
269 Ret, | 278 Ret, |
270 Sbc, | 279 Sbc, |
271 Sub, | 280 Sub, |
272 Umull | 281 Umull |
273 }; | 282 }; |
274 | 283 |
275 static const char *getWidthString(Type Ty); | 284 static const char *getWidthString(Type Ty); |
276 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); | 285 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); |
277 | 286 |
278 void dump(const Cfg *Func) const override; | 287 void dump(const Cfg *Func) const override; |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 void emitIAS(const Cfg *Func) const override; | 684 void emitIAS(const Cfg *Func) const override; |
676 void dump(const Cfg *Func) const override; | 685 void dump(const Cfg *Func) const override; |
677 static bool classof(const Inst *Inst) { return isClassof(Inst, Mla); } | 686 static bool classof(const Inst *Inst) { return isClassof(Inst, Mla); } |
678 | 687 |
679 private: | 688 private: |
680 InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1, | 689 InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1, |
681 Variable *Acc, CondARM32::Cond Predicate); | 690 Variable *Acc, CondARM32::Cond Predicate); |
682 ~InstARM32Mla() override {} | 691 ~InstARM32Mla() override {} |
683 }; | 692 }; |
684 | 693 |
| 694 // Pop into a list of GPRs. Technically this can be predicated, but we don't |
| 695 // need that functionality. |
| 696 class InstARM32Pop : public InstARM32 { |
| 697 InstARM32Pop() = delete; |
| 698 InstARM32Pop(const InstARM32Pop &) = delete; |
| 699 InstARM32Pop &operator=(const InstARM32Pop &) = delete; |
| 700 |
| 701 public: |
| 702 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { |
| 703 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); |
| 704 } |
| 705 void emit(const Cfg *Func) const override; |
| 706 void emitIAS(const Cfg *Func) const override; |
| 707 void dump(const Cfg *Func) const override; |
| 708 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } |
| 709 |
| 710 private: |
| 711 InstARM32Pop(Cfg *Func, const VarList &Dests); |
| 712 ~InstARM32Pop() override {} |
| 713 VarList Dests; |
| 714 }; |
| 715 |
| 716 // Push a list of GPRs. Technically this can be predicated, but we don't |
| 717 // need that functionality. |
| 718 class InstARM32Push : public InstARM32 { |
| 719 InstARM32Push() = delete; |
| 720 InstARM32Push(const InstARM32Push &) = delete; |
| 721 InstARM32Push &operator=(const InstARM32Push &) = delete; |
| 722 |
| 723 public: |
| 724 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { |
| 725 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); |
| 726 } |
| 727 void emit(const Cfg *Func) const override; |
| 728 void emitIAS(const Cfg *Func) const override; |
| 729 void dump(const Cfg *Func) const override; |
| 730 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } |
| 731 |
| 732 private: |
| 733 InstARM32Push(Cfg *Func, const VarList &Srcs); |
| 734 ~InstARM32Push() override {} |
| 735 }; |
| 736 |
685 // Ret pseudo-instruction. This is actually a "bx" instruction with | 737 // Ret pseudo-instruction. This is actually a "bx" instruction with |
686 // an "lr" register operand, but epilogue lowering will search for a Ret | 738 // an "lr" register operand, but epilogue lowering will search for a Ret |
687 // instead of a generic "bx". This instruction also takes a Source | 739 // instead of a generic "bx". This instruction also takes a Source |
688 // operand (for non-void returning functions) for liveness analysis, though | 740 // operand (for non-void returning functions) for liveness analysis, though |
689 // a FakeUse before the ret would do just as well. | 741 // a FakeUse before the ret would do just as well. |
690 // | 742 // |
691 // NOTE: Even though "bx" can be predicated, for now leave out the predication | 743 // NOTE: Even though "bx" can be predicated, for now leave out the predication |
692 // since it's not yet known to be useful for Ret. That may complicate finding | 744 // since it's not yet known to be useful for Ret. That may complicate finding |
693 // the terminator instruction if it's not guaranteed to be executed. | 745 // the terminator instruction if it's not guaranteed to be executed. |
694 class InstARM32Ret : public InstARM32 { | 746 class InstARM32Ret : public InstARM32 { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 // Declare partial template specializations of emit() methods that | 792 // Declare partial template specializations of emit() methods that |
741 // already have default implementations. Without this, there is the | 793 // already have default implementations. Without this, there is the |
742 // possibility of ODR violations and link errors. | 794 // possibility of ODR violations and link errors. |
743 | 795 |
744 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 796 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
745 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 797 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
746 | 798 |
747 } // end of namespace Ice | 799 } // end of namespace Ice |
748 | 800 |
749 #endif // SUBZERO_SRC_ICEINSTARM32_H | 801 #endif // SUBZERO_SRC_ICEINSTARM32_H |
OLD | NEW |