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

Side by Side Diff: src/arm/assembler-arm.cc

Issue 11428137: ARM: Make use of d16-d31 when available. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use an ExternalReference to check CpuFeatures in generated code Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_ = 0;
52 52
53 53
54 ExternalReference ExternalReference::cpu_features() {
55 ASSERT(CpuFeatures::initialized_);
56 return ExternalReference(&CpuFeatures::supported_);
57 }
58
54 // 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
55 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS 60 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS
56 // 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
57 // snapshot. 62 // snapshot.
58 static unsigned CpuFeaturesImpliedByCompiler() { 63 static unsigned CpuFeaturesImpliedByCompiler() {
59 unsigned answer = 0; 64 unsigned answer = 0;
60 #ifdef CAN_USE_ARMV7_INSTRUCTIONS 65 #ifdef CAN_USE_ARMV7_INSTRUCTIONS
61 answer |= 1u << ARMv7; 66 answer |= 1u << ARMv7;
62 #endif // CAN_USE_ARMV7_INSTRUCTIONS 67 #endif // CAN_USE_ARMV7_INSTRUCTIONS
63 #ifdef CAN_USE_VFP3_INSTRUCTIONS 68 #ifdef CAN_USE_VFP3_INSTRUCTIONS
64 answer |= 1u << VFP3 | 1u << VFP2 | 1u << ARMv7; 69 answer |= 1u << VFP3 | 1u << VFP2 | 1u << ARMv7;
65 #endif // CAN_USE_VFP3_INSTRUCTIONS 70 #endif // CAN_USE_VFP3_INSTRUCTIONS
66 #ifdef CAN_USE_VFP2_INSTRUCTIONS 71 #ifdef CAN_USE_VFP2_INSTRUCTIONS
67 answer |= 1u << VFP2; 72 answer |= 1u << VFP2;
68 #endif // CAN_USE_VFP2_INSTRUCTIONS 73 #endif // CAN_USE_VFP2_INSTRUCTIONS
74 #ifdef CAN_USE_VFP32DREGS
75 answer |= 1u << VFP32DREGS;
76 #endif // CAN_USE_VFP32DREGS
69 77
70 #ifdef __arm__ 78 #ifdef __arm__
71 // If the compiler is allowed to use VFP then we can use VFP too in our code 79 // If the compiler is allowed to use VFP then we can use VFP too in our code
72 // generation even when generating snapshots. ARMv7 and hardware floating 80 // generation even when generating snapshots. ARMv7 and hardware floating
73 // point support implies VFPv3, see ARM DDI 0406B, page A1-6. 81 // point support implies VFPv3, see ARM DDI 0406B, page A1-6.
74 #if defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) \ 82 #if defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) \
75 && !defined(__SOFTFP__) 83 && !defined(__SOFTFP__)
76 answer |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; 84 answer |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2;
77 #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) 85 #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__)
78 // && !defined(__SOFTFP__) 86 // && !defined(__SOFTFP__)
79 #endif // _arm__ 87 #endif // _arm__
80 if (answer & (1u << ARMv7)) { 88 if (answer & (1u << ARMv7)) {
81 answer |= 1u << UNALIGNED_ACCESSES; 89 answer |= 1u << UNALIGNED_ACCESSES;
82 } 90 }
83 91
84 return answer; 92 return answer;
85 } 93 }
86 94
87 95
88 const char* DwVfpRegister::AllocationIndexToString(int index) { 96 const char* DwVfpRegister::AllocationIndexToString(int index) {
89 if (CpuFeatures::IsSupported(VFP2)) { 97 if (CpuFeatures::IsSupported(VFP2)) {
90 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 98 ASSERT(index >= 0 && index < NumAllocatableRegisters());
99 ASSERT(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
100 kNumReservedRegisters - 1);
101 if (index >= kDoubleRegZero.code())
102 index += kNumReservedRegisters;
103
104 // TODO(hans): Maybe this could just use VFPRegisters::Name()?
91 const char* const names[] = { 105 const char* const names[] = {
92 "d0", 106 "d0",
93 "d1", 107 "d1",
94 "d2", 108 "d2",
95 "d3", 109 "d3",
96 "d4", 110 "d4",
97 "d5", 111 "d5",
98 "d6", 112 "d6",
99 "d7", 113 "d7",
100 "d8", 114 "d8",
101 "d9", 115 "d9",
102 "d10", 116 "d10",
103 "d11", 117 "d11",
104 "d12", 118 "d12",
105 "d13" 119 "d13"
120 "d14",
121 "d15",
122 "d16",
123 "d17",
124 "d18",
125 "d19",
126 "d20",
127 "d21",
128 "d22",
129 "d23",
130 "d24",
131 "d25",
132 "d26",
133 "d27",
134 "d28",
135 "d29",
136 "d30",
137 "d31"
106 }; 138 };
107 return names[index]; 139 return names[index];
108 } else { 140 } else {
109 ASSERT(index == 0); 141 ASSERT(index == 0);
110 return "sfpd0"; 142 return "sfpd0";
111 } 143 }
112 } 144 }
113 145
114 146
115 void CpuFeatures::Probe() { 147 void CpuFeatures::Probe() {
(...skipping 25 matching lines...) Expand all
141 supported_ |= 1u << ARMv7; 173 supported_ |= 1u << ARMv7;
142 } 174 }
143 175
144 if (FLAG_enable_sudiv) { 176 if (FLAG_enable_sudiv) {
145 supported_ |= 1u << SUDIV; 177 supported_ |= 1u << SUDIV;
146 } 178 }
147 179
148 if (FLAG_enable_movw_movt) { 180 if (FLAG_enable_movw_movt) {
149 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; 181 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
150 } 182 }
183
184 if (FLAG_enable_32dregs) {
185 supported_ |= 1u << VFP32DREGS;
186 }
187
151 #else // __arm__ 188 #else // __arm__
152 // Probe for additional features not already known to be available. 189 // Probe for additional features not already known to be available.
153 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { 190 if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) {
154 // This implementation also sets the VFP flags if runtime 191 // This implementation also sets the VFP flags if runtime
155 // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI 192 // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI
156 // 0406B, page A1-6. 193 // 0406B, page A1-6.
157 found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; 194 found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2;
158 } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) { 195 } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) {
159 found_by_runtime_probing_ |= 1u << VFP2; 196 found_by_runtime_probing_ |= 1u << VFP2;
160 } 197 }
161 198
162 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { 199 if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) {
163 found_by_runtime_probing_ |= 1u << ARMv7; 200 found_by_runtime_probing_ |= 1u << ARMv7;
164 } 201 }
165 202
166 if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) { 203 if (!IsSupported(SUDIV) && OS::ArmCpuHasFeature(SUDIV)) {
167 found_by_runtime_probing_ |= 1u << SUDIV; 204 found_by_runtime_probing_ |= 1u << SUDIV;
168 } 205 }
169 206
170 if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) { 207 if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) {
171 found_by_runtime_probing_ |= 1u << UNALIGNED_ACCESSES; 208 found_by_runtime_probing_ |= 1u << UNALIGNED_ACCESSES;
172 } 209 }
173 210
174 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER && 211 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER &&
175 OS::ArmCpuHasFeature(ARMv7)) { 212 OS::ArmCpuHasFeature(ARMv7)) {
176 found_by_runtime_probing_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; 213 found_by_runtime_probing_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
177 } 214 }
178 215
216 if (!IsSupported(VFP32DREGS) && OS::ArmCpuHasFeature(VFP32DREGS)) {
217 found_by_runtime_probing_ |= 1u << VFP32DREGS;
218 }
219
179 supported_ |= found_by_runtime_probing_; 220 supported_ |= found_by_runtime_probing_;
180 #endif 221 #endif
181 222
182 // Assert that VFP3 implies VFP2 and ARMv7. 223 // Assert that VFP3 implies VFP2 and ARMv7.
183 ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7))); 224 ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7)));
184 } 225 }
185 226
186 227
187 // ----------------------------------------------------------------------------- 228 // -----------------------------------------------------------------------------
188 // Implementation of RelocInfo 229 // Implementation of RelocInfo
(...skipping 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 } 1780 }
1740 1781
1741 1782
1742 // Support for VFP. 1783 // Support for VFP.
1743 1784
1744 void Assembler::vldr(const DwVfpRegister dst, 1785 void Assembler::vldr(const DwVfpRegister dst,
1745 const Register base, 1786 const Register base,
1746 int offset, 1787 int offset,
1747 const Condition cond) { 1788 const Condition cond) {
1748 // Ddst = MEM(Rbase + offset). 1789 // Ddst = MEM(Rbase + offset).
1749 // Instruction details available in ARM DDI 0406A, A8-628. 1790 // Instruction details available in ARM DDI 0406C.b, A8-924.
1750 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | 1791 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) |
1751 // Vdst(15-12) | 1011(11-8) | offset 1792 // Vd(15-12) | 1011(11-8) | offset
1752 ASSERT(CpuFeatures::IsEnabled(VFP2)); 1793 ASSERT(CpuFeatures::IsEnabled(VFP2));
1753 int u = 1; 1794 int u = 1;
1754 if (offset < 0) { 1795 if (offset < 0) {
1755 offset = -offset; 1796 offset = -offset;
1756 u = 0; 1797 u = 0;
1757 } 1798 }
1799 int vd, d;
1800 dst.split_code(&vd, &d);
1758 1801
1759 ASSERT(offset >= 0); 1802 ASSERT(offset >= 0);
1760 if ((offset % 4) == 0 && (offset / 4) < 256) { 1803 if ((offset % 4) == 0 && (offset / 4) < 256) {
1761 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | 1804 emit(cond | 0xD*B24 | u*B23 | d*B22 | B20 | base.code()*B16 | vd*B12 |
1762 0xB*B8 | ((offset / 4) & 255)); 1805 0xB*B8 | ((offset / 4) & 255));
1763 } else { 1806 } else {
1764 // Larger offsets must be handled by computing the correct address 1807 // Larger offsets must be handled by computing the correct address
1765 // in the ip register. 1808 // in the ip register.
1766 ASSERT(!base.is(ip)); 1809 ASSERT(!base.is(ip));
1767 if (u == 1) { 1810 if (u == 1) {
1768 add(ip, base, Operand(offset)); 1811 add(ip, base, Operand(offset));
1769 } else { 1812 } else {
1770 sub(ip, base, Operand(offset)); 1813 sub(ip, base, Operand(offset));
1771 } 1814 }
1772 emit(cond | 0xD1*B20 | ip.code()*B16 | dst.code()*B12 | 0xB*B8); 1815 emit(cond | 0xD*B24 | d*B22 | B20 | ip.code()*B16 | vd*B12 | 0xB*B8);
1773 } 1816 }
1774 } 1817 }
1775 1818
1776 1819
1777 void Assembler::vldr(const DwVfpRegister dst, 1820 void Assembler::vldr(const DwVfpRegister dst,
1778 const MemOperand& operand, 1821 const MemOperand& operand,
1779 const Condition cond) { 1822 const Condition cond) {
1780 ASSERT(!operand.rm().is_valid()); 1823 ASSERT(!operand.rm().is_valid());
1781 ASSERT(operand.am_ == Offset); 1824 ASSERT(operand.am_ == Offset);
1782 vldr(dst, operand.rn(), operand.offset(), cond); 1825 vldr(dst, operand.rn(), operand.offset(), cond);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 ASSERT(operand.am_ == Offset); 1868 ASSERT(operand.am_ == Offset);
1826 vldr(dst, operand.rn(), operand.offset(), cond); 1869 vldr(dst, operand.rn(), operand.offset(), cond);
1827 } 1870 }
1828 1871
1829 1872
1830 void Assembler::vstr(const DwVfpRegister src, 1873 void Assembler::vstr(const DwVfpRegister src,
1831 const Register base, 1874 const Register base,
1832 int offset, 1875 int offset,
1833 const Condition cond) { 1876 const Condition cond) {
1834 // MEM(Rbase + offset) = Dsrc. 1877 // MEM(Rbase + offset) = Dsrc.
1835 // Instruction details available in ARM DDI 0406A, A8-786. 1878 // Instruction details available in ARM DDI 0406C.b, A8-1082.
1836 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | 1879 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) |
1837 // Vsrc(15-12) | 1011(11-8) | (offset/4) 1880 // Vd(15-12) | 1011(11-8) | (offset/4)
1838 ASSERT(CpuFeatures::IsEnabled(VFP2)); 1881 ASSERT(CpuFeatures::IsEnabled(VFP2));
1839 int u = 1; 1882 int u = 1;
1840 if (offset < 0) { 1883 if (offset < 0) {
1841 offset = -offset; 1884 offset = -offset;
1842 u = 0; 1885 u = 0;
1843 } 1886 }
1844 ASSERT(offset >= 0); 1887 ASSERT(offset >= 0);
1888 int vd, d;
1889 src.split_code(&vd, &d);
1890
1845 if ((offset % 4) == 0 && (offset / 4) < 256) { 1891 if ((offset % 4) == 0 && (offset / 4) < 256) {
1846 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | 1892 emit(cond | 0xD*B24 | u*B23 | d*B22 | base.code()*B16 | vd*B12 | 0xB*B8 |
1847 0xB*B8 | ((offset / 4) & 255)); 1893 ((offset / 4) & 255));
1848 } else { 1894 } else {
1849 // Larger offsets must be handled by computing the correct address 1895 // Larger offsets must be handled by computing the correct address
1850 // in the ip register. 1896 // in the ip register.
1851 ASSERT(!base.is(ip)); 1897 ASSERT(!base.is(ip));
1852 if (u == 1) { 1898 if (u == 1) {
1853 add(ip, base, Operand(offset)); 1899 add(ip, base, Operand(offset));
1854 } else { 1900 } else {
1855 sub(ip, base, Operand(offset)); 1901 sub(ip, base, Operand(offset));
1856 } 1902 }
1857 emit(cond | 0xD0*B20 | ip.code()*B16 | src.code()*B12 | 0xB*B8); 1903 emit(cond | 0xD*B24 | d*B22 | ip.code()*B16 | vd*B12 | 0xB*B8);
1858 } 1904 }
1859 } 1905 }
1860 1906
1861 1907
1862 void Assembler::vstr(const DwVfpRegister src, 1908 void Assembler::vstr(const DwVfpRegister src,
1863 const MemOperand& operand, 1909 const MemOperand& operand,
1864 const Condition cond) { 1910 const Condition cond) {
1865 ASSERT(!operand.rm().is_valid()); 1911 ASSERT(!operand.rm().is_valid());
1866 ASSERT(operand.am_ == Offset); 1912 ASSERT(operand.am_ == Offset);
1867 vstr(src, operand.rn(), operand.offset(), cond); 1913 vstr(src, operand.rn(), operand.offset(), cond);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1909 ASSERT(operand.am_ == Offset); 1955 ASSERT(operand.am_ == Offset);
1910 vstr(src, operand.rn(), operand.offset(), cond); 1956 vstr(src, operand.rn(), operand.offset(), cond);
1911 } 1957 }
1912 1958
1913 1959
1914 void Assembler::vldm(BlockAddrMode am, 1960 void Assembler::vldm(BlockAddrMode am,
1915 Register base, 1961 Register base,
1916 DwVfpRegister first, 1962 DwVfpRegister first,
1917 DwVfpRegister last, 1963 DwVfpRegister last,
1918 Condition cond) { 1964 Condition cond) {
1919 // Instruction details available in ARM DDI 0406A, A8-626. 1965 // Instruction details available in ARM DDI 0406C.b, A8-922.
1920 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | 1966 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
1921 // first(15-12) | 1010(11-8) | (count * 2) 1967 // first(15-12) | 1011(11-8) | (count * 2)
1922 ASSERT(CpuFeatures::IsEnabled(VFP2)); 1968 ASSERT(CpuFeatures::IsEnabled(VFP2));
1923 ASSERT_LE(first.code(), last.code()); 1969 ASSERT_LE(first.code(), last.code());
1924 ASSERT(am == ia || am == ia_w || am == db_w); 1970 ASSERT(am == ia || am == ia_w || am == db_w);
1925 ASSERT(!base.is(pc)); 1971 ASSERT(!base.is(pc));
1926 1972
1927 int sd, d; 1973 int sd, d;
1928 first.split_code(&sd, &d); 1974 first.split_code(&sd, &d);
1929 int count = last.code() - first.code() + 1; 1975 int count = last.code() - first.code() + 1;
1930 ASSERT(count <= 16); 1976 ASSERT(count <= 16);
1931 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | 1977 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
1932 0xB*B8 | count*2); 1978 0xB*B8 | count*2);
1933 } 1979 }
1934 1980
1935 1981
1936 void Assembler::vstm(BlockAddrMode am, 1982 void Assembler::vstm(BlockAddrMode am,
1937 Register base, 1983 Register base,
1938 DwVfpRegister first, 1984 DwVfpRegister first,
1939 DwVfpRegister last, 1985 DwVfpRegister last,
1940 Condition cond) { 1986 Condition cond) {
1941 // Instruction details available in ARM DDI 0406A, A8-784. 1987 // Instruction details available in ARM DDI 0406C.b, A8-1080.
1942 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | 1988 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
1943 // first(15-12) | 1011(11-8) | (count * 2) 1989 // first(15-12) | 1011(11-8) | (count * 2)
1944 ASSERT(CpuFeatures::IsEnabled(VFP2)); 1990 ASSERT(CpuFeatures::IsEnabled(VFP2));
1945 ASSERT_LE(first.code(), last.code()); 1991 ASSERT_LE(first.code(), last.code());
1946 ASSERT(am == ia || am == ia_w || am == db_w); 1992 ASSERT(am == ia || am == ia_w || am == db_w);
1947 ASSERT(!base.is(pc)); 1993 ASSERT(!base.is(pc));
1948 1994
1949 int sd, d; 1995 int sd, d;
1950 first.split_code(&sd, &d); 1996 first.split_code(&sd, &d);
1951 int count = last.code() - first.code() + 1; 1997 int count = last.code() - first.code() + 1;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2051 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. 2097 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble.
2052 2098
2053 return true; 2099 return true;
2054 } 2100 }
2055 2101
2056 2102
2057 void Assembler::vmov(const DwVfpRegister dst, 2103 void Assembler::vmov(const DwVfpRegister dst,
2058 double imm, 2104 double imm,
2059 const Register scratch, 2105 const Register scratch,
2060 const Condition cond) { 2106 const Condition cond) {
2061 // Dd = immediate
2062 // Instruction details available in ARM DDI 0406B, A8-640.
2063 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2107 ASSERT(CpuFeatures::IsEnabled(VFP2));
2064 2108
2065 uint32_t enc; 2109 uint32_t enc;
2066 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { 2110 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) {
2067 // The double can be encoded in the instruction. 2111 // The double can be encoded in the instruction.
2068 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc); 2112 //
2113 // Dd = immediate
2114 // Instruction details available in ARM DDI 0406C.b, A8-936.
2115 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) |
2116 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0)
2117 int vd, d;
2118 dst.split_code(&vd, &d);
2119 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc);
2069 } else if (FLAG_enable_vldr_imm) { 2120 } else if (FLAG_enable_vldr_imm) {
2070 // TODO(jfb) Temporarily turned off until we have constant blinding or 2121 // TODO(jfb) Temporarily turned off until we have constant blinding or
2071 // some equivalent mitigation: an attacker can otherwise control 2122 // some equivalent mitigation: an attacker can otherwise control
2072 // generated data which also happens to be executable, a Very Bad 2123 // generated data which also happens to be executable, a Very Bad
2073 // Thing indeed. 2124 // Thing indeed.
2074 // Blinding gets tricky because we don't have xor, we probably 2125 // Blinding gets tricky because we don't have xor, we probably
2075 // need to add/subtract without losing precision, which requires a 2126 // need to add/subtract without losing precision, which requires a
2076 // cookie value that Lithium is probably better positioned to 2127 // cookie value that Lithium is probably better positioned to
2077 // choose. 2128 // choose.
2078 // We could also add a few peepholes here like detecting 0.0 and 2129 // We could also add a few peepholes here like detecting 0.0 and
2079 // -0.0 and doing a vmov from the sequestered d14, forcing denorms 2130 // -0.0 and doing a vmov from the sequestered d14, forcing denorms
2080 // to zero (we set flush-to-zero), and normalizing NaN values. 2131 // to zero (we set flush-to-zero), and normalizing NaN values.
2081 // We could also detect redundant values. 2132 // We could also detect redundant values.
2082 // The code could also randomize the order of values, though 2133 // The code could also randomize the order of values, though
2083 // that's tricky because vldr has a limited reach. Furthermore 2134 // that's tricky because vldr has a limited reach. Furthermore
2084 // it breaks load locality. 2135 // it breaks load locality.
2085 RecordRelocInfo(imm); 2136 RecordRelocInfo(imm);
2086 vldr(dst, MemOperand(pc, 0), cond); 2137 vldr(dst, MemOperand(pc, 0), cond);
2087 } else { 2138 } else {
2088 // Synthesise the double from ARM immediates. 2139 // Synthesise the double from ARM immediates.
2089 uint32_t lo, hi; 2140 uint32_t lo, hi;
2090 DoubleAsTwoUInt32(imm, &lo, &hi); 2141 DoubleAsTwoUInt32(imm, &lo, &hi);
2091 mov(ip, Operand(lo)); 2142 mov(ip, Operand(lo));
2092 2143
2093 if (scratch.is(no_reg)) { 2144 if (scratch.is(no_reg)) {
2094 // Move the low part of the double into the lower of the corresponsing S 2145 // Move the low and high part separately using vmov.32.
2095 // registers of D register dst. 2146 vmov(dst, 0, ip, cond);
2096 vmov(dst.low(), ip, cond);
2097
2098 // Move the high part of the double into the higher of the corresponsing S
2099 // registers of D register dst.
2100 mov(ip, Operand(hi)); 2147 mov(ip, Operand(hi));
2101 vmov(dst.high(), ip, cond); 2148 vmov(dst, 1, ip, cond);
2102 } else { 2149 } else {
2103 // Move the low and high parts of the double to a D register in one 2150 // Move the low and high parts of the double to a D register in one
2104 // instruction. 2151 // instruction.
2105 mov(scratch, Operand(hi)); 2152 mov(scratch, Operand(hi));
2106 vmov(dst, ip, scratch, cond); 2153 vmov(dst, ip, scratch, cond);
2107 } 2154 }
2108 } 2155 }
2109 } 2156 }
2110 2157
2111 2158
2112 void Assembler::vmov(const SwVfpRegister dst, 2159 void Assembler::vmov(const SwVfpRegister dst,
2113 const SwVfpRegister src, 2160 const SwVfpRegister src,
2114 const Condition cond) { 2161 const Condition cond) {
2115 // Sd = Sm 2162 // Sd = Sm
2116 // Instruction details available in ARM DDI 0406B, A8-642. 2163 // Instruction details available in ARM DDI 0406B, A8-642.
2117 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2164 ASSERT(CpuFeatures::IsEnabled(VFP2));
2118 int sd, d, sm, m; 2165 int sd, d, sm, m;
2119 dst.split_code(&sd, &d); 2166 dst.split_code(&sd, &d);
2120 src.split_code(&sm, &m); 2167 src.split_code(&sm, &m);
2121 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); 2168 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm);
2122 } 2169 }
2123 2170
2124 2171
2125 void Assembler::vmov(const DwVfpRegister dst, 2172 void Assembler::vmov(const DwVfpRegister dst,
2126 const DwVfpRegister src, 2173 const DwVfpRegister src,
2127 const Condition cond) { 2174 const Condition cond) {
2128 // Dd = Dm 2175 // Dd = Dm
2129 // Instruction details available in ARM DDI 0406B, A8-642. 2176 // Instruction details available in ARM DDI 0406C.b, A8-938.
2177 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) |
2178 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2130 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2179 ASSERT(CpuFeatures::IsEnabled(VFP2));
2131 emit(cond | 0xE*B24 | 0xB*B20 | 2180 int vd, d;
2132 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); 2181 dst.split_code(&vd, &d);
2182 int vm, m;
2183 src.split_code(&vm, &m);
2184 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 |
2185 vm);
2133 } 2186 }
2134 2187
2135 2188
2189 void Assembler::vmov(const DwVfpRegister dst,
2190 int index,
2191 const Register src,
2192 const Condition cond) {
2193 // Dd[index] = Rt
2194 // Instruction details available in ARM DDI 0406C.b, A8-940.
2195 // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) |
2196 // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
2197 ASSERT(CpuFeatures::IsEnabled(VFP2));
2198 ASSERT(index == 0 || index == 1);
2199 int vd, d;
2200 dst.split_code(&vd, &d);
2201 emit(cond | 0xE*B24 | index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 | d*B7 |
2202 B4);
2203 }
2204
2205
2136 void Assembler::vmov(const DwVfpRegister dst, 2206 void Assembler::vmov(const DwVfpRegister dst,
2137 const Register src1, 2207 const Register src1,
2138 const Register src2, 2208 const Register src2,
2139 const Condition cond) { 2209 const Condition cond) {
2140 // Dm = <Rt,Rt2>. 2210 // Dm = <Rt,Rt2>.
2141 // Instruction details available in ARM DDI 0406A, A8-646. 2211 // Instruction details available in ARM DDI 0406C.b, A8-948.
2142 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | 2212 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) |
2143 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm 2213 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2144 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2214 ASSERT(CpuFeatures::IsEnabled(VFP2));
2145 ASSERT(!src1.is(pc) && !src2.is(pc)); 2215 ASSERT(!src1.is(pc) && !src2.is(pc));
2216 int vm, m;
2217 dst.split_code(&vm, &m);
2146 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | 2218 emit(cond | 0xC*B24 | B22 | src2.code()*B16 |
2147 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); 2219 src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm);
2148 } 2220 }
2149 2221
2150 2222
2151 void Assembler::vmov(const Register dst1, 2223 void Assembler::vmov(const Register dst1,
2152 const Register dst2, 2224 const Register dst2,
2153 const DwVfpRegister src, 2225 const DwVfpRegister src,
2154 const Condition cond) { 2226 const Condition cond) {
2155 // <Rt,Rt2> = Dm. 2227 // <Rt,Rt2> = Dm.
2156 // Instruction details available in ARM DDI 0406A, A8-646. 2228 // Instruction details available in ARM DDI 0406C.b, A8-948.
2157 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | 2229 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) |
2158 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm 2230 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2159 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2231 ASSERT(CpuFeatures::IsEnabled(VFP2));
2160 ASSERT(!dst1.is(pc) && !dst2.is(pc)); 2232 ASSERT(!dst1.is(pc) && !dst2.is(pc));
2233 int vm, m;
2234 src.split_code(&vm, &m);
2161 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | 2235 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 |
2162 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); 2236 dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm);
2163 } 2237 }
2164 2238
2165 2239
2166 void Assembler::vmov(const SwVfpRegister dst, 2240 void Assembler::vmov(const SwVfpRegister dst,
2167 const Register src, 2241 const Register src,
2168 const Condition cond) { 2242 const Condition cond) {
2169 // Sn = Rt. 2243 // Sn = Rt.
2170 // Instruction details available in ARM DDI 0406A, A8-642. 2244 // Instruction details available in ARM DDI 0406A, A8-642.
2171 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | 2245 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) |
2172 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) 2246 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2365 VFPConversionMode mode, 2439 VFPConversionMode mode,
2366 const Condition cond) { 2440 const Condition cond) {
2367 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2441 ASSERT(CpuFeatures::IsEnabled(VFP2));
2368 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); 2442 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond));
2369 } 2443 }
2370 2444
2371 2445
2372 void Assembler::vneg(const DwVfpRegister dst, 2446 void Assembler::vneg(const DwVfpRegister dst,
2373 const DwVfpRegister src, 2447 const DwVfpRegister src,
2374 const Condition cond) { 2448 const Condition cond) {
2449 // Instruction details available in ARM DDI 0406C.b, A8-968.
2450 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) |
2451 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2375 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2452 ASSERT(CpuFeatures::IsEnabled(VFP2));
2376 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | 2453 int vd, d;
2377 0x5*B9 | B8 | B6 | src.code()); 2454 dst.split_code(&vd, &d);
2455 int vm, m;
2456 src.split_code(&vm, &m);
2457
2458 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 |
2459 m*B5 | vm);
2378 } 2460 }
2379 2461
2380 2462
2381 void Assembler::vabs(const DwVfpRegister dst, 2463 void Assembler::vabs(const DwVfpRegister dst,
2382 const DwVfpRegister src, 2464 const DwVfpRegister src,
2383 const Condition cond) { 2465 const Condition cond) {
2466 // Instruction details available in ARM DDI 0406C.b, A8-524.
2467 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) |
2468 // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2384 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2469 ASSERT(CpuFeatures::IsEnabled(VFP2));
2385 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 2470 int vd, d;
2386 0x5*B9 | B8 | 0x3*B6 | src.code()); 2471 dst.split_code(&vd, &d);
2472 int vm, m;
2473 src.split_code(&vm, &m);
2474 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 |
2475 m*B5 | vm);
2387 } 2476 }
2388 2477
2389 2478
2390 void Assembler::vadd(const DwVfpRegister dst, 2479 void Assembler::vadd(const DwVfpRegister dst,
2391 const DwVfpRegister src1, 2480 const DwVfpRegister src1,
2392 const DwVfpRegister src2, 2481 const DwVfpRegister src2,
2393 const Condition cond) { 2482 const Condition cond) {
2394 // Dd = vadd(Dn, Dm) double precision floating point addition. 2483 // Dd = vadd(Dn, Dm) double precision floating point addition.
2395 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. 2484 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2396 // Instruction details available in ARM DDI 0406A, A8-536. 2485 // Instruction details available in ARM DDI 0406C.b, A8-830.
2397 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | 2486 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) |
2398 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) 2487 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2399 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2488 ASSERT(CpuFeatures::IsEnabled(VFP2));
2400 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | 2489 int vd, d;
2401 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); 2490 dst.split_code(&vd, &d);
2491 int vn, n;
2492 src1.split_code(&vn, &n);
2493 int vm, m;
2494 src2.split_code(&vm, &m);
2495 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2496 n*B7 | m*B5 | vm);
2402 } 2497 }
2403 2498
2404 2499
2405 void Assembler::vsub(const DwVfpRegister dst, 2500 void Assembler::vsub(const DwVfpRegister dst,
2406 const DwVfpRegister src1, 2501 const DwVfpRegister src1,
2407 const DwVfpRegister src2, 2502 const DwVfpRegister src2,
2408 const Condition cond) { 2503 const Condition cond) {
2409 // Dd = vsub(Dn, Dm) double precision floating point subtraction. 2504 // Dd = vsub(Dn, Dm) double precision floating point subtraction.
2410 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. 2505 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2411 // Instruction details available in ARM DDI 0406A, A8-784. 2506 // Instruction details available in ARM DDI 0406C.b, A8-1086.
2412 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | 2507 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) |
2413 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0) 2508 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2414 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2509 ASSERT(CpuFeatures::IsEnabled(VFP2));
2415 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | 2510 int vd, d;
2416 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); 2511 dst.split_code(&vd, &d);
2512 int vn, n;
2513 src1.split_code(&vn, &n);
2514 int vm, m;
2515 src2.split_code(&vm, &m);
2516 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2517 n*B7 | B6 | m*B5 | vm);
2417 } 2518 }
2418 2519
2419 2520
2420 void Assembler::vmul(const DwVfpRegister dst, 2521 void Assembler::vmul(const DwVfpRegister dst,
2421 const DwVfpRegister src1, 2522 const DwVfpRegister src1,
2422 const DwVfpRegister src2, 2523 const DwVfpRegister src2,
2423 const Condition cond) { 2524 const Condition cond) {
2424 // Dd = vmul(Dn, Dm) double precision floating point multiplication. 2525 // Dd = vmul(Dn, Dm) double precision floating point multiplication.
2425 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. 2526 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2426 // Instruction details available in ARM DDI 0406A, A8-784. 2527 // Instruction details available in ARM DDI 0406C.b, A8-960.
2427 // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | 2528 // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) |
2428 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) 2529 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2429 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2530 ASSERT(CpuFeatures::IsEnabled(VFP2));
2430 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | 2531 int vd, d;
2431 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); 2532 dst.split_code(&vd, &d);
2533 int vn, n;
2534 src1.split_code(&vn, &n);
2535 int vm, m;
2536 src2.split_code(&vm, &m);
2537 emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2538 n*B7 | m*B5 | vm);
2432 } 2539 }
2433 2540
2434 2541
2435 void Assembler::vmla(const DwVfpRegister dst, 2542 void Assembler::vmla(const DwVfpRegister dst,
2436 const DwVfpRegister src1, 2543 const DwVfpRegister src1,
2437 const DwVfpRegister src2, 2544 const DwVfpRegister src2,
2438 const Condition cond) { 2545 const Condition cond) {
2439 // Instruction details available in ARM DDI 0406C.b, A8-892. 2546 // Instruction details available in ARM DDI 0406C.b, A8-932.
2440 // cond(31-28) | 11100(27-23) | D=?(22) | 00(21-20) | Vn(19-16) | 2547 // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) |
2441 // Vd(15-12) | 101(11-9) | sz(8)=1 | N=?(7) | op(6)=0 | M=?(5) | 0(4) | 2548 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=0(6) | M(5) | 0(4) | Vm(3-0)
2442 // Vm(3-0) 2549 int vd, d;
2443 unsigned x = (cond | 0x1C*B23 | src1.code()*B16 | 2550 dst.split_code(&vd, &d);
2444 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); 2551 int vn, n;
2445 emit(x); 2552 src1.split_code(&vn, &n);
2553 int vm, m;
2554 src2.split_code(&vm, &m);
2555 emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 |
2556 vm);
2446 } 2557 }
2447 2558
2448 2559
2449 void Assembler::vdiv(const DwVfpRegister dst, 2560 void Assembler::vdiv(const DwVfpRegister dst,
2450 const DwVfpRegister src1, 2561 const DwVfpRegister src1,
2451 const DwVfpRegister src2, 2562 const DwVfpRegister src2,
2452 const Condition cond) { 2563 const Condition cond) {
2453 // Dd = vdiv(Dn, Dm) double precision floating point division. 2564 // Dd = vdiv(Dn, Dm) double precision floating point division.
2454 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. 2565 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2455 // Instruction details available in ARM DDI 0406A, A8-584. 2566 // Instruction details available in ARM DDI 0406C.b, A8-882.
2456 // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | 2567 // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) |
2457 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0) 2568 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2458 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2569 ASSERT(CpuFeatures::IsEnabled(VFP2));
2459 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | 2570 int vd, d;
2460 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); 2571 dst.split_code(&vd, &d);
2572 int vn, n;
2573 src1.split_code(&vn, &n);
2574 int vm, m;
2575 src2.split_code(&vm, &m);
2576 emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 |
2577 vm);
2461 } 2578 }
2462 2579
2463 2580
2464 void Assembler::vcmp(const DwVfpRegister src1, 2581 void Assembler::vcmp(const DwVfpRegister src1,
2465 const DwVfpRegister src2, 2582 const DwVfpRegister src2,
2466 const Condition cond) { 2583 const Condition cond) {
2467 // vcmp(Dd, Dm) double precision floating point comparison. 2584 // vcmp(Dd, Dm) double precision floating point comparison.
2468 // Instruction details available in ARM DDI 0406A, A8-570. 2585 // Instruction details available in ARM DDI 0406C.b, A8-864.
2469 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | 2586 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) |
2470 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0) 2587 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2471 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2588 ASSERT(CpuFeatures::IsEnabled(VFP2));
2472 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | 2589 int vd, d;
2473 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); 2590 src1.split_code(&vd, &d);
2591 int vm, m;
2592 src2.split_code(&vm, &m);
2593 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 |
2594 m*B5 | vm);
2474 } 2595 }
2475 2596
2476 2597
2477 void Assembler::vcmp(const DwVfpRegister src1, 2598 void Assembler::vcmp(const DwVfpRegister src1,
2478 const double src2, 2599 const double src2,
2479 const Condition cond) { 2600 const Condition cond) {
2480 // vcmp(Dd, Dm) double precision floating point comparison. 2601 // vcmp(Dd, #0.0) double precision floating point comparison.
2481 // Instruction details available in ARM DDI 0406A, A8-570. 2602 // Instruction details available in ARM DDI 0406C.b, A8-864.
2482 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) | 2603 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) |
2483 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0) 2604 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0)
2484 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2605 ASSERT(CpuFeatures::IsEnabled(VFP2));
2485 ASSERT(src2 == 0.0); 2606 ASSERT(src2 == 0.0);
2486 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | 2607 int vd, d;
2487 src1.code()*B12 | 0x5*B9 | B8 | B6); 2608 src1.split_code(&vd, &d);
2609 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6);
2488 } 2610 }
2489 2611
2490 2612
2491 void Assembler::vmsr(Register dst, Condition cond) { 2613 void Assembler::vmsr(Register dst, Condition cond) {
2492 // Instruction details available in ARM DDI 0406A, A8-652. 2614 // Instruction details available in ARM DDI 0406A, A8-652.
2493 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | 2615 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) |
2494 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) 2616 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
2495 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2617 ASSERT(CpuFeatures::IsEnabled(VFP2));
2496 emit(cond | 0xE*B24 | 0xE*B20 | B16 | 2618 emit(cond | 0xE*B24 | 0xE*B20 | B16 |
2497 dst.code()*B12 | 0xA*B8 | B4); 2619 dst.code()*B12 | 0xA*B8 | B4);
2498 } 2620 }
2499 2621
2500 2622
2501 void Assembler::vmrs(Register dst, Condition cond) { 2623 void Assembler::vmrs(Register dst, Condition cond) {
2502 // Instruction details available in ARM DDI 0406A, A8-652. 2624 // Instruction details available in ARM DDI 0406A, A8-652.
2503 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | 2625 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) |
2504 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) 2626 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
2505 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2627 ASSERT(CpuFeatures::IsEnabled(VFP2));
2506 emit(cond | 0xE*B24 | 0xF*B20 | B16 | 2628 emit(cond | 0xE*B24 | 0xF*B20 | B16 |
2507 dst.code()*B12 | 0xA*B8 | B4); 2629 dst.code()*B12 | 0xA*B8 | B4);
2508 } 2630 }
2509 2631
2510 2632
2511 void Assembler::vsqrt(const DwVfpRegister dst, 2633 void Assembler::vsqrt(const DwVfpRegister dst,
2512 const DwVfpRegister src, 2634 const DwVfpRegister src,
2513 const Condition cond) { 2635 const Condition cond) {
2514 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) | 2636 // Instruction details available in ARM DDI 0406C.b, A8-1058.
2515 // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0) 2637 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) |
2638 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0)
2516 ASSERT(CpuFeatures::IsEnabled(VFP2)); 2639 ASSERT(CpuFeatures::IsEnabled(VFP2));
2517 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | 2640 int vd, d;
2518 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); 2641 dst.split_code(&vd, &d);
2642 int vm, m;
2643 src.split_code(&vm, &m);
2644 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 |
2645 m*B5 | vm);
2519 } 2646 }
2520 2647
2521 2648
2522 // Pseudo instructions. 2649 // Pseudo instructions.
2523 void Assembler::nop(int type) { 2650 void Assembler::nop(int type) {
2524 // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes 2651 // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes
2525 // some of the CPU's pipeline and has to issue. Older ARM chips simply used 2652 // some of the CPU's pipeline and has to issue. Older ARM chips simply used
2526 // MOV Rx, Rx as NOP and it performs better even in newer CPUs. 2653 // MOV Rx, Rx as NOP and it performs better even in newer CPUs.
2527 // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode 2654 // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
2528 // a type. 2655 // a type.
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
2919 3046
2920 // Since a constant pool was just emitted, move the check offset forward by 3047 // Since a constant pool was just emitted, move the check offset forward by
2921 // the standard interval. 3048 // the standard interval.
2922 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3049 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
2923 } 3050 }
2924 3051
2925 3052
2926 } } // namespace v8::internal 3053 } } // namespace v8::internal
2927 3054
2928 #endif // V8_TARGET_ARCH_ARM 3055 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698