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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1535233002: Refactor PUSH/POP in ARM assemblers. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Remove "#if 0' Created 5 years 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/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8> 1681 // orr{s}<c> <Rd>, <Rn>, #<RotatedImm8>
1682 // 1682 //
1683 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 1683 // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
1684 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 1684 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
1685 constexpr const char *OrrName = "orr"; 1685 constexpr const char *OrrName = "orr";
1686 constexpr IValueT OrrOpcode = B3 | B2; // i.e. 1100 1686 constexpr IValueT OrrOpcode = B3 | B2; // i.e. 1100
1687 emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, 1687 emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
1688 OrrName); 1688 OrrName);
1689 } 1689 }
1690 1690
1691 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) { 1691 void AssemblerARM32::emitStackTextOp(const Cfg *Func, const IValueT Registers,
1692 CondARM32::Cond Cond,
1693 const char *InstName) {
1694 Ostream &Str = Func->getContext()->getStrEmit();
1695 Str << "\t" << InstName << Cond << "\t{";
1696 bool isFirst = true;
1697 for (SizeT i = 0; i < RegARM32::getNumGPRegs(); ++i) {
1698 if (mask(Registers, i, 1) == 0)
1699 continue;
1700 if (isFirst) {
1701 isFirst = false;
1702 } else {
1703 Str << ", ";
1704 }
1705 Str << RegARM32::getGPRegName(i);
1706 }
1707 Str << "}";
1708 }
1709
1710 void AssemblerARM32::emitStackTextOp(const Cfg *Func, const Operand *OpRt,
1711 CondARM32::Cond Cond,
1712 const char *InstName) {
1713 const IValueT Rt = encodeRegister(OpRt, "Rt", InstName);
1714 const IValueT GPRegisters = 1 << Rt;
1715 emitStackTextOp(Func, GPRegisters, Cond, InstName);
1716 }
1717
1718 template <>
1719 void AssemblerARM32::pop<TextualAssembly>(const Cfg *Func, const Operand *OpRt,
1720 CondARM32::Cond Cond) {
1721 constexpr const char *Pop = "pop";
1722 emitStackTextOp(Func, OpRt, Cond, Pop);
1723 }
1724
1725 template <>
1726 void AssemblerARM32::pop<BinaryAssembly>(const Cfg *Func, const Operand *OpRt,
1727 CondARM32::Cond Cond) {
1728 (void)Func;
1692 // POP - ARM section A8.8.132, encoding A2: 1729 // POP - ARM section A8.8.132, encoding A2:
1693 // pop<c> {Rt} 1730 // pop<c> {Rt}
1694 // 1731 //
1695 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. 1732 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
1696 constexpr const char *Pop = "pop"; 1733 constexpr const char *Pop = "pop";
1697 IValueT Rt = encodeRegister(OpRt, "Rt", Pop); 1734 const IValueT Rt = encodeRegister(OpRt, "Rt", Pop);
1698 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop); 1735 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop);
1699 // Same as load instruction. 1736 // Same as load instruction.
1700 constexpr bool IsLoad = true; 1737 constexpr bool IsLoad = true;
1701 constexpr bool IsByte = false; 1738 constexpr bool IsByte = false;
1702 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, 1739 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
1703 OperandARM32Mem::PostIndex); 1740 OperandARM32Mem::PostIndex);
1704 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, Pop); 1741 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address, Pop);
1705 } 1742 }
1706 1743
1707 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { 1744 template <>
1745 void AssemblerARM32::popList<TextualAssembly>(const Cfg *Func,
1746 const IValueT Registers,
1747 CondARM32::Cond Cond) {
1748 constexpr const char *PopList = "pop";
1749 emitStackTextOp(Func, Registers, Cond, PopList);
1750 }
1751
1752 template <>
1753 void AssemblerARM32::popList<BinaryAssembly>(const Cfg *Func,
1754 const IValueT Registers,
1755 CondARM32::Cond Cond) {
1756 (void)Func;
1708 // POP - ARM section A8.*.131, encoding A1: 1757 // POP - ARM section A8.*.131, encoding A1:
1709 // pop<c> <registers> 1758 // pop<c> <registers>
1710 // 1759 //
1711 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and 1760 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and
1712 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1761 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1713 constexpr const char *PopListName = "pop {}"; 1762 constexpr const char *PopListName = "pop {}";
1714 constexpr bool IsLoad = true; 1763 constexpr bool IsLoad = true;
1715 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers, 1764 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers,
1716 PopListName); 1765 PopListName);
1717 } 1766 }
1718 1767
1719 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { 1768 template <>
1769 void AssemblerARM32::push<TextualAssembly>(const Cfg *Func, const Operand *OpRt,
1770 CondARM32::Cond Cond) {
1771 constexpr const char *Push = "push";
1772 emitStackTextOp(Func, OpRt, Cond, Push);
1773 }
1774
1775 template <>
1776 void AssemblerARM32::push<BinaryAssembly>(const Cfg *Func, const Operand *OpRt,
1777 CondARM32::Cond Cond) {
1778 (void)Func;
1720 // PUSH - ARM section A8.8.133, encoding A2: 1779 // PUSH - ARM section A8.8.133, encoding A2:
1721 // push<c> {Rt} 1780 // push<c> {Rt}
1722 // 1781 //
1723 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. 1782 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond.
1724 constexpr const char *Push = "push"; 1783 constexpr const char *Push = "push";
1725 IValueT Rt = encodeRegister(OpRt, "Rt", Push); 1784 IValueT Rt = encodeRegister(OpRt, "Rt", Push);
1726 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push); 1785 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push);
1727 // Same as store instruction. 1786 // Same as store instruction.
1728 constexpr bool isLoad = false; 1787 constexpr bool isLoad = false;
1729 constexpr bool isByte = false; 1788 constexpr bool isByte = false;
1730 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, 1789 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
1731 OperandARM32Mem::PreIndex); 1790 OperandARM32Mem::PreIndex);
1732 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address, Push); 1791 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address, Push);
1733 } 1792 }
1734 1793
1735 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { 1794 template <>
1795 void AssemblerARM32::pushList<TextualAssembly>(const Cfg *Func,
1796 const IValueT Registers,
1797 CondARM32::Cond Cond) {
1798 constexpr const char *PushList = "push";
1799 emitStackTextOp(Func, Registers, Cond, PushList);
1800 }
1801
1802 template <>
1803 void AssemblerARM32::pushList<BinaryAssembly>(const Cfg *Func,
1804 const IValueT Registers,
1805 CondARM32::Cond Cond) {
1806 (void)Func;
1736 // PUSH - ARM section A8.8.133, encoding A1: 1807 // PUSH - ARM section A8.8.133, encoding A1:
1737 // push<c> <Registers> 1808 // push<c> <Registers>
1738 // 1809 //
1739 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and 1810 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and
1740 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1811 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1741 constexpr const char *PushListName = "push {}"; 1812 constexpr const char *PushListName = "push {}";
1742 constexpr bool IsLoad = false; 1813 constexpr bool IsLoad = false;
1743 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers, 1814 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers,
1744 PushListName); 1815 PushListName);
1745 } 1816 }
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName); 2070 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName);
2000 } 2071 }
2001 2072
2002 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, 2073 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
2003 CondARM32::Cond Cond) { 2074 CondARM32::Cond Cond) {
2004 constexpr const char *UxtName = "uxt"; 2075 constexpr const char *UxtName = "uxt";
2005 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; 2076 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21;
2006 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); 2077 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
2007 } 2078 }
2008 2079
2009 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode, 2080 template <>
2010 const Variable *OpBaseReg, 2081 void AssemblerARM32::emitVStackOp<TextualAssembly>(
2011 SizeT NumConsecRegs, const char *InstName) { 2082 const Cfg *Func, CondARM32::Cond Cond, IValueT Opcode,
2083 const Variable *OpBaseReg, SizeT NumConsecRegs, const char *InstName) {
2084 (void)Opcode;
2085 if (!BuildDefs::dump())
2086 return;
2012 2087
2088 Ostream &Str = Func->getContext()->getStrEmit();
2089 Str << "\t" << InstName << Cond << "\t{";
2090 IValueT BaseReg = getEncodedSRegNum(OpBaseReg);
2091 assert(0 < NumConsecRegs);
2092 assert(NumConsecRegs <= VpushVpopMaxConsecRegs);
2093 assert((BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs());
2094 bool isFirst = true;
2095 for (SizeT i = 0; i < NumConsecRegs; ++i) {
2096 if (isFirst) {
2097 isFirst = false;
2098 } else {
2099 Str << ", ";
2100 }
2101 Str << RegARM32::getSRegName(BaseReg + i);
2102 }
2103 Str << "}";
2104 }
2105
2106 template <>
2107 void AssemblerARM32::emitVStackOp<BinaryAssembly>(
2108 const Cfg *Func, CondARM32::Cond Cond, IValueT Opcode,
2109 const Variable *OpBaseReg, SizeT NumConsecRegs, const char *InstName) {
2110 (void)Func;
2013 const IValueT BaseReg = getEncodedSRegNum(OpBaseReg); 2111 const IValueT BaseReg = getEncodedSRegNum(OpBaseReg);
2014 const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register. 2112 const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register.
2015 const IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register. 2113 const IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register.
2016 assert(0 < NumConsecRegs); 2114 assert(0 < NumConsecRegs);
2017 assert(NumConsecRegs <= VpushVpopMaxConsecRegs); 2115 assert(NumConsecRegs <= VpushVpopMaxConsecRegs);
2018 assert((BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs()); 2116 assert((BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs());
2019 verifyCondDefined(Cond, InstName); 2117 verifyCondDefined(Cond, InstName);
2020 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2118 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2021 const IValueT Encoding = Opcode | (Cond << kConditionShift) | DLastBit | 2119 const IValueT Encoding = Opcode | (Cond << kConditionShift) | DLastBit |
2022 (Rd << kRdShift) | NumConsecRegs; 2120 (Rd << kRdShift) | NumConsecRegs;
2023 emitInst(Encoding); 2121 emitInst(Encoding);
2024 } 2122 }
2025 2123
2026 void AssemblerARM32::vpop(const Variable *OpBaseReg, SizeT NumConsecRegs, 2124 template <AssemblyOutputForm Form>
2027 CondARM32::Cond Cond) { 2125 void AssemblerARM32::vpop(const Cfg *Func, const Variable *OpBaseReg,
2126 SizeT NumConsecRegs, CondARM32::Cond Cond) {
2028 // Note: Current implementation assumes that OpBaseReg is defined using S 2127 // Note: Current implementation assumes that OpBaseReg is defined using S
2029 // registers. It doesn't implement the D register form. 2128 // registers. It doesn't implement the D register form.
2030 // 2129 //
2031 // VPOP - ARM section A8.8.367, encoding A2: 2130 // VPOP - ARM section A8.8.367, encoding A2:
2032 // vpop<c> <RegList> 2131 // vpop<c> <RegList>
2033 // 2132 //
2034 // cccc11001D111101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and 2133 // cccc11001D111101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
2035 // iiiiiiii=NumConsecRegs. 2134 // iiiiiiii=NumConsecRegs.
2036 constexpr const char *VpopName = "vpop"; 2135 constexpr const char *VpopName = "vpop";
2037 constexpr IValueT VpopOpcode = 2136 constexpr IValueT VpopOpcode =
2038 B27 | B26 | B23 | B21 | B20 | B19 | B18 | B16 | B11 | B9; 2137 B27 | B26 | B23 | B21 | B20 | B19 | B18 | B16 | B11 | B9;
2039 emitVStackOp(Cond, VpopOpcode, OpBaseReg, NumConsecRegs, VpopName); 2138 emitVStackOp<Form>(Func, Cond, VpopOpcode, OpBaseReg, NumConsecRegs,
2139 VpopName);
2040 } 2140 }
2041 2141
2042 void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs, 2142 template <AssemblyOutputForm Form>
2043 CondARM32::Cond Cond) { 2143 void AssemblerARM32::vpush(const Cfg *Func, const Variable *OpBaseReg,
2144 SizeT NumConsecRegs, CondARM32::Cond Cond) {
2044 // Note: Current implementation assumes that OpBaseReg is defined using S 2145 // Note: Current implementation assumes that OpBaseReg is defined using S
2045 // registers. It doesn't implement the D register form. 2146 // registers. It doesn't implement the D register form.
2046 // 2147 //
2047 // VPUSH - ARM section A8.8.368, encoding A2: 2148 // VPUSH - ARM section A8.8.368, encoding A2:
2048 // vpush<c> <RegList> 2149 // vpush<c> <RegList>
2049 // 2150 //
2050 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and 2151 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
2051 // iiiiiiii=NumConsecRegs. 2152 // iiiiiiii=NumConsecRegs.
2052 constexpr const char *VpushName = "vpush"; 2153 constexpr const char *VpushName = "vpush";
2053 constexpr IValueT VpushOpcode = 2154 constexpr IValueT VpushOpcode =
2054 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9; 2155 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9;
2055 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs, VpushName); 2156 emitVStackOp<Form>(Func, Cond, VpushOpcode, OpBaseReg, NumConsecRegs,
2157 VpushName);
2056 } 2158 }
2057 2159
2160 // Force template instantiations.
2161
2162 template void AssemblerARM32::vpop<TextualAssembly>(const Cfg *Func,
2163 const Variable *OpBaseReg,
2164 SizeT NumConsecRegs,
2165 CondARM32::Cond Cond);
2166
2167 template void AssemblerARM32::vpop<BinaryAssembly>(const Cfg *Func,
2168 const Variable *OpBaseReg,
2169 SizeT NumConsecRegs,
2170 CondARM32::Cond Cond);
2171
2172 template void AssemblerARM32::vpush<TextualAssembly>(const Cfg *Func,
2173 const Variable *OpBaseReg,
2174 SizeT NumConsecRegs,
2175 CondARM32::Cond Cond);
2176
2177 template void AssemblerARM32::vpush<BinaryAssembly>(const Cfg *Func,
2178 const Variable *OpBaseReg,
2179 SizeT NumConsecRegs,
2180 CondARM32::Cond Cond);
2181
2058 } // end of namespace ARM32 2182 } // end of namespace ARM32
2059 } // end of namespace Ice 2183 } // end of namespace Ice
OLDNEW
« src/IceAssemblerARM32.h ('K') | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698