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