OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 30 matching lines...) Expand all Loading... |
41 #include "arm/assembler-arm-inl.h" | 41 #include "arm/assembler-arm-inl.h" |
42 #include "serialize.h" | 42 #include "serialize.h" |
43 | 43 |
44 namespace v8 { | 44 namespace v8 { |
45 namespace internal { | 45 namespace internal { |
46 | 46 |
47 #ifdef DEBUG | 47 #ifdef DEBUG |
48 bool CpuFeatures::initialized_ = false; | 48 bool CpuFeatures::initialized_ = false; |
49 #endif | 49 #endif |
50 unsigned CpuFeatures::supported_ = 0; | 50 unsigned CpuFeatures::supported_ = 0; |
51 unsigned CpuFeatures::found_by_runtime_probing_ = 0; | 51 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0; |
52 | 52 |
53 | 53 |
54 ExternalReference ExternalReference::cpu_features() { | 54 ExternalReference ExternalReference::cpu_features() { |
55 ASSERT(CpuFeatures::initialized_); | 55 ASSERT(CpuFeatures::initialized_); |
56 return ExternalReference(&CpuFeatures::supported_); | 56 return ExternalReference(&CpuFeatures::supported_); |
57 } | 57 } |
58 | 58 |
59 // Get the CPU features enabled by the build. For cross compilation the | 59 // Get the CPU features enabled by the build. For cross compilation the |
60 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS | 60 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS |
61 // can be defined to enable ARMv7 and VFPv3 instructions when building the | 61 // can be defined to enable ARMv7 and VFPv3 instructions when building the |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 103 |
104 return VFPRegisters::Name(index, true); | 104 return VFPRegisters::Name(index, true); |
105 } else { | 105 } else { |
106 ASSERT(index == 0); | 106 ASSERT(index == 0); |
107 return "sfpd0"; | 107 return "sfpd0"; |
108 } | 108 } |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 void CpuFeatures::Probe() { | 112 void CpuFeatures::Probe() { |
113 unsigned standard_features = static_cast<unsigned>( | 113 uint64_t standard_features = static_cast<unsigned>( |
114 OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler(); | 114 OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler(); |
115 ASSERT(supported_ == 0 || supported_ == standard_features); | 115 ASSERT(supported_ == 0 || supported_ == standard_features); |
116 #ifdef DEBUG | 116 #ifdef DEBUG |
117 initialized_ = true; | 117 initialized_ = true; |
118 #endif | 118 #endif |
119 | 119 |
120 // Get the features implied by the OS and the compiler settings. This is the | 120 // Get the features implied by the OS and the compiler settings. This is the |
121 // minimal set of features which is also alowed for generated code in the | 121 // minimal set of features which is also alowed for generated code in the |
122 // snapshot. | 122 // snapshot. |
123 supported_ |= standard_features; | 123 supported_ |= standard_features; |
124 | 124 |
125 if (Serializer::enabled()) { | 125 if (Serializer::enabled()) { |
126 // No probing for features if we might serialize (generate snapshot). | 126 // No probing for features if we might serialize (generate snapshot). |
127 return; | 127 return; |
128 } | 128 } |
129 | 129 |
130 #ifndef __arm__ | 130 #ifndef __arm__ |
131 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is | 131 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is |
132 // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. | 132 // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. |
133 if (FLAG_enable_vfp3) { | 133 if (FLAG_enable_vfp3) { |
134 supported_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; | 134 supported_ |= |
| 135 static_cast<uint64_t>(1) << VFP3 | |
| 136 static_cast<uint64_t>(1) << ARMv7 | |
| 137 static_cast<uint64_t>(1) << VFP2; |
135 } | 138 } |
136 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled | 139 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled |
137 if (FLAG_enable_armv7) { | 140 if (FLAG_enable_armv7) { |
138 supported_ |= 1u << ARMv7; | 141 supported_ |= static_cast<uint64_t>(1) << ARMv7; |
139 } | 142 } |
140 | 143 |
141 if (FLAG_enable_sudiv) { | 144 if (FLAG_enable_sudiv) { |
142 supported_ |= 1u << SUDIV; | 145 supported_ |= static_cast<uint64_t>(1) << SUDIV; |
143 } | 146 } |
144 | 147 |
145 if (FLAG_enable_movw_movt) { | 148 if (FLAG_enable_movw_movt) { |
146 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | 149 supported_ |= static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS; |
147 } | 150 } |
148 | 151 |
149 if (FLAG_enable_32dregs) { | 152 if (FLAG_enable_32dregs) { |
150 supported_ |= 1u << VFP32DREGS; | 153 supported_ |= static_cast<uint64_t>(1) << VFP32DREGS; |
151 } | 154 } |
152 | 155 |
153 #else // __arm__ | 156 #else // __arm__ |
154 // Probe for additional features not already known to be available. | 157 // Probe for additional features not already known to be available. |
155 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { | 158 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { |
156 // This implementation also sets the VFP flags if runtime | 159 // This implementation also sets the VFP flags if runtime |
157 // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI | 160 // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI |
158 // 0406B, page A1-6. | 161 // 0406B, page A1-6. |
159 found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; | 162 found_by_runtime_probing_only_ |= |
| 163 static_cast<uint64_t>(1) << VFP3 | |
| 164 static_cast<uint64_t>(1) << ARMv7 | |
| 165 static_cast<uint64_t>(1) << VFP2; |
160 } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) { | 166 } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) { |
161 found_by_runtime_probing_ |= 1u << VFP2; | 167 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP2; |
162 } | 168 } |
163 | 169 |
164 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { | 170 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { |
165 found_by_runtime_probing_ |= 1u << ARMv7; | 171 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << ARMv7; |
166 } | 172 } |
167 | 173 |
168 if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) { | 174 if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) { |
169 found_by_runtime_probing_ |= 1u << SUDIV; | 175 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << SUDIV; |
170 } | 176 } |
171 | 177 |
172 if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) { | 178 if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) { |
173 found_by_runtime_probing_ |= 1u << UNALIGNED_ACCESSES; | 179 found_by_runtime_probing_only_ |= |
| 180 static_cast<uint64_t>(1) << UNALIGNED_ACCESSES; |
174 } | 181 } |
175 | 182 |
176 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER && | 183 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER && |
177 OS::ArmCpuHasFeature(ARMv7)) { | 184 OS::ArmCpuHasFeature(ARMv7)) { |
178 found_by_runtime_probing_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | 185 found_by_runtime_probing_only_ |= |
| 186 static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS; |
179 } | 187 } |
180 | 188 |
181 if (!IsSupported(VFP32DREGS) && OS::ArmCpuHasFeature(VFP32DREGS)) { | 189 if (!IsSupported(VFP32DREGS) && OS::ArmCpuHasFeature(VFP32DREGS)) { |
182 found_by_runtime_probing_ |= 1u << VFP32DREGS; | 190 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP32DREGS; |
183 } | 191 } |
184 | 192 |
185 supported_ |= found_by_runtime_probing_; | 193 supported_ |= found_by_runtime_probing_only_; |
186 #endif | 194 #endif |
187 | 195 |
188 // Assert that VFP3 implies VFP2 and ARMv7. | 196 // Assert that VFP3 implies VFP2 and ARMv7. |
189 ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7))); | 197 ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7))); |
190 } | 198 } |
191 | 199 |
192 | 200 |
193 // ----------------------------------------------------------------------------- | 201 // ----------------------------------------------------------------------------- |
194 // Implementation of RelocInfo | 202 // Implementation of RelocInfo |
195 | 203 |
(...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 } | 1542 } |
1535 | 1543 |
1536 | 1544 |
1537 void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) { | 1545 void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) { |
1538 addrmod3(cond | L | B7 | S6 | H | B4, dst, src); | 1546 addrmod3(cond | L | B7 | S6 | H | B4, dst, src); |
1539 } | 1547 } |
1540 | 1548 |
1541 | 1549 |
1542 void Assembler::ldrd(Register dst1, Register dst2, | 1550 void Assembler::ldrd(Register dst1, Register dst2, |
1543 const MemOperand& src, Condition cond) { | 1551 const MemOperand& src, Condition cond) { |
1544 ASSERT(CpuFeatures::IsEnabled(ARMv7)); | 1552 ASSERT(IsEnabled(ARMv7)); |
1545 ASSERT(src.rm().is(no_reg)); | 1553 ASSERT(src.rm().is(no_reg)); |
1546 ASSERT(!dst1.is(lr)); // r14. | 1554 ASSERT(!dst1.is(lr)); // r14. |
1547 ASSERT_EQ(0, dst1.code() % 2); | 1555 ASSERT_EQ(0, dst1.code() % 2); |
1548 ASSERT_EQ(dst1.code() + 1, dst2.code()); | 1556 ASSERT_EQ(dst1.code() + 1, dst2.code()); |
1549 addrmod3(cond | B7 | B6 | B4, dst1, src); | 1557 addrmod3(cond | B7 | B6 | B4, dst1, src); |
1550 } | 1558 } |
1551 | 1559 |
1552 | 1560 |
1553 void Assembler::strd(Register src1, Register src2, | 1561 void Assembler::strd(Register src1, Register src2, |
1554 const MemOperand& dst, Condition cond) { | 1562 const MemOperand& dst, Condition cond) { |
1555 ASSERT(dst.rm().is(no_reg)); | 1563 ASSERT(dst.rm().is(no_reg)); |
1556 ASSERT(!src1.is(lr)); // r14. | 1564 ASSERT(!src1.is(lr)); // r14. |
1557 ASSERT_EQ(0, src1.code() % 2); | 1565 ASSERT_EQ(0, src1.code() % 2); |
1558 ASSERT_EQ(src1.code() + 1, src2.code()); | 1566 ASSERT_EQ(src1.code() + 1, src2.code()); |
1559 ASSERT(CpuFeatures::IsEnabled(ARMv7)); | 1567 ASSERT(IsEnabled(ARMv7)); |
1560 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst); | 1568 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst); |
1561 } | 1569 } |
1562 | 1570 |
1563 // Load/Store multiple instructions. | 1571 // Load/Store multiple instructions. |
1564 void Assembler::ldm(BlockAddrMode am, | 1572 void Assembler::ldm(BlockAddrMode am, |
1565 Register base, | 1573 Register base, |
1566 RegList dst, | 1574 RegList dst, |
1567 Condition cond) { | 1575 Condition cond) { |
1568 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable. | 1576 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable. |
1569 ASSERT(base.is(sp) || (dst & sp.bit()) == 0); | 1577 ASSERT(base.is(sp) || (dst & sp.bit()) == 0); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1748 // Support for VFP. | 1756 // Support for VFP. |
1749 | 1757 |
1750 void Assembler::vldr(const DwVfpRegister dst, | 1758 void Assembler::vldr(const DwVfpRegister dst, |
1751 const Register base, | 1759 const Register base, |
1752 int offset, | 1760 int offset, |
1753 const Condition cond) { | 1761 const Condition cond) { |
1754 // Ddst = MEM(Rbase + offset). | 1762 // Ddst = MEM(Rbase + offset). |
1755 // Instruction details available in ARM DDI 0406C.b, A8-924. | 1763 // Instruction details available in ARM DDI 0406C.b, A8-924. |
1756 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) | | 1764 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) | |
1757 // Vd(15-12) | 1011(11-8) | offset | 1765 // Vd(15-12) | 1011(11-8) | offset |
1758 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1766 ASSERT(IsEnabled(VFP2)); |
1759 int u = 1; | 1767 int u = 1; |
1760 if (offset < 0) { | 1768 if (offset < 0) { |
1761 offset = -offset; | 1769 offset = -offset; |
1762 u = 0; | 1770 u = 0; |
1763 } | 1771 } |
1764 int vd, d; | 1772 int vd, d; |
1765 dst.split_code(&vd, &d); | 1773 dst.split_code(&vd, &d); |
1766 | 1774 |
1767 ASSERT(offset >= 0); | 1775 ASSERT(offset >= 0); |
1768 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1776 if ((offset % 4) == 0 && (offset / 4) < 256) { |
(...skipping 23 matching lines...) Expand all Loading... |
1792 | 1800 |
1793 | 1801 |
1794 void Assembler::vldr(const SwVfpRegister dst, | 1802 void Assembler::vldr(const SwVfpRegister dst, |
1795 const Register base, | 1803 const Register base, |
1796 int offset, | 1804 int offset, |
1797 const Condition cond) { | 1805 const Condition cond) { |
1798 // Sdst = MEM(Rbase + offset). | 1806 // Sdst = MEM(Rbase + offset). |
1799 // Instruction details available in ARM DDI 0406A, A8-628. | 1807 // Instruction details available in ARM DDI 0406A, A8-628. |
1800 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | | 1808 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | |
1801 // Vdst(15-12) | 1010(11-8) | offset | 1809 // Vdst(15-12) | 1010(11-8) | offset |
1802 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1810 ASSERT(IsEnabled(VFP2)); |
1803 int u = 1; | 1811 int u = 1; |
1804 if (offset < 0) { | 1812 if (offset < 0) { |
1805 offset = -offset; | 1813 offset = -offset; |
1806 u = 0; | 1814 u = 0; |
1807 } | 1815 } |
1808 int sd, d; | 1816 int sd, d; |
1809 dst.split_code(&sd, &d); | 1817 dst.split_code(&sd, &d); |
1810 ASSERT(offset >= 0); | 1818 ASSERT(offset >= 0); |
1811 | 1819 |
1812 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1820 if ((offset % 4) == 0 && (offset / 4) < 256) { |
(...skipping 23 matching lines...) Expand all Loading... |
1836 | 1844 |
1837 | 1845 |
1838 void Assembler::vstr(const DwVfpRegister src, | 1846 void Assembler::vstr(const DwVfpRegister src, |
1839 const Register base, | 1847 const Register base, |
1840 int offset, | 1848 int offset, |
1841 const Condition cond) { | 1849 const Condition cond) { |
1842 // MEM(Rbase + offset) = Dsrc. | 1850 // MEM(Rbase + offset) = Dsrc. |
1843 // Instruction details available in ARM DDI 0406C.b, A8-1082. | 1851 // Instruction details available in ARM DDI 0406C.b, A8-1082. |
1844 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) | | 1852 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) | |
1845 // Vd(15-12) | 1011(11-8) | (offset/4) | 1853 // Vd(15-12) | 1011(11-8) | (offset/4) |
1846 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1854 ASSERT(IsEnabled(VFP2)); |
1847 int u = 1; | 1855 int u = 1; |
1848 if (offset < 0) { | 1856 if (offset < 0) { |
1849 offset = -offset; | 1857 offset = -offset; |
1850 u = 0; | 1858 u = 0; |
1851 } | 1859 } |
1852 ASSERT(offset >= 0); | 1860 ASSERT(offset >= 0); |
1853 int vd, d; | 1861 int vd, d; |
1854 src.split_code(&vd, &d); | 1862 src.split_code(&vd, &d); |
1855 | 1863 |
1856 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1864 if ((offset % 4) == 0 && (offset / 4) < 256) { |
(...skipping 23 matching lines...) Expand all Loading... |
1880 | 1888 |
1881 | 1889 |
1882 void Assembler::vstr(const SwVfpRegister src, | 1890 void Assembler::vstr(const SwVfpRegister src, |
1883 const Register base, | 1891 const Register base, |
1884 int offset, | 1892 int offset, |
1885 const Condition cond) { | 1893 const Condition cond) { |
1886 // MEM(Rbase + offset) = SSrc. | 1894 // MEM(Rbase + offset) = SSrc. |
1887 // Instruction details available in ARM DDI 0406A, A8-786. | 1895 // Instruction details available in ARM DDI 0406A, A8-786. |
1888 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | | 1896 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | |
1889 // Vdst(15-12) | 1010(11-8) | (offset/4) | 1897 // Vdst(15-12) | 1010(11-8) | (offset/4) |
1890 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1898 ASSERT(IsEnabled(VFP2)); |
1891 int u = 1; | 1899 int u = 1; |
1892 if (offset < 0) { | 1900 if (offset < 0) { |
1893 offset = -offset; | 1901 offset = -offset; |
1894 u = 0; | 1902 u = 0; |
1895 } | 1903 } |
1896 int sd, d; | 1904 int sd, d; |
1897 src.split_code(&sd, &d); | 1905 src.split_code(&sd, &d); |
1898 ASSERT(offset >= 0); | 1906 ASSERT(offset >= 0); |
1899 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1907 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1900 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | | 1908 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | |
(...skipping 22 matching lines...) Expand all Loading... |
1923 | 1931 |
1924 | 1932 |
1925 void Assembler::vldm(BlockAddrMode am, | 1933 void Assembler::vldm(BlockAddrMode am, |
1926 Register base, | 1934 Register base, |
1927 DwVfpRegister first, | 1935 DwVfpRegister first, |
1928 DwVfpRegister last, | 1936 DwVfpRegister last, |
1929 Condition cond) { | 1937 Condition cond) { |
1930 // Instruction details available in ARM DDI 0406C.b, A8-922. | 1938 // Instruction details available in ARM DDI 0406C.b, A8-922. |
1931 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 1939 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
1932 // first(15-12) | 1011(11-8) | (count * 2) | 1940 // first(15-12) | 1011(11-8) | (count * 2) |
1933 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1941 ASSERT(IsEnabled(VFP2)); |
1934 ASSERT_LE(first.code(), last.code()); | 1942 ASSERT_LE(first.code(), last.code()); |
1935 ASSERT(am == ia || am == ia_w || am == db_w); | 1943 ASSERT(am == ia || am == ia_w || am == db_w); |
1936 ASSERT(!base.is(pc)); | 1944 ASSERT(!base.is(pc)); |
1937 | 1945 |
1938 int sd, d; | 1946 int sd, d; |
1939 first.split_code(&sd, &d); | 1947 first.split_code(&sd, &d); |
1940 int count = last.code() - first.code() + 1; | 1948 int count = last.code() - first.code() + 1; |
1941 ASSERT(count <= 16); | 1949 ASSERT(count <= 16); |
1942 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 1950 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
1943 0xB*B8 | count*2); | 1951 0xB*B8 | count*2); |
1944 } | 1952 } |
1945 | 1953 |
1946 | 1954 |
1947 void Assembler::vstm(BlockAddrMode am, | 1955 void Assembler::vstm(BlockAddrMode am, |
1948 Register base, | 1956 Register base, |
1949 DwVfpRegister first, | 1957 DwVfpRegister first, |
1950 DwVfpRegister last, | 1958 DwVfpRegister last, |
1951 Condition cond) { | 1959 Condition cond) { |
1952 // Instruction details available in ARM DDI 0406C.b, A8-1080. | 1960 // Instruction details available in ARM DDI 0406C.b, A8-1080. |
1953 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 1961 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
1954 // first(15-12) | 1011(11-8) | (count * 2) | 1962 // first(15-12) | 1011(11-8) | (count * 2) |
1955 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1963 ASSERT(IsEnabled(VFP2)); |
1956 ASSERT_LE(first.code(), last.code()); | 1964 ASSERT_LE(first.code(), last.code()); |
1957 ASSERT(am == ia || am == ia_w || am == db_w); | 1965 ASSERT(am == ia || am == ia_w || am == db_w); |
1958 ASSERT(!base.is(pc)); | 1966 ASSERT(!base.is(pc)); |
1959 | 1967 |
1960 int sd, d; | 1968 int sd, d; |
1961 first.split_code(&sd, &d); | 1969 first.split_code(&sd, &d); |
1962 int count = last.code() - first.code() + 1; | 1970 int count = last.code() - first.code() + 1; |
1963 ASSERT(count <= 16); | 1971 ASSERT(count <= 16); |
1964 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 1972 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
1965 0xB*B8 | count*2); | 1973 0xB*B8 | count*2); |
1966 } | 1974 } |
1967 | 1975 |
1968 void Assembler::vldm(BlockAddrMode am, | 1976 void Assembler::vldm(BlockAddrMode am, |
1969 Register base, | 1977 Register base, |
1970 SwVfpRegister first, | 1978 SwVfpRegister first, |
1971 SwVfpRegister last, | 1979 SwVfpRegister last, |
1972 Condition cond) { | 1980 Condition cond) { |
1973 // Instruction details available in ARM DDI 0406A, A8-626. | 1981 // Instruction details available in ARM DDI 0406A, A8-626. |
1974 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 1982 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
1975 // first(15-12) | 1010(11-8) | (count/2) | 1983 // first(15-12) | 1010(11-8) | (count/2) |
1976 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 1984 ASSERT(IsEnabled(VFP2)); |
1977 ASSERT_LE(first.code(), last.code()); | 1985 ASSERT_LE(first.code(), last.code()); |
1978 ASSERT(am == ia || am == ia_w || am == db_w); | 1986 ASSERT(am == ia || am == ia_w || am == db_w); |
1979 ASSERT(!base.is(pc)); | 1987 ASSERT(!base.is(pc)); |
1980 | 1988 |
1981 int sd, d; | 1989 int sd, d; |
1982 first.split_code(&sd, &d); | 1990 first.split_code(&sd, &d); |
1983 int count = last.code() - first.code() + 1; | 1991 int count = last.code() - first.code() + 1; |
1984 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 1992 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
1985 0xA*B8 | count); | 1993 0xA*B8 | count); |
1986 } | 1994 } |
1987 | 1995 |
1988 | 1996 |
1989 void Assembler::vstm(BlockAddrMode am, | 1997 void Assembler::vstm(BlockAddrMode am, |
1990 Register base, | 1998 Register base, |
1991 SwVfpRegister first, | 1999 SwVfpRegister first, |
1992 SwVfpRegister last, | 2000 SwVfpRegister last, |
1993 Condition cond) { | 2001 Condition cond) { |
1994 // Instruction details available in ARM DDI 0406A, A8-784. | 2002 // Instruction details available in ARM DDI 0406A, A8-784. |
1995 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 2003 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
1996 // first(15-12) | 1011(11-8) | (count/2) | 2004 // first(15-12) | 1011(11-8) | (count/2) |
1997 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2005 ASSERT(IsEnabled(VFP2)); |
1998 ASSERT_LE(first.code(), last.code()); | 2006 ASSERT_LE(first.code(), last.code()); |
1999 ASSERT(am == ia || am == ia_w || am == db_w); | 2007 ASSERT(am == ia || am == ia_w || am == db_w); |
2000 ASSERT(!base.is(pc)); | 2008 ASSERT(!base.is(pc)); |
2001 | 2009 |
2002 int sd, d; | 2010 int sd, d; |
2003 first.split_code(&sd, &d); | 2011 first.split_code(&sd, &d); |
2004 int count = last.code() - first.code() + 1; | 2012 int count = last.code() - first.code() + 1; |
2005 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 2013 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
2006 0xA*B8 | count); | 2014 0xA*B8 | count); |
2007 } | 2015 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2061 *encoding |= (hi >> 4) & 0x70000; // Low three bits of the high nybble. | 2069 *encoding |= (hi >> 4) & 0x70000; // Low three bits of the high nybble. |
2062 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. | 2070 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. |
2063 | 2071 |
2064 return true; | 2072 return true; |
2065 } | 2073 } |
2066 | 2074 |
2067 | 2075 |
2068 void Assembler::vmov(const DwVfpRegister dst, | 2076 void Assembler::vmov(const DwVfpRegister dst, |
2069 double imm, | 2077 double imm, |
2070 const Register scratch) { | 2078 const Register scratch) { |
2071 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2079 ASSERT(IsEnabled(VFP2)); |
2072 | 2080 |
2073 uint32_t enc; | 2081 uint32_t enc; |
2074 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { | 2082 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { |
2075 // The double can be encoded in the instruction. | 2083 // The double can be encoded in the instruction. |
2076 // | 2084 // |
2077 // Dd = immediate | 2085 // Dd = immediate |
2078 // Instruction details available in ARM DDI 0406C.b, A8-936. | 2086 // Instruction details available in ARM DDI 0406C.b, A8-936. |
2079 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | | 2087 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
2080 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) | 2088 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) |
2081 int vd, d; | 2089 int vd, d; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2133 } | 2141 } |
2134 } | 2142 } |
2135 } | 2143 } |
2136 | 2144 |
2137 | 2145 |
2138 void Assembler::vmov(const SwVfpRegister dst, | 2146 void Assembler::vmov(const SwVfpRegister dst, |
2139 const SwVfpRegister src, | 2147 const SwVfpRegister src, |
2140 const Condition cond) { | 2148 const Condition cond) { |
2141 // Sd = Sm | 2149 // Sd = Sm |
2142 // Instruction details available in ARM DDI 0406B, A8-642. | 2150 // Instruction details available in ARM DDI 0406B, A8-642. |
2143 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2151 ASSERT(IsEnabled(VFP2)); |
2144 int sd, d, sm, m; | 2152 int sd, d, sm, m; |
2145 dst.split_code(&sd, &d); | 2153 dst.split_code(&sd, &d); |
2146 src.split_code(&sm, &m); | 2154 src.split_code(&sm, &m); |
2147 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); | 2155 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); |
2148 } | 2156 } |
2149 | 2157 |
2150 | 2158 |
2151 void Assembler::vmov(const DwVfpRegister dst, | 2159 void Assembler::vmov(const DwVfpRegister dst, |
2152 const DwVfpRegister src, | 2160 const DwVfpRegister src, |
2153 const Condition cond) { | 2161 const Condition cond) { |
2154 // Dd = Dm | 2162 // Dd = Dm |
2155 // Instruction details available in ARM DDI 0406C.b, A8-938. | 2163 // Instruction details available in ARM DDI 0406C.b, A8-938. |
2156 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | | 2164 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
2157 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2165 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2158 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2166 ASSERT(IsEnabled(VFP2)); |
2159 int vd, d; | 2167 int vd, d; |
2160 dst.split_code(&vd, &d); | 2168 dst.split_code(&vd, &d); |
2161 int vm, m; | 2169 int vm, m; |
2162 src.split_code(&vm, &m); | 2170 src.split_code(&vm, &m); |
2163 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 | | 2171 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 | |
2164 vm); | 2172 vm); |
2165 } | 2173 } |
2166 | 2174 |
2167 | 2175 |
2168 void Assembler::vmov(const DwVfpRegister dst, | 2176 void Assembler::vmov(const DwVfpRegister dst, |
2169 const VmovIndex index, | 2177 const VmovIndex index, |
2170 const Register src, | 2178 const Register src, |
2171 const Condition cond) { | 2179 const Condition cond) { |
2172 // Dd[index] = Rt | 2180 // Dd[index] = Rt |
2173 // Instruction details available in ARM DDI 0406C.b, A8-940. | 2181 // Instruction details available in ARM DDI 0406C.b, A8-940. |
2174 // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) | | 2182 // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) | |
2175 // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0) | 2183 // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0) |
2176 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2184 ASSERT(IsEnabled(VFP2)); |
2177 ASSERT(index.index == 0 || index.index == 1); | 2185 ASSERT(index.index == 0 || index.index == 1); |
2178 int vd, d; | 2186 int vd, d; |
2179 dst.split_code(&vd, &d); | 2187 dst.split_code(&vd, &d); |
2180 emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 | | 2188 emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 | |
2181 d*B7 | B4); | 2189 d*B7 | B4); |
2182 } | 2190 } |
2183 | 2191 |
2184 | 2192 |
2185 void Assembler::vmov(const DwVfpRegister dst, | 2193 void Assembler::vmov(const DwVfpRegister dst, |
2186 const Register src1, | 2194 const Register src1, |
2187 const Register src2, | 2195 const Register src2, |
2188 const Condition cond) { | 2196 const Condition cond) { |
2189 // Dm = <Rt,Rt2>. | 2197 // Dm = <Rt,Rt2>. |
2190 // Instruction details available in ARM DDI 0406C.b, A8-948. | 2198 // Instruction details available in ARM DDI 0406C.b, A8-948. |
2191 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | | 2199 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | |
2192 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2200 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
2193 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2201 ASSERT(IsEnabled(VFP2)); |
2194 ASSERT(!src1.is(pc) && !src2.is(pc)); | 2202 ASSERT(!src1.is(pc) && !src2.is(pc)); |
2195 int vm, m; | 2203 int vm, m; |
2196 dst.split_code(&vm, &m); | 2204 dst.split_code(&vm, &m); |
2197 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | | 2205 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
2198 src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); | 2206 src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
2199 } | 2207 } |
2200 | 2208 |
2201 | 2209 |
2202 void Assembler::vmov(const Register dst1, | 2210 void Assembler::vmov(const Register dst1, |
2203 const Register dst2, | 2211 const Register dst2, |
2204 const DwVfpRegister src, | 2212 const DwVfpRegister src, |
2205 const Condition cond) { | 2213 const Condition cond) { |
2206 // <Rt,Rt2> = Dm. | 2214 // <Rt,Rt2> = Dm. |
2207 // Instruction details available in ARM DDI 0406C.b, A8-948. | 2215 // Instruction details available in ARM DDI 0406C.b, A8-948. |
2208 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | | 2216 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | |
2209 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2217 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
2210 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2218 ASSERT(IsEnabled(VFP2)); |
2211 ASSERT(!dst1.is(pc) && !dst2.is(pc)); | 2219 ASSERT(!dst1.is(pc) && !dst2.is(pc)); |
2212 int vm, m; | 2220 int vm, m; |
2213 src.split_code(&vm, &m); | 2221 src.split_code(&vm, &m); |
2214 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | | 2222 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
2215 dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); | 2223 dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
2216 } | 2224 } |
2217 | 2225 |
2218 | 2226 |
2219 void Assembler::vmov(const SwVfpRegister dst, | 2227 void Assembler::vmov(const SwVfpRegister dst, |
2220 const Register src, | 2228 const Register src, |
2221 const Condition cond) { | 2229 const Condition cond) { |
2222 // Sn = Rt. | 2230 // Sn = Rt. |
2223 // Instruction details available in ARM DDI 0406A, A8-642. | 2231 // Instruction details available in ARM DDI 0406A, A8-642. |
2224 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | | 2232 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | |
2225 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2233 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2226 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2234 ASSERT(IsEnabled(VFP2)); |
2227 ASSERT(!src.is(pc)); | 2235 ASSERT(!src.is(pc)); |
2228 int sn, n; | 2236 int sn, n; |
2229 dst.split_code(&sn, &n); | 2237 dst.split_code(&sn, &n); |
2230 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); | 2238 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); |
2231 } | 2239 } |
2232 | 2240 |
2233 | 2241 |
2234 void Assembler::vmov(const Register dst, | 2242 void Assembler::vmov(const Register dst, |
2235 const SwVfpRegister src, | 2243 const SwVfpRegister src, |
2236 const Condition cond) { | 2244 const Condition cond) { |
2237 // Rt = Sn. | 2245 // Rt = Sn. |
2238 // Instruction details available in ARM DDI 0406A, A8-642. | 2246 // Instruction details available in ARM DDI 0406A, A8-642. |
2239 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | | 2247 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | |
2240 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2248 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2241 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2249 ASSERT(IsEnabled(VFP2)); |
2242 ASSERT(!dst.is(pc)); | 2250 ASSERT(!dst.is(pc)); |
2243 int sn, n; | 2251 int sn, n; |
2244 src.split_code(&sn, &n); | 2252 src.split_code(&sn, &n); |
2245 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); | 2253 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); |
2246 } | 2254 } |
2247 | 2255 |
2248 | 2256 |
2249 // Type of data to read from or write to VFP register. | 2257 // Type of data to read from or write to VFP register. |
2250 // Used as specifier in generic vcvt instruction. | 2258 // Used as specifier in generic vcvt instruction. |
2251 enum VFPType { S32, U32, F32, F64 }; | 2259 enum VFPType { S32, U32, F32, F64 }; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2356 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | | 2364 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | |
2357 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); | 2365 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); |
2358 } | 2366 } |
2359 } | 2367 } |
2360 | 2368 |
2361 | 2369 |
2362 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, | 2370 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, |
2363 const SwVfpRegister src, | 2371 const SwVfpRegister src, |
2364 VFPConversionMode mode, | 2372 VFPConversionMode mode, |
2365 const Condition cond) { | 2373 const Condition cond) { |
2366 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2374 ASSERT(IsEnabled(VFP2)); |
2367 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); | 2375 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); |
2368 } | 2376 } |
2369 | 2377 |
2370 | 2378 |
2371 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, | 2379 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, |
2372 const SwVfpRegister src, | 2380 const SwVfpRegister src, |
2373 VFPConversionMode mode, | 2381 VFPConversionMode mode, |
2374 const Condition cond) { | 2382 const Condition cond) { |
2375 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2383 ASSERT(IsEnabled(VFP2)); |
2376 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); | 2384 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); |
2377 } | 2385 } |
2378 | 2386 |
2379 | 2387 |
2380 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, | 2388 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, |
2381 const SwVfpRegister src, | 2389 const SwVfpRegister src, |
2382 VFPConversionMode mode, | 2390 VFPConversionMode mode, |
2383 const Condition cond) { | 2391 const Condition cond) { |
2384 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2392 ASSERT(IsEnabled(VFP2)); |
2385 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); | 2393 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); |
2386 } | 2394 } |
2387 | 2395 |
2388 | 2396 |
2389 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, | 2397 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, |
2390 const DwVfpRegister src, | 2398 const DwVfpRegister src, |
2391 VFPConversionMode mode, | 2399 VFPConversionMode mode, |
2392 const Condition cond) { | 2400 const Condition cond) { |
2393 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2401 ASSERT(IsEnabled(VFP2)); |
2394 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); | 2402 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); |
2395 } | 2403 } |
2396 | 2404 |
2397 | 2405 |
2398 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, | 2406 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, |
2399 const DwVfpRegister src, | 2407 const DwVfpRegister src, |
2400 VFPConversionMode mode, | 2408 VFPConversionMode mode, |
2401 const Condition cond) { | 2409 const Condition cond) { |
2402 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2410 ASSERT(IsEnabled(VFP2)); |
2403 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); | 2411 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); |
2404 } | 2412 } |
2405 | 2413 |
2406 | 2414 |
2407 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, | 2415 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, |
2408 const SwVfpRegister src, | 2416 const SwVfpRegister src, |
2409 VFPConversionMode mode, | 2417 VFPConversionMode mode, |
2410 const Condition cond) { | 2418 const Condition cond) { |
2411 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2419 ASSERT(IsEnabled(VFP2)); |
2412 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); | 2420 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); |
2413 } | 2421 } |
2414 | 2422 |
2415 | 2423 |
2416 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, | 2424 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, |
2417 const DwVfpRegister src, | 2425 const DwVfpRegister src, |
2418 VFPConversionMode mode, | 2426 VFPConversionMode mode, |
2419 const Condition cond) { | 2427 const Condition cond) { |
2420 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2428 ASSERT(IsEnabled(VFP2)); |
2421 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); | 2429 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); |
2422 } | 2430 } |
2423 | 2431 |
2424 | 2432 |
2425 void Assembler::vneg(const DwVfpRegister dst, | 2433 void Assembler::vneg(const DwVfpRegister dst, |
2426 const DwVfpRegister src, | 2434 const DwVfpRegister src, |
2427 const Condition cond) { | 2435 const Condition cond) { |
2428 // Instruction details available in ARM DDI 0406C.b, A8-968. | 2436 // Instruction details available in ARM DDI 0406C.b, A8-968. |
2429 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | | 2437 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | |
2430 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2438 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2431 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2439 ASSERT(IsEnabled(VFP2)); |
2432 int vd, d; | 2440 int vd, d; |
2433 dst.split_code(&vd, &d); | 2441 dst.split_code(&vd, &d); |
2434 int vm, m; | 2442 int vm, m; |
2435 src.split_code(&vm, &m); | 2443 src.split_code(&vm, &m); |
2436 | 2444 |
2437 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 | | 2445 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
2438 m*B5 | vm); | 2446 m*B5 | vm); |
2439 } | 2447 } |
2440 | 2448 |
2441 | 2449 |
2442 void Assembler::vabs(const DwVfpRegister dst, | 2450 void Assembler::vabs(const DwVfpRegister dst, |
2443 const DwVfpRegister src, | 2451 const DwVfpRegister src, |
2444 const Condition cond) { | 2452 const Condition cond) { |
2445 // Instruction details available in ARM DDI 0406C.b, A8-524. | 2453 // Instruction details available in ARM DDI 0406C.b, A8-524. |
2446 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | | 2454 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
2447 // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2455 // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2448 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2456 ASSERT(IsEnabled(VFP2)); |
2449 int vd, d; | 2457 int vd, d; |
2450 dst.split_code(&vd, &d); | 2458 dst.split_code(&vd, &d); |
2451 int vm, m; | 2459 int vm, m; |
2452 src.split_code(&vm, &m); | 2460 src.split_code(&vm, &m); |
2453 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 | | 2461 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 | |
2454 m*B5 | vm); | 2462 m*B5 | vm); |
2455 } | 2463 } |
2456 | 2464 |
2457 | 2465 |
2458 void Assembler::vadd(const DwVfpRegister dst, | 2466 void Assembler::vadd(const DwVfpRegister dst, |
2459 const DwVfpRegister src1, | 2467 const DwVfpRegister src1, |
2460 const DwVfpRegister src2, | 2468 const DwVfpRegister src2, |
2461 const Condition cond) { | 2469 const Condition cond) { |
2462 // Dd = vadd(Dn, Dm) double precision floating point addition. | 2470 // Dd = vadd(Dn, Dm) double precision floating point addition. |
2463 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2471 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2464 // Instruction details available in ARM DDI 0406C.b, A8-830. | 2472 // Instruction details available in ARM DDI 0406C.b, A8-830. |
2465 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | | 2473 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
2466 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 2474 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
2467 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2475 ASSERT(IsEnabled(VFP2)); |
2468 int vd, d; | 2476 int vd, d; |
2469 dst.split_code(&vd, &d); | 2477 dst.split_code(&vd, &d); |
2470 int vn, n; | 2478 int vn, n; |
2471 src1.split_code(&vn, &n); | 2479 src1.split_code(&vn, &n); |
2472 int vm, m; | 2480 int vm, m; |
2473 src2.split_code(&vm, &m); | 2481 src2.split_code(&vm, &m); |
2474 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 2482 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
2475 n*B7 | m*B5 | vm); | 2483 n*B7 | m*B5 | vm); |
2476 } | 2484 } |
2477 | 2485 |
2478 | 2486 |
2479 void Assembler::vsub(const DwVfpRegister dst, | 2487 void Assembler::vsub(const DwVfpRegister dst, |
2480 const DwVfpRegister src1, | 2488 const DwVfpRegister src1, |
2481 const DwVfpRegister src2, | 2489 const DwVfpRegister src2, |
2482 const Condition cond) { | 2490 const Condition cond) { |
2483 // Dd = vsub(Dn, Dm) double precision floating point subtraction. | 2491 // Dd = vsub(Dn, Dm) double precision floating point subtraction. |
2484 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2492 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2485 // Instruction details available in ARM DDI 0406C.b, A8-1086. | 2493 // Instruction details available in ARM DDI 0406C.b, A8-1086. |
2486 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | | 2494 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
2487 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2495 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2488 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2496 ASSERT(IsEnabled(VFP2)); |
2489 int vd, d; | 2497 int vd, d; |
2490 dst.split_code(&vd, &d); | 2498 dst.split_code(&vd, &d); |
2491 int vn, n; | 2499 int vn, n; |
2492 src1.split_code(&vn, &n); | 2500 src1.split_code(&vn, &n); |
2493 int vm, m; | 2501 int vm, m; |
2494 src2.split_code(&vm, &m); | 2502 src2.split_code(&vm, &m); |
2495 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 2503 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
2496 n*B7 | B6 | m*B5 | vm); | 2504 n*B7 | B6 | m*B5 | vm); |
2497 } | 2505 } |
2498 | 2506 |
2499 | 2507 |
2500 void Assembler::vmul(const DwVfpRegister dst, | 2508 void Assembler::vmul(const DwVfpRegister dst, |
2501 const DwVfpRegister src1, | 2509 const DwVfpRegister src1, |
2502 const DwVfpRegister src2, | 2510 const DwVfpRegister src2, |
2503 const Condition cond) { | 2511 const Condition cond) { |
2504 // Dd = vmul(Dn, Dm) double precision floating point multiplication. | 2512 // Dd = vmul(Dn, Dm) double precision floating point multiplication. |
2505 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2513 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2506 // Instruction details available in ARM DDI 0406C.b, A8-960. | 2514 // Instruction details available in ARM DDI 0406C.b, A8-960. |
2507 // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) | | 2515 // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) | |
2508 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 2516 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
2509 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2517 ASSERT(IsEnabled(VFP2)); |
2510 int vd, d; | 2518 int vd, d; |
2511 dst.split_code(&vd, &d); | 2519 dst.split_code(&vd, &d); |
2512 int vn, n; | 2520 int vn, n; |
2513 src1.split_code(&vn, &n); | 2521 src1.split_code(&vn, &n); |
2514 int vm, m; | 2522 int vm, m; |
2515 src2.split_code(&vm, &m); | 2523 src2.split_code(&vm, &m); |
2516 emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 2524 emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
2517 n*B7 | m*B5 | vm); | 2525 n*B7 | m*B5 | vm); |
2518 } | 2526 } |
2519 | 2527 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2556 | 2564 |
2557 void Assembler::vdiv(const DwVfpRegister dst, | 2565 void Assembler::vdiv(const DwVfpRegister dst, |
2558 const DwVfpRegister src1, | 2566 const DwVfpRegister src1, |
2559 const DwVfpRegister src2, | 2567 const DwVfpRegister src2, |
2560 const Condition cond) { | 2568 const Condition cond) { |
2561 // Dd = vdiv(Dn, Dm) double precision floating point division. | 2569 // Dd = vdiv(Dn, Dm) double precision floating point division. |
2562 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2570 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2563 // Instruction details available in ARM DDI 0406C.b, A8-882. | 2571 // Instruction details available in ARM DDI 0406C.b, A8-882. |
2564 // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) | | 2572 // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) | |
2565 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 2573 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
2566 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2574 ASSERT(IsEnabled(VFP2)); |
2567 int vd, d; | 2575 int vd, d; |
2568 dst.split_code(&vd, &d); | 2576 dst.split_code(&vd, &d); |
2569 int vn, n; | 2577 int vn, n; |
2570 src1.split_code(&vn, &n); | 2578 src1.split_code(&vn, &n); |
2571 int vm, m; | 2579 int vm, m; |
2572 src2.split_code(&vm, &m); | 2580 src2.split_code(&vm, &m); |
2573 emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | | 2581 emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | |
2574 vm); | 2582 vm); |
2575 } | 2583 } |
2576 | 2584 |
2577 | 2585 |
2578 void Assembler::vcmp(const DwVfpRegister src1, | 2586 void Assembler::vcmp(const DwVfpRegister src1, |
2579 const DwVfpRegister src2, | 2587 const DwVfpRegister src2, |
2580 const Condition cond) { | 2588 const Condition cond) { |
2581 // vcmp(Dd, Dm) double precision floating point comparison. | 2589 // vcmp(Dd, Dm) double precision floating point comparison. |
2582 // Instruction details available in ARM DDI 0406C.b, A8-864. | 2590 // Instruction details available in ARM DDI 0406C.b, A8-864. |
2583 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) | | 2591 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) | |
2584 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2592 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2585 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2593 ASSERT(IsEnabled(VFP2)); |
2586 int vd, d; | 2594 int vd, d; |
2587 src1.split_code(&vd, &d); | 2595 src1.split_code(&vd, &d); |
2588 int vm, m; | 2596 int vm, m; |
2589 src2.split_code(&vm, &m); | 2597 src2.split_code(&vm, &m); |
2590 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 | | 2598 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
2591 m*B5 | vm); | 2599 m*B5 | vm); |
2592 } | 2600 } |
2593 | 2601 |
2594 | 2602 |
2595 void Assembler::vcmp(const DwVfpRegister src1, | 2603 void Assembler::vcmp(const DwVfpRegister src1, |
2596 const double src2, | 2604 const double src2, |
2597 const Condition cond) { | 2605 const Condition cond) { |
2598 // vcmp(Dd, #0.0) double precision floating point comparison. | 2606 // vcmp(Dd, #0.0) double precision floating point comparison. |
2599 // Instruction details available in ARM DDI 0406C.b, A8-864. | 2607 // Instruction details available in ARM DDI 0406C.b, A8-864. |
2600 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | | 2608 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | |
2601 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) | 2609 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) |
2602 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2610 ASSERT(IsEnabled(VFP2)); |
2603 ASSERT(src2 == 0.0); | 2611 ASSERT(src2 == 0.0); |
2604 int vd, d; | 2612 int vd, d; |
2605 src1.split_code(&vd, &d); | 2613 src1.split_code(&vd, &d); |
2606 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6); | 2614 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6); |
2607 } | 2615 } |
2608 | 2616 |
2609 | 2617 |
2610 void Assembler::vmsr(Register dst, Condition cond) { | 2618 void Assembler::vmsr(Register dst, Condition cond) { |
2611 // Instruction details available in ARM DDI 0406A, A8-652. | 2619 // Instruction details available in ARM DDI 0406A, A8-652. |
2612 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | | 2620 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | |
2613 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 2621 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
2614 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2622 ASSERT(IsEnabled(VFP2)); |
2615 emit(cond | 0xE*B24 | 0xE*B20 | B16 | | 2623 emit(cond | 0xE*B24 | 0xE*B20 | B16 | |
2616 dst.code()*B12 | 0xA*B8 | B4); | 2624 dst.code()*B12 | 0xA*B8 | B4); |
2617 } | 2625 } |
2618 | 2626 |
2619 | 2627 |
2620 void Assembler::vmrs(Register dst, Condition cond) { | 2628 void Assembler::vmrs(Register dst, Condition cond) { |
2621 // Instruction details available in ARM DDI 0406A, A8-652. | 2629 // Instruction details available in ARM DDI 0406A, A8-652. |
2622 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | | 2630 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | |
2623 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 2631 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
2624 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2632 ASSERT(IsEnabled(VFP2)); |
2625 emit(cond | 0xE*B24 | 0xF*B20 | B16 | | 2633 emit(cond | 0xE*B24 | 0xF*B20 | B16 | |
2626 dst.code()*B12 | 0xA*B8 | B4); | 2634 dst.code()*B12 | 0xA*B8 | B4); |
2627 } | 2635 } |
2628 | 2636 |
2629 | 2637 |
2630 void Assembler::vsqrt(const DwVfpRegister dst, | 2638 void Assembler::vsqrt(const DwVfpRegister dst, |
2631 const DwVfpRegister src, | 2639 const DwVfpRegister src, |
2632 const Condition cond) { | 2640 const Condition cond) { |
2633 // Instruction details available in ARM DDI 0406C.b, A8-1058. | 2641 // Instruction details available in ARM DDI 0406C.b, A8-1058. |
2634 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) | | 2642 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) | |
2635 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) | 2643 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) |
2636 ASSERT(CpuFeatures::IsEnabled(VFP2)); | 2644 ASSERT(IsEnabled(VFP2)); |
2637 int vd, d; | 2645 int vd, d; |
2638 dst.split_code(&vd, &d); | 2646 dst.split_code(&vd, &d); |
2639 int vm, m; | 2647 int vm, m; |
2640 src.split_code(&vm, &m); | 2648 src.split_code(&vm, &m); |
2641 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | | 2649 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | |
2642 m*B5 | vm); | 2650 m*B5 | vm); |
2643 } | 2651 } |
2644 | 2652 |
2645 | 2653 |
2646 // Pseudo instructions. | 2654 // Pseudo instructions. |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 | 3051 |
3044 // Since a constant pool was just emitted, move the check offset forward by | 3052 // Since a constant pool was just emitted, move the check offset forward by |
3045 // the standard interval. | 3053 // the standard interval. |
3046 next_buffer_check_ = pc_offset() + kCheckPoolInterval; | 3054 next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
3047 } | 3055 } |
3048 | 3056 |
3049 | 3057 |
3050 } } // namespace v8::internal | 3058 } } // namespace v8::internal |
3051 | 3059 |
3052 #endif // V8_TARGET_ARCH_ARM | 3060 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |