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