Chromium Code Reviews| 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 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 891 for (SizeT i = 0; i < RegCount; ++i) { | 891 for (SizeT i = 0; i < RegCount; ++i) { |
| 892 if (IsFirst) | 892 if (IsFirst) |
| 893 IsFirst = false; | 893 IsFirst = false; |
| 894 else | 894 else |
| 895 Str << ", "; | 895 Str << ", "; |
| 896 Str << RegARM32::getRegName(Base + i); | 896 Str << RegARM32::getRegName(Base + i); |
| 897 } | 897 } |
| 898 Str << "}"; | 898 Str << "}"; |
| 899 } | 899 } |
| 900 | 900 |
| 901 void InstARM32RegisterStackOp::emitSRegsOp(const Cfg *Func, EmitForm Form, | |
| 902 const Variable *BaseReg, | |
| 903 SizeT RegCount, | |
| 904 SizeT InstIndex) const { | |
| 905 if (Form == Emit_Text && BuildDefs::dump() && InstIndex > 0) { | |
| 906 startNextInst(Func); | |
| 907 Func->getContext()->getStrEmit() << "\n"; | |
| 908 } | |
| 909 emitSRegs(Func, Form, BaseReg, RegCount); | |
| 910 } | |
| 911 | |
| 901 namespace { | 912 namespace { |
| 902 | 913 |
| 903 bool isAssignedConsecutiveRegisters(const Variable *Before, | 914 bool isAssignedConsecutiveRegisters(const Variable *Before, |
| 904 const Variable *After) { | 915 const Variable *After) { |
| 905 assert(Before->hasReg()); | 916 return RegARM32::getEncodedSReg(Before->getRegNum()) + 1 == |
| 906 assert(After->hasReg()); | 917 RegARM32::getEncodedSReg(After->getRegNum()); |
| 907 return Before->getRegNum() + 1 == After->getRegNum(); | |
| 908 } | 918 } |
| 909 | 919 |
| 910 } // end of anonymous namespace | 920 } // end of anonymous namespace |
| 911 | 921 |
| 912 void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func, | 922 void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func, |
| 913 const EmitForm Form) const { | 923 const EmitForm Form) const { |
| 914 SizeT NumRegs = getNumStackRegs(); | 924 SizeT NumRegs = getNumStackRegs(); |
| 915 assert(NumRegs); | 925 assert(NumRegs); |
| 916 | 926 |
| 917 const auto *Reg = llvm::cast<Variable>(getStackReg(0)); | 927 const auto *Reg = llvm::cast<Variable>(getStackReg(0)); |
| 918 if (isScalarIntegerType(Reg->getType())) { | 928 if (isScalarIntegerType(Reg->getType())) { |
| 919 // Pop GPR registers. | 929 // Push/pop GPR registers. |
| 920 SizeT IntegerCount = 0; | 930 SizeT IntegerCount = 0; |
| 921 ARM32::IValueT GPRegisters = 0; | 931 ARM32::IValueT GPRegisters = 0; |
| 922 const Variable *LastDest = nullptr; | 932 const Variable *LastDest = nullptr; |
| 923 for (SizeT i = 0; i < NumRegs; ++i) { | 933 for (SizeT i = 0; i < NumRegs; ++i) { |
| 924 const Variable *Var = getStackReg(i); | 934 const Variable *Var = getStackReg(i); |
| 925 assert(Var->hasReg() && "stack op only applies to registers"); | 935 assert(Var->hasReg() && "stack op only applies to registers"); |
| 926 int32_t Reg = RegARM32::getEncodedGPR(Var->getRegNum()); | 936 int32_t Reg = RegARM32::getEncodedGPR(Var->getRegNum()); |
| 927 LastDest = Var; | 937 LastDest = Var; |
| 928 GPRegisters |= (1 << Reg); | 938 GPRegisters |= (1 << Reg); |
| 929 ++IntegerCount; | 939 ++IntegerCount; |
| 930 } | 940 } |
| 931 if (IntegerCount == 1) { | 941 if (IntegerCount == 1) { |
| 932 emitSingleGPR(Func, Form, LastDest); | 942 emitSingleGPR(Func, Form, LastDest); |
| 933 } else { | 943 } else { |
| 934 emitMultipleGPRs(Func, Form, GPRegisters); | 944 emitMultipleGPRs(Func, Form, GPRegisters); |
| 935 } | 945 } |
| 936 } else { | 946 return; |
| 937 // Pop vector/floating point registers. | 947 } |
| 938 const Variable *BaseReg = nullptr; | 948 |
| 939 SizeT RegCount = 0; | 949 // Push/pop floating point registers. Divide into a list of instructions, |
| 940 for (SizeT i = 0; i < NumRegs; ++i) { | 950 // defined on consecutive register ranges. Then generate the corresponding |
| 941 const Variable *NextReg = getStackReg(i); | 951 // instructions. |
| 942 if (BaseReg == nullptr) { | 952 llvm::SmallVector<std::pair<const Variable *, SizeT>, 5> InstData; |
|
Jim Stichnoth
2016/02/08 17:15:58
Could you document the choice of "5"? With a cons
Karl
2016/02/09 20:24:27
Done.
| |
| 943 BaseReg = NextReg; | 953 const Variable *BaseReg = nullptr; |
| 944 RegCount = 1; | 954 SizeT RegCount = 0; |
| 945 } else if (RegCount < VpushVpopMaxConsecRegs && | 955 for (SizeT i = 0; i < NumRegs; ++i) { |
| 946 isAssignedConsecutiveRegisters(Reg, NextReg)) { | 956 const Variable *NextReg = getStackReg(i); |
| 947 ++RegCount; | 957 assert(NextReg->hasReg()); |
| 948 } else { | 958 if (BaseReg == nullptr) { |
| 949 emitSRegs(Func, Form, BaseReg, RegCount); | 959 BaseReg = NextReg; |
| 950 if (Form == Emit_Text && BuildDefs::dump()) { | 960 RegCount = 1; |
| 951 startNextInst(Func); | 961 } else if (RegCount < VpushVpopMaxConsecRegs && |
| 952 Func->getContext()->getStrEmit() << "\n"; | 962 isAssignedConsecutiveRegisters(Reg, NextReg)) { |
| 953 } | 963 ++RegCount; |
| 954 BaseReg = NextReg; | 964 } else { |
| 955 RegCount = 1; | 965 InstData.push_back(std::make_pair(BaseReg, RegCount)); |
|
Jim Stichnoth
2016/02/08 17:15:58
InstData.emplace_back(BaseReg, RegCount);
Karl
2016/02/09 20:24:27
Done.
| |
| 956 } | 966 BaseReg = NextReg; |
| 957 Reg = NextReg; | 967 RegCount = 1; |
| 958 } | 968 } |
| 959 if (RegCount) { | 969 Reg = NextReg; |
| 960 emitSRegs(Func, Form, BaseReg, RegCount); | |
| 961 } | |
| 962 } | 970 } |
| 971 if (RegCount) { | |
| 972 InstData.push_back(std::make_pair(BaseReg, RegCount)); | |
|
Jim Stichnoth
2016/02/08 17:15:58
emplace_back
Karl
2016/02/09 20:24:27
Done.
| |
| 973 } | |
| 974 SizeT InstCount = 0; | |
| 975 if (llvm::isa<InstARM32Push>(*this)) { | |
| 976 for (const auto &Pair : InstData) | |
| 977 emitSRegsOp(Func, Form, Pair.first, Pair.second, InstCount++); | |
| 978 return; | |
| 979 } | |
| 980 assert(llvm::isa<InstARM32Pop>(*this)); | |
| 981 for (const auto &Pair : reverse_range(InstData)) | |
| 982 emitSRegsOp(Func, Form, Pair.first, Pair.second, InstCount++); | |
| 963 } | 983 } |
| 964 | 984 |
| 965 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) | 985 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) |
| 966 : InstARM32RegisterStackOp(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { | 986 : InstARM32RegisterStackOp(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { |
| 967 // Track modifications to Dests separately via FakeDefs. Also, a pop | 987 // Track modifications to Dests separately via FakeDefs. Also, a pop |
| 968 // instruction affects the stack pointer and so it should not be allowed to | 988 // instruction affects the stack pointer and so it should not be allowed to |
| 969 // be automatically dead-code eliminated. This is automatic since we leave | 989 // be automatically dead-code eliminated. This is automatic since we leave |
| 970 // the Dest as nullptr. | 990 // the Dest as nullptr. |
| 971 validatePushOrPopRegisterListOrDie(Dests); | 991 validatePushOrPopRegisterListOrDie(Dests); |
| 972 } | 992 } |
| (...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2540 | 2560 |
| 2541 template class InstARM32FourAddrGPR<InstARM32::Mla>; | 2561 template class InstARM32FourAddrGPR<InstARM32::Mla>; |
| 2542 template class InstARM32FourAddrGPR<InstARM32::Mls>; | 2562 template class InstARM32FourAddrGPR<InstARM32::Mls>; |
| 2543 | 2563 |
| 2544 template class InstARM32CmpLike<InstARM32::Cmn>; | 2564 template class InstARM32CmpLike<InstARM32::Cmn>; |
| 2545 template class InstARM32CmpLike<InstARM32::Cmp>; | 2565 template class InstARM32CmpLike<InstARM32::Cmp>; |
| 2546 template class InstARM32CmpLike<InstARM32::Tst>; | 2566 template class InstARM32CmpLike<InstARM32::Tst>; |
| 2547 | 2567 |
| 2548 } // end of namespace ARM32 | 2568 } // end of namespace ARM32 |
| 2549 } // end of namespace Ice | 2569 } // end of namespace Ice |
| OLD | NEW |