| 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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 Adc, | 284 Adc, |
| 285 Add, | 285 Add, |
| 286 Adjuststack, | 286 Adjuststack, |
| 287 And, | 287 And, |
| 288 Asr, | 288 Asr, |
| 289 Bic, | 289 Bic, |
| 290 Br, | 290 Br, |
| 291 Call, | 291 Call, |
| 292 Cmp, | 292 Cmp, |
| 293 Clz, | 293 Clz, |
| 294 Dmb, |
| 294 Eor, | 295 Eor, |
| 295 Label, | 296 Label, |
| 296 Ldr, | 297 Ldr, |
| 298 Ldrex, |
| 297 Lsl, | 299 Lsl, |
| 298 Lsr, | 300 Lsr, |
| 299 Mla, | 301 Mla, |
| 300 Mls, | 302 Mls, |
| 301 Mov, | 303 Mov, |
| 302 Movt, | 304 Movt, |
| 303 Movw, | 305 Movw, |
| 304 Mul, | 306 Mul, |
| 305 Mvn, | 307 Mvn, |
| 306 Orr, | 308 Orr, |
| 307 Pop, | 309 Pop, |
| 308 Push, | 310 Push, |
| 309 Rbit, | 311 Rbit, |
| 310 Ret, | 312 Ret, |
| 311 Rev, | 313 Rev, |
| 312 Rsb, | 314 Rsb, |
| 313 Sbc, | 315 Sbc, |
| 314 Sdiv, | 316 Sdiv, |
| 315 Str, | 317 Str, |
| 318 Strex, |
| 316 Sub, | 319 Sub, |
| 317 Sxt, | 320 Sxt, |
| 318 Trap, | 321 Trap, |
| 319 Tst, | 322 Tst, |
| 320 Udiv, | 323 Udiv, |
| 321 Umull, | 324 Umull, |
| 322 Uxt, | 325 Uxt, |
| 323 Vabs, | 326 Vabs, |
| 324 Vadd, | 327 Vadd, |
| 325 Vcmp, | 328 Vcmp, |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 InstARM32TwoAddrGPR(Cfg *Func, Variable *Dest, Operand *Src, | 521 InstARM32TwoAddrGPR(Cfg *Func, Variable *Dest, Operand *Src, |
| 519 CondARM32::Cond Predicate) | 522 CondARM32::Cond Predicate) |
| 520 : InstARM32Pred(Func, K, 2, Dest, Predicate) { | 523 : InstARM32Pred(Func, K, 2, Dest, Predicate) { |
| 521 addSource(Dest); | 524 addSource(Dest); |
| 522 addSource(Src); | 525 addSource(Src); |
| 523 } | 526 } |
| 524 | 527 |
| 525 static const char *Opcode; | 528 static const char *Opcode; |
| 526 }; | 529 }; |
| 527 | 530 |
| 528 /// Base class for assignment instructions. These can be tested for redundancy | 531 /// Base class for load instructions. |
| 529 /// (and elided if redundant). | |
| 530 template <InstARM32::InstKindARM32 K> | 532 template <InstARM32::InstKindARM32 K> |
| 531 class InstARM32Movlike : public InstARM32Pred { | 533 class InstARM32LoadBase : public InstARM32Pred { |
| 532 InstARM32Movlike() = delete; | 534 InstARM32LoadBase() = delete; |
| 533 InstARM32Movlike(const InstARM32Movlike &) = delete; | 535 InstARM32LoadBase(const InstARM32LoadBase &) = delete; |
| 534 InstARM32Movlike &operator=(const InstARM32Movlike &) = delete; | 536 InstARM32LoadBase &operator=(const InstARM32LoadBase &) = delete; |
| 535 | 537 |
| 536 public: | 538 public: |
| 537 static InstARM32Movlike *create(Cfg *Func, Variable *Dest, Operand *Source, | 539 static InstARM32LoadBase *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 538 CondARM32::Cond Predicate) { | 540 CondARM32::Cond Predicate) { |
| 539 return new (Func->allocate<InstARM32Movlike>()) | 541 return new (Func->allocate<InstARM32LoadBase>()) |
| 540 InstARM32Movlike(Func, Dest, Source, Predicate); | 542 InstARM32LoadBase(Func, Dest, Source, Predicate); |
| 541 } | 543 } |
| 542 bool isRedundantAssign() const override { | |
| 543 return checkForRedundantAssign(getDest(), getSrc(0)); | |
| 544 } | |
| 545 bool isSimpleAssign() const override { return true; } | |
| 546 void emit(const Cfg *Func) const override; | 544 void emit(const Cfg *Func) const override; |
| 547 void emitIAS(const Cfg *Func) const override; | 545 void emitIAS(const Cfg *Func) const override; |
| 548 void dump(const Cfg *Func) const override { | 546 void dump(const Cfg *Func) const override { |
| 549 if (!BuildDefs::dump()) | 547 if (!BuildDefs::dump()) |
| 550 return; | 548 return; |
| 551 Ostream &Str = Func->getContext()->getStrDump(); | 549 Ostream &Str = Func->getContext()->getStrDump(); |
| 552 dumpOpcodePred(Str, Opcode, getDest()->getType()); | 550 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
| 553 Str << " "; | 551 Str << " "; |
| 554 dumpDest(Func); | 552 dumpDest(Func); |
| 555 Str << ", "; | 553 Str << ", "; |
| 556 dumpSources(Func); | 554 dumpSources(Func); |
| 557 } | 555 } |
| 558 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 556 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 559 | 557 |
| 560 private: | 558 private: |
| 561 InstARM32Movlike(Cfg *Func, Variable *Dest, Operand *Source, | 559 InstARM32LoadBase(Cfg *Func, Variable *Dest, Operand *Source, |
| 562 CondARM32::Cond Predicate) | 560 CondARM32::Cond Predicate) |
| 563 : InstARM32Pred(Func, K, 1, Dest, Predicate) { | 561 : InstARM32Pred(Func, K, 1, Dest, Predicate) { |
| 564 addSource(Source); | 562 addSource(Source); |
| 565 } | 563 } |
| 566 | 564 |
| 567 static const char *Opcode; | 565 static const char *Opcode; |
| 568 }; | 566 }; |
| 569 | 567 |
| 570 /// Instructions of the form x := y op z. May have the side-effect of setting | 568 /// Instructions of the form x := y op z. May have the side-effect of setting |
| 571 /// status flags. | 569 /// status flags. |
| 572 template <InstARM32::InstKindARM32 K> | 570 template <InstARM32::InstKindARM32 K> |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; | 769 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; |
| 772 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; | 770 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; |
| 773 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; | 771 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; |
| 774 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; | 772 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; |
| 775 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; | 773 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; |
| 776 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; | 774 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; |
| 777 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; | 775 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; |
| 778 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; | 776 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; |
| 779 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; | 777 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; |
| 780 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; | 778 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; |
| 781 using InstARM32Ldr = InstARM32Movlike<InstARM32::Ldr>; | 779 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>; |
| 780 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>; |
| 782 /// MovT leaves the bottom bits alone so dest is also a source. This helps | 781 /// MovT leaves the bottom bits alone so dest is also a source. This helps |
| 783 /// indicate that a previous MovW setting dest is not dead code. | 782 /// indicate that a previous MovW setting dest is not dead code. |
| 784 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; | 783 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; |
| 785 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; | 784 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; |
| 786 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; | 785 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; |
| 787 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; | 786 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; |
| 788 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; | 787 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; |
| 789 using InstARM32Rev = InstARM32UnaryopGPR<InstARM32::Rev, false>; | 788 using InstARM32Rev = InstARM32UnaryopGPR<InstARM32::Rev, false>; |
| 790 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation operand | 789 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation operand |
| 791 // as well (rotate source by 8, 16, 24 bits prior to extending), but we aren't | 790 // as well (rotate source by 8, 16, 24 bits prior to extending), but we aren't |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 void emitIAS(const Cfg *Func) const override; | 1012 void emitIAS(const Cfg *Func) const override; |
| 1014 void dump(const Cfg *Func) const override; | 1013 void dump(const Cfg *Func) const override; |
| 1015 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } | 1014 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } |
| 1016 | 1015 |
| 1017 private: | 1016 private: |
| 1018 InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source); | 1017 InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source); |
| 1019 }; | 1018 }; |
| 1020 | 1019 |
| 1021 /// Store instruction. It's important for liveness that there is no Dest operand | 1020 /// Store instruction. It's important for liveness that there is no Dest operand |
| 1022 /// (OperandARM32Mem instead of Dest Variable). | 1021 /// (OperandARM32Mem instead of Dest Variable). |
| 1023 class InstARM32Str : public InstARM32Pred { | 1022 class InstARM32Str final : public InstARM32Pred { |
| 1024 InstARM32Str() = delete; | 1023 InstARM32Str() = delete; |
| 1025 InstARM32Str(const InstARM32Str &) = delete; | 1024 InstARM32Str(const InstARM32Str &) = delete; |
| 1026 InstARM32Str &operator=(const InstARM32Str &) = delete; | 1025 InstARM32Str &operator=(const InstARM32Str &) = delete; |
| 1027 | 1026 |
| 1028 public: | 1027 public: |
| 1029 /// Value must be a register. | 1028 /// Value must be a register. |
| 1030 static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 1029 static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| 1031 CondARM32::Cond Predicate) { | 1030 CondARM32::Cond Predicate) { |
| 1032 return new (Func->allocate<InstARM32Str>()) | 1031 return new (Func->allocate<InstARM32Str>()) |
| 1033 InstARM32Str(Func, Value, Mem, Predicate); | 1032 InstARM32Str(Func, Value, Mem, Predicate); |
| 1034 } | 1033 } |
| 1035 void emit(const Cfg *Func) const override; | 1034 void emit(const Cfg *Func) const override; |
| 1036 void emitIAS(const Cfg *Func) const override; | 1035 void emitIAS(const Cfg *Func) const override; |
| 1037 void dump(const Cfg *Func) const override; | 1036 void dump(const Cfg *Func) const override; |
| 1038 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); } | 1037 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); } |
| 1039 | 1038 |
| 1040 private: | 1039 private: |
| 1041 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 1040 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| 1042 CondARM32::Cond Predicate); | 1041 CondARM32::Cond Predicate); |
| 1043 }; | 1042 }; |
| 1044 | 1043 |
| 1044 /// Exclusive Store instruction. Like its non-exclusive sibling, it's important |
| 1045 /// for liveness that there is no Dest operand (OperandARM32Mem instead of Dest |
| 1046 /// Variable). |
| 1047 class InstARM32Strex final : public InstARM32Pred { |
| 1048 InstARM32Strex() = delete; |
| 1049 InstARM32Strex(const InstARM32Strex &) = delete; |
| 1050 InstARM32Strex &operator=(const InstARM32Strex &) = delete; |
| 1051 |
| 1052 public: |
| 1053 /// Value must be a register. |
| 1054 static InstARM32Strex *create(Cfg *Func, Variable *Dest, Variable *Value, |
| 1055 OperandARM32Mem *Mem, |
| 1056 CondARM32::Cond Predicate) { |
| 1057 return new (Func->allocate<InstARM32Strex>()) |
| 1058 InstARM32Strex(Func, Dest, Value, Mem, Predicate); |
| 1059 } |
| 1060 void emit(const Cfg *Func) const override; |
| 1061 void emitIAS(const Cfg *Func) const override; |
| 1062 void dump(const Cfg *Func) const override; |
| 1063 static bool classof(const Inst *Inst) { return isClassof(Inst, Strex); } |
| 1064 |
| 1065 private: |
| 1066 InstARM32Strex(Cfg *Func, Variable *Dest, Variable *Value, |
| 1067 OperandARM32Mem *Mem, CondARM32::Cond Predicate); |
| 1068 }; |
| 1069 |
| 1045 class InstARM32Trap : public InstARM32 { | 1070 class InstARM32Trap : public InstARM32 { |
| 1046 InstARM32Trap() = delete; | 1071 InstARM32Trap() = delete; |
| 1047 InstARM32Trap(const InstARM32Trap &) = delete; | 1072 InstARM32Trap(const InstARM32Trap &) = delete; |
| 1048 InstARM32Trap &operator=(const InstARM32Trap &) = delete; | 1073 InstARM32Trap &operator=(const InstARM32Trap &) = delete; |
| 1049 | 1074 |
| 1050 public: | 1075 public: |
| 1051 static InstARM32Trap *create(Cfg *Func) { | 1076 static InstARM32Trap *create(Cfg *Func) { |
| 1052 return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func); | 1077 return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func); |
| 1053 } | 1078 } |
| 1054 void emit(const Cfg *Func) const override; | 1079 void emit(const Cfg *Func) const override; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 } | 1231 } |
| 1207 void emit(const Cfg *Func) const override; | 1232 void emit(const Cfg *Func) const override; |
| 1208 void emitIAS(const Cfg *Func) const override; | 1233 void emitIAS(const Cfg *Func) const override; |
| 1209 void dump(const Cfg *Func) const override; | 1234 void dump(const Cfg *Func) const override; |
| 1210 static bool classof(const Inst *Inst) { return isClassof(Inst, Vabs); } | 1235 static bool classof(const Inst *Inst) { return isClassof(Inst, Vabs); } |
| 1211 | 1236 |
| 1212 private: | 1237 private: |
| 1213 InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src, | 1238 InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src, |
| 1214 CondARM32::Cond Predicate); | 1239 CondARM32::Cond Predicate); |
| 1215 }; | 1240 }; |
| 1241 |
| 1242 class InstARM32Dmb final : public InstARM32Pred { |
| 1243 InstARM32Dmb() = delete; |
| 1244 InstARM32Dmb(const InstARM32Dmb &) = delete; |
| 1245 InstARM32Dmb &operator=(const InstARM32Dmb &) = delete; |
| 1246 |
| 1247 public: |
| 1248 static InstARM32Dmb *create(Cfg *Func) { |
| 1249 return new (Func->allocate<InstARM32Dmb>()) InstARM32Dmb(Func); |
| 1250 } |
| 1251 void emit(const Cfg *Func) const override; |
| 1252 void emitIAS(const Cfg *Func) const override; |
| 1253 void dump(const Cfg *Func) const override; |
| 1254 static bool classof(const Inst *Inst) { return isClassof(Inst, Dmb); } |
| 1255 |
| 1256 private: |
| 1257 explicit InstARM32Dmb(Cfg *Func); |
| 1258 }; |
| 1259 |
| 1216 // Declare partial template specializations of emit() methods that already have | 1260 // Declare partial template specializations of emit() methods that already have |
| 1217 // default implementations. Without this, there is the possibility of ODR | 1261 // default implementations. Without this, there is the possibility of ODR |
| 1218 // violations and link errors. | 1262 // violations and link errors. |
| 1219 | 1263 |
| 1220 template <> void InstARM32Ldr::emit(const Cfg *Func) const; | 1264 template <> void InstARM32Ldr::emit(const Cfg *Func) const; |
| 1221 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 1265 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
| 1222 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 1266 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
| 1223 | 1267 |
| 1224 } // end of namespace Ice | 1268 } // end of namespace Ice |
| 1225 | 1269 |
| 1226 #endif // SUBZERO_SRC_ICEINSTARM32_H | 1270 #endif // SUBZERO_SRC_ICEINSTARM32_H |
| OLD | NEW |