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

Side by Side Diff: src/IceInstARM32.h

Issue 1481133002: Subzero. ARM32. Show FP lowering some love. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years 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
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 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 Tst, 411 Tst,
412 Udiv, 412 Udiv,
413 Umull, 413 Umull,
414 Uxt, 414 Uxt,
415 Vabs, 415 Vabs,
416 Vadd, 416 Vadd,
417 Vcmp, 417 Vcmp,
418 Vcvt, 418 Vcvt,
419 Vdiv, 419 Vdiv,
420 Veor, 420 Veor,
421 Vmla,
422 Vmls,
421 Vmrs, 423 Vmrs,
422 Vmul, 424 Vmul,
423 Vsqrt, 425 Vsqrt,
424 Vsub 426 Vsub
425 }; 427 };
426 428
427 static constexpr size_t InstSize = sizeof(uint32_t); 429 static constexpr size_t InstSize = sizeof(uint32_t);
428 430
429 static const char *getWidthString(Type Ty); 431 static const char *getWidthString(Type Ty);
430 static const char *getVecWidthString(Type Ty); 432 static const char *getVecWidthString(Type Ty);
431 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); 433 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond);
432 434
433 /// Called inside derived methods emit() to communicate that multiple 435 /// Called inside derived methods emit() to communicate that multiple
434 /// instructions are being generated. Used by emitIAS() methods to 436 /// instructions are being generated. Used by emitIAS() methods to
435 /// generate textual fixups for instructions that are not yet 437 /// generate textual fixups for instructions that are not yet
436 /// implemented. 438 /// implemented.
437 void startNextInst(const Cfg *Func) const; 439 void startNextInst(const Cfg *Func) const;
438 440
439 /// Shared emit routines for common forms of instructions. 441 /// Shared emit routines for common forms of instructions.
440 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, 442 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst,
441 const Cfg *Func); 443 const Cfg *Func);
444 static void emitFourAddrFP(const char *Opcode, const InstARM32 *Inst,
445 const Cfg *Func);
442 446
443 void dump(const Cfg *Func) const override; 447 void dump(const Cfg *Func) const override;
444 448
445 void emitIAS(const Cfg *Func) const override; 449 void emitIAS(const Cfg *Func) const override;
446 450
447 protected: 451 protected:
448 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) 452 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest)
449 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 453 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
450 454
451 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { 455 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) {
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { 705 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) {
702 HasSideEffects = SetFlags; 706 HasSideEffects = SetFlags;
703 addSource(Src0); 707 addSource(Src0);
704 addSource(Src1); 708 addSource(Src1);
705 } 709 }
706 710
707 static const char *Opcode; 711 static const char *Opcode;
708 bool SetFlags; 712 bool SetFlags;
709 }; 713 };
710 714
711 /// Instructions of the form x := y op z, for vector/FP. We leave these as 715 /// Instructions of the form x := y op z, for vector/FP. we leave these as
Jim Stichnoth 2015/12/07 20:58:14 I think you accidentally lower-cased most of this
John 2015/12/08 13:54:24 Done.
712 /// unconditional: "ARM deprecates the conditional execution of any instruction 716 /// unconditional: "arm deprecates the conditional execution of any instruction
713 /// encoding provided by the Advanced SIMD Extension that is not also provided 717 /// encoding provided by the advanced simd extension that is not also provided
714 /// by the Floating-point (VFP) extension". They do not set flags. 718 /// by the floating-point (vfp) extension". they do not set flags.
Karl 2015/12/07 19:11:07 Why are "We" and "They" switched to "we" and "they
John 2015/12/08 13:54:24 I honestly do not know what happened here... o.O
715 template <InstARM32::InstKindARM32 K> 719 template <InstARM32::InstKindARM32 K>
716 class InstARM32ThreeAddrFP : public InstARM32 { 720 class InstARM32ThreeAddrFP : public InstARM32 {
717 InstARM32ThreeAddrFP() = delete; 721 InstARM32ThreeAddrFP() = delete;
718 InstARM32ThreeAddrFP(const InstARM32ThreeAddrFP &) = delete; 722 InstARM32ThreeAddrFP(const InstARM32ThreeAddrFP &) = delete;
719 InstARM32ThreeAddrFP &operator=(const InstARM32ThreeAddrFP &) = delete; 723 InstARM32ThreeAddrFP &operator=(const InstARM32ThreeAddrFP &) = delete;
720 724
721 public: 725 public:
722 /// Create a vector/FP binary-op instruction like vadd, and vsub. Everything 726 /// Create a vector/FP binary-op instruction like vadd, and vsub. Everything
723 /// must be a register. 727 /// must be a register.
724 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0, 728 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 CondARM32::Cond Predicate) 796 CondARM32::Cond Predicate)
793 : InstARM32Pred(Func, K, 3, Dest, Predicate) { 797 : InstARM32Pred(Func, K, 3, Dest, Predicate) {
794 addSource(Src0); 798 addSource(Src0);
795 addSource(Src1); 799 addSource(Src1);
796 addSource(Src2); 800 addSource(Src2);
797 } 801 }
798 802
799 static const char *Opcode; 803 static const char *Opcode;
800 }; 804 };
801 805
806 /// Instructions of the form x := x op1 (y op2 z). E.g., multiply accumulate.
807 /// we leave these as unconditional: "arm deprecates the conditional execution
Jim Stichnoth 2015/12/07 20:58:14 Capitalization, as above.
John 2015/12/08 13:54:24 Done.
808 /// of any instruction encoding provided by the advanced simd extension that is
809 /// not also provided by the floating-point (vfp) extension". they do not set
Karl 2015/12/07 19:11:07 Same here for "they" (last sentence).
John 2015/12/08 13:54:24 Done.
810 /// flags.
811 template <InstARM32::InstKindARM32 K>
812 class InstARM32FourAddrFP : public InstARM32 {
813 InstARM32FourAddrFP() = delete;
814 InstARM32FourAddrFP(const InstARM32FourAddrFP &) = delete;
815 InstARM32FourAddrFP &operator=(const InstARM32FourAddrFP &) = delete;
816
817 public:
818 // Every operand must be a register.
819 static InstARM32FourAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0,
820 Variable *Src1) {
821 return new (Func->allocate<InstARM32FourAddrFP>())
822 InstARM32FourAddrFP(Func, Dest, Src0, Src1);
823 }
824 void emit(const Cfg *Func) const override {
825 if (!BuildDefs::dump())
826 return;
827 emitFourAddrFP(Opcode, this, Func);
828 }
829 void emitIAS(const Cfg *Func) const override { emitUsingTextFixup(Func); }
830 void dump(const Cfg *Func) const override {
831 if (!BuildDefs::dump())
832 return;
833 Ostream &Str = Func->getContext()->getStrDump();
834 dumpDest(Func);
835 Str << " = ";
836 Str << Opcode << "." << getDest()->getType() << " ";
837 dumpDest(Func);
Jim Stichnoth 2015/12/07 20:58:14 Doesn't this print Dest too many times, since it's
John 2015/12/08 13:54:24 These instructions' semantics are x = x [+/-] (a
Jim Stichnoth 2015/12/08 19:20:16 OK, I see.
838 Str << ", ";
839 dumpSources(Func);
840 }
841 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
842
843 private:
844 InstARM32FourAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1)
845 : InstARM32(Func, K, 3, Dest) {
846 addSource(Dest);
847 addSource(Src0);
848 addSource(Src1);
849 }
850
851 static const char *Opcode;
852 };
853
802 /// Instructions of the form x cmpop y (setting flags). 854 /// Instructions of the form x cmpop y (setting flags).
803 template <InstARM32::InstKindARM32 K> 855 template <InstARM32::InstKindARM32 K>
804 class InstARM32CmpLike : public InstARM32Pred { 856 class InstARM32CmpLike : public InstARM32Pred {
805 InstARM32CmpLike() = delete; 857 InstARM32CmpLike() = delete;
806 InstARM32CmpLike(const InstARM32CmpLike &) = delete; 858 InstARM32CmpLike(const InstARM32CmpLike &) = delete;
807 InstARM32CmpLike &operator=(const InstARM32CmpLike &) = delete; 859 InstARM32CmpLike &operator=(const InstARM32CmpLike &) = delete;
808 860
809 public: 861 public:
810 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1, 862 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1,
811 CondARM32::Cond Predicate) { 863 CondARM32::Cond Predicate) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 using InstARM32Mul = InstARM32ThreeAddrGPR<InstARM32::Mul>; 903 using InstARM32Mul = InstARM32ThreeAddrGPR<InstARM32::Mul>;
852 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; 904 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>;
853 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; 905 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>;
854 using InstARM32Rsc = InstARM32ThreeAddrGPR<InstARM32::Rsc>; 906 using InstARM32Rsc = InstARM32ThreeAddrGPR<InstARM32::Rsc>;
855 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; 907 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>;
856 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; 908 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>;
857 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; 909 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>;
858 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; 910 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>;
859 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; 911 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>;
860 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; 912 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>;
913 using InstARM32Veor = InstARM32ThreeAddrFP<InstARM32::Veor>;
914 using InstARM32Vmla = InstARM32FourAddrFP<InstARM32::Vmla>;
915 using InstARM32Vmls = InstARM32FourAddrFP<InstARM32::Vmls>;
861 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; 916 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>;
862 using InstARM32Veor = InstARM32ThreeAddrFP<InstARM32::Veor>;
863 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; 917 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>;
864 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>; 918 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>;
865 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>; 919 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>;
866 /// MovT leaves the bottom bits alone so dest is also a source. This helps 920 /// MovT leaves the bottom bits alone so dest is also a source. This helps
867 /// indicate that a previous MovW setting dest is not dead code. 921 /// indicate that a previous MovW setting dest is not dead code.
868 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; 922 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>;
869 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; 923 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>;
870 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; 924 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>;
871 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; 925 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>;
872 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; 926 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 Operand *getCallTarget() const { return getSrc(0); } 1051 Operand *getCallTarget() const { return getSrc(0); }
998 void emit(const Cfg *Func) const override; 1052 void emit(const Cfg *Func) const override;
999 void emitIAS(const Cfg *Func) const override; 1053 void emitIAS(const Cfg *Func) const override;
1000 void dump(const Cfg *Func) const override; 1054 void dump(const Cfg *Func) const override;
1001 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 1055 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
1002 1056
1003 private: 1057 private:
1004 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 1058 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
1005 }; 1059 };
1006 1060
1007 /// Pop into a list of GPRs. Technically this can be predicated, but we don't 1061 /// Pops a list of registers. It may be a list of GPRs, or a list of VFP "s"
1008 /// need that functionality. 1062 /// regs, but not both. in any case, the list must be sorted.
Jim Stichnoth 2015/12/07 20:58:14 In (capitalized)
John 2015/12/08 13:54:24 Done.
1009 class InstARM32Pop : public InstARM32 { 1063 class InstARM32Pop : public InstARM32 {
1010 InstARM32Pop() = delete; 1064 InstARM32Pop() = delete;
1011 InstARM32Pop(const InstARM32Pop &) = delete; 1065 InstARM32Pop(const InstARM32Pop &) = delete;
1012 InstARM32Pop &operator=(const InstARM32Pop &) = delete; 1066 InstARM32Pop &operator=(const InstARM32Pop &) = delete;
1013 1067
1014 public: 1068 public:
1015 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { 1069 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) {
1016 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); 1070 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests);
1017 } 1071 }
1018 void emit(const Cfg *Func) const override; 1072 void emit(const Cfg *Func) const override;
1019 void emitIAS(const Cfg *Func) const override; 1073 void emitIAS(const Cfg *Func) const override;
1020 void dump(const Cfg *Func) const override; 1074 void dump(const Cfg *Func) const override;
1021 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } 1075 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1022 1076
1023 private: 1077 private:
1024 InstARM32Pop(Cfg *Func, const VarList &Dests); 1078 InstARM32Pop(Cfg *Func, const VarList &Dests);
1025 1079
1026 VarList Dests; 1080 VarList Dests;
1027 }; 1081 };
1028 1082
1029 /// Push a list of GPRs. Technically this can be predicated, but we don't need 1083 /// Pushs a list of registers. Just like Pop (see above) the list may be of
Jim Stichnoth 2015/12/07 20:58:14 Pushes
Jim Stichnoth 2015/12/07 20:58:14 Nit: I would put a comma after "(see above)".
John 2015/12/08 13:54:24 Done.
John 2015/12/08 13:54:24 Done.
1030 /// that functionality. 1084 /// GPRs, or VFP "s" registers, but not both.
1031 class InstARM32Push : public InstARM32 { 1085 class InstARM32Push : public InstARM32 {
1032 InstARM32Push() = delete; 1086 InstARM32Push() = delete;
1033 InstARM32Push(const InstARM32Push &) = delete; 1087 InstARM32Push(const InstARM32Push &) = delete;
1034 InstARM32Push &operator=(const InstARM32Push &) = delete; 1088 InstARM32Push &operator=(const InstARM32Push &) = delete;
1035 1089
1036 public: 1090 public:
1037 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { 1091 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) {
1038 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); 1092 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs);
1039 } 1093 }
1040 void emit(const Cfg *Func) const override; 1094 void emit(const Cfg *Func) const override;
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 // default implementations. Without this, there is the possibility of ODR 1374 // default implementations. Without this, there is the possibility of ODR
1321 // violations and link errors. 1375 // violations and link errors.
1322 1376
1323 template <> void InstARM32Ldr::emit(const Cfg *Func) const; 1377 template <> void InstARM32Ldr::emit(const Cfg *Func) const;
1324 template <> void InstARM32Movw::emit(const Cfg *Func) const; 1378 template <> void InstARM32Movw::emit(const Cfg *Func) const;
1325 template <> void InstARM32Movt::emit(const Cfg *Func) const; 1379 template <> void InstARM32Movt::emit(const Cfg *Func) const;
1326 1380
1327 } // end of namespace Ice 1381 } // end of namespace Ice
1328 1382
1329 #endif // SUBZERO_SRC_ICEINSTARM32_H 1383 #endif // SUBZERO_SRC_ICEINSTARM32_H
OLDNEW
« no previous file with comments | « src/IceCfgNode.cpp ('k') | src/IceInstARM32.cpp » ('j') | src/IceInstARM32.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698