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 /// \file | 10 /// \file |
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; | 778 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; |
779 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; | 779 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; |
780 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; | 780 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; |
781 using InstARM32Ldr = InstARM32Movlike<InstARM32::Ldr>; | 781 using InstARM32Ldr = InstARM32Movlike<InstARM32::Ldr>; |
782 /// Move instruction (variable <- flex). This is more of a pseudo-inst. | 782 /// Move instruction (variable <- flex). This is more of a pseudo-inst. |
783 /// If var is a register, then we use "mov". If var is stack, then we use | 783 /// If var is a register, then we use "mov". If var is stack, then we use |
784 /// "str" to store to the stack. | 784 /// "str" to store to the stack. |
785 using InstARM32Mov = InstARM32Movlike<InstARM32::Mov>; | 785 using InstARM32Mov = InstARM32Movlike<InstARM32::Mov>; |
786 /// Represents various vector mov instruction forms (simple single source, | 786 /// Represents various vector mov instruction forms (simple single source, |
787 /// single dest forms only, not the 2 GPR <-> 1 D reg forms, etc.). | 787 /// single dest forms only, not the 2 GPR <-> 1 D reg forms, etc.). |
788 using InstARM32Vmov = InstARM32Movlike<InstARM32::Vmov>; | |
789 using InstARM32Vldr = InstARM32Movlike<InstARM32::Vldr>; | 788 using InstARM32Vldr = InstARM32Movlike<InstARM32::Vldr>; |
790 /// MovT leaves the bottom bits alone so dest is also a source. | 789 /// MovT leaves the bottom bits alone so dest is also a source. |
791 /// This helps indicate that a previous MovW setting dest is not dead code. | 790 /// This helps indicate that a previous MovW setting dest is not dead code. |
792 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; | 791 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; |
793 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; | 792 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; |
794 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; | 793 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; |
795 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; | 794 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; |
796 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; | 795 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; |
797 using InstARM32Rev = InstARM32UnaryopGPR<InstARM32::Rev, false>; | 796 using InstARM32Rev = InstARM32UnaryopGPR<InstARM32::Rev, false>; |
798 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation | 797 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 void dump(const Cfg *Func) const override; | 1111 void dump(const Cfg *Func) const override; |
1113 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcvt); } | 1112 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcvt); } |
1114 | 1113 |
1115 private: | 1114 private: |
1116 InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant, | 1115 InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant, |
1117 CondARM32::Cond Predicate); | 1116 CondARM32::Cond Predicate); |
1118 | 1117 |
1119 const VcvtVariant Variant; | 1118 const VcvtVariant Variant; |
1120 }; | 1119 }; |
1121 | 1120 |
| 1121 /// Handles (some of) vmov's various formats. |
| 1122 class InstARM32Vmov final : public InstARM32Pred { |
| 1123 InstARM32Vmov() = delete; |
| 1124 InstARM32Vmov(const InstARM32Vmov &) = delete; |
| 1125 InstARM32Vmov &operator=(const InstARM32Vmov &) = delete; |
| 1126 |
| 1127 public: |
| 1128 /// RegisterPair is used to group registers in |
| 1129 /// |
| 1130 /// vmov D, (R, R) |
| 1131 /// |
| 1132 /// and |
| 1133 /// |
| 1134 /// vmov (R, R), D |
| 1135 struct RegisterPair { |
| 1136 explicit RegisterPair(Variable *V0, Variable *V1) : _0(V0), _1(V1) { |
| 1137 assert(V0->getType() == IceType_i32); |
| 1138 assert(V1->getType() == IceType_i32); |
| 1139 } |
| 1140 Variable *_0; |
| 1141 Variable *_1; |
| 1142 }; |
| 1143 |
| 1144 static InstARM32Vmov *create(Cfg *Func, Variable *Dest, Operand *Src, |
| 1145 CondARM32::Cond Predicate) { |
| 1146 return new (Func->allocate<InstARM32Vmov>()) |
| 1147 InstARM32Vmov(Func, Dest, Src, Predicate); |
| 1148 } |
| 1149 static InstARM32Vmov *create(Cfg *Func, const RegisterPair &Dests, |
| 1150 Variable *Src, CondARM32::Cond Predicate) { |
| 1151 return new (Func->allocate<InstARM32Vmov>()) |
| 1152 InstARM32Vmov(Func, Dests, Src, Predicate); |
| 1153 } |
| 1154 static InstARM32Vmov *create(Cfg *Func, Variable *Dest, |
| 1155 const RegisterPair &Srcs, |
| 1156 CondARM32::Cond Predicate) { |
| 1157 return new (Func->allocate<InstARM32Vmov>()) |
| 1158 InstARM32Vmov(Func, Dest, Srcs, Predicate); |
| 1159 } |
| 1160 bool isRedundantAssign() const override { |
| 1161 return Dest1 == nullptr && getSrcSize() == 1 && |
| 1162 checkForRedundantAssign(getDest(), getSrc(0)); |
| 1163 } |
| 1164 bool isSimpleAssign() const override { return true; } |
| 1165 void emit(const Cfg *Func) const override; |
| 1166 void emitIAS(const Cfg *Func) const override; |
| 1167 void dump(const Cfg *Func) const override; |
| 1168 static bool classof(const Inst *Inst) { return isClassof(Inst, Vmov); } |
| 1169 |
| 1170 private: |
| 1171 InstARM32Vmov(Cfg *Func, Variable *Dest, Operand *Src, |
| 1172 CondARM32::Cond Predicate) |
| 1173 : InstARM32Pred(Func, InstARM32::Vmov, 1, Dest, Predicate) { |
| 1174 addSource(Src); |
| 1175 } |
| 1176 |
| 1177 InstARM32Vmov(Cfg *Func, const RegisterPair &Dests, Variable *Src, |
| 1178 CondARM32::Cond Predicate) |
| 1179 : InstARM32Pred(Func, InstARM32::Vmov, 1, Dests._0, Predicate), |
| 1180 Dest1(Dests._1) { |
| 1181 addSource(Src); |
| 1182 } |
| 1183 |
| 1184 InstARM32Vmov(Cfg *Func, Variable *Dest, const RegisterPair &Srcs, |
| 1185 CondARM32::Cond Predicate) |
| 1186 : InstARM32Pred(Func, InstARM32::Vmov, 2, Dest, Predicate) { |
| 1187 addSource(Srcs._0); |
| 1188 addSource(Srcs._1); |
| 1189 } |
| 1190 |
| 1191 bool isMultiDest() const { |
| 1192 assert(getDest() != nullptr); |
| 1193 return Dest1 != nullptr; |
| 1194 } |
| 1195 |
| 1196 bool isMultiSource() const { |
| 1197 assert(getSrcSize() >= 1); |
| 1198 return getSrcSize() > 1; |
| 1199 } |
| 1200 |
| 1201 void emitMultiDestSingleSource(const Cfg *Func) const; |
| 1202 void emitSingleDestMultiSource(const Cfg *Func) const; |
| 1203 void emitSingleDestSingleSource(const Cfg *Func) const; |
| 1204 |
| 1205 Variable *Dest1 = nullptr; |
| 1206 }; |
| 1207 |
1122 // Declare partial template specializations of emit() methods that | 1208 // Declare partial template specializations of emit() methods that |
1123 // already have default implementations. Without this, there is the | 1209 // already have default implementations. Without this, there is the |
1124 // possibility of ODR violations and link errors. | 1210 // possibility of ODR violations and link errors. |
1125 | 1211 |
1126 template <> void InstARM32Ldr::emit(const Cfg *Func) const; | 1212 template <> void InstARM32Ldr::emit(const Cfg *Func) const; |
1127 template <> void InstARM32Mov::emit(const Cfg *Func) const; | 1213 template <> void InstARM32Mov::emit(const Cfg *Func) const; |
1128 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 1214 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
1129 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 1215 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
1130 template <> void InstARM32Vldr::emit(const Cfg *Func) const; | 1216 template <> void InstARM32Vldr::emit(const Cfg *Func) const; |
1131 template <> void InstARM32Vmov::emit(const Cfg *Func) const; | |
1132 | 1217 |
1133 } // end of namespace Ice | 1218 } // end of namespace Ice |
1134 | 1219 |
1135 #endif // SUBZERO_SRC_ICEINSTARM32_H | 1220 #endif // SUBZERO_SRC_ICEINSTARM32_H |
OLD | NEW |