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 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 Sbc, | 313 Sbc, |
314 Sdiv, | 314 Sdiv, |
315 Str, | 315 Str, |
316 Sub, | 316 Sub, |
317 Sxt, | 317 Sxt, |
318 Trap, | 318 Trap, |
319 Tst, | 319 Tst, |
320 Udiv, | 320 Udiv, |
321 Umull, | 321 Umull, |
322 Uxt, | 322 Uxt, |
| 323 Vabs, |
323 Vadd, | 324 Vadd, |
324 Vcmp, | 325 Vcmp, |
325 Vcvt, | 326 Vcvt, |
326 Vdiv, | 327 Vdiv, |
327 Vldr, | |
328 Vmov, | |
329 Vmrs, | 328 Vmrs, |
330 Vmul, | 329 Vmul, |
331 Vsqrt, | 330 Vsqrt, |
332 Vsub | 331 Vsub |
333 }; | 332 }; |
334 | 333 |
335 static const char *getWidthString(Type Ty); | 334 static const char *getWidthString(Type Ty); |
336 static const char *getVecWidthString(Type Ty); | 335 static const char *getVecWidthString(Type Ty); |
337 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); | 336 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); |
338 | 337 |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; | 772 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; |
774 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; | 773 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; |
775 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; | 774 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; |
776 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; | 775 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; |
777 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; | 776 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; |
778 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; | 777 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; |
779 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; | 778 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; |
780 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; | 779 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; |
781 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; | 780 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; |
782 using InstARM32Ldr = InstARM32Movlike<InstARM32::Ldr>; | 781 using InstARM32Ldr = InstARM32Movlike<InstARM32::Ldr>; |
783 /// Move instruction (variable <- flex). This is more of a pseudo-inst. If var | |
784 /// is a register, then we use "mov". If var is stack, then we use "str" to | |
785 /// store to the stack. | |
786 using InstARM32Mov = InstARM32Movlike<InstARM32::Mov>; | |
787 /// Represents various vector mov instruction forms (simple single source, | |
788 /// single dest forms only, not the 2 GPR <-> 1 D reg forms, etc.). | |
789 using InstARM32Vldr = InstARM32Movlike<InstARM32::Vldr>; | |
790 /// MovT leaves the bottom bits alone so dest is also a source. This helps | 782 /// MovT leaves the bottom bits alone so dest is also a source. This helps |
791 /// indicate that a previous MovW setting dest is not dead code. | 783 /// indicate that a previous MovW setting dest is not dead code. |
792 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; | 784 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; |
793 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; | 785 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; |
794 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; | 786 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; |
795 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; | 787 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; |
796 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; | 788 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; |
797 using InstARM32Rev = InstARM32UnaryopGPR<InstARM32::Rev, false>; | 789 using InstARM32Rev = InstARM32UnaryopGPR<InstARM32::Rev, false>; |
798 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation operand | 790 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation operand |
799 // as well (rotate source by 8, 16, 24 bits prior to extending), but we aren't | 791 // as well (rotate source by 8, 16, 24 bits prior to extending), but we aren't |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcvt); } | 1105 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcvt); } |
1114 | 1106 |
1115 private: | 1107 private: |
1116 InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant, | 1108 InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant, |
1117 CondARM32::Cond Predicate); | 1109 CondARM32::Cond Predicate); |
1118 | 1110 |
1119 const VcvtVariant Variant; | 1111 const VcvtVariant Variant; |
1120 }; | 1112 }; |
1121 | 1113 |
1122 /// Handles (some of) vmov's various formats. | 1114 /// Handles (some of) vmov's various formats. |
1123 class InstARM32Vmov final : public InstARM32Pred { | 1115 class InstARM32Mov final : public InstARM32Pred { |
1124 InstARM32Vmov() = delete; | 1116 InstARM32Mov() = delete; |
1125 InstARM32Vmov(const InstARM32Vmov &) = delete; | 1117 InstARM32Mov(const InstARM32Mov &) = delete; |
1126 InstARM32Vmov &operator=(const InstARM32Vmov &) = delete; | 1118 InstARM32Mov &operator=(const InstARM32Mov &) = delete; |
1127 | 1119 |
1128 public: | 1120 public: |
1129 /// RegisterPair is used to group registers in | 1121 static InstARM32Mov *create(Cfg *Func, Variable *Dest, Operand *Src, |
1130 /// | 1122 CondARM32::Cond Predicate) { |
1131 /// vmov D, (R, R) | 1123 return new (Func->allocate<InstARM32Mov>()) |
1132 /// | 1124 InstARM32Mov(Func, Dest, Src, Predicate); |
1133 /// and | |
1134 /// | |
1135 /// vmov (R, R), D | |
1136 struct RegisterPair { | |
1137 explicit RegisterPair(Variable *V0, Variable *V1) : _0(V0), _1(V1) { | |
1138 assert(V0->getType() == IceType_i32); | |
1139 assert(V1->getType() == IceType_i32); | |
1140 } | |
1141 Variable *_0; | |
1142 Variable *_1; | |
1143 }; | |
1144 | |
1145 static InstARM32Vmov *create(Cfg *Func, Variable *Dest, Operand *Src, | |
1146 CondARM32::Cond Predicate) { | |
1147 return new (Func->allocate<InstARM32Vmov>()) | |
1148 InstARM32Vmov(Func, Dest, Src, Predicate); | |
1149 } | |
1150 static InstARM32Vmov *create(Cfg *Func, const RegisterPair &Dests, | |
1151 Variable *Src, CondARM32::Cond Predicate) { | |
1152 return new (Func->allocate<InstARM32Vmov>()) | |
1153 InstARM32Vmov(Func, Dests, Src, Predicate); | |
1154 } | |
1155 static InstARM32Vmov *create(Cfg *Func, Variable *Dest, | |
1156 const RegisterPair &Srcs, | |
1157 CondARM32::Cond Predicate) { | |
1158 return new (Func->allocate<InstARM32Vmov>()) | |
1159 InstARM32Vmov(Func, Dest, Srcs, Predicate); | |
1160 } | 1125 } |
1161 bool isRedundantAssign() const override { | 1126 bool isRedundantAssign() const override { |
1162 return Dest1 == nullptr && getSrcSize() == 1 && | 1127 return !isMultiDest() && !isMultiSource() && |
1163 checkForRedundantAssign(getDest(), getSrc(0)); | 1128 checkForRedundantAssign(getDest(), getSrc(0)); |
1164 } | 1129 } |
1165 bool isSimpleAssign() const override { return true; } | 1130 bool isSimpleAssign() const override { return true; } |
1166 void emit(const Cfg *Func) const override; | 1131 void emit(const Cfg *Func) const override; |
1167 void emitIAS(const Cfg *Func) const override; | 1132 void emitIAS(const Cfg *Func) const override; |
1168 void dump(const Cfg *Func) const override; | 1133 void dump(const Cfg *Func) const override; |
1169 static bool classof(const Inst *Inst) { return isClassof(Inst, Vmov); } | 1134 static bool classof(const Inst *Inst) { return isClassof(Inst, Mov); } |
1170 | |
1171 private: | |
1172 InstARM32Vmov(Cfg *Func, Variable *Dest, Operand *Src, | |
1173 CondARM32::Cond Predicate) | |
1174 : InstARM32Pred(Func, InstARM32::Vmov, 1, Dest, Predicate) { | |
1175 addSource(Src); | |
1176 } | |
1177 | |
1178 InstARM32Vmov(Cfg *Func, const RegisterPair &Dests, Variable *Src, | |
1179 CondARM32::Cond Predicate) | |
1180 : InstARM32Pred(Func, InstARM32::Vmov, 1, Dests._0, Predicate), | |
1181 Dest1(Dests._1) { | |
1182 addSource(Src); | |
1183 } | |
1184 | |
1185 InstARM32Vmov(Cfg *Func, Variable *Dest, const RegisterPair &Srcs, | |
1186 CondARM32::Cond Predicate) | |
1187 : InstARM32Pred(Func, InstARM32::Vmov, 2, Dest, Predicate) { | |
1188 addSource(Srcs._0); | |
1189 addSource(Srcs._1); | |
1190 } | |
1191 | 1135 |
1192 bool isMultiDest() const { | 1136 bool isMultiDest() const { |
1193 assert(getDest() != nullptr); | 1137 assert(getDest() != nullptr); |
1194 return Dest1 != nullptr; | 1138 return llvm::isa<Variable64On32>(getDest()); |
1195 } | 1139 } |
1196 | 1140 |
1197 bool isMultiSource() const { | 1141 bool isMultiSource() const { |
1198 assert(getSrcSize() >= 1); | 1142 assert(getSrcSize() == 1); |
1199 return getSrcSize() > 1; | 1143 return llvm::isa<Variable64On32>(getSrc(0)); |
| 1144 } |
| 1145 |
| 1146 private: |
| 1147 InstARM32Mov(Cfg *Func, Variable *Dest, Operand *Src, |
| 1148 CondARM32::Cond Predicate) |
| 1149 : InstARM32Pred(Func, InstARM32::Mov, 1, Dest, Predicate) { |
| 1150 addSource(Src); |
1200 } | 1151 } |
1201 | 1152 |
1202 void emitMultiDestSingleSource(const Cfg *Func) const; | 1153 void emitMultiDestSingleSource(const Cfg *Func) const; |
1203 void emitSingleDestMultiSource(const Cfg *Func) const; | 1154 void emitSingleDestMultiSource(const Cfg *Func) const; |
1204 void emitSingleDestSingleSource(const Cfg *Func) const; | 1155 void emitSingleDestSingleSource(const Cfg *Func) const; |
1205 | |
1206 Variable *Dest1 = nullptr; | |
1207 }; | 1156 }; |
1208 | 1157 |
1209 class InstARM32Vcmp final : public InstARM32Pred { | 1158 class InstARM32Vcmp final : public InstARM32Pred { |
1210 InstARM32Vcmp() = delete; | 1159 InstARM32Vcmp() = delete; |
1211 InstARM32Vcmp(const InstARM32Vcmp &) = delete; | 1160 InstARM32Vcmp(const InstARM32Vcmp &) = delete; |
1212 InstARM32Vcmp &operator=(const InstARM32Vcmp &) = delete; | 1161 InstARM32Vcmp &operator=(const InstARM32Vcmp &) = delete; |
1213 | 1162 |
1214 public: | 1163 public: |
1215 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, Variable *Src1, | 1164 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, Variable *Src1, |
1216 CondARM32::Cond Predicate) { | 1165 CondARM32::Cond Predicate) { |
(...skipping 22 matching lines...) Expand all Loading... |
1239 } | 1188 } |
1240 void emit(const Cfg *Func) const override; | 1189 void emit(const Cfg *Func) const override; |
1241 void emitIAS(const Cfg *Func) const override; | 1190 void emitIAS(const Cfg *Func) const override; |
1242 void dump(const Cfg *Func) const override; | 1191 void dump(const Cfg *Func) const override; |
1243 static bool classof(const Inst *Inst) { return isClassof(Inst, Vmrs); } | 1192 static bool classof(const Inst *Inst) { return isClassof(Inst, Vmrs); } |
1244 | 1193 |
1245 private: | 1194 private: |
1246 InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate); | 1195 InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate); |
1247 }; | 1196 }; |
1248 | 1197 |
| 1198 class InstARM32Vabs final : public InstARM32Pred { |
| 1199 InstARM32Vabs() = delete; |
| 1200 InstARM32Vabs(const InstARM32Vabs &) = delete; |
| 1201 InstARM32Vabs &operator=(const InstARM32Vabs &) = delete; |
| 1202 |
| 1203 public: |
| 1204 static InstARM32Vabs *create(Cfg *Func, Variable *Dest, Variable *Src, |
| 1205 CondARM32::Cond Predicate) { |
| 1206 return new (Func->allocate<InstARM32Vabs>()) |
| 1207 InstARM32Vabs(Func, Dest, Src, Predicate); |
| 1208 } |
| 1209 void emit(const Cfg *Func) const override; |
| 1210 void emitIAS(const Cfg *Func) const override; |
| 1211 void dump(const Cfg *Func) const override; |
| 1212 static bool classof(const Inst *Inst) { return isClassof(Inst, Vabs); } |
| 1213 |
| 1214 private: |
| 1215 InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src, |
| 1216 CondARM32::Cond Predicate); |
| 1217 }; |
1249 // Declare partial template specializations of emit() methods that already have | 1218 // Declare partial template specializations of emit() methods that already have |
1250 // default implementations. Without this, there is the possibility of ODR | 1219 // default implementations. Without this, there is the possibility of ODR |
1251 // violations and link errors. | 1220 // violations and link errors. |
1252 | 1221 |
1253 template <> void InstARM32Ldr::emit(const Cfg *Func) const; | 1222 template <> void InstARM32Ldr::emit(const Cfg *Func) const; |
1254 template <> void InstARM32Mov::emit(const Cfg *Func) const; | |
1255 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 1223 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
1256 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 1224 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
1257 template <> void InstARM32Vldr::emit(const Cfg *Func) const; | |
1258 | 1225 |
1259 } // end of namespace Ice | 1226 } // end of namespace Ice |
1260 | 1227 |
1261 #endif // SUBZERO_SRC_ICEINSTARM32_H | 1228 #endif // SUBZERO_SRC_ICEINSTARM32_H |
OLD | NEW |