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

Side by Side Diff: src/IceInstARM32.cpp

Issue 1669973002: Fix ARM assembler to pop registers in reverse order of pushes. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 4 years, 10 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 | « src/IceInstARM32.h ('k') | tests_lit/assembler/arm32/popmult.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 for (SizeT i = 0; i < RegCount; ++i) { 893 for (SizeT i = 0; i < RegCount; ++i) {
894 if (IsFirst) 894 if (IsFirst)
895 IsFirst = false; 895 IsFirst = false;
896 else 896 else
897 Str << ", "; 897 Str << ", ";
898 Str << RegARM32::getRegName(Base + i); 898 Str << RegARM32::getRegName(Base + i);
899 } 899 }
900 Str << "}"; 900 Str << "}";
901 } 901 }
902 902
903 void InstARM32RegisterStackOp::emitSRegsOp(const Cfg *Func, EmitForm Form,
904 const Variable *BaseReg,
905 SizeT RegCount,
906 SizeT InstIndex) const {
907 if (Form == Emit_Text && BuildDefs::dump() && InstIndex > 0) {
908 startNextInst(Func);
909 Func->getContext()->getStrEmit() << "\n";
910 }
911 emitSRegs(Func, Form, BaseReg, RegCount);
912 }
913
903 namespace { 914 namespace {
904 915
905 bool isAssignedConsecutiveRegisters(const Variable *Before, 916 bool isAssignedConsecutiveRegisters(const Variable *Before,
906 const Variable *After) { 917 const Variable *After) {
907 assert(Before->hasReg()); 918 return RegARM32::getEncodedSReg(Before->getRegNum()) + 1 ==
908 assert(After->hasReg()); 919 RegARM32::getEncodedSReg(After->getRegNum());
909 return Before->getRegNum() + 1 == After->getRegNum();
910 } 920 }
911 921
912 } // end of anonymous namespace 922 } // end of anonymous namespace
913 923
914 void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func, 924 void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func,
915 const EmitForm Form) const { 925 const EmitForm Form) const {
916 SizeT NumRegs = getNumStackRegs(); 926 SizeT NumRegs = getNumStackRegs();
917 assert(NumRegs); 927 assert(NumRegs);
918 928
919 const auto *Reg = llvm::cast<Variable>(getStackReg(0)); 929 const auto *Reg = llvm::cast<Variable>(getStackReg(0));
920 if (isScalarIntegerType(Reg->getType())) { 930 if (isScalarIntegerType(Reg->getType())) {
921 // Pop GPR registers. 931 // Push/pop GPR registers.
922 SizeT IntegerCount = 0; 932 SizeT IntegerCount = 0;
923 ARM32::IValueT GPRegisters = 0; 933 ARM32::IValueT GPRegisters = 0;
924 const Variable *LastDest = nullptr; 934 const Variable *LastDest = nullptr;
925 for (SizeT i = 0; i < NumRegs; ++i) { 935 for (SizeT i = 0; i < NumRegs; ++i) {
926 const Variable *Var = getStackReg(i); 936 const Variable *Var = getStackReg(i);
927 assert(Var->hasReg() && "stack op only applies to registers"); 937 assert(Var->hasReg() && "stack op only applies to registers");
928 int32_t Reg = RegARM32::getEncodedGPR(Var->getRegNum()); 938 int32_t Reg = RegARM32::getEncodedGPR(Var->getRegNum());
929 LastDest = Var; 939 LastDest = Var;
930 GPRegisters |= (1 << Reg); 940 GPRegisters |= (1 << Reg);
931 ++IntegerCount; 941 ++IntegerCount;
932 } 942 }
933 if (IntegerCount == 1) { 943 if (IntegerCount == 1) {
934 emitSingleGPR(Func, Form, LastDest); 944 emitSingleGPR(Func, Form, LastDest);
935 } else { 945 } else {
936 emitMultipleGPRs(Func, Form, GPRegisters); 946 emitMultipleGPRs(Func, Form, GPRegisters);
937 } 947 }
938 } else { 948 return;
939 // Pop vector/floating point registers. 949 }
940 const Variable *BaseReg = nullptr; 950
941 SizeT RegCount = 0; 951 // Push/pop floating point registers. Divide into a list of instructions,
942 for (SizeT i = 0; i < NumRegs; ++i) { 952 // defined on consecutive register ranges. Then generate the corresponding
943 const Variable *NextReg = getStackReg(i); 953 // instructions.
944 if (BaseReg == nullptr) { 954
945 BaseReg = NextReg; 955 // Typical max number of registers ranges pushed/popd is no more than 5.
946 RegCount = 1; 956 llvm::SmallVector<std::pair<const Variable *, SizeT>, 5> InstData;
947 } else if (RegCount < VpushVpopMaxConsecRegs && 957 const Variable *BaseReg = nullptr;
948 isAssignedConsecutiveRegisters(Reg, NextReg)) { 958 SizeT RegCount = 0;
949 ++RegCount; 959 for (SizeT i = 0; i < NumRegs; ++i) {
950 } else { 960 const Variable *NextReg = getStackReg(i);
951 emitSRegs(Func, Form, BaseReg, RegCount); 961 assert(NextReg->hasReg());
952 if (Form == Emit_Text && BuildDefs::dump()) { 962 if (BaseReg == nullptr) {
953 startNextInst(Func); 963 BaseReg = NextReg;
954 Func->getContext()->getStrEmit() << "\n"; 964 RegCount = 1;
955 } 965 } else if (RegCount < VpushVpopMaxConsecRegs &&
956 BaseReg = NextReg; 966 isAssignedConsecutiveRegisters(Reg, NextReg)) {
957 RegCount = 1; 967 ++RegCount;
958 } 968 } else {
959 Reg = NextReg; 969 InstData.emplace_back(BaseReg, RegCount);
970 BaseReg = NextReg;
971 RegCount = 1;
960 } 972 }
961 if (RegCount) { 973 Reg = NextReg;
962 emitSRegs(Func, Form, BaseReg, RegCount);
963 }
964 } 974 }
975 if (RegCount) {
976 InstData.emplace_back(BaseReg, RegCount);
977 }
978 SizeT InstCount = 0;
979 if (llvm::isa<InstARM32Push>(*this)) {
980 for (const auto &Pair : InstData)
981 emitSRegsOp(Func, Form, Pair.first, Pair.second, InstCount++);
982 return;
983 }
984 assert(llvm::isa<InstARM32Pop>(*this));
985 for (const auto &Pair : reverse_range(InstData))
986 emitSRegsOp(Func, Form, Pair.first, Pair.second, InstCount++);
965 } 987 }
966 988
967 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) 989 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests)
968 : InstARM32RegisterStackOp(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { 990 : InstARM32RegisterStackOp(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) {
969 // Track modifications to Dests separately via FakeDefs. Also, a pop 991 // Track modifications to Dests separately via FakeDefs. Also, a pop
970 // instruction affects the stack pointer and so it should not be allowed to 992 // instruction affects the stack pointer and so it should not be allowed to
971 // be automatically dead-code eliminated. This is automatic since we leave 993 // be automatically dead-code eliminated. This is automatic since we leave
972 // the Dest as nullptr. 994 // the Dest as nullptr.
973 validatePushOrPopRegisterListOrDie(Dests); 995 validatePushOrPopRegisterListOrDie(Dests);
974 } 996 }
(...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after
2668 2690
2669 template class InstARM32FourAddrGPR<InstARM32::Mla>; 2691 template class InstARM32FourAddrGPR<InstARM32::Mla>;
2670 template class InstARM32FourAddrGPR<InstARM32::Mls>; 2692 template class InstARM32FourAddrGPR<InstARM32::Mls>;
2671 2693
2672 template class InstARM32CmpLike<InstARM32::Cmn>; 2694 template class InstARM32CmpLike<InstARM32::Cmn>;
2673 template class InstARM32CmpLike<InstARM32::Cmp>; 2695 template class InstARM32CmpLike<InstARM32::Cmp>;
2674 template class InstARM32CmpLike<InstARM32::Tst>; 2696 template class InstARM32CmpLike<InstARM32::Tst>;
2675 2697
2676 } // end of namespace ARM32 2698 } // end of namespace ARM32
2677 } // end of namespace Ice 2699 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstARM32.h ('k') | tests_lit/assembler/arm32/popmult.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698