Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: src/IceInstARM32.h

Issue 1378303003: Subzero. Adds ldrex, strex, and dmb support (ARM32) (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/IceInstARM32.cpp » ('j') | src/IceInstARM32.cpp » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/IceInstARM32.cpp » ('j') | src/IceInstARM32.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698