OLD | NEW |
1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// | 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// |
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 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 } | 881 } |
882 | 882 |
883 void InstARM32RegisterStackOp::emitSRegsAsText(const Cfg *Func, | 883 void InstARM32RegisterStackOp::emitSRegsAsText(const Cfg *Func, |
884 const Variable *BaseReg, | 884 const Variable *BaseReg, |
885 SizeT RegCount) const { | 885 SizeT RegCount) const { |
886 if (!BuildDefs::dump()) | 886 if (!BuildDefs::dump()) |
887 return; | 887 return; |
888 Ostream &Str = Func->getContext()->getStrEmit(); | 888 Ostream &Str = Func->getContext()->getStrEmit(); |
889 Str << "\t" << getSRegOpcode() << "\t{"; | 889 Str << "\t" << getSRegOpcode() << "\t{"; |
890 bool IsFirst = true; | 890 bool IsFirst = true; |
891 int32_t Base = BaseReg->getRegNum(); | 891 const auto Base = BaseReg->getRegNum(); |
892 for (SizeT i = 0; i < RegCount; ++i) { | 892 for (SizeT i = 0; i < RegCount; ++i) { |
893 if (IsFirst) | 893 if (IsFirst) |
894 IsFirst = false; | 894 IsFirst = false; |
895 else | 895 else |
896 Str << ", "; | 896 Str << ", "; |
897 Str << RegARM32::getRegName(Base + i); | 897 Str << RegARM32::getRegName(RegNumT::fixme(Base + i)); |
898 } | 898 } |
899 Str << "}"; | 899 Str << "}"; |
900 } | 900 } |
901 | 901 |
902 void InstARM32RegisterStackOp::emitSRegsOp(const Cfg *Func, EmitForm Form, | 902 void InstARM32RegisterStackOp::emitSRegsOp(const Cfg *Func, EmitForm Form, |
903 const Variable *BaseReg, | 903 const Variable *BaseReg, |
904 SizeT RegCount, | 904 SizeT RegCount, |
905 SizeT InstIndex) const { | 905 SizeT InstIndex) const { |
906 if (Form == Emit_Text && BuildDefs::dump() && InstIndex > 0) { | 906 if (Form == Emit_Text && BuildDefs::dump() && InstIndex > 0) { |
907 startNextInst(Func); | 907 startNextInst(Func); |
908 Func->getContext()->getStrEmit() << "\n"; | 908 Func->getContext()->getStrEmit() << "\n"; |
909 } | 909 } |
910 emitSRegs(Func, Form, BaseReg, RegCount); | 910 emitSRegs(Func, Form, BaseReg, RegCount); |
911 } | 911 } |
912 | 912 |
913 namespace { | 913 namespace { |
914 | 914 |
915 bool isAssignedConsecutiveRegisters(const Variable *Before, | 915 bool isAssignedConsecutiveRegisters(const Variable *Before, |
916 const Variable *After) { | 916 const Variable *After) { |
917 return RegARM32::getEncodedSReg(Before->getRegNum()) + 1 == | 917 assert(Before->hasReg()); |
918 RegARM32::getEncodedSReg(After->getRegNum()); | 918 assert(After->hasReg()); |
| 919 return RegNumT::fixme(Before->getRegNum() + 1) == After->getRegNum(); |
919 } | 920 } |
920 | 921 |
921 } // end of anonymous namespace | 922 } // end of anonymous namespace |
922 | 923 |
923 void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func, | 924 void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func, |
924 const EmitForm Form) const { | 925 const EmitForm Form) const { |
925 SizeT NumRegs = getNumStackRegs(); | 926 SizeT NumRegs = getNumStackRegs(); |
926 assert(NumRegs); | 927 assert(NumRegs); |
927 | 928 |
928 const auto *Reg = llvm::cast<Variable>(getStackReg(0)); | 929 const auto *Reg = llvm::cast<Variable>(getStackReg(0)); |
929 if (isScalarIntegerType(Reg->getType())) { | 930 if (isScalarIntegerType(Reg->getType())) { |
930 // Push/pop GPR registers. | 931 // Push/pop GPR registers. |
931 SizeT IntegerCount = 0; | 932 SizeT IntegerCount = 0; |
932 ARM32::IValueT GPRegisters = 0; | 933 ARM32::IValueT GPRegisters = 0; |
933 const Variable *LastDest = nullptr; | 934 const Variable *LastDest = nullptr; |
934 for (SizeT i = 0; i < NumRegs; ++i) { | 935 for (SizeT i = 0; i < NumRegs; ++i) { |
935 const Variable *Var = getStackReg(i); | 936 const Variable *Var = getStackReg(i); |
936 assert(Var->hasReg() && "stack op only applies to registers"); | 937 assert(Var->hasReg() && "stack op only applies to registers"); |
937 int32_t Reg = RegARM32::getEncodedGPR(Var->getRegNum()); | 938 const RegARM32::GPRRegister Reg = |
| 939 RegARM32::getEncodedGPR(Var->getRegNum()); |
938 LastDest = Var; | 940 LastDest = Var; |
939 GPRegisters |= (1 << Reg); | 941 GPRegisters |= (1 << Reg); |
940 ++IntegerCount; | 942 ++IntegerCount; |
941 } | 943 } |
942 if (IntegerCount == 1) { | 944 if (IntegerCount == 1) { |
943 emitSingleGPR(Func, Form, LastDest); | 945 emitSingleGPR(Func, Form, LastDest); |
944 } else { | 946 } else { |
945 emitMultipleGPRs(Func, Form, GPRegisters); | 947 emitMultipleGPRs(Func, Form, GPRegisters); |
946 } | 948 } |
947 return; | 949 return; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 } else { | 1064 } else { |
1063 addSource(Src64->getLo()); | 1065 addSource(Src64->getLo()); |
1064 addSource(Src64->getHi()); | 1066 addSource(Src64->getHi()); |
1065 } | 1067 } |
1066 } | 1068 } |
1067 | 1069 |
1068 // These next two functions find the D register that maps to the half of the Q | 1070 // These next two functions find the D register that maps to the half of the Q |
1069 // register that this instruction is accessing. | 1071 // register that this instruction is accessing. |
1070 Register getDRegister(const Variable *Src, uint32_t Index) { | 1072 Register getDRegister(const Variable *Src, uint32_t Index) { |
1071 assert(Src->hasReg()); | 1073 assert(Src->hasReg()); |
1072 const auto SrcReg = static_cast<Register>(Src->getRegNum()); | 1074 const auto SrcReg = Src->getRegNum(); |
1073 | 1075 |
1074 const RegARM32::RegTableType &SrcEntry = RegARM32::RegTable[SrcReg]; | 1076 const RegARM32::RegTableType &SrcEntry = RegARM32::RegTable[SrcReg]; |
1075 assert(SrcEntry.IsVec128); | 1077 assert(SrcEntry.IsVec128); |
1076 | 1078 |
1077 const uint32_t NumElements = typeNumElements(Src->getType()); | 1079 const uint32_t NumElements = typeNumElements(Src->getType()); |
1078 | 1080 |
1079 // This code assumes the Aliases list goes Q_n, S_2n, S_2n+1. The asserts in | 1081 // This code assumes the Aliases list goes Q_n, S_2n, S_2n+1. The asserts in |
1080 // the next two branches help to check that this is still true. | 1082 // the next two branches help to check that this is still true. |
1081 if (Index < NumElements / 2) { | 1083 if (Index < NumElements / 2) { |
1082 // We have a Q register that's made up of two D registers. This assert is | 1084 // We have a Q register that's made up of two D registers. This assert is |
(...skipping 17 matching lines...) Expand all Loading... |
1100 } | 1102 } |
1101 | 1103 |
1102 constexpr uint32_t getDIndex(uint32_t NumElements, uint32_t Index) { | 1104 constexpr uint32_t getDIndex(uint32_t NumElements, uint32_t Index) { |
1103 return (Index < NumElements / 2) ? Index : Index - (NumElements / 2); | 1105 return (Index < NumElements / 2) ? Index : Index - (NumElements / 2); |
1104 } | 1106 } |
1105 | 1107 |
1106 // For floating point values, we can insertelement or extractelement by moving | 1108 // For floating point values, we can insertelement or extractelement by moving |
1107 // directly from an S register. This function finds the right one. | 1109 // directly from an S register. This function finds the right one. |
1108 Register getSRegister(const Variable *Src, uint32_t Index) { | 1110 Register getSRegister(const Variable *Src, uint32_t Index) { |
1109 assert(Src->hasReg()); | 1111 assert(Src->hasReg()); |
1110 const auto SrcReg = static_cast<Register>(Src->getRegNum()); | 1112 const auto SrcReg = Src->getRegNum(); |
1111 | 1113 |
1112 // For floating point values, we need to be allocated to Q0 - Q7, so we can | 1114 // For floating point values, we need to be allocated to Q0 - Q7, so we can |
1113 // directly access the value we want as one of the S registers. | 1115 // directly access the value we want as one of the S registers. |
1114 assert(Src->getType() == IceType_v4f32); | 1116 assert(Src->getType() == IceType_v4f32); |
1115 assert(SrcReg < RegARM32::Reg_q8); | 1117 assert(SrcReg < RegARM32::Reg_q8); |
1116 | 1118 |
1117 // This part assumes the register alias list goes q0, d0, d1, s0, s1, s2, s3. | 1119 // This part assumes the register alias list goes q0, d0, d1, s0, s1, s2, s3. |
1118 assert(Index < 4); | 1120 assert(Index < 4); |
1119 | 1121 |
1120 // TODO(jpp): find a way to do this that doesn't rely on ordering of the alias | 1122 // TODO(jpp): find a way to do this that doesn't rely on ordering of the alias |
(...skipping 1591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2712 | 2714 |
2713 template class InstARM32FourAddrGPR<InstARM32::Mla>; | 2715 template class InstARM32FourAddrGPR<InstARM32::Mla>; |
2714 template class InstARM32FourAddrGPR<InstARM32::Mls>; | 2716 template class InstARM32FourAddrGPR<InstARM32::Mls>; |
2715 | 2717 |
2716 template class InstARM32CmpLike<InstARM32::Cmn>; | 2718 template class InstARM32CmpLike<InstARM32::Cmn>; |
2717 template class InstARM32CmpLike<InstARM32::Cmp>; | 2719 template class InstARM32CmpLike<InstARM32::Cmp>; |
2718 template class InstARM32CmpLike<InstARM32::Tst>; | 2720 template class InstARM32CmpLike<InstARM32::Tst>; |
2719 | 2721 |
2720 } // end of namespace ARM32 | 2722 } // end of namespace ARM32 |
2721 } // end of namespace Ice | 2723 } // end of namespace Ice |
OLD | NEW |