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

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: 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
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 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 namespace {
902
903 bool isAssignedConsecutiveRegisters(const Variable *Before,
904 const Variable *After) {
905 assert(Before->hasReg());
906 assert(After->hasReg());
907 return Before->getRegNum() + 1 == After->getRegNum();
908 }
909
910 } // end of anonymous namespace
911
912 void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func, 901 void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func,
913 const EmitForm Form) const { 902 const EmitForm Form) const {
914 SizeT NumRegs = getNumStackRegs(); 903 SizeT NumRegs = getNumStackRegs();
915 assert(NumRegs); 904 assert(NumRegs);
916 905
917 const auto *Reg = llvm::cast<Variable>(getStackReg(0)); 906 const auto *Reg = llvm::cast<Variable>(getStackReg(0));
918 if (isScalarIntegerType(Reg->getType())) { 907 if (isScalarIntegerType(Reg->getType())) {
919 // Pop GPR registers. 908 // Pop GPR registers.
920 SizeT IntegerCount = 0; 909 SizeT IntegerCount = 0;
921 ARM32::IValueT GPRegisters = 0; 910 ARM32::IValueT GPRegisters = 0;
922 const Variable *LastDest = nullptr; 911 const Variable *LastDest = nullptr;
923 for (SizeT i = 0; i < NumRegs; ++i) { 912 for (SizeT i = 0; i < NumRegs; ++i) {
924 const Variable *Var = getStackReg(i); 913 const Variable *Var = getStackReg(i);
925 assert(Var->hasReg() && "stack op only applies to registers"); 914 assert(Var->hasReg() && "stack op only applies to registers");
926 int32_t Reg = RegARM32::getEncodedGPR(Var->getRegNum()); 915 int32_t Reg = RegARM32::getEncodedGPR(Var->getRegNum());
927 LastDest = Var; 916 LastDest = Var;
928 GPRegisters |= (1 << Reg); 917 GPRegisters |= (1 << Reg);
929 ++IntegerCount; 918 ++IntegerCount;
930 } 919 }
931 if (IntegerCount == 1) { 920 if (IntegerCount == 1) {
932 emitSingleGPR(Func, Form, LastDest); 921 emitSingleGPR(Func, Form, LastDest);
933 } else { 922 } else {
934 emitMultipleGPRs(Func, Form, GPRegisters); 923 emitMultipleGPRs(Func, Form, GPRegisters);
935 } 924 }
936 } else { 925 } else {
937 // Pop vector/floating point registers. 926 // Pop vector/floating point registers.
938 const Variable *BaseReg = nullptr; 927 const Variable *BaseReg = nullptr;
939 SizeT RegCount = 0; 928 SizeT RegCount = 0;
940 for (SizeT i = 0; i < NumRegs; ++i) { 929 for (SizeT i = 0; i < NumRegs; ++i) {
941 const Variable *NextReg = getStackReg(i); 930 const Variable *NextReg = getStackSReg(i, NumRegs);
931 assert(NextReg->hasReg());
942 if (BaseReg == nullptr) { 932 if (BaseReg == nullptr) {
943 BaseReg = NextReg; 933 BaseReg = NextReg;
944 RegCount = 1; 934 RegCount = 1;
945 } else if (RegCount < VpushVpopMaxConsecRegs && 935 } else if (RegCount < VpushVpopMaxConsecRegs &&
946 isAssignedConsecutiveRegisters(Reg, NextReg)) { 936 isAssignedConsecutiveRegisters(Reg, NextReg)) {
937 BaseReg = updateBaseReg(BaseReg, NextReg);
947 ++RegCount; 938 ++RegCount;
948 } else { 939 } else {
949 emitSRegs(Func, Form, BaseReg, RegCount); 940 emitSRegs(Func, Form, BaseReg, RegCount);
950 if (Form == Emit_Text && BuildDefs::dump()) { 941 if (Form == Emit_Text && BuildDefs::dump()) {
951 startNextInst(Func); 942 startNextInst(Func);
952 Func->getContext()->getStrEmit() << "\n"; 943 Func->getContext()->getStrEmit() << "\n";
953 } 944 }
954 BaseReg = NextReg; 945 BaseReg = NextReg;
955 RegCount = 1; 946 RegCount = 1;
956 } 947 }
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 } 1764 }
1774 1765
1775 const char *InstARM32Pop::getGPROpcode() const { return "pop"; } 1766 const char *InstARM32Pop::getGPROpcode() const { return "pop"; }
1776 1767
1777 const char *InstARM32Pop::getSRegOpcode() const { return "vpop"; } 1768 const char *InstARM32Pop::getSRegOpcode() const { return "vpop"; }
1778 1769
1779 Variable *InstARM32Pop::getStackReg(SizeT Index) const { return Dests[Index]; } 1770 Variable *InstARM32Pop::getStackReg(SizeT Index) const { return Dests[Index]; }
1780 1771
1781 SizeT InstARM32Pop::getNumStackRegs() const { return Dests.size(); } 1772 SizeT InstARM32Pop::getNumStackRegs() const { return Dests.size(); }
1782 1773
1774 bool InstARM32Pop::isAssignedConsecutiveRegisters(const Variable *Before,
1775 const Variable *After) const {
1776 return Before->getRegNum() - 1 == After->getRegNum();
Jim Stichnoth 2016/02/05 00:48:17 I realize this is just transplanted code, but...
John 2016/02/05 01:46:25 The only issue with encoded reg values (that is al
Karl 2016/02/05 17:00:05 Done.
1777 }
1778
1779 Variable *InstARM32Pop::getStackSReg(SizeT Index, SizeT Size) const {
John 2016/02/05 01:46:25 Do you need to pass Size here? Isn't size the same
Karl 2016/02/05 17:00:05 No longer needed. Removed need for virtuals.
1780 return getStackReg(Size - (Index + 1));
1781 }
1782
1783 const Variable *InstARM32Pop::updateBaseReg(const Variable *BaseReg,
1784 const Variable *NextReg) const {
1785 (void)BaseReg;
1786 return NextReg;
1787 }
1788
1783 void InstARM32Pop::emitSingleGPR(const Cfg *Func, const EmitForm Form, 1789 void InstARM32Pop::emitSingleGPR(const Cfg *Func, const EmitForm Form,
1784 const Variable *Reg) const { 1790 const Variable *Reg) const {
1785 switch (Form) { 1791 switch (Form) {
1786 case Emit_Text: 1792 case Emit_Text:
1787 emitGPRsAsText(Func); 1793 emitGPRsAsText(Func);
1788 return; 1794 return;
1789 case Emit_Binary: 1795 case Emit_Binary:
1790 Func->getAssembler<ARM32::AssemblerARM32>()->pop(Reg, CondARM32::AL); 1796 Func->getAssembler<ARM32::AssemblerARM32>()->pop(Reg, CondARM32::AL);
1791 return; 1797 return;
1792 } 1798 }
(...skipping 28 matching lines...) Expand all
1821 const char *InstARM32Push::getGPROpcode() const { return "push"; } 1827 const char *InstARM32Push::getGPROpcode() const { return "push"; }
1822 1828
1823 const char *InstARM32Push::getSRegOpcode() const { return "vpush"; } 1829 const char *InstARM32Push::getSRegOpcode() const { return "vpush"; }
1824 1830
1825 Variable *InstARM32Push::getStackReg(SizeT Index) const { 1831 Variable *InstARM32Push::getStackReg(SizeT Index) const {
1826 return llvm::cast<Variable>(getSrc(Index)); 1832 return llvm::cast<Variable>(getSrc(Index));
1827 } 1833 }
1828 1834
1829 SizeT InstARM32Push::getNumStackRegs() const { return getSrcSize(); } 1835 SizeT InstARM32Push::getNumStackRegs() const { return getSrcSize(); }
1830 1836
1837 bool InstARM32Push::isAssignedConsecutiveRegisters(
1838 const Variable *Before, const Variable *After) const {
1839 return Before->getRegNum() + 1 == After->getRegNum();
1840 }
1841
1842 Variable *InstARM32Push::getStackSReg(SizeT Index, SizeT Size) const {
1843 (void)Size;
1844 return getStackReg(Index);
1845 }
1846
1847 const Variable *InstARM32Push::updateBaseReg(const Variable *BaseReg,
1848 const Variable *NextReg) const {
1849 (void)NextReg;
1850 return BaseReg;
1851 }
1852
1831 void InstARM32Push::emitSingleGPR(const Cfg *Func, const EmitForm Form, 1853 void InstARM32Push::emitSingleGPR(const Cfg *Func, const EmitForm Form,
1832 const Variable *Reg) const { 1854 const Variable *Reg) const {
1833 switch (Form) { 1855 switch (Form) {
1834 case Emit_Text: 1856 case Emit_Text:
1835 emitGPRsAsText(Func); 1857 emitGPRsAsText(Func);
1836 return; 1858 return;
1837 case Emit_Binary: 1859 case Emit_Binary:
1838 Func->getAssembler<ARM32::AssemblerARM32>()->push(Reg, CondARM32::AL); 1860 Func->getAssembler<ARM32::AssemblerARM32>()->push(Reg, CondARM32::AL);
1839 return; 1861 return;
1840 } 1862 }
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 2569
2548 template class InstARM32FourAddrGPR<InstARM32::Mla>; 2570 template class InstARM32FourAddrGPR<InstARM32::Mla>;
2549 template class InstARM32FourAddrGPR<InstARM32::Mls>; 2571 template class InstARM32FourAddrGPR<InstARM32::Mls>;
2550 2572
2551 template class InstARM32CmpLike<InstARM32::Cmn>; 2573 template class InstARM32CmpLike<InstARM32::Cmn>;
2552 template class InstARM32CmpLike<InstARM32::Cmp>; 2574 template class InstARM32CmpLike<InstARM32::Cmp>;
2553 template class InstARM32CmpLike<InstARM32::Tst>; 2575 template class InstARM32CmpLike<InstARM32::Tst>;
2554 2576
2555 } // end of namespace ARM32 2577 } // end of namespace ARM32
2556 } // end of namespace Ice 2578 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698