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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 |
62 // snapshot. | 62 // snapshot. |
63 static unsigned CpuFeaturesImpliedByCompiler() { | 63 static unsigned CpuFeaturesImpliedByCompiler() { |
64 unsigned answer = 0; | 64 unsigned answer = 0; |
65 #ifdef CAN_USE_ARMV7_INSTRUCTIONS | 65 #ifdef CAN_USE_ARMV7_INSTRUCTIONS |
66 answer |= 1u << ARMv7; | 66 answer |= 1u << ARMv7; |
67 #endif // CAN_USE_ARMV7_INSTRUCTIONS | 67 #endif // CAN_USE_ARMV7_INSTRUCTIONS |
68 #ifdef CAN_USE_VFP3_INSTRUCTIONS | 68 #ifdef CAN_USE_VFP3_INSTRUCTIONS |
69 answer |= 1u << VFP3 | 1u << VFP2 | 1u << ARMv7; | 69 answer |= 1u << VFP3 | 1u << ARMv7; |
70 #endif // CAN_USE_VFP3_INSTRUCTIONS | 70 #endif // CAN_USE_VFP3_INSTRUCTIONS |
71 #ifdef CAN_USE_VFP2_INSTRUCTIONS | |
72 answer |= 1u << VFP2; | |
73 #endif // CAN_USE_VFP2_INSTRUCTIONS | |
74 #ifdef CAN_USE_VFP32DREGS | 71 #ifdef CAN_USE_VFP32DREGS |
75 answer |= 1u << VFP32DREGS; | 72 answer |= 1u << VFP32DREGS; |
76 #endif // CAN_USE_VFP32DREGS | 73 #endif // CAN_USE_VFP32DREGS |
77 | 74 |
78 #ifdef __arm__ | 75 #ifdef __arm__ |
79 // If the compiler is allowed to use VFP then we can use VFP too in our code | 76 // If the compiler is allowed to use VFP then we can use VFP too in our code |
80 // generation even when generating snapshots. ARMv7 and hardware floating | 77 // generation even when generating snapshots. ARMv7 and hardware floating |
81 // point support implies VFPv3, see ARM DDI 0406B, page A1-6. | 78 // point support implies VFPv3, see ARM DDI 0406B, page A1-6. |
82 #if defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) \ | 79 #if defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) \ |
83 && !defined(__SOFTFP__) | 80 && !defined(__SOFTFP__) |
84 answer |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; | 81 answer |= 1u << VFP3 | 1u << ARMv7; |
85 #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) | 82 #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) |
86 // && !defined(__SOFTFP__) | 83 // && !defined(__SOFTFP__) |
87 #endif // _arm__ | 84 #endif // _arm__ |
88 if (answer & (1u << ARMv7)) { | 85 if (answer & (1u << ARMv7)) { |
89 answer |= 1u << UNALIGNED_ACCESSES; | 86 answer |= 1u << UNALIGNED_ACCESSES; |
90 } | 87 } |
91 | 88 |
92 return answer; | 89 return answer; |
93 } | 90 } |
94 | 91 |
95 | 92 |
96 const char* DwVfpRegister::AllocationIndexToString(int index) { | 93 const char* DwVfpRegister::AllocationIndexToString(int index) { |
97 if (CpuFeatures::IsSupported(VFP2)) { | 94 ASSERT(index >= 0 && index < NumAllocatableRegisters()); |
98 ASSERT(index >= 0 && index < NumAllocatableRegisters()); | 95 ASSERT(kScratchDoubleReg.code() - kDoubleRegZero.code() == |
99 ASSERT(kScratchDoubleReg.code() - kDoubleRegZero.code() == | 96 kNumReservedRegisters - 1); |
100 kNumReservedRegisters - 1); | 97 if (index >= kDoubleRegZero.code()) |
101 if (index >= kDoubleRegZero.code()) | 98 index += kNumReservedRegisters; |
102 index += kNumReservedRegisters; | |
103 | 99 |
104 return VFPRegisters::Name(index, true); | 100 return VFPRegisters::Name(index, true); |
105 } else { | |
106 ASSERT(index == 0); | |
107 return "sfpd0"; | |
108 } | |
109 } | 101 } |
110 | 102 |
111 | 103 |
112 void CpuFeatures::Probe() { | 104 void CpuFeatures::Probe() { |
113 uint64_t standard_features = static_cast<unsigned>( | 105 uint64_t standard_features = static_cast<unsigned>( |
114 OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler(); | 106 OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler(); |
115 ASSERT(supported_ == 0 || supported_ == standard_features); | 107 ASSERT(supported_ == 0 || supported_ == standard_features); |
116 #ifdef DEBUG | 108 #ifdef DEBUG |
117 initialized_ = true; | 109 initialized_ = true; |
118 #endif | 110 #endif |
119 | 111 |
120 // Get the features implied by the OS and the compiler settings. This is the | 112 // 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 | 113 // minimal set of features which is also alowed for generated code in the |
122 // snapshot. | 114 // snapshot. |
123 supported_ |= standard_features; | 115 supported_ |= standard_features; |
124 | 116 |
125 if (Serializer::enabled()) { | 117 if (Serializer::enabled()) { |
126 // No probing for features if we might serialize (generate snapshot). | 118 // No probing for features if we might serialize (generate snapshot). |
127 return; | 119 return; |
128 } | 120 } |
129 | 121 |
130 #ifndef __arm__ | 122 #ifndef __arm__ |
131 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is | 123 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is |
132 // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. | 124 // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. |
133 if (FLAG_enable_vfp3) { | 125 if (FLAG_enable_vfp3) { |
134 supported_ |= | 126 supported_ |= |
135 static_cast<uint64_t>(1) << VFP3 | | 127 static_cast<uint64_t>(1) << VFP3 | |
136 static_cast<uint64_t>(1) << ARMv7 | | 128 static_cast<uint64_t>(1) << ARMv7; |
137 static_cast<uint64_t>(1) << VFP2; | |
138 } | 129 } |
139 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled | 130 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled |
140 if (FLAG_enable_armv7) { | 131 if (FLAG_enable_armv7) { |
141 supported_ |= static_cast<uint64_t>(1) << ARMv7; | 132 supported_ |= static_cast<uint64_t>(1) << ARMv7; |
142 } | 133 } |
143 | 134 |
144 if (FLAG_enable_sudiv) { | 135 if (FLAG_enable_sudiv) { |
145 supported_ |= static_cast<uint64_t>(1) << SUDIV; | 136 supported_ |= static_cast<uint64_t>(1) << SUDIV; |
146 } | 137 } |
147 | 138 |
148 if (FLAG_enable_movw_movt) { | 139 if (FLAG_enable_movw_movt) { |
149 supported_ |= static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS; | 140 supported_ |= static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS; |
150 } | 141 } |
151 | 142 |
152 if (FLAG_enable_32dregs) { | 143 if (FLAG_enable_32dregs) { |
153 supported_ |= static_cast<uint64_t>(1) << VFP32DREGS; | 144 supported_ |= static_cast<uint64_t>(1) << VFP32DREGS; |
154 } | 145 } |
155 | 146 |
156 #else // __arm__ | 147 #else // __arm__ |
157 // Probe for additional features not already known to be available. | 148 // Probe for additional features not already known to be available. |
158 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { | 149 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { |
159 // This implementation also sets the VFP flags if runtime | 150 // This implementation also sets the VFP flags if runtime |
160 // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI | 151 // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI |
161 // 0406B, page A1-6. | 152 // 0406B, page A1-6. |
162 found_by_runtime_probing_only_ |= | 153 found_by_runtime_probing_only_ |= |
163 static_cast<uint64_t>(1) << VFP3 | | 154 static_cast<uint64_t>(1) << VFP3 | |
164 static_cast<uint64_t>(1) << ARMv7 | | 155 static_cast<uint64_t>(1) << ARMv7; |
165 static_cast<uint64_t>(1) << VFP2; | |
166 } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) { | |
167 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP2; | |
168 } | 156 } |
169 | 157 |
170 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { | 158 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { |
171 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << ARMv7; | 159 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << ARMv7; |
172 } | 160 } |
173 | 161 |
174 if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) { | 162 if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) { |
175 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << SUDIV; | 163 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << SUDIV; |
176 } | 164 } |
177 | 165 |
178 if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) { | 166 if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) { |
179 found_by_runtime_probing_only_ |= | 167 found_by_runtime_probing_only_ |= |
180 static_cast<uint64_t>(1) << UNALIGNED_ACCESSES; | 168 static_cast<uint64_t>(1) << UNALIGNED_ACCESSES; |
181 } | 169 } |
182 | 170 |
183 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER && | 171 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER && |
184 OS::ArmCpuHasFeature(ARMv7)) { | 172 OS::ArmCpuHasFeature(ARMv7)) { |
185 found_by_runtime_probing_only_ |= | 173 found_by_runtime_probing_only_ |= |
186 static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS; | 174 static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS; |
187 } | 175 } |
188 | 176 |
189 if (!IsSupported(VFP32DREGS) && OS::ArmCpuHasFeature(VFP32DREGS)) { | 177 if (!IsSupported(VFP32DREGS) && OS::ArmCpuHasFeature(VFP32DREGS)) { |
190 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP32DREGS; | 178 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP32DREGS; |
191 } | 179 } |
192 | 180 |
193 supported_ |= found_by_runtime_probing_only_; | 181 supported_ |= found_by_runtime_probing_only_; |
194 #endif | 182 #endif |
195 | 183 |
196 // Assert that VFP3 implies VFP2 and ARMv7. | 184 // Assert that VFP3 implies ARMv7. |
197 ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7))); | 185 ASSERT(!IsSupported(VFP3) || IsSupported(ARMv7)); |
198 } | 186 } |
199 | 187 |
200 | 188 |
201 // ----------------------------------------------------------------------------- | 189 // ----------------------------------------------------------------------------- |
202 // Implementation of RelocInfo | 190 // Implementation of RelocInfo |
203 | 191 |
204 const int RelocInfo::kApplyMask = 0; | 192 const int RelocInfo::kApplyMask = 0; |
205 | 193 |
206 | 194 |
207 bool RelocInfo::IsCodedSpecially() { | 195 bool RelocInfo::IsCodedSpecially() { |
(...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 // Support for VFP. | 1744 // Support for VFP. |
1757 | 1745 |
1758 void Assembler::vldr(const DwVfpRegister dst, | 1746 void Assembler::vldr(const DwVfpRegister dst, |
1759 const Register base, | 1747 const Register base, |
1760 int offset, | 1748 int offset, |
1761 const Condition cond) { | 1749 const Condition cond) { |
1762 // Ddst = MEM(Rbase + offset). | 1750 // Ddst = MEM(Rbase + offset). |
1763 // Instruction details available in ARM DDI 0406C.b, A8-924. | 1751 // Instruction details available in ARM DDI 0406C.b, A8-924. |
1764 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) | | 1752 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) | |
1765 // Vd(15-12) | 1011(11-8) | offset | 1753 // Vd(15-12) | 1011(11-8) | offset |
1766 ASSERT(IsEnabled(VFP2)); | |
1767 int u = 1; | 1754 int u = 1; |
1768 if (offset < 0) { | 1755 if (offset < 0) { |
1769 offset = -offset; | 1756 offset = -offset; |
1770 u = 0; | 1757 u = 0; |
1771 } | 1758 } |
1772 int vd, d; | 1759 int vd, d; |
1773 dst.split_code(&vd, &d); | 1760 dst.split_code(&vd, &d); |
1774 | 1761 |
1775 ASSERT(offset >= 0); | 1762 ASSERT(offset >= 0); |
1776 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1763 if ((offset % 4) == 0 && (offset / 4) < 256) { |
(...skipping 23 matching lines...) Expand all Loading... |
1800 | 1787 |
1801 | 1788 |
1802 void Assembler::vldr(const SwVfpRegister dst, | 1789 void Assembler::vldr(const SwVfpRegister dst, |
1803 const Register base, | 1790 const Register base, |
1804 int offset, | 1791 int offset, |
1805 const Condition cond) { | 1792 const Condition cond) { |
1806 // Sdst = MEM(Rbase + offset). | 1793 // Sdst = MEM(Rbase + offset). |
1807 // Instruction details available in ARM DDI 0406A, A8-628. | 1794 // Instruction details available in ARM DDI 0406A, A8-628. |
1808 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | | 1795 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | |
1809 // Vdst(15-12) | 1010(11-8) | offset | 1796 // Vdst(15-12) | 1010(11-8) | offset |
1810 ASSERT(IsEnabled(VFP2)); | |
1811 int u = 1; | 1797 int u = 1; |
1812 if (offset < 0) { | 1798 if (offset < 0) { |
1813 offset = -offset; | 1799 offset = -offset; |
1814 u = 0; | 1800 u = 0; |
1815 } | 1801 } |
1816 int sd, d; | 1802 int sd, d; |
1817 dst.split_code(&sd, &d); | 1803 dst.split_code(&sd, &d); |
1818 ASSERT(offset >= 0); | 1804 ASSERT(offset >= 0); |
1819 | 1805 |
1820 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1806 if ((offset % 4) == 0 && (offset / 4) < 256) { |
(...skipping 23 matching lines...) Expand all Loading... |
1844 | 1830 |
1845 | 1831 |
1846 void Assembler::vstr(const DwVfpRegister src, | 1832 void Assembler::vstr(const DwVfpRegister src, |
1847 const Register base, | 1833 const Register base, |
1848 int offset, | 1834 int offset, |
1849 const Condition cond) { | 1835 const Condition cond) { |
1850 // MEM(Rbase + offset) = Dsrc. | 1836 // MEM(Rbase + offset) = Dsrc. |
1851 // Instruction details available in ARM DDI 0406C.b, A8-1082. | 1837 // Instruction details available in ARM DDI 0406C.b, A8-1082. |
1852 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) | | 1838 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) | |
1853 // Vd(15-12) | 1011(11-8) | (offset/4) | 1839 // Vd(15-12) | 1011(11-8) | (offset/4) |
1854 ASSERT(IsEnabled(VFP2)); | |
1855 int u = 1; | 1840 int u = 1; |
1856 if (offset < 0) { | 1841 if (offset < 0) { |
1857 offset = -offset; | 1842 offset = -offset; |
1858 u = 0; | 1843 u = 0; |
1859 } | 1844 } |
1860 ASSERT(offset >= 0); | 1845 ASSERT(offset >= 0); |
1861 int vd, d; | 1846 int vd, d; |
1862 src.split_code(&vd, &d); | 1847 src.split_code(&vd, &d); |
1863 | 1848 |
1864 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1849 if ((offset % 4) == 0 && (offset / 4) < 256) { |
(...skipping 23 matching lines...) Expand all Loading... |
1888 | 1873 |
1889 | 1874 |
1890 void Assembler::vstr(const SwVfpRegister src, | 1875 void Assembler::vstr(const SwVfpRegister src, |
1891 const Register base, | 1876 const Register base, |
1892 int offset, | 1877 int offset, |
1893 const Condition cond) { | 1878 const Condition cond) { |
1894 // MEM(Rbase + offset) = SSrc. | 1879 // MEM(Rbase + offset) = SSrc. |
1895 // Instruction details available in ARM DDI 0406A, A8-786. | 1880 // Instruction details available in ARM DDI 0406A, A8-786. |
1896 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | | 1881 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | |
1897 // Vdst(15-12) | 1010(11-8) | (offset/4) | 1882 // Vdst(15-12) | 1010(11-8) | (offset/4) |
1898 ASSERT(IsEnabled(VFP2)); | |
1899 int u = 1; | 1883 int u = 1; |
1900 if (offset < 0) { | 1884 if (offset < 0) { |
1901 offset = -offset; | 1885 offset = -offset; |
1902 u = 0; | 1886 u = 0; |
1903 } | 1887 } |
1904 int sd, d; | 1888 int sd, d; |
1905 src.split_code(&sd, &d); | 1889 src.split_code(&sd, &d); |
1906 ASSERT(offset >= 0); | 1890 ASSERT(offset >= 0); |
1907 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1891 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1908 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | | 1892 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | |
(...skipping 22 matching lines...) Expand all Loading... |
1931 | 1915 |
1932 | 1916 |
1933 void Assembler::vldm(BlockAddrMode am, | 1917 void Assembler::vldm(BlockAddrMode am, |
1934 Register base, | 1918 Register base, |
1935 DwVfpRegister first, | 1919 DwVfpRegister first, |
1936 DwVfpRegister last, | 1920 DwVfpRegister last, |
1937 Condition cond) { | 1921 Condition cond) { |
1938 // Instruction details available in ARM DDI 0406C.b, A8-922. | 1922 // Instruction details available in ARM DDI 0406C.b, A8-922. |
1939 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 1923 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
1940 // first(15-12) | 1011(11-8) | (count * 2) | 1924 // first(15-12) | 1011(11-8) | (count * 2) |
1941 ASSERT(IsEnabled(VFP2)); | |
1942 ASSERT_LE(first.code(), last.code()); | 1925 ASSERT_LE(first.code(), last.code()); |
1943 ASSERT(am == ia || am == ia_w || am == db_w); | 1926 ASSERT(am == ia || am == ia_w || am == db_w); |
1944 ASSERT(!base.is(pc)); | 1927 ASSERT(!base.is(pc)); |
1945 | 1928 |
1946 int sd, d; | 1929 int sd, d; |
1947 first.split_code(&sd, &d); | 1930 first.split_code(&sd, &d); |
1948 int count = last.code() - first.code() + 1; | 1931 int count = last.code() - first.code() + 1; |
1949 ASSERT(count <= 16); | 1932 ASSERT(count <= 16); |
1950 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 1933 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
1951 0xB*B8 | count*2); | 1934 0xB*B8 | count*2); |
1952 } | 1935 } |
1953 | 1936 |
1954 | 1937 |
1955 void Assembler::vstm(BlockAddrMode am, | 1938 void Assembler::vstm(BlockAddrMode am, |
1956 Register base, | 1939 Register base, |
1957 DwVfpRegister first, | 1940 DwVfpRegister first, |
1958 DwVfpRegister last, | 1941 DwVfpRegister last, |
1959 Condition cond) { | 1942 Condition cond) { |
1960 // Instruction details available in ARM DDI 0406C.b, A8-1080. | 1943 // Instruction details available in ARM DDI 0406C.b, A8-1080. |
1961 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 1944 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
1962 // first(15-12) | 1011(11-8) | (count * 2) | 1945 // first(15-12) | 1011(11-8) | (count * 2) |
1963 ASSERT(IsEnabled(VFP2)); | |
1964 ASSERT_LE(first.code(), last.code()); | 1946 ASSERT_LE(first.code(), last.code()); |
1965 ASSERT(am == ia || am == ia_w || am == db_w); | 1947 ASSERT(am == ia || am == ia_w || am == db_w); |
1966 ASSERT(!base.is(pc)); | 1948 ASSERT(!base.is(pc)); |
1967 | 1949 |
1968 int sd, d; | 1950 int sd, d; |
1969 first.split_code(&sd, &d); | 1951 first.split_code(&sd, &d); |
1970 int count = last.code() - first.code() + 1; | 1952 int count = last.code() - first.code() + 1; |
1971 ASSERT(count <= 16); | 1953 ASSERT(count <= 16); |
1972 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 1954 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
1973 0xB*B8 | count*2); | 1955 0xB*B8 | count*2); |
1974 } | 1956 } |
1975 | 1957 |
1976 void Assembler::vldm(BlockAddrMode am, | 1958 void Assembler::vldm(BlockAddrMode am, |
1977 Register base, | 1959 Register base, |
1978 SwVfpRegister first, | 1960 SwVfpRegister first, |
1979 SwVfpRegister last, | 1961 SwVfpRegister last, |
1980 Condition cond) { | 1962 Condition cond) { |
1981 // Instruction details available in ARM DDI 0406A, A8-626. | 1963 // Instruction details available in ARM DDI 0406A, A8-626. |
1982 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 1964 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
1983 // first(15-12) | 1010(11-8) | (count/2) | 1965 // first(15-12) | 1010(11-8) | (count/2) |
1984 ASSERT(IsEnabled(VFP2)); | |
1985 ASSERT_LE(first.code(), last.code()); | 1966 ASSERT_LE(first.code(), last.code()); |
1986 ASSERT(am == ia || am == ia_w || am == db_w); | 1967 ASSERT(am == ia || am == ia_w || am == db_w); |
1987 ASSERT(!base.is(pc)); | 1968 ASSERT(!base.is(pc)); |
1988 | 1969 |
1989 int sd, d; | 1970 int sd, d; |
1990 first.split_code(&sd, &d); | 1971 first.split_code(&sd, &d); |
1991 int count = last.code() - first.code() + 1; | 1972 int count = last.code() - first.code() + 1; |
1992 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 1973 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
1993 0xA*B8 | count); | 1974 0xA*B8 | count); |
1994 } | 1975 } |
1995 | 1976 |
1996 | 1977 |
1997 void Assembler::vstm(BlockAddrMode am, | 1978 void Assembler::vstm(BlockAddrMode am, |
1998 Register base, | 1979 Register base, |
1999 SwVfpRegister first, | 1980 SwVfpRegister first, |
2000 SwVfpRegister last, | 1981 SwVfpRegister last, |
2001 Condition cond) { | 1982 Condition cond) { |
2002 // Instruction details available in ARM DDI 0406A, A8-784. | 1983 // Instruction details available in ARM DDI 0406A, A8-784. |
2003 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 1984 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
2004 // first(15-12) | 1011(11-8) | (count/2) | 1985 // first(15-12) | 1011(11-8) | (count/2) |
2005 ASSERT(IsEnabled(VFP2)); | |
2006 ASSERT_LE(first.code(), last.code()); | 1986 ASSERT_LE(first.code(), last.code()); |
2007 ASSERT(am == ia || am == ia_w || am == db_w); | 1987 ASSERT(am == ia || am == ia_w || am == db_w); |
2008 ASSERT(!base.is(pc)); | 1988 ASSERT(!base.is(pc)); |
2009 | 1989 |
2010 int sd, d; | 1990 int sd, d; |
2011 first.split_code(&sd, &d); | 1991 first.split_code(&sd, &d); |
2012 int count = last.code() - first.code() + 1; | 1992 int count = last.code() - first.code() + 1; |
2013 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 1993 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
2014 0xA*B8 | count); | 1994 0xA*B8 | count); |
2015 } | 1995 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 *encoding |= (hi >> 4) & 0x70000; // Low three bits of the high nybble. | 2049 *encoding |= (hi >> 4) & 0x70000; // Low three bits of the high nybble. |
2070 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. | 2050 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. |
2071 | 2051 |
2072 return true; | 2052 return true; |
2073 } | 2053 } |
2074 | 2054 |
2075 | 2055 |
2076 void Assembler::vmov(const DwVfpRegister dst, | 2056 void Assembler::vmov(const DwVfpRegister dst, |
2077 double imm, | 2057 double imm, |
2078 const Register scratch) { | 2058 const Register scratch) { |
2079 ASSERT(IsEnabled(VFP2)); | |
2080 | |
2081 uint32_t enc; | 2059 uint32_t enc; |
2082 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { | 2060 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { |
2083 // The double can be encoded in the instruction. | 2061 // The double can be encoded in the instruction. |
2084 // | 2062 // |
2085 // Dd = immediate | 2063 // Dd = immediate |
2086 // Instruction details available in ARM DDI 0406C.b, A8-936. | 2064 // Instruction details available in ARM DDI 0406C.b, A8-936. |
2087 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | | 2065 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
2088 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) | 2066 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) |
2089 int vd, d; | 2067 int vd, d; |
2090 dst.split_code(&vd, &d); | 2068 dst.split_code(&vd, &d); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2141 } | 2119 } |
2142 } | 2120 } |
2143 } | 2121 } |
2144 | 2122 |
2145 | 2123 |
2146 void Assembler::vmov(const SwVfpRegister dst, | 2124 void Assembler::vmov(const SwVfpRegister dst, |
2147 const SwVfpRegister src, | 2125 const SwVfpRegister src, |
2148 const Condition cond) { | 2126 const Condition cond) { |
2149 // Sd = Sm | 2127 // Sd = Sm |
2150 // Instruction details available in ARM DDI 0406B, A8-642. | 2128 // Instruction details available in ARM DDI 0406B, A8-642. |
2151 ASSERT(IsEnabled(VFP2)); | |
2152 int sd, d, sm, m; | 2129 int sd, d, sm, m; |
2153 dst.split_code(&sd, &d); | 2130 dst.split_code(&sd, &d); |
2154 src.split_code(&sm, &m); | 2131 src.split_code(&sm, &m); |
2155 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); | 2132 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); |
2156 } | 2133 } |
2157 | 2134 |
2158 | 2135 |
2159 void Assembler::vmov(const DwVfpRegister dst, | 2136 void Assembler::vmov(const DwVfpRegister dst, |
2160 const DwVfpRegister src, | 2137 const DwVfpRegister src, |
2161 const Condition cond) { | 2138 const Condition cond) { |
2162 // Dd = Dm | 2139 // Dd = Dm |
2163 // Instruction details available in ARM DDI 0406C.b, A8-938. | 2140 // Instruction details available in ARM DDI 0406C.b, A8-938. |
2164 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | | 2141 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
2165 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2142 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2166 ASSERT(IsEnabled(VFP2)); | |
2167 int vd, d; | 2143 int vd, d; |
2168 dst.split_code(&vd, &d); | 2144 dst.split_code(&vd, &d); |
2169 int vm, m; | 2145 int vm, m; |
2170 src.split_code(&vm, &m); | 2146 src.split_code(&vm, &m); |
2171 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 | | 2147 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 | |
2172 vm); | 2148 vm); |
2173 } | 2149 } |
2174 | 2150 |
2175 | 2151 |
2176 void Assembler::vmov(const DwVfpRegister dst, | 2152 void Assembler::vmov(const DwVfpRegister dst, |
2177 const VmovIndex index, | 2153 const VmovIndex index, |
2178 const Register src, | 2154 const Register src, |
2179 const Condition cond) { | 2155 const Condition cond) { |
2180 // Dd[index] = Rt | 2156 // Dd[index] = Rt |
2181 // Instruction details available in ARM DDI 0406C.b, A8-940. | 2157 // Instruction details available in ARM DDI 0406C.b, A8-940. |
2182 // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) | | 2158 // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) | |
2183 // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0) | 2159 // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0) |
2184 ASSERT(IsEnabled(VFP2)); | |
2185 ASSERT(index.index == 0 || index.index == 1); | 2160 ASSERT(index.index == 0 || index.index == 1); |
2186 int vd, d; | 2161 int vd, d; |
2187 dst.split_code(&vd, &d); | 2162 dst.split_code(&vd, &d); |
2188 emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 | | 2163 emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 | |
2189 d*B7 | B4); | 2164 d*B7 | B4); |
2190 } | 2165 } |
2191 | 2166 |
2192 | 2167 |
2193 void Assembler::vmov(const DwVfpRegister dst, | 2168 void Assembler::vmov(const DwVfpRegister dst, |
2194 const Register src1, | 2169 const Register src1, |
2195 const Register src2, | 2170 const Register src2, |
2196 const Condition cond) { | 2171 const Condition cond) { |
2197 // Dm = <Rt,Rt2>. | 2172 // Dm = <Rt,Rt2>. |
2198 // Instruction details available in ARM DDI 0406C.b, A8-948. | 2173 // Instruction details available in ARM DDI 0406C.b, A8-948. |
2199 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | | 2174 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | |
2200 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2175 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
2201 ASSERT(IsEnabled(VFP2)); | |
2202 ASSERT(!src1.is(pc) && !src2.is(pc)); | 2176 ASSERT(!src1.is(pc) && !src2.is(pc)); |
2203 int vm, m; | 2177 int vm, m; |
2204 dst.split_code(&vm, &m); | 2178 dst.split_code(&vm, &m); |
2205 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | | 2179 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
2206 src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); | 2180 src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
2207 } | 2181 } |
2208 | 2182 |
2209 | 2183 |
2210 void Assembler::vmov(const Register dst1, | 2184 void Assembler::vmov(const Register dst1, |
2211 const Register dst2, | 2185 const Register dst2, |
2212 const DwVfpRegister src, | 2186 const DwVfpRegister src, |
2213 const Condition cond) { | 2187 const Condition cond) { |
2214 // <Rt,Rt2> = Dm. | 2188 // <Rt,Rt2> = Dm. |
2215 // Instruction details available in ARM DDI 0406C.b, A8-948. | 2189 // Instruction details available in ARM DDI 0406C.b, A8-948. |
2216 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | | 2190 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | |
2217 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2191 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
2218 ASSERT(IsEnabled(VFP2)); | |
2219 ASSERT(!dst1.is(pc) && !dst2.is(pc)); | 2192 ASSERT(!dst1.is(pc) && !dst2.is(pc)); |
2220 int vm, m; | 2193 int vm, m; |
2221 src.split_code(&vm, &m); | 2194 src.split_code(&vm, &m); |
2222 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | | 2195 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
2223 dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); | 2196 dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
2224 } | 2197 } |
2225 | 2198 |
2226 | 2199 |
2227 void Assembler::vmov(const SwVfpRegister dst, | 2200 void Assembler::vmov(const SwVfpRegister dst, |
2228 const Register src, | 2201 const Register src, |
2229 const Condition cond) { | 2202 const Condition cond) { |
2230 // Sn = Rt. | 2203 // Sn = Rt. |
2231 // Instruction details available in ARM DDI 0406A, A8-642. | 2204 // Instruction details available in ARM DDI 0406A, A8-642. |
2232 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | | 2205 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | |
2233 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2206 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2234 ASSERT(IsEnabled(VFP2)); | |
2235 ASSERT(!src.is(pc)); | 2207 ASSERT(!src.is(pc)); |
2236 int sn, n; | 2208 int sn, n; |
2237 dst.split_code(&sn, &n); | 2209 dst.split_code(&sn, &n); |
2238 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); | 2210 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); |
2239 } | 2211 } |
2240 | 2212 |
2241 | 2213 |
2242 void Assembler::vmov(const Register dst, | 2214 void Assembler::vmov(const Register dst, |
2243 const SwVfpRegister src, | 2215 const SwVfpRegister src, |
2244 const Condition cond) { | 2216 const Condition cond) { |
2245 // Rt = Sn. | 2217 // Rt = Sn. |
2246 // Instruction details available in ARM DDI 0406A, A8-642. | 2218 // Instruction details available in ARM DDI 0406A, A8-642. |
2247 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | | 2219 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | |
2248 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2220 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2249 ASSERT(IsEnabled(VFP2)); | |
2250 ASSERT(!dst.is(pc)); | 2221 ASSERT(!dst.is(pc)); |
2251 int sn, n; | 2222 int sn, n; |
2252 src.split_code(&sn, &n); | 2223 src.split_code(&sn, &n); |
2253 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); | 2224 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); |
2254 } | 2225 } |
2255 | 2226 |
2256 | 2227 |
2257 // Type of data to read from or write to VFP register. | 2228 // Type of data to read from or write to VFP register. |
2258 // Used as specifier in generic vcvt instruction. | 2229 // Used as specifier in generic vcvt instruction. |
2259 enum VFPType { S32, U32, F32, F64 }; | 2230 enum VFPType { S32, U32, F32, F64 }; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2364 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | | 2335 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | |
2365 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); | 2336 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); |
2366 } | 2337 } |
2367 } | 2338 } |
2368 | 2339 |
2369 | 2340 |
2370 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, | 2341 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, |
2371 const SwVfpRegister src, | 2342 const SwVfpRegister src, |
2372 VFPConversionMode mode, | 2343 VFPConversionMode mode, |
2373 const Condition cond) { | 2344 const Condition cond) { |
2374 ASSERT(IsEnabled(VFP2)); | |
2375 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); | 2345 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); |
2376 } | 2346 } |
2377 | 2347 |
2378 | 2348 |
2379 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, | 2349 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, |
2380 const SwVfpRegister src, | 2350 const SwVfpRegister src, |
2381 VFPConversionMode mode, | 2351 VFPConversionMode mode, |
2382 const Condition cond) { | 2352 const Condition cond) { |
2383 ASSERT(IsEnabled(VFP2)); | |
2384 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); | 2353 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); |
2385 } | 2354 } |
2386 | 2355 |
2387 | 2356 |
2388 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, | 2357 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, |
2389 const SwVfpRegister src, | 2358 const SwVfpRegister src, |
2390 VFPConversionMode mode, | 2359 VFPConversionMode mode, |
2391 const Condition cond) { | 2360 const Condition cond) { |
2392 ASSERT(IsEnabled(VFP2)); | |
2393 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); | 2361 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); |
2394 } | 2362 } |
2395 | 2363 |
2396 | 2364 |
2397 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, | 2365 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, |
2398 const DwVfpRegister src, | 2366 const DwVfpRegister src, |
2399 VFPConversionMode mode, | 2367 VFPConversionMode mode, |
2400 const Condition cond) { | 2368 const Condition cond) { |
2401 ASSERT(IsEnabled(VFP2)); | |
2402 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); | 2369 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); |
2403 } | 2370 } |
2404 | 2371 |
2405 | 2372 |
2406 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, | 2373 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, |
2407 const DwVfpRegister src, | 2374 const DwVfpRegister src, |
2408 VFPConversionMode mode, | 2375 VFPConversionMode mode, |
2409 const Condition cond) { | 2376 const Condition cond) { |
2410 ASSERT(IsEnabled(VFP2)); | |
2411 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); | 2377 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); |
2412 } | 2378 } |
2413 | 2379 |
2414 | 2380 |
2415 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, | 2381 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, |
2416 const SwVfpRegister src, | 2382 const SwVfpRegister src, |
2417 VFPConversionMode mode, | 2383 VFPConversionMode mode, |
2418 const Condition cond) { | 2384 const Condition cond) { |
2419 ASSERT(IsEnabled(VFP2)); | |
2420 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); | 2385 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); |
2421 } | 2386 } |
2422 | 2387 |
2423 | 2388 |
2424 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, | 2389 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, |
2425 const DwVfpRegister src, | 2390 const DwVfpRegister src, |
2426 VFPConversionMode mode, | 2391 VFPConversionMode mode, |
2427 const Condition cond) { | 2392 const Condition cond) { |
2428 ASSERT(IsEnabled(VFP2)); | |
2429 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); | 2393 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); |
2430 } | 2394 } |
2431 | 2395 |
2432 | 2396 |
2433 void Assembler::vneg(const DwVfpRegister dst, | 2397 void Assembler::vneg(const DwVfpRegister dst, |
2434 const DwVfpRegister src, | 2398 const DwVfpRegister src, |
2435 const Condition cond) { | 2399 const Condition cond) { |
2436 // Instruction details available in ARM DDI 0406C.b, A8-968. | 2400 // Instruction details available in ARM DDI 0406C.b, A8-968. |
2437 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | | 2401 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | |
2438 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2402 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2439 ASSERT(IsEnabled(VFP2)); | |
2440 int vd, d; | 2403 int vd, d; |
2441 dst.split_code(&vd, &d); | 2404 dst.split_code(&vd, &d); |
2442 int vm, m; | 2405 int vm, m; |
2443 src.split_code(&vm, &m); | 2406 src.split_code(&vm, &m); |
2444 | 2407 |
2445 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 | | 2408 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
2446 m*B5 | vm); | 2409 m*B5 | vm); |
2447 } | 2410 } |
2448 | 2411 |
2449 | 2412 |
2450 void Assembler::vabs(const DwVfpRegister dst, | 2413 void Assembler::vabs(const DwVfpRegister dst, |
2451 const DwVfpRegister src, | 2414 const DwVfpRegister src, |
2452 const Condition cond) { | 2415 const Condition cond) { |
2453 // Instruction details available in ARM DDI 0406C.b, A8-524. | 2416 // Instruction details available in ARM DDI 0406C.b, A8-524. |
2454 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | | 2417 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
2455 // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2418 // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2456 ASSERT(IsEnabled(VFP2)); | |
2457 int vd, d; | 2419 int vd, d; |
2458 dst.split_code(&vd, &d); | 2420 dst.split_code(&vd, &d); |
2459 int vm, m; | 2421 int vm, m; |
2460 src.split_code(&vm, &m); | 2422 src.split_code(&vm, &m); |
2461 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 | | 2423 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 | |
2462 m*B5 | vm); | 2424 m*B5 | vm); |
2463 } | 2425 } |
2464 | 2426 |
2465 | 2427 |
2466 void Assembler::vadd(const DwVfpRegister dst, | 2428 void Assembler::vadd(const DwVfpRegister dst, |
2467 const DwVfpRegister src1, | 2429 const DwVfpRegister src1, |
2468 const DwVfpRegister src2, | 2430 const DwVfpRegister src2, |
2469 const Condition cond) { | 2431 const Condition cond) { |
2470 // Dd = vadd(Dn, Dm) double precision floating point addition. | 2432 // Dd = vadd(Dn, Dm) double precision floating point addition. |
2471 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2433 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2472 // Instruction details available in ARM DDI 0406C.b, A8-830. | 2434 // Instruction details available in ARM DDI 0406C.b, A8-830. |
2473 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | | 2435 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
2474 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 2436 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
2475 ASSERT(IsEnabled(VFP2)); | |
2476 int vd, d; | 2437 int vd, d; |
2477 dst.split_code(&vd, &d); | 2438 dst.split_code(&vd, &d); |
2478 int vn, n; | 2439 int vn, n; |
2479 src1.split_code(&vn, &n); | 2440 src1.split_code(&vn, &n); |
2480 int vm, m; | 2441 int vm, m; |
2481 src2.split_code(&vm, &m); | 2442 src2.split_code(&vm, &m); |
2482 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 2443 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
2483 n*B7 | m*B5 | vm); | 2444 n*B7 | m*B5 | vm); |
2484 } | 2445 } |
2485 | 2446 |
2486 | 2447 |
2487 void Assembler::vsub(const DwVfpRegister dst, | 2448 void Assembler::vsub(const DwVfpRegister dst, |
2488 const DwVfpRegister src1, | 2449 const DwVfpRegister src1, |
2489 const DwVfpRegister src2, | 2450 const DwVfpRegister src2, |
2490 const Condition cond) { | 2451 const Condition cond) { |
2491 // Dd = vsub(Dn, Dm) double precision floating point subtraction. | 2452 // Dd = vsub(Dn, Dm) double precision floating point subtraction. |
2492 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2453 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2493 // Instruction details available in ARM DDI 0406C.b, A8-1086. | 2454 // Instruction details available in ARM DDI 0406C.b, A8-1086. |
2494 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | | 2455 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
2495 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2456 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2496 ASSERT(IsEnabled(VFP2)); | |
2497 int vd, d; | 2457 int vd, d; |
2498 dst.split_code(&vd, &d); | 2458 dst.split_code(&vd, &d); |
2499 int vn, n; | 2459 int vn, n; |
2500 src1.split_code(&vn, &n); | 2460 src1.split_code(&vn, &n); |
2501 int vm, m; | 2461 int vm, m; |
2502 src2.split_code(&vm, &m); | 2462 src2.split_code(&vm, &m); |
2503 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 2463 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
2504 n*B7 | B6 | m*B5 | vm); | 2464 n*B7 | B6 | m*B5 | vm); |
2505 } | 2465 } |
2506 | 2466 |
2507 | 2467 |
2508 void Assembler::vmul(const DwVfpRegister dst, | 2468 void Assembler::vmul(const DwVfpRegister dst, |
2509 const DwVfpRegister src1, | 2469 const DwVfpRegister src1, |
2510 const DwVfpRegister src2, | 2470 const DwVfpRegister src2, |
2511 const Condition cond) { | 2471 const Condition cond) { |
2512 // Dd = vmul(Dn, Dm) double precision floating point multiplication. | 2472 // Dd = vmul(Dn, Dm) double precision floating point multiplication. |
2513 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2473 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2514 // Instruction details available in ARM DDI 0406C.b, A8-960. | 2474 // Instruction details available in ARM DDI 0406C.b, A8-960. |
2515 // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) | | 2475 // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) | |
2516 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 2476 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
2517 ASSERT(IsEnabled(VFP2)); | |
2518 int vd, d; | 2477 int vd, d; |
2519 dst.split_code(&vd, &d); | 2478 dst.split_code(&vd, &d); |
2520 int vn, n; | 2479 int vn, n; |
2521 src1.split_code(&vn, &n); | 2480 src1.split_code(&vn, &n); |
2522 int vm, m; | 2481 int vm, m; |
2523 src2.split_code(&vm, &m); | 2482 src2.split_code(&vm, &m); |
2524 emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 2483 emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
2525 n*B7 | m*B5 | vm); | 2484 n*B7 | m*B5 | vm); |
2526 } | 2485 } |
2527 | 2486 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2564 | 2523 |
2565 void Assembler::vdiv(const DwVfpRegister dst, | 2524 void Assembler::vdiv(const DwVfpRegister dst, |
2566 const DwVfpRegister src1, | 2525 const DwVfpRegister src1, |
2567 const DwVfpRegister src2, | 2526 const DwVfpRegister src2, |
2568 const Condition cond) { | 2527 const Condition cond) { |
2569 // Dd = vdiv(Dn, Dm) double precision floating point division. | 2528 // Dd = vdiv(Dn, Dm) double precision floating point division. |
2570 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2529 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2571 // Instruction details available in ARM DDI 0406C.b, A8-882. | 2530 // Instruction details available in ARM DDI 0406C.b, A8-882. |
2572 // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) | | 2531 // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) | |
2573 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 2532 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
2574 ASSERT(IsEnabled(VFP2)); | |
2575 int vd, d; | 2533 int vd, d; |
2576 dst.split_code(&vd, &d); | 2534 dst.split_code(&vd, &d); |
2577 int vn, n; | 2535 int vn, n; |
2578 src1.split_code(&vn, &n); | 2536 src1.split_code(&vn, &n); |
2579 int vm, m; | 2537 int vm, m; |
2580 src2.split_code(&vm, &m); | 2538 src2.split_code(&vm, &m); |
2581 emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | | 2539 emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | |
2582 vm); | 2540 vm); |
2583 } | 2541 } |
2584 | 2542 |
2585 | 2543 |
2586 void Assembler::vcmp(const DwVfpRegister src1, | 2544 void Assembler::vcmp(const DwVfpRegister src1, |
2587 const DwVfpRegister src2, | 2545 const DwVfpRegister src2, |
2588 const Condition cond) { | 2546 const Condition cond) { |
2589 // vcmp(Dd, Dm) double precision floating point comparison. | 2547 // vcmp(Dd, Dm) double precision floating point comparison. |
2590 // Instruction details available in ARM DDI 0406C.b, A8-864. | 2548 // Instruction details available in ARM DDI 0406C.b, A8-864. |
2591 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) | | 2549 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) | |
2592 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2550 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
2593 ASSERT(IsEnabled(VFP2)); | |
2594 int vd, d; | 2551 int vd, d; |
2595 src1.split_code(&vd, &d); | 2552 src1.split_code(&vd, &d); |
2596 int vm, m; | 2553 int vm, m; |
2597 src2.split_code(&vm, &m); | 2554 src2.split_code(&vm, &m); |
2598 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 | | 2555 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
2599 m*B5 | vm); | 2556 m*B5 | vm); |
2600 } | 2557 } |
2601 | 2558 |
2602 | 2559 |
2603 void Assembler::vcmp(const DwVfpRegister src1, | 2560 void Assembler::vcmp(const DwVfpRegister src1, |
2604 const double src2, | 2561 const double src2, |
2605 const Condition cond) { | 2562 const Condition cond) { |
2606 // vcmp(Dd, #0.0) double precision floating point comparison. | 2563 // vcmp(Dd, #0.0) double precision floating point comparison. |
2607 // Instruction details available in ARM DDI 0406C.b, A8-864. | 2564 // Instruction details available in ARM DDI 0406C.b, A8-864. |
2608 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | | 2565 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | |
2609 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) | 2566 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) |
2610 ASSERT(IsEnabled(VFP2)); | |
2611 ASSERT(src2 == 0.0); | 2567 ASSERT(src2 == 0.0); |
2612 int vd, d; | 2568 int vd, d; |
2613 src1.split_code(&vd, &d); | 2569 src1.split_code(&vd, &d); |
2614 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6); | 2570 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6); |
2615 } | 2571 } |
2616 | 2572 |
2617 | 2573 |
2618 void Assembler::vmsr(Register dst, Condition cond) { | 2574 void Assembler::vmsr(Register dst, Condition cond) { |
2619 // Instruction details available in ARM DDI 0406A, A8-652. | 2575 // Instruction details available in ARM DDI 0406A, A8-652. |
2620 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | | 2576 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | |
2621 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 2577 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
2622 ASSERT(IsEnabled(VFP2)); | |
2623 emit(cond | 0xE*B24 | 0xE*B20 | B16 | | 2578 emit(cond | 0xE*B24 | 0xE*B20 | B16 | |
2624 dst.code()*B12 | 0xA*B8 | B4); | 2579 dst.code()*B12 | 0xA*B8 | B4); |
2625 } | 2580 } |
2626 | 2581 |
2627 | 2582 |
2628 void Assembler::vmrs(Register dst, Condition cond) { | 2583 void Assembler::vmrs(Register dst, Condition cond) { |
2629 // Instruction details available in ARM DDI 0406A, A8-652. | 2584 // Instruction details available in ARM DDI 0406A, A8-652. |
2630 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | | 2585 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | |
2631 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 2586 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
2632 ASSERT(IsEnabled(VFP2)); | |
2633 emit(cond | 0xE*B24 | 0xF*B20 | B16 | | 2587 emit(cond | 0xE*B24 | 0xF*B20 | B16 | |
2634 dst.code()*B12 | 0xA*B8 | B4); | 2588 dst.code()*B12 | 0xA*B8 | B4); |
2635 } | 2589 } |
2636 | 2590 |
2637 | 2591 |
2638 void Assembler::vsqrt(const DwVfpRegister dst, | 2592 void Assembler::vsqrt(const DwVfpRegister dst, |
2639 const DwVfpRegister src, | 2593 const DwVfpRegister src, |
2640 const Condition cond) { | 2594 const Condition cond) { |
2641 // Instruction details available in ARM DDI 0406C.b, A8-1058. | 2595 // Instruction details available in ARM DDI 0406C.b, A8-1058. |
2642 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) | | 2596 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) | |
2643 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) | 2597 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) |
2644 ASSERT(IsEnabled(VFP2)); | |
2645 int vd, d; | 2598 int vd, d; |
2646 dst.split_code(&vd, &d); | 2599 dst.split_code(&vd, &d); |
2647 int vm, m; | 2600 int vm, m; |
2648 src.split_code(&vm, &m); | 2601 src.split_code(&vm, &m); |
2649 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | | 2602 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | |
2650 m*B5 | vm); | 2603 m*B5 | vm); |
2651 } | 2604 } |
2652 | 2605 |
2653 | 2606 |
2654 // Pseudo instructions. | 2607 // Pseudo instructions. |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3051 | 3004 |
3052 // Since a constant pool was just emitted, move the check offset forward by | 3005 // Since a constant pool was just emitted, move the check offset forward by |
3053 // the standard interval. | 3006 // the standard interval. |
3054 next_buffer_check_ = pc_offset() + kCheckPoolInterval; | 3007 next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
3055 } | 3008 } |
3056 | 3009 |
3057 | 3010 |
3058 } } // namespace v8::internal | 3011 } } // namespace v8::internal |
3059 | 3012 |
3060 #endif // V8_TARGET_ARCH_ARM | 3013 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |