OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/os.h" | 10 #include "vm/os.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 __ LoadHalfWordUnaligned(R1, R0, TMP); | 101 __ LoadHalfWordUnaligned(R1, R0, TMP); |
102 __ mov(R0, Operand(R1)); | 102 __ mov(R0, Operand(R1)); |
103 __ bx(LR); | 103 __ bx(LR); |
104 } | 104 } |
105 | 105 |
106 | 106 |
107 ASSEMBLER_TEST_RUN(LoadHalfWordUnaligned, test) { | 107 ASSEMBLER_TEST_RUN(LoadHalfWordUnaligned, test) { |
108 EXPECT(test != NULL); | 108 EXPECT(test != NULL); |
109 typedef intptr_t (*LoadHalfWordUnaligned)(intptr_t) DART_UNUSED; | 109 typedef intptr_t (*LoadHalfWordUnaligned)(intptr_t) DART_UNUSED; |
110 uint8_t buffer[4] = { | 110 uint8_t buffer[4] = { |
111 0x89, 0xAB, 0xCD, 0xEF, | 111 0x89, 0xAB, 0xCD, 0xEF, |
112 }; | 112 }; |
113 | 113 |
114 EXPECT_EQ(static_cast<int16_t>(static_cast<uint16_t>(0xAB89)), | 114 EXPECT_EQ( |
115 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 115 static_cast<int16_t>(static_cast<uint16_t>(0xAB89)), |
116 LoadHalfWordUnaligned, | 116 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadHalfWordUnaligned, test->entry(), |
117 test->entry(), | 117 reinterpret_cast<intptr_t>(&buffer[0]))); |
118 reinterpret_cast<intptr_t>(&buffer[0]))); | 118 EXPECT_EQ( |
119 EXPECT_EQ(static_cast<int16_t>(static_cast<uint16_t>(0xCDAB)), | 119 static_cast<int16_t>(static_cast<uint16_t>(0xCDAB)), |
120 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 120 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadHalfWordUnaligned, test->entry(), |
121 LoadHalfWordUnaligned, | 121 reinterpret_cast<intptr_t>(&buffer[1]))); |
122 test->entry(), | |
123 reinterpret_cast<intptr_t>(&buffer[1]))); | |
124 } | 122 } |
125 | 123 |
126 | 124 |
127 ASSEMBLER_TEST_GENERATE(LoadHalfWordUnsignedUnaligned, assembler) { | 125 ASSEMBLER_TEST_GENERATE(LoadHalfWordUnsignedUnaligned, assembler) { |
128 __ LoadHalfWordUnsignedUnaligned(R1, R0, TMP); | 126 __ LoadHalfWordUnsignedUnaligned(R1, R0, TMP); |
129 __ mov(R0, Operand(R1)); | 127 __ mov(R0, Operand(R1)); |
130 __ bx(LR); | 128 __ bx(LR); |
131 } | 129 } |
132 | 130 |
133 | 131 |
134 ASSEMBLER_TEST_RUN(LoadHalfWordUnsignedUnaligned, test) { | 132 ASSEMBLER_TEST_RUN(LoadHalfWordUnsignedUnaligned, test) { |
135 EXPECT(test != NULL); | 133 EXPECT(test != NULL); |
136 typedef intptr_t (*LoadHalfWordUnsignedUnaligned)(intptr_t) DART_UNUSED; | 134 typedef intptr_t (*LoadHalfWordUnsignedUnaligned)(intptr_t) DART_UNUSED; |
137 uint8_t buffer[4] = { | 135 uint8_t buffer[4] = { |
138 0x89, 0xAB, 0xCD, 0xEF, | 136 0x89, 0xAB, 0xCD, 0xEF, |
139 }; | 137 }; |
140 | 138 |
141 EXPECT_EQ(0xAB89, | 139 EXPECT_EQ(0xAB89, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
142 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 140 LoadHalfWordUnsignedUnaligned, test->entry(), |
143 LoadHalfWordUnsignedUnaligned, | 141 reinterpret_cast<intptr_t>(&buffer[0]))); |
144 test->entry(), | 142 EXPECT_EQ(0xCDAB, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
145 reinterpret_cast<intptr_t>(&buffer[0]))); | 143 LoadHalfWordUnsignedUnaligned, test->entry(), |
146 EXPECT_EQ(0xCDAB, | 144 reinterpret_cast<intptr_t>(&buffer[1]))); |
147 EXECUTE_TEST_CODE_INTPTR_INTPTR( | |
148 LoadHalfWordUnsignedUnaligned, | |
149 test->entry(), | |
150 reinterpret_cast<intptr_t>(&buffer[1]))); | |
151 } | 145 } |
152 | 146 |
153 | 147 |
154 ASSEMBLER_TEST_GENERATE(StoreHalfWordUnaligned, assembler) { | 148 ASSEMBLER_TEST_GENERATE(StoreHalfWordUnaligned, assembler) { |
155 __ LoadImmediate(R1, 0xABCD); | 149 __ LoadImmediate(R1, 0xABCD); |
156 __ StoreWordUnaligned(R1, R0, TMP); | 150 __ StoreWordUnaligned(R1, R0, TMP); |
157 __ mov(R0, Operand(R1)); | 151 __ mov(R0, Operand(R1)); |
158 __ bx(LR); | 152 __ bx(LR); |
159 } | 153 } |
160 | 154 |
161 | 155 |
162 ASSEMBLER_TEST_RUN(StoreHalfWordUnaligned, test) { | 156 ASSEMBLER_TEST_RUN(StoreHalfWordUnaligned, test) { |
163 EXPECT(test != NULL); | 157 EXPECT(test != NULL); |
164 typedef intptr_t (*StoreHalfWordUnaligned)(intptr_t) DART_UNUSED; | 158 typedef intptr_t (*StoreHalfWordUnaligned)(intptr_t) DART_UNUSED; |
165 uint8_t buffer[4] = { | 159 uint8_t buffer[4] = { |
166 0, 0, 0, 0, | 160 0, 0, 0, 0, |
167 }; | 161 }; |
168 | 162 |
169 EXPECT_EQ(0xABCD, | 163 EXPECT_EQ(0xABCD, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
170 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 164 StoreHalfWordUnaligned, test->entry(), |
171 StoreHalfWordUnaligned, | 165 reinterpret_cast<intptr_t>(&buffer[0]))); |
172 test->entry(), | |
173 reinterpret_cast<intptr_t>(&buffer[0]))); | |
174 EXPECT_EQ(0xCD, buffer[0]); | 166 EXPECT_EQ(0xCD, buffer[0]); |
175 EXPECT_EQ(0xAB, buffer[1]); | 167 EXPECT_EQ(0xAB, buffer[1]); |
176 EXPECT_EQ(0, buffer[2]); | 168 EXPECT_EQ(0, buffer[2]); |
177 | 169 |
178 EXPECT_EQ(0xABCD, | 170 EXPECT_EQ(0xABCD, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
179 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 171 StoreHalfWordUnaligned, test->entry(), |
180 StoreHalfWordUnaligned, | 172 reinterpret_cast<intptr_t>(&buffer[1]))); |
181 test->entry(), | |
182 reinterpret_cast<intptr_t>(&buffer[1]))); | |
183 EXPECT_EQ(0xCD, buffer[1]); | 173 EXPECT_EQ(0xCD, buffer[1]); |
184 EXPECT_EQ(0xAB, buffer[2]); | 174 EXPECT_EQ(0xAB, buffer[2]); |
185 EXPECT_EQ(0, buffer[3]); | 175 EXPECT_EQ(0, buffer[3]); |
186 } | 176 } |
187 | 177 |
188 | 178 |
189 ASSEMBLER_TEST_GENERATE(LoadWordUnaligned, assembler) { | 179 ASSEMBLER_TEST_GENERATE(LoadWordUnaligned, assembler) { |
190 __ LoadWordUnaligned(R1, R0, TMP); | 180 __ LoadWordUnaligned(R1, R0, TMP); |
191 __ mov(R0, Operand(R1)); | 181 __ mov(R0, Operand(R1)); |
192 __ bx(LR); | 182 __ bx(LR); |
193 } | 183 } |
194 | 184 |
195 | 185 |
196 ASSEMBLER_TEST_RUN(LoadWordUnaligned, test) { | 186 ASSEMBLER_TEST_RUN(LoadWordUnaligned, test) { |
197 EXPECT(test != NULL); | 187 EXPECT(test != NULL); |
198 typedef intptr_t (*LoadWordUnaligned)(intptr_t) DART_UNUSED; | 188 typedef intptr_t (*LoadWordUnaligned)(intptr_t) DART_UNUSED; |
199 uint8_t buffer[8] = { | 189 uint8_t buffer[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; |
200 0x12, 0x34, 0x56, 0x78, | |
201 0x9A, 0xBC, 0xDE, 0xF0 | |
202 }; | |
203 | 190 |
204 EXPECT_EQ(0x78563412, | 191 EXPECT_EQ(0x78563412, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
205 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 192 LoadWordUnaligned, test->entry(), |
206 LoadWordUnaligned, | 193 reinterpret_cast<intptr_t>(&buffer[0]))); |
207 test->entry(), | 194 EXPECT_EQ(0x9A785634, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
208 reinterpret_cast<intptr_t>(&buffer[0]))); | 195 LoadWordUnaligned, test->entry(), |
209 EXPECT_EQ(0x9A785634, | 196 reinterpret_cast<intptr_t>(&buffer[1]))); |
210 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 197 EXPECT_EQ(0xBC9A7856, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
211 LoadWordUnaligned, | 198 LoadWordUnaligned, test->entry(), |
212 test->entry(), | 199 reinterpret_cast<intptr_t>(&buffer[2]))); |
213 reinterpret_cast<intptr_t>(&buffer[1]))); | 200 EXPECT_EQ(0xDEBC9A78, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
214 EXPECT_EQ(0xBC9A7856, | 201 LoadWordUnaligned, test->entry(), |
215 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 202 reinterpret_cast<intptr_t>(&buffer[3]))); |
216 LoadWordUnaligned, | |
217 test->entry(), | |
218 reinterpret_cast<intptr_t>(&buffer[2]))); | |
219 EXPECT_EQ(0xDEBC9A78, | |
220 EXECUTE_TEST_CODE_INTPTR_INTPTR( | |
221 LoadWordUnaligned, | |
222 test->entry(), | |
223 reinterpret_cast<intptr_t>(&buffer[3]))); | |
224 } | 203 } |
225 | 204 |
226 | 205 |
227 ASSEMBLER_TEST_GENERATE(StoreWordUnaligned, assembler) { | 206 ASSEMBLER_TEST_GENERATE(StoreWordUnaligned, assembler) { |
228 __ LoadImmediate(R1, 0x12345678); | 207 __ LoadImmediate(R1, 0x12345678); |
229 __ StoreWordUnaligned(R1, R0, TMP); | 208 __ StoreWordUnaligned(R1, R0, TMP); |
230 __ mov(R0, Operand(R1)); | 209 __ mov(R0, Operand(R1)); |
231 __ bx(LR); | 210 __ bx(LR); |
232 } | 211 } |
233 | 212 |
234 | 213 |
235 ASSEMBLER_TEST_RUN(StoreWordUnaligned, test) { | 214 ASSEMBLER_TEST_RUN(StoreWordUnaligned, test) { |
236 EXPECT(test != NULL); | 215 EXPECT(test != NULL); |
237 typedef intptr_t (*StoreWordUnaligned)(intptr_t) DART_UNUSED; | 216 typedef intptr_t (*StoreWordUnaligned)(intptr_t) DART_UNUSED; |
238 uint8_t buffer[8] = { | 217 uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
239 0, 0, 0, 0, | |
240 0, 0, 0, 0 | |
241 }; | |
242 | 218 |
243 EXPECT_EQ(0x12345678, | 219 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
244 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 220 StoreWordUnaligned, test->entry(), |
245 StoreWordUnaligned, | 221 reinterpret_cast<intptr_t>(&buffer[0]))); |
246 test->entry(), | |
247 reinterpret_cast<intptr_t>(&buffer[0]))); | |
248 EXPECT_EQ(0x78, buffer[0]); | 222 EXPECT_EQ(0x78, buffer[0]); |
249 EXPECT_EQ(0x56, buffer[1]); | 223 EXPECT_EQ(0x56, buffer[1]); |
250 EXPECT_EQ(0x34, buffer[2]); | 224 EXPECT_EQ(0x34, buffer[2]); |
251 EXPECT_EQ(0x12, buffer[3]); | 225 EXPECT_EQ(0x12, buffer[3]); |
252 | 226 |
253 EXPECT_EQ(0x12345678, | 227 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
254 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 228 StoreWordUnaligned, test->entry(), |
255 StoreWordUnaligned, | 229 reinterpret_cast<intptr_t>(&buffer[1]))); |
256 test->entry(), | |
257 reinterpret_cast<intptr_t>(&buffer[1]))); | |
258 EXPECT_EQ(0x78, buffer[1]); | 230 EXPECT_EQ(0x78, buffer[1]); |
259 EXPECT_EQ(0x56, buffer[2]); | 231 EXPECT_EQ(0x56, buffer[2]); |
260 EXPECT_EQ(0x34, buffer[3]); | 232 EXPECT_EQ(0x34, buffer[3]); |
261 EXPECT_EQ(0x12, buffer[4]); | 233 EXPECT_EQ(0x12, buffer[4]); |
262 | 234 |
263 EXPECT_EQ(0x12345678, | 235 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
264 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 236 StoreWordUnaligned, test->entry(), |
265 StoreWordUnaligned, | 237 reinterpret_cast<intptr_t>(&buffer[2]))); |
266 test->entry(), | |
267 reinterpret_cast<intptr_t>(&buffer[2]))); | |
268 EXPECT_EQ(0x78, buffer[2]); | 238 EXPECT_EQ(0x78, buffer[2]); |
269 EXPECT_EQ(0x56, buffer[3]); | 239 EXPECT_EQ(0x56, buffer[3]); |
270 EXPECT_EQ(0x34, buffer[4]); | 240 EXPECT_EQ(0x34, buffer[4]); |
271 EXPECT_EQ(0x12, buffer[5]); | 241 EXPECT_EQ(0x12, buffer[5]); |
272 | 242 |
273 EXPECT_EQ(0x12345678, | 243 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
274 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 244 StoreWordUnaligned, test->entry(), |
275 StoreWordUnaligned, | 245 reinterpret_cast<intptr_t>(&buffer[3]))); |
276 test->entry(), | |
277 reinterpret_cast<intptr_t>(&buffer[3]))); | |
278 EXPECT_EQ(0x78, buffer[3]); | 246 EXPECT_EQ(0x78, buffer[3]); |
279 EXPECT_EQ(0x56, buffer[4]); | 247 EXPECT_EQ(0x56, buffer[4]); |
280 EXPECT_EQ(0x34, buffer[5]); | 248 EXPECT_EQ(0x34, buffer[5]); |
281 EXPECT_EQ(0x12, buffer[6]); | 249 EXPECT_EQ(0x12, buffer[6]); |
282 } | 250 } |
283 | 251 |
284 | 252 |
285 ASSEMBLER_TEST_GENERATE(Vmov, assembler) { | 253 ASSEMBLER_TEST_GENERATE(Vmov, assembler) { |
286 if (TargetCPUFeatures::vfp_supported()) { | 254 if (TargetCPUFeatures::vfp_supported()) { |
287 __ mov(R3, Operand(43)); | 255 __ mov(R3, Operand(43)); |
288 __ mov(R1, Operand(41)); | 256 __ mov(R1, Operand(41)); |
289 __ vmovsrr(S1, R1, R3); // S1:S2 = 41:43 | 257 __ vmovsrr(S1, R1, R3); // S1:S2 = 41:43 |
290 __ vmovs(S0, S2); // S0 = S2, S0:S1 == 43:41 | 258 __ vmovs(S0, S2); // S0 = S2, S0:S1 == 43:41 |
291 __ vmovd(D2, D0); // D2 = D0, S4:S5 == 43:41 | 259 __ vmovd(D2, D0); // D2 = D0, S4:S5 == 43:41 |
292 __ vmovrs(R3, S5); // R3 = S5, R3 == 41 | 260 __ vmovrs(R3, S5); // R3 = S5, R3 == 41 |
293 __ vmovrrs(R1, R2, S4); // R1:R2 = S4:S5, R1:R2 == 43:41 | 261 __ vmovrrs(R1, R2, S4); // R1:R2 = S4:S5, R1:R2 == 43:41 |
294 __ vmovdrr(D3, R3, R2); // D3 = R3:R2, S6:S7 == 41:41 | 262 __ vmovdrr(D3, R3, R2); // D3 = R3:R2, S6:S7 == 41:41 |
295 __ vmovdr(D3, 1, R1); // D3[1] == S7 = R1, S6:S7 == 41:43 | 263 __ vmovdr(D3, 1, R1); // D3[1] == S7 = R1, S6:S7 == 41:43 |
296 __ vmovrrd(R0, R1, D3); // R0:R1 = D3, R0:R1 == 41:43 | 264 __ vmovrrd(R0, R1, D3); // R0:R1 = D3, R0:R1 == 41:43 |
297 __ sub(R0, R1, Operand(R0)); // 43-41 | 265 __ sub(R0, R1, Operand(R0)); // 43-41 |
298 } | 266 } |
299 __ bx(LR); | 267 __ bx(LR); |
300 } | 268 } |
301 | 269 |
302 | 270 |
303 ASSEMBLER_TEST_RUN(Vmov, test) { | 271 ASSEMBLER_TEST_RUN(Vmov, test) { |
304 EXPECT(test != NULL); | 272 EXPECT(test != NULL); |
305 if (TargetCPUFeatures::vfp_supported()) { | 273 if (TargetCPUFeatures::vfp_supported()) { |
306 typedef int (*Vmov)() DART_UNUSED; | 274 typedef int (*Vmov)() DART_UNUSED; |
(...skipping 14 matching lines...) Expand all Loading... |
321 } | 289 } |
322 __ bx(LR); | 290 __ bx(LR); |
323 } | 291 } |
324 | 292 |
325 | 293 |
326 ASSEMBLER_TEST_RUN(SingleVLoadStore, test) { | 294 ASSEMBLER_TEST_RUN(SingleVLoadStore, test) { |
327 EXPECT(test != NULL); | 295 EXPECT(test != NULL); |
328 if (TargetCPUFeatures::vfp_supported()) { | 296 if (TargetCPUFeatures::vfp_supported()) { |
329 typedef float (*SingleVLoadStore)() DART_UNUSED; | 297 typedef float (*SingleVLoadStore)() DART_UNUSED; |
330 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry()); | 298 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry()); |
331 EXPECT_FLOAT_EQ(2*12.3f, res, 0.001f); | 299 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f); |
332 } | 300 } |
333 } | 301 } |
334 | 302 |
335 | 303 |
336 ASSEMBLER_TEST_GENERATE(SingleVShiftLoadStore, assembler) { | 304 ASSEMBLER_TEST_GENERATE(SingleVShiftLoadStore, assembler) { |
337 if (TargetCPUFeatures::vfp_supported()) { | 305 if (TargetCPUFeatures::vfp_supported()) { |
338 __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f)); | 306 __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f)); |
339 __ mov(R2, Operand(SP)); | 307 __ mov(R2, Operand(SP)); |
340 // Expressing __str(R0, Address(SP, (-kWordSize * 32), Address::PreIndex)); | 308 // Expressing __str(R0, Address(SP, (-kWordSize * 32), Address::PreIndex)); |
341 // as: | 309 // as: |
342 __ mov(R1, Operand(kWordSize)); | 310 __ mov(R1, Operand(kWordSize)); |
343 __ str(R0, Address(SP, R1, LSL, 5, Address::NegPreIndex)); | 311 __ str(R0, Address(SP, R1, LSL, 5, Address::NegPreIndex)); |
344 __ vldrs(S0, Address(R2, (-kWordSize * 32))); | 312 __ vldrs(S0, Address(R2, (-kWordSize * 32))); |
345 __ vadds(S0, S0, S0); | 313 __ vadds(S0, S0, S0); |
346 __ vstrs(S0, Address(R2, (-kWordSize * 32))); | 314 __ vstrs(S0, Address(R2, (-kWordSize * 32))); |
347 // Expressing __ldr(R0, Address(SP, (kWordSize * 32), Address::PostIndex)); | 315 // Expressing __ldr(R0, Address(SP, (kWordSize * 32), Address::PostIndex)); |
348 // as: | 316 // as: |
349 __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex)); | 317 __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex)); |
350 } | 318 } |
351 __ bx(LR); | 319 __ bx(LR); |
352 } | 320 } |
353 | 321 |
354 | 322 |
355 ASSEMBLER_TEST_RUN(SingleVShiftLoadStore, test) { | 323 ASSEMBLER_TEST_RUN(SingleVShiftLoadStore, test) { |
356 EXPECT(test != NULL); | 324 EXPECT(test != NULL); |
357 if (TargetCPUFeatures::vfp_supported()) { | 325 if (TargetCPUFeatures::vfp_supported()) { |
358 typedef float (*SingleVLoadStore)() DART_UNUSED; | 326 typedef float (*SingleVLoadStore)() DART_UNUSED; |
359 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry()); | 327 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry()); |
360 EXPECT_FLOAT_EQ(2*12.3f, res, 0.001f); | 328 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f); |
361 } | 329 } |
362 } | 330 } |
363 | 331 |
364 | 332 |
365 ASSEMBLER_TEST_GENERATE(DoubleVLoadStore, assembler) { | 333 ASSEMBLER_TEST_GENERATE(DoubleVLoadStore, assembler) { |
366 if (TargetCPUFeatures::vfp_supported()) { | 334 if (TargetCPUFeatures::vfp_supported()) { |
367 int64_t value = bit_cast<int64_t, double>(12.3); | 335 int64_t value = bit_cast<int64_t, double>(12.3); |
368 __ LoadImmediate(R0, Utils::Low32Bits(value)); | 336 __ LoadImmediate(R0, Utils::Low32Bits(value)); |
369 __ LoadImmediate(R1, Utils::High32Bits(value)); | 337 __ LoadImmediate(R1, Utils::High32Bits(value)); |
370 __ mov(R2, Operand(SP)); | 338 __ mov(R2, Operand(SP)); |
371 __ str(R0, Address(SP, (-kWordSize * 30), Address::PreIndex)); | 339 __ str(R0, Address(SP, (-kWordSize * 30), Address::PreIndex)); |
372 __ str(R1, Address(R2, (-kWordSize * 29))); | 340 __ str(R1, Address(R2, (-kWordSize * 29))); |
373 __ vldrd(D0, Address(R2, (-kWordSize * 30))); | 341 __ vldrd(D0, Address(R2, (-kWordSize * 30))); |
374 __ vaddd(D0, D0, D0); | 342 __ vaddd(D0, D0, D0); |
375 __ vstrd(D0, Address(R2, (-kWordSize * 30))); | 343 __ vstrd(D0, Address(R2, (-kWordSize * 30))); |
376 __ ldr(R1, Address(R2, (-kWordSize * 29))); | 344 __ ldr(R1, Address(R2, (-kWordSize * 29))); |
377 __ ldr(R0, Address(SP, (kWordSize * 30), Address::PostIndex)); | 345 __ ldr(R0, Address(SP, (kWordSize * 30), Address::PostIndex)); |
378 } | 346 } |
379 __ bx(LR); | 347 __ bx(LR); |
380 } | 348 } |
381 | 349 |
382 | 350 |
383 ASSEMBLER_TEST_RUN(DoubleVLoadStore, test) { | 351 ASSEMBLER_TEST_RUN(DoubleVLoadStore, test) { |
384 EXPECT(test != NULL); | 352 EXPECT(test != NULL); |
385 if (TargetCPUFeatures::vfp_supported()) { | 353 if (TargetCPUFeatures::vfp_supported()) { |
386 typedef double (*DoubleVLoadStore)() DART_UNUSED; | 354 typedef double (*DoubleVLoadStore)() DART_UNUSED; |
387 float res = EXECUTE_TEST_CODE_DOUBLE(DoubleVLoadStore, test->entry()); | 355 float res = EXECUTE_TEST_CODE_DOUBLE(DoubleVLoadStore, test->entry()); |
388 EXPECT_FLOAT_EQ(2*12.3f, res, 0.001f); | 356 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f); |
389 } | 357 } |
390 } | 358 } |
391 | 359 |
392 | 360 |
393 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) { | 361 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) { |
394 if (TargetCPUFeatures::vfp_supported()) { | 362 if (TargetCPUFeatures::vfp_supported()) { |
395 __ LoadSImmediate(S0, 12.3f); | 363 __ LoadSImmediate(S0, 12.3f); |
396 __ LoadSImmediate(S1, 3.4f); | 364 __ LoadSImmediate(S1, 3.4f); |
397 __ vnegs(S0, S0); // -12.3f | 365 __ vnegs(S0, S0); // -12.3f |
398 __ vabss(S0, S0); // 12.3f | 366 __ vabss(S0, S0); // 12.3f |
399 __ vadds(S0, S0, S1); // 15.7f | 367 __ vadds(S0, S0, S1); // 15.7f |
400 __ vmuls(S0, S0, S1); // 53.38f | 368 __ vmuls(S0, S0, S1); // 53.38f |
401 __ vsubs(S0, S0, S1); // 49.98f | 369 __ vsubs(S0, S0, S1); // 49.98f |
402 __ vdivs(S0, S0, S1); // 14.7f | 370 __ vdivs(S0, S0, S1); // 14.7f |
403 __ vsqrts(S0, S0); // 3.8340579f | 371 __ vsqrts(S0, S0); // 3.8340579f |
404 } | 372 } |
405 __ bx(LR); | 373 __ bx(LR); |
406 } | 374 } |
407 | 375 |
408 | 376 |
409 ASSEMBLER_TEST_RUN(SingleFPOperations, test) { | 377 ASSEMBLER_TEST_RUN(SingleFPOperations, test) { |
410 EXPECT(test != NULL); | 378 EXPECT(test != NULL); |
411 if (TargetCPUFeatures::vfp_supported()) { | 379 if (TargetCPUFeatures::vfp_supported()) { |
412 typedef float (*SingleFPOperations)() DART_UNUSED; | 380 typedef float (*SingleFPOperations)() DART_UNUSED; |
413 float res = EXECUTE_TEST_CODE_FLOAT(SingleFPOperations, test->entry()); | 381 float res = EXECUTE_TEST_CODE_FLOAT(SingleFPOperations, test->entry()); |
414 EXPECT_FLOAT_EQ(3.8340579f, res, 0.001f); | 382 EXPECT_FLOAT_EQ(3.8340579f, res, 0.001f); |
415 } | 383 } |
416 } | 384 } |
417 | 385 |
418 | 386 |
419 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) { | 387 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) { |
420 if (TargetCPUFeatures::vfp_supported()) { | 388 if (TargetCPUFeatures::vfp_supported()) { |
421 __ LoadDImmediate(D0, 12.3, R0); | 389 __ LoadDImmediate(D0, 12.3, R0); |
422 __ LoadDImmediate(D1, 3.4, R0); | 390 __ LoadDImmediate(D1, 3.4, R0); |
423 __ vnegd(D0, D0); // -12.3 | 391 __ vnegd(D0, D0); // -12.3 |
424 __ vabsd(D0, D0); // 12.3 | 392 __ vabsd(D0, D0); // 12.3 |
425 __ vaddd(D0, D0, D1); // 15.7 | 393 __ vaddd(D0, D0, D1); // 15.7 |
426 __ vmuld(D0, D0, D1); // 53.38 | 394 __ vmuld(D0, D0, D1); // 53.38 |
427 __ vsubd(D0, D0, D1); // 49.98 | 395 __ vsubd(D0, D0, D1); // 49.98 |
428 __ vdivd(D0, D0, D1); // 14.7 | 396 __ vdivd(D0, D0, D1); // 14.7 |
429 __ vsqrtd(D0, D0); // 3.8340579 | 397 __ vsqrtd(D0, D0); // 3.8340579 |
430 } | 398 } |
431 __ bx(LR); | 399 __ bx(LR); |
432 } | 400 } |
433 | 401 |
434 | 402 |
435 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) { | 403 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) { |
436 EXPECT(test != NULL); | 404 EXPECT(test != NULL); |
437 if (TargetCPUFeatures::vfp_supported()) { | 405 if (TargetCPUFeatures::vfp_supported()) { |
438 typedef double (*DoubleFPOperations)() DART_UNUSED; | 406 typedef double (*DoubleFPOperations)() DART_UNUSED; |
439 double res = EXECUTE_TEST_CODE_DOUBLE(DoubleFPOperations, test->entry()); | 407 double res = EXECUTE_TEST_CODE_DOUBLE(DoubleFPOperations, test->entry()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 __ vcvtdi(D0, S3); | 440 __ vcvtdi(D0, S3); |
473 } | 441 } |
474 __ bx(LR); | 442 __ bx(LR); |
475 } | 443 } |
476 | 444 |
477 | 445 |
478 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { | 446 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { |
479 EXPECT(test != NULL); | 447 EXPECT(test != NULL); |
480 if (TargetCPUFeatures::vfp_supported()) { | 448 if (TargetCPUFeatures::vfp_supported()) { |
481 typedef double (*IntToDoubleConversionCode)() DART_UNUSED; | 449 typedef double (*IntToDoubleConversionCode)() DART_UNUSED; |
482 double res = EXECUTE_TEST_CODE_DOUBLE(IntToDoubleConversionCode, | 450 double res = |
483 test->entry()); | 451 EXECUTE_TEST_CODE_DOUBLE(IntToDoubleConversionCode, test->entry()); |
484 EXPECT_FLOAT_EQ(6.0, res, 0.001); | 452 EXPECT_FLOAT_EQ(6.0, res, 0.001); |
485 } | 453 } |
486 } | 454 } |
487 | 455 |
488 | 456 |
489 ASSEMBLER_TEST_GENERATE(LongToDoubleConversion, assembler) { | 457 ASSEMBLER_TEST_GENERATE(LongToDoubleConversion, assembler) { |
490 if (TargetCPUFeatures::vfp_supported()) { | 458 if (TargetCPUFeatures::vfp_supported()) { |
491 int64_t value = 60000000000LL; | 459 int64_t value = 60000000000LL; |
492 __ LoadImmediate(R0, Utils::Low32Bits(value)); | 460 __ LoadImmediate(R0, Utils::Low32Bits(value)); |
493 __ LoadImmediate(R1, Utils::High32Bits(value)); | 461 __ LoadImmediate(R1, Utils::High32Bits(value)); |
494 __ vmovsr(S0, R0); | 462 __ vmovsr(S0, R0); |
495 __ vmovsr(S2, R1); | 463 __ vmovsr(S2, R1); |
496 __ vcvtdu(D0, S0); | 464 __ vcvtdu(D0, S0); |
497 __ vcvtdi(D1, S2); | 465 __ vcvtdi(D1, S2); |
498 __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0); | 466 __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0); |
499 __ vmlad(D0, D1, D2); | 467 __ vmlad(D0, D1, D2); |
500 } | 468 } |
501 __ bx(LR); | 469 __ bx(LR); |
502 } | 470 } |
503 | 471 |
504 | 472 |
505 ASSEMBLER_TEST_RUN(LongToDoubleConversion, test) { | 473 ASSEMBLER_TEST_RUN(LongToDoubleConversion, test) { |
506 EXPECT(test != NULL); | 474 EXPECT(test != NULL); |
507 if (TargetCPUFeatures::vfp_supported()) { | 475 if (TargetCPUFeatures::vfp_supported()) { |
508 typedef double (*LongToDoubleConversionCode)() DART_UNUSED; | 476 typedef double (*LongToDoubleConversionCode)() DART_UNUSED; |
509 double res = EXECUTE_TEST_CODE_DOUBLE(LongToDoubleConversionCode, | 477 double res = |
510 test->entry()); | 478 EXECUTE_TEST_CODE_DOUBLE(LongToDoubleConversionCode, test->entry()); |
511 EXPECT_FLOAT_EQ(60000000000.0, res, 0.001); | 479 EXPECT_FLOAT_EQ(60000000000.0, res, 0.001); |
512 } | 480 } |
513 } | 481 } |
514 | 482 |
515 | 483 |
516 ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) { | 484 ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) { |
517 if (TargetCPUFeatures::vfp_supported()) { | 485 if (TargetCPUFeatures::vfp_supported()) { |
518 __ mov(R3, Operand(6)); | 486 __ mov(R3, Operand(6)); |
519 __ vmovsr(S3, R3); | 487 __ vmovsr(S3, R3); |
520 __ vcvtsi(S0, S3); | 488 __ vcvtsi(S0, S3); |
521 } | 489 } |
522 __ bx(LR); | 490 __ bx(LR); |
523 } | 491 } |
524 | 492 |
525 | 493 |
526 ASSEMBLER_TEST_RUN(IntToFloatConversion, test) { | 494 ASSEMBLER_TEST_RUN(IntToFloatConversion, test) { |
527 EXPECT(test != NULL); | 495 EXPECT(test != NULL); |
528 if (TargetCPUFeatures::vfp_supported()) { | 496 if (TargetCPUFeatures::vfp_supported()) { |
529 typedef float (*IntToFloatConversionCode)() DART_UNUSED; | 497 typedef float (*IntToFloatConversionCode)() DART_UNUSED; |
530 float res = EXECUTE_TEST_CODE_FLOAT(IntToFloatConversionCode, | 498 float res = |
531 test->entry()); | 499 EXECUTE_TEST_CODE_FLOAT(IntToFloatConversionCode, test->entry()); |
532 EXPECT_FLOAT_EQ(6.0, res, 0.001); | 500 EXPECT_FLOAT_EQ(6.0, res, 0.001); |
533 } | 501 } |
534 } | 502 } |
535 | 503 |
536 | 504 |
537 ASSEMBLER_TEST_GENERATE(FloatToIntConversion, assembler) { | 505 ASSEMBLER_TEST_GENERATE(FloatToIntConversion, assembler) { |
538 if (TargetCPUFeatures::vfp_supported()) { | 506 if (TargetCPUFeatures::vfp_supported()) { |
539 __ vcvtis(S1, S0); | 507 __ vcvtis(S1, S0); |
540 __ vmovrs(R0, S1); | 508 __ vmovrs(R0, S1); |
541 } | 509 } |
542 __ bx(LR); | 510 __ bx(LR); |
543 } | 511 } |
544 | 512 |
545 | 513 |
546 ASSEMBLER_TEST_RUN(FloatToIntConversion, test) { | 514 ASSEMBLER_TEST_RUN(FloatToIntConversion, test) { |
547 EXPECT(test != NULL); | 515 EXPECT(test != NULL); |
548 if (TargetCPUFeatures::vfp_supported()) { | 516 if (TargetCPUFeatures::vfp_supported()) { |
549 typedef int (*FloatToIntConversion)(float arg) DART_UNUSED; | 517 typedef int (*FloatToIntConversion)(float arg) DART_UNUSED; |
550 EXPECT_EQ(12, | 518 EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(), |
551 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(), | 519 12.8f)); |
552 12.8f)); | 520 EXPECT_EQ(INT_MIN, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, |
553 EXPECT_EQ(INT_MIN, | 521 test->entry(), -FLT_MAX)); |
554 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(), | 522 EXPECT_EQ(INT_MAX, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, |
555 -FLT_MAX)); | 523 test->entry(), FLT_MAX)); |
556 EXPECT_EQ(INT_MAX, | |
557 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(), | |
558 FLT_MAX)); | |
559 } | 524 } |
560 } | 525 } |
561 | 526 |
562 | 527 |
563 ASSEMBLER_TEST_GENERATE(DoubleToIntConversion, assembler) { | 528 ASSEMBLER_TEST_GENERATE(DoubleToIntConversion, assembler) { |
564 if (TargetCPUFeatures::vfp_supported()) { | 529 if (TargetCPUFeatures::vfp_supported()) { |
565 __ vcvtid(S0, D0); | 530 __ vcvtid(S0, D0); |
566 __ vmovrs(R0, S0); | 531 __ vmovrs(R0, S0); |
567 } | 532 } |
568 __ bx(LR); | 533 __ bx(LR); |
569 } | 534 } |
570 | 535 |
571 | 536 |
572 ASSEMBLER_TEST_RUN(DoubleToIntConversion, test) { | 537 ASSEMBLER_TEST_RUN(DoubleToIntConversion, test) { |
573 if (TargetCPUFeatures::vfp_supported()) { | 538 if (TargetCPUFeatures::vfp_supported()) { |
574 typedef int (*DoubleToIntConversion)(double arg) DART_UNUSED; | 539 typedef int (*DoubleToIntConversion)(double arg) DART_UNUSED; |
575 EXPECT(test != NULL); | 540 EXPECT(test != NULL); |
576 EXPECT_EQ(12, | 541 EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, |
577 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(), | 542 test->entry(), 12.8)); |
578 12.8)); | 543 EXPECT_EQ(INT_MIN, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, |
579 EXPECT_EQ(INT_MIN, | 544 test->entry(), -DBL_MAX)); |
580 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(), | 545 EXPECT_EQ(INT_MAX, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, |
581 -DBL_MAX)); | 546 test->entry(), DBL_MAX)); |
582 EXPECT_EQ(INT_MAX, | |
583 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(), | |
584 DBL_MAX)); | |
585 } | 547 } |
586 } | 548 } |
587 | 549 |
588 | 550 |
589 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) { | 551 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) { |
590 if (TargetCPUFeatures::vfp_supported()) { | 552 if (TargetCPUFeatures::vfp_supported()) { |
591 __ LoadSImmediate(S2, 12.8f); | 553 __ LoadSImmediate(S2, 12.8f); |
592 __ vcvtds(D0, S2); | 554 __ vcvtds(D0, S2); |
593 } | 555 } |
594 __ bx(LR); | 556 __ bx(LR); |
595 } | 557 } |
596 | 558 |
597 | 559 |
598 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) { | 560 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) { |
599 if (TargetCPUFeatures::vfp_supported()) { | 561 if (TargetCPUFeatures::vfp_supported()) { |
600 typedef double (*FloatToDoubleConversionCode)() DART_UNUSED; | 562 typedef double (*FloatToDoubleConversionCode)() DART_UNUSED; |
601 EXPECT(test != NULL); | 563 EXPECT(test != NULL); |
602 double res = EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, | 564 double res = |
603 test->entry()); | 565 EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, test->entry()); |
604 EXPECT_FLOAT_EQ(12.8, res, 0.001); | 566 EXPECT_FLOAT_EQ(12.8, res, 0.001); |
605 } | 567 } |
606 } | 568 } |
607 | 569 |
608 | 570 |
609 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) { | 571 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) { |
610 if (TargetCPUFeatures::vfp_supported()) { | 572 if (TargetCPUFeatures::vfp_supported()) { |
611 __ LoadDImmediate(D1, 12.8, R0); | 573 __ LoadDImmediate(D1, 12.8, R0); |
612 __ vcvtsd(S0, D1); | 574 __ vcvtsd(S0, D1); |
613 } | 575 } |
614 __ bx(LR); | 576 __ bx(LR); |
615 } | 577 } |
616 | 578 |
617 | 579 |
618 ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) { | 580 ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) { |
619 EXPECT(test != NULL); | 581 EXPECT(test != NULL); |
620 if (TargetCPUFeatures::vfp_supported()) { | 582 if (TargetCPUFeatures::vfp_supported()) { |
621 typedef float (*DoubleToFloatConversionCode)() DART_UNUSED; | 583 typedef float (*DoubleToFloatConversionCode)() DART_UNUSED; |
622 float res = EXECUTE_TEST_CODE_FLOAT(DoubleToFloatConversionCode, | 584 float res = |
623 test->entry()); | 585 EXECUTE_TEST_CODE_FLOAT(DoubleToFloatConversionCode, test->entry()); |
624 EXPECT_FLOAT_EQ(12.8, res, 0.001); | 586 EXPECT_FLOAT_EQ(12.8, res, 0.001); |
625 } | 587 } |
626 } | 588 } |
627 | 589 |
628 | 590 |
629 ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) { | 591 ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) { |
630 if (TargetCPUFeatures::vfp_supported()) { | 592 if (TargetCPUFeatures::vfp_supported()) { |
631 // Test 12.3f vs 12.5f. | 593 // Test 12.3f vs 12.5f. |
632 __ LoadSImmediate(S0, 12.3f); | 594 __ LoadSImmediate(S0, 12.3f); |
633 __ LoadSImmediate(S1, 12.5f); | 595 __ LoadSImmediate(S1, 12.5f); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 if (TargetCPUFeatures::arm_version() != ARMv5TE) { | 762 if (TargetCPUFeatures::arm_version() != ARMv5TE) { |
801 __ mov(R0, Operand(40)); | 763 __ mov(R0, Operand(40)); |
802 __ mov(R1, Operand(42)); | 764 __ mov(R1, Operand(42)); |
803 __ Push(R0); | 765 __ Push(R0); |
804 Label retry; | 766 Label retry; |
805 __ Bind(&retry); | 767 __ Bind(&retry); |
806 __ ldrex(R0, SP); | 768 __ ldrex(R0, SP); |
807 __ strex(IP, R1, SP); // IP == 0, success | 769 __ strex(IP, R1, SP); // IP == 0, success |
808 __ tst(IP, Operand(0)); | 770 __ tst(IP, Operand(0)); |
809 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex. | 771 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex. |
810 __ Pop(R0); // 42 | 772 __ Pop(R0); // 42 |
811 } | 773 } |
812 __ bx(LR); | 774 __ bx(LR); |
813 } | 775 } |
814 | 776 |
815 | 777 |
816 ASSEMBLER_TEST_RUN(Semaphore, test) { | 778 ASSEMBLER_TEST_RUN(Semaphore, test) { |
817 EXPECT(test != NULL); | 779 EXPECT(test != NULL); |
818 if (TargetCPUFeatures::arm_version() != ARMv5TE) { | 780 if (TargetCPUFeatures::arm_version() != ARMv5TE) { |
819 typedef int (*Semaphore)() DART_UNUSED; | 781 typedef int (*Semaphore)() DART_UNUSED; |
820 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Semaphore, test->entry())); | 782 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Semaphore, test->entry())); |
821 } | 783 } |
822 } | 784 } |
823 | 785 |
824 | 786 |
825 ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) { | 787 ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) { |
826 if (TargetCPUFeatures::arm_version() != ARMv5TE) { | 788 if (TargetCPUFeatures::arm_version() != ARMv5TE) { |
827 __ mov(R0, Operand(40)); | 789 __ mov(R0, Operand(40)); |
828 __ mov(R1, Operand(42)); | 790 __ mov(R1, Operand(42)); |
829 __ Push(R0); | 791 __ Push(R0); |
830 __ ldrex(R0, SP); | 792 __ ldrex(R0, SP); |
831 __ clrex(); // Simulate a context switch. | 793 __ clrex(); // Simulate a context switch. |
832 __ strex(IP, R1, SP); // IP == 1, failure | 794 __ strex(IP, R1, SP); // IP == 1, failure |
833 __ Pop(R0); // 40 | 795 __ Pop(R0); // 40 |
834 __ add(R0, R0, Operand(IP)); | 796 __ add(R0, R0, Operand(IP)); |
835 } | 797 } |
836 __ bx(LR); | 798 __ bx(LR); |
837 } | 799 } |
838 | 800 |
839 | 801 |
840 ASSEMBLER_TEST_RUN(FailedSemaphore, test) { | 802 ASSEMBLER_TEST_RUN(FailedSemaphore, test) { |
841 EXPECT(test != NULL); | 803 EXPECT(test != NULL); |
842 if (TargetCPUFeatures::arm_version() != ARMv5TE) { | 804 if (TargetCPUFeatures::arm_version() != ARMv5TE) { |
843 typedef int (*FailedSemaphore)() DART_UNUSED; | 805 typedef int (*FailedSemaphore)() DART_UNUSED; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarry, test->entry())); | 841 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarry, test->entry())); |
880 } | 842 } |
881 | 843 |
882 | 844 |
883 ASSEMBLER_TEST_GENERATE(AddCarryInOut, assembler) { | 845 ASSEMBLER_TEST_GENERATE(AddCarryInOut, assembler) { |
884 __ LoadImmediate(R2, 0xFFFFFFFF); | 846 __ LoadImmediate(R2, 0xFFFFFFFF); |
885 __ mov(R1, Operand(1)); | 847 __ mov(R1, Operand(1)); |
886 __ mov(R0, Operand(0)); | 848 __ mov(R0, Operand(0)); |
887 __ adds(IP, R2, Operand(R1)); // c_out = 1. | 849 __ adds(IP, R2, Operand(R1)); // c_out = 1. |
888 __ adcs(IP, R2, Operand(R0)); // c_in = 1, c_out = 1. | 850 __ adcs(IP, R2, Operand(R0)); // c_in = 1, c_out = 1. |
889 __ adc(R0, R0, Operand(R0)); // c_in = 1. | 851 __ adc(R0, R0, Operand(R0)); // c_in = 1. |
890 __ bx(LR); | 852 __ bx(LR); |
891 } | 853 } |
892 | 854 |
893 | 855 |
894 ASSEMBLER_TEST_RUN(AddCarryInOut, test) { | 856 ASSEMBLER_TEST_RUN(AddCarryInOut, test) { |
895 EXPECT(test != NULL); | 857 EXPECT(test != NULL); |
896 typedef int (*AddCarryInOut)() DART_UNUSED; | 858 typedef int (*AddCarryInOut)() DART_UNUSED; |
897 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarryInOut, test->entry())); | 859 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarryInOut, test->entry())); |
898 } | 860 } |
899 | 861 |
(...skipping 13 matching lines...) Expand all Loading... |
913 typedef int (*SubCarry)() DART_UNUSED; | 875 typedef int (*SubCarry)() DART_UNUSED; |
914 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarry, test->entry())); | 876 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarry, test->entry())); |
915 } | 877 } |
916 | 878 |
917 | 879 |
918 ASSEMBLER_TEST_GENERATE(SubCarryInOut, assembler) { | 880 ASSEMBLER_TEST_GENERATE(SubCarryInOut, assembler) { |
919 __ mov(R1, Operand(1)); | 881 __ mov(R1, Operand(1)); |
920 __ mov(R0, Operand(0)); | 882 __ mov(R0, Operand(0)); |
921 __ subs(IP, R0, Operand(R1)); // c_out = 1. | 883 __ subs(IP, R0, Operand(R1)); // c_out = 1. |
922 __ sbcs(IP, R0, Operand(R0)); // c_in = 1, c_out = 1. | 884 __ sbcs(IP, R0, Operand(R0)); // c_in = 1, c_out = 1. |
923 __ sbc(R0, R0, Operand(R0)); // c_in = 1. | 885 __ sbc(R0, R0, Operand(R0)); // c_in = 1. |
924 __ bx(LR); | 886 __ bx(LR); |
925 } | 887 } |
926 | 888 |
927 | 889 |
928 ASSEMBLER_TEST_RUN(SubCarryInOut, test) { | 890 ASSEMBLER_TEST_RUN(SubCarryInOut, test) { |
929 EXPECT(test != NULL); | 891 EXPECT(test != NULL); |
930 typedef int (*SubCarryInOut)() DART_UNUSED; | 892 typedef int (*SubCarryInOut)() DART_UNUSED; |
931 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarryInOut, test->entry())); | 893 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarryInOut, test->entry())); |
932 } | 894 } |
933 | 895 |
(...skipping 27 matching lines...) Expand all Loading... |
961 | 923 |
962 ASSEMBLER_TEST_RUN(AndOrr, test) { | 924 ASSEMBLER_TEST_RUN(AndOrr, test) { |
963 EXPECT(test != NULL); | 925 EXPECT(test != NULL); |
964 typedef int (*AndOrr)() DART_UNUSED; | 926 typedef int (*AndOrr)() DART_UNUSED; |
965 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(AndOrr, test->entry())); | 927 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(AndOrr, test->entry())); |
966 } | 928 } |
967 | 929 |
968 | 930 |
969 ASSEMBLER_TEST_GENERATE(Orrs, assembler) { | 931 ASSEMBLER_TEST_GENERATE(Orrs, assembler) { |
970 __ mov(R0, Operand(0)); | 932 __ mov(R0, Operand(0)); |
971 __ tst(R0, Operand(R1)); // Set zero-flag. | 933 __ tst(R0, Operand(R1)); // Set zero-flag. |
972 __ orrs(R0, R0, Operand(1)); // Clear zero-flag. | 934 __ orrs(R0, R0, Operand(1)); // Clear zero-flag. |
973 __ bx(LR, EQ); | 935 __ bx(LR, EQ); |
974 __ mov(R0, Operand(42)); | 936 __ mov(R0, Operand(42)); |
975 __ bx(LR, NE); // Only this return should fire. | 937 __ bx(LR, NE); // Only this return should fire. |
976 __ mov(R0, Operand(2)); | 938 __ mov(R0, Operand(2)); |
977 __ bx(LR); | 939 __ bx(LR); |
978 } | 940 } |
979 | 941 |
980 | 942 |
981 ASSEMBLER_TEST_RUN(Orrs, test) { | 943 ASSEMBLER_TEST_RUN(Orrs, test) { |
(...skipping 20 matching lines...) Expand all Loading... |
1002 | 964 |
1003 | 965 |
1004 ASSEMBLER_TEST_GENERATE(QuotientRemainder, assembler) { | 966 ASSEMBLER_TEST_GENERATE(QuotientRemainder, assembler) { |
1005 if (TargetCPUFeatures::vfp_supported()) { | 967 if (TargetCPUFeatures::vfp_supported()) { |
1006 __ vmovsr(S2, R0); | 968 __ vmovsr(S2, R0); |
1007 __ vmovsr(S4, R2); | 969 __ vmovsr(S4, R2); |
1008 __ vcvtdi(D1, S2); | 970 __ vcvtdi(D1, S2); |
1009 __ vcvtdi(D2, S4); | 971 __ vcvtdi(D2, S4); |
1010 __ vdivd(D0, D1, D2); | 972 __ vdivd(D0, D1, D2); |
1011 __ vcvtid(S0, D0); | 973 __ vcvtid(S0, D0); |
1012 __ vmovrs(R1, S0); // r1 = r0/r2 | 974 __ vmovrs(R1, S0); // r1 = r0/r2 |
1013 __ mls(R0, R1, R2, R0); // r0 = r0 - r1*r2 | 975 __ mls(R0, R1, R2, R0); // r0 = r0 - r1*r2 |
1014 } | 976 } |
1015 __ bx(LR); | 977 __ bx(LR); |
1016 } | 978 } |
1017 | 979 |
1018 | 980 |
1019 ASSEMBLER_TEST_RUN(QuotientRemainder, test) { | 981 ASSEMBLER_TEST_RUN(QuotientRemainder, test) { |
1020 EXPECT(test != NULL); | 982 EXPECT(test != NULL); |
1021 if (TargetCPUFeatures::vfp_supported()) { | 983 if (TargetCPUFeatures::vfp_supported()) { |
1022 typedef int64_t (*QuotientRemainder) | 984 typedef int64_t (*QuotientRemainder)(int64_t dividend, int64_t divisor) |
1023 (int64_t dividend, int64_t divisor) DART_UNUSED; | 985 DART_UNUSED; |
1024 EXPECT_EQ(0x1000400000da8LL, | 986 EXPECT_EQ(0x1000400000da8LL, |
1025 EXECUTE_TEST_CODE_INT64_LL(QuotientRemainder, test->entry(), | 987 EXECUTE_TEST_CODE_INT64_LL(QuotientRemainder, test->entry(), |
1026 0x12345678, 0x1234)); | 988 0x12345678, 0x1234)); |
1027 } | 989 } |
1028 } | 990 } |
1029 | 991 |
1030 | 992 |
1031 ASSEMBLER_TEST_GENERATE(Multiply64To64, assembler) { | 993 ASSEMBLER_TEST_GENERATE(Multiply64To64, assembler) { |
1032 __ Push(R4); | 994 __ Push(R4); |
1033 __ mov(IP, Operand(R0)); | 995 __ mov(IP, Operand(R0)); |
1034 __ mul(R4, R2, R1); | 996 __ mul(R4, R2, R1); |
1035 __ umull(R0, R1, R2, IP); | 997 __ umull(R0, R1, R2, IP); |
1036 __ mla(R2, IP, R3, R4); | 998 __ mla(R2, IP, R3, R4); |
1037 __ add(R1, R2, Operand(R1)); | 999 __ add(R1, R2, Operand(R1)); |
1038 __ Pop(R4); | 1000 __ Pop(R4); |
1039 __ bx(LR); | 1001 __ bx(LR); |
1040 } | 1002 } |
1041 | 1003 |
1042 | 1004 |
1043 ASSEMBLER_TEST_RUN(Multiply64To64, test) { | 1005 ASSEMBLER_TEST_RUN(Multiply64To64, test) { |
1044 EXPECT(test != NULL); | 1006 EXPECT(test != NULL); |
1045 typedef int64_t (*Multiply64To64) | 1007 typedef int64_t (*Multiply64To64)(int64_t operand0, int64_t operand1) |
1046 (int64_t operand0, int64_t operand1) DART_UNUSED; | 1008 DART_UNUSED; |
1047 EXPECT_EQ(6, | 1009 EXPECT_EQ(6, |
1048 EXECUTE_TEST_CODE_INT64_LL(Multiply64To64, test->entry(), -3, -2)); | 1010 EXECUTE_TEST_CODE_INT64_LL(Multiply64To64, test->entry(), -3, -2)); |
1049 } | 1011 } |
1050 | 1012 |
1051 | 1013 |
1052 ASSEMBLER_TEST_GENERATE(Multiply32To64, assembler) { | 1014 ASSEMBLER_TEST_GENERATE(Multiply32To64, assembler) { |
1053 __ smull(R0, R1, R0, R2); | 1015 __ smull(R0, R1, R0, R2); |
1054 __ bx(LR); | 1016 __ bx(LR); |
1055 } | 1017 } |
1056 | 1018 |
1057 | 1019 |
1058 ASSEMBLER_TEST_RUN(Multiply32To64, test) { | 1020 ASSEMBLER_TEST_RUN(Multiply32To64, test) { |
1059 EXPECT(test != NULL); | 1021 EXPECT(test != NULL); |
1060 typedef int64_t (*Multiply32To64) | 1022 typedef int64_t (*Multiply32To64)(int64_t operand0, int64_t operand1) |
1061 (int64_t operand0, int64_t operand1) DART_UNUSED; | 1023 DART_UNUSED; |
1062 EXPECT_EQ(6, | 1024 EXPECT_EQ(6, |
1063 EXECUTE_TEST_CODE_INT64_LL(Multiply32To64, test->entry(), -3, -2)); | 1025 EXECUTE_TEST_CODE_INT64_LL(Multiply32To64, test->entry(), -3, -2)); |
1064 } | 1026 } |
1065 | 1027 |
1066 | 1028 |
1067 ASSEMBLER_TEST_GENERATE(MultiplyAccumAccum32To64, assembler) { | 1029 ASSEMBLER_TEST_GENERATE(MultiplyAccumAccum32To64, assembler) { |
1068 __ umaal(R0, R1, R2, R3); | 1030 __ umaal(R0, R1, R2, R3); |
1069 __ bx(LR); | 1031 __ bx(LR); |
1070 } | 1032 } |
1071 | 1033 |
1072 | 1034 |
1073 ASSEMBLER_TEST_RUN(MultiplyAccumAccum32To64, test) { | 1035 ASSEMBLER_TEST_RUN(MultiplyAccumAccum32To64, test) { |
1074 EXPECT(test != NULL); | 1036 EXPECT(test != NULL); |
1075 typedef int64_t (*MultiplyAccumAccum32To64) | 1037 typedef int64_t (*MultiplyAccumAccum32To64)(int64_t operand0, |
1076 (int64_t operand0, int64_t operand1) DART_UNUSED; | 1038 int64_t operand1) DART_UNUSED; |
1077 EXPECT_EQ(3 + 7 + 5 * 11, | 1039 EXPECT_EQ(3 + 7 + 5 * 11, |
1078 EXECUTE_TEST_CODE_INT64_LL(MultiplyAccumAccum32To64, test->entry(), | 1040 EXECUTE_TEST_CODE_INT64_LL(MultiplyAccumAccum32To64, test->entry(), |
1079 (3LL << 32) + 7, (5LL << 32) + 11)); | 1041 (3LL << 32) + 7, (5LL << 32) + 11)); |
1080 } | 1042 } |
1081 | 1043 |
1082 | 1044 |
1083 ASSEMBLER_TEST_GENERATE(Clz, assembler) { | 1045 ASSEMBLER_TEST_GENERATE(Clz, assembler) { |
1084 Label error; | 1046 Label error; |
1085 | 1047 |
1086 __ mov(R0, Operand(0)); | 1048 __ mov(R0, Operand(0)); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 | 1289 |
1328 ASSEMBLER_TEST_RUN(Ldrh1, test) { | 1290 ASSEMBLER_TEST_RUN(Ldrh1, test) { |
1329 EXPECT(test != NULL); | 1291 EXPECT(test != NULL); |
1330 typedef int (*Tst)() DART_UNUSED; | 1292 typedef int (*Tst)() DART_UNUSED; |
1331 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 1293 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
1332 } | 1294 } |
1333 | 1295 |
1334 | 1296 |
1335 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) { | 1297 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) { |
1336 __ mov(IP, Operand(SP)); | 1298 __ mov(IP, Operand(SP)); |
1337 __ sub(SP, SP, Operand(kWordSize*30)); | 1299 __ sub(SP, SP, Operand(kWordSize * 30)); |
1338 __ strd(R2, R3, SP, 0); | 1300 __ strd(R2, R3, SP, 0); |
1339 __ strd(R0, R1, IP, (-kWordSize*28)); | 1301 __ strd(R0, R1, IP, (-kWordSize * 28)); |
1340 __ ldrd(R2, R3, IP, (-kWordSize*28)); | 1302 __ ldrd(R2, R3, IP, (-kWordSize * 28)); |
1341 __ ldrd(R0, R1, SP, 0); | 1303 __ ldrd(R0, R1, SP, 0); |
1342 __ add(SP, SP, Operand(kWordSize*30)); | 1304 __ add(SP, SP, Operand(kWordSize * 30)); |
1343 __ sub(R0, R0, Operand(R2)); | 1305 __ sub(R0, R0, Operand(R2)); |
1344 __ add(R1, R1, Operand(R3)); | 1306 __ add(R1, R1, Operand(R3)); |
1345 __ bx(LR); | 1307 __ bx(LR); |
1346 } | 1308 } |
1347 | 1309 |
1348 | 1310 |
1349 ASSEMBLER_TEST_RUN(Ldrd, test) { | 1311 ASSEMBLER_TEST_RUN(Ldrd, test) { |
1350 EXPECT(test != NULL); | 1312 EXPECT(test != NULL); |
1351 typedef int64_t (*Tst)(int64_t r0r1, int64_t r2r3) DART_UNUSED; | 1313 typedef int64_t (*Tst)(int64_t r0r1, int64_t r2r3) DART_UNUSED; |
1352 EXPECT_EQ(0x0000444400002222LL, EXECUTE_TEST_CODE_INT64_LL( | 1314 EXPECT_EQ(0x0000444400002222LL, |
1353 Tst, test->entry(), 0x0000111100000000LL, 0x0000333300002222LL)); | 1315 EXECUTE_TEST_CODE_INT64_LL(Tst, test->entry(), 0x0000111100000000LL, |
| 1316 0x0000333300002222LL)); |
1354 } | 1317 } |
1355 | 1318 |
1356 | 1319 |
1357 ASSEMBLER_TEST_GENERATE(Ldm_stm_da, assembler) { | 1320 ASSEMBLER_TEST_GENERATE(Ldm_stm_da, assembler) { |
1358 __ mov(R0, Operand(1)); | 1321 __ mov(R0, Operand(1)); |
1359 __ mov(R1, Operand(7)); | 1322 __ mov(R1, Operand(7)); |
1360 __ mov(R2, Operand(11)); | 1323 __ mov(R2, Operand(11)); |
1361 __ mov(R3, Operand(31)); | 1324 __ mov(R3, Operand(31)); |
1362 __ Push(R9); // We use R9 as accumulator. | 1325 __ Push(R9); // We use R9 as accumulator. |
1363 __ Push(R9); | 1326 __ Push(R9); |
1364 __ Push(R9); | 1327 __ Push(R9); |
1365 __ Push(R9); | 1328 __ Push(R9); |
1366 __ Push(R9); | 1329 __ Push(R9); |
1367 __ Push(R0); // Make room, so we can decrement after. | 1330 __ Push(R0); // Make room, so we can decrement after. |
1368 __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3)); | 1331 __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3)); |
1369 __ str(R2, Address(SP)); // Should be a free slot. | 1332 __ str(R2, Address(SP)); // Should be a free slot. |
1370 __ ldr(R9, Address(SP, 1 * kWordSize)); // R0. R9 = +1. | 1333 __ ldr(R9, Address(SP, 1 * kWordSize)); // R0. R9 = +1. |
1371 __ ldr(IP, Address(SP, 2 * kWordSize)); // R1. | 1334 __ ldr(IP, Address(SP, 2 * kWordSize)); // R1. |
1372 __ sub(R9, R9, Operand(IP)); // -R1. R9 = -6. | 1335 __ sub(R9, R9, Operand(IP)); // -R1. R9 = -6. |
1373 __ ldr(IP, Address(SP, 3 * kWordSize)); // R2. | 1336 __ ldr(IP, Address(SP, 3 * kWordSize)); // R2. |
1374 __ add(R9, R9, Operand(IP)); // +R2. R9 = +5. | 1337 __ add(R9, R9, Operand(IP)); // +R2. R9 = +5. |
1375 __ ldr(IP, Address(SP, 4 * kWordSize)); // R3. | 1338 __ ldr(IP, Address(SP, 4 * kWordSize)); // R3. |
1376 __ sub(R9, R9, Operand(IP)); // -R3. R9 = -26. | 1339 __ sub(R9, R9, Operand(IP)); // -R3. R9 = -26. |
1377 __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3)); | 1340 __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3)); |
1378 // Same operations again. But this time from the restore registers. | 1341 // Same operations again. But this time from the restore registers. |
1379 __ add(R9, R9, Operand(R0)); | 1342 __ add(R9, R9, Operand(R0)); |
1380 __ sub(R9, R9, Operand(R1)); | 1343 __ sub(R9, R9, Operand(R1)); |
1381 __ add(R9, R9, Operand(R2)); | 1344 __ add(R9, R9, Operand(R2)); |
1382 __ sub(R0, R9, Operand(R3)); // R0 = result = -52. | 1345 __ sub(R0, R9, Operand(R3)); // R0 = result = -52. |
1383 __ Pop(R1); // Remove storage slot. | 1346 __ Pop(R1); // Remove storage slot. |
1384 __ Pop(R9); // Restore R9. | 1347 __ Pop(R9); // Restore R9. |
1385 __ Pop(R9); // Restore R9. | 1348 __ Pop(R9); // Restore R9. |
1386 __ Pop(R9); // Restore R9. | 1349 __ Pop(R9); // Restore R9. |
1387 __ Pop(R9); // Restore R9. | 1350 __ Pop(R9); // Restore R9. |
1388 __ Pop(R9); // Restore R9. | 1351 __ Pop(R9); // Restore R9. |
1389 __ bx(LR); | 1352 __ bx(LR); |
1390 } | 1353 } |
1391 | 1354 |
1392 | 1355 |
1393 ASSEMBLER_TEST_RUN(Ldm_stm_da, test) { | 1356 ASSEMBLER_TEST_RUN(Ldm_stm_da, test) { |
1394 EXPECT(test != NULL); | 1357 EXPECT(test != NULL); |
1395 typedef int (*Tst)() DART_UNUSED; | 1358 typedef int (*Tst)() DART_UNUSED; |
1396 EXPECT_EQ(-52, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 1359 EXPECT_EQ(-52, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
1397 } | 1360 } |
1398 | 1361 |
(...skipping 1758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3157 if (TargetCPUFeatures::neon_supported()) { | 3120 if (TargetCPUFeatures::neon_supported()) { |
3158 typedef int (*Tst)() DART_UNUSED; | 3121 typedef int (*Tst)() DART_UNUSED; |
3159 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 3122 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
3160 } | 3123 } |
3161 } | 3124 } |
3162 | 3125 |
3163 | 3126 |
3164 ASSEMBLER_TEST_GENERATE(Vmvnq, assembler) { | 3127 ASSEMBLER_TEST_GENERATE(Vmvnq, assembler) { |
3165 if (TargetCPUFeatures::neon_supported()) { | 3128 if (TargetCPUFeatures::neon_supported()) { |
3166 __ LoadImmediate(R1, 42); // R1 <- 42. | 3129 __ LoadImmediate(R1, 42); // R1 <- 42. |
3167 __ vmovsr(S2, R1); // S2 <- R1. | 3130 __ vmovsr(S2, R1); // S2 <- R1. |
3168 __ vmvnq(Q1, Q0); // Q1 <- ~Q0. | 3131 __ vmvnq(Q1, Q0); // Q1 <- ~Q0. |
3169 __ vmvnq(Q2, Q1); // Q2 <- ~Q1. | 3132 __ vmvnq(Q2, Q1); // Q2 <- ~Q1. |
3170 __ vmovrs(R0, S10); // Now R0 should be 42 again. | 3133 __ vmovrs(R0, S10); // Now R0 should be 42 again. |
3171 } | 3134 } |
3172 __ bx(LR); | 3135 __ bx(LR); |
3173 } | 3136 } |
3174 | 3137 |
3175 | 3138 |
3176 ASSEMBLER_TEST_RUN(Vmvnq, test) { | 3139 ASSEMBLER_TEST_RUN(Vmvnq, test) { |
3177 EXPECT(test != NULL); | 3140 EXPECT(test != NULL); |
3178 if (TargetCPUFeatures::neon_supported()) { | 3141 if (TargetCPUFeatures::neon_supported()) { |
3179 typedef int (*Tst)() DART_UNUSED; | 3142 typedef int (*Tst)() DART_UNUSED; |
3180 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 3143 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3695 if (TargetCPUFeatures::neon_supported()) { | 3658 if (TargetCPUFeatures::neon_supported()) { |
3696 typedef int (*Tst)() DART_UNUSED; | 3659 typedef int (*Tst)() DART_UNUSED; |
3697 EXPECT_EQ(14, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 3660 EXPECT_EQ(14, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
3698 } | 3661 } |
3699 } | 3662 } |
3700 | 3663 |
3701 | 3664 |
3702 // This is the same function as in the Simulator. | 3665 // This is the same function as in the Simulator. |
3703 static float arm_recip_estimate(float a) { | 3666 static float arm_recip_estimate(float a) { |
3704 // From the ARM Architecture Reference Manual A2-85. | 3667 // From the ARM Architecture Reference Manual A2-85. |
3705 if (isinf(a) || (fabs(a) >= exp2f(126))) return 0.0; | 3668 if (isinf(a) || (fabs(a) >= exp2f(126))) |
3706 else if (a == 0.0) return kPosInfinity; | 3669 return 0.0; |
3707 else if (isnan(a)) return a; | 3670 else if (a == 0.0) |
| 3671 return kPosInfinity; |
| 3672 else if (isnan(a)) |
| 3673 return a; |
3708 | 3674 |
3709 uint32_t a_bits = bit_cast<uint32_t, float>(a); | 3675 uint32_t a_bits = bit_cast<uint32_t, float>(a); |
3710 // scaled = '0011 1111 1110' : a<22:0> : Zeros(29) | 3676 // scaled = '0011 1111 1110' : a<22:0> : Zeros(29) |
3711 uint64_t scaled = (static_cast<uint64_t>(0x3fe) << 52) | | 3677 uint64_t scaled = (static_cast<uint64_t>(0x3fe) << 52) | |
3712 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); | 3678 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); |
3713 // result_exp = 253 - UInt(a<30:23>) | 3679 // result_exp = 253 - UInt(a<30:23>) |
3714 int32_t result_exp = 253 - ((a_bits >> 23) & 0xff); | 3680 int32_t result_exp = 253 - ((a_bits >> 23) & 0xff); |
3715 ASSERT((result_exp >= 1) && (result_exp <= 252)); | 3681 ASSERT((result_exp >= 1) && (result_exp <= 252)); |
3716 | 3682 |
3717 double scaled_d = bit_cast<double, uint64_t>(scaled); | 3683 double scaled_d = bit_cast<double, uint64_t>(scaled); |
3718 ASSERT((scaled_d >= 0.5) && (scaled_d < 1.0)); | 3684 ASSERT((scaled_d >= 0.5) && (scaled_d < 1.0)); |
3719 | 3685 |
3720 // a in units of 1/512 rounded down. | 3686 // a in units of 1/512 rounded down. |
3721 int32_t q = static_cast<int32_t>(scaled_d * 512.0); | 3687 int32_t q = static_cast<int32_t>(scaled_d * 512.0); |
3722 // reciprocal r. | 3688 // reciprocal r. |
3723 double r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0); | 3689 double r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0); |
3724 // r in units of 1/256 rounded to nearest. | 3690 // r in units of 1/256 rounded to nearest. |
3725 int32_t s = static_cast<int32_t>(256.0 * r + 0.5); | 3691 int32_t s = static_cast<int32_t>(256.0 * r + 0.5); |
3726 double estimate = static_cast<double>(s) / 256.0; | 3692 double estimate = static_cast<double>(s) / 256.0; |
3727 ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0))); | 3693 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); |
3728 | 3694 |
3729 // result = sign : result_exp<7:0> : estimate<51:29> | 3695 // result = sign : result_exp<7:0> : estimate<51:29> |
3730 int32_t result_bits = | 3696 int32_t result_bits = |
3731 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | | 3697 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | |
3732 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); | 3698 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
3733 return bit_cast<float, int32_t>(result_bits); | 3699 return bit_cast<float, int32_t>(result_bits); |
3734 } | 3700 } |
3735 | 3701 |
3736 | 3702 |
3737 ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) { | 3703 ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3801 } | 3767 } |
3802 __ bx(LR); | 3768 __ bx(LR); |
3803 } | 3769 } |
3804 | 3770 |
3805 | 3771 |
3806 ASSEMBLER_TEST_RUN(Reciprocal, test) { | 3772 ASSEMBLER_TEST_RUN(Reciprocal, test) { |
3807 EXPECT(test != NULL); | 3773 EXPECT(test != NULL); |
3808 if (TargetCPUFeatures::neon_supported()) { | 3774 if (TargetCPUFeatures::neon_supported()) { |
3809 typedef float (*Reciprocal)() DART_UNUSED; | 3775 typedef float (*Reciprocal)() DART_UNUSED; |
3810 float res = EXECUTE_TEST_CODE_FLOAT(Reciprocal, test->entry()); | 3776 float res = EXECUTE_TEST_CODE_FLOAT(Reciprocal, test->entry()); |
3811 EXPECT_FLOAT_EQ(1.0/147000.0, res, 0.0001f); | 3777 EXPECT_FLOAT_EQ(1.0 / 147000.0, res, 0.0001f); |
3812 } | 3778 } |
3813 } | 3779 } |
3814 | 3780 |
3815 | 3781 |
3816 static float arm_reciprocal_sqrt_estimate(float a) { | 3782 static float arm_reciprocal_sqrt_estimate(float a) { |
3817 // From the ARM Architecture Reference Manual A2-87. | 3783 // From the ARM Architecture Reference Manual A2-87. |
3818 if (isinf(a) || (fabs(a) >= exp2f(126))) return 0.0; | 3784 if (isinf(a) || (fabs(a) >= exp2f(126))) |
3819 else if (a == 0.0) return kPosInfinity; | 3785 return 0.0; |
3820 else if (isnan(a)) return a; | 3786 else if (a == 0.0) |
| 3787 return kPosInfinity; |
| 3788 else if (isnan(a)) |
| 3789 return a; |
3821 | 3790 |
3822 uint32_t a_bits = bit_cast<uint32_t, float>(a); | 3791 uint32_t a_bits = bit_cast<uint32_t, float>(a); |
3823 uint64_t scaled; | 3792 uint64_t scaled; |
3824 if (((a_bits >> 23) & 1) != 0) { | 3793 if (((a_bits >> 23) & 1) != 0) { |
3825 // scaled = '0 01111111101' : operand<22:0> : Zeros(29) | 3794 // scaled = '0 01111111101' : operand<22:0> : Zeros(29) |
3826 scaled = (static_cast<uint64_t>(0x3fd) << 52) | | 3795 scaled = (static_cast<uint64_t>(0x3fd) << 52) | |
3827 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); | 3796 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); |
3828 } else { | 3797 } else { |
3829 // scaled = '0 01111111110' : operand<22:0> : Zeros(29) | 3798 // scaled = '0 01111111110' : operand<22:0> : Zeros(29) |
3830 scaled = (static_cast<uint64_t>(0x3fe) << 52) | | 3799 scaled = (static_cast<uint64_t>(0x3fe) << 52) | |
(...skipping 17 matching lines...) Expand all Loading... |
3848 // range 0.5 <= a < 1.0 | 3817 // range 0.5 <= a < 1.0 |
3849 | 3818 |
3850 // a in units of 1/256 rounded down. | 3819 // a in units of 1/256 rounded down. |
3851 int32_t q1 = static_cast<int32_t>(scaled_d * 256.0); | 3820 int32_t q1 = static_cast<int32_t>(scaled_d * 256.0); |
3852 // reciprocal root r. | 3821 // reciprocal root r. |
3853 r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0); | 3822 r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0); |
3854 } | 3823 } |
3855 // r in units of 1/256 rounded to nearest. | 3824 // r in units of 1/256 rounded to nearest. |
3856 int32_t s = static_cast<int>(256.0 * r + 0.5); | 3825 int32_t s = static_cast<int>(256.0 * r + 0.5); |
3857 double estimate = static_cast<double>(s) / 256.0; | 3826 double estimate = static_cast<double>(s) / 256.0; |
3858 ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0))); | 3827 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); |
3859 | 3828 |
3860 // result = 0 : result_exp<7:0> : estimate<51:29> | 3829 // result = 0 : result_exp<7:0> : estimate<51:29> |
3861 int32_t result_bits = ((result_exp & 0xff) << 23) | | 3830 int32_t result_bits = |
| 3831 ((result_exp & 0xff) << 23) | |
3862 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); | 3832 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
3863 return bit_cast<float, int32_t>(result_bits); | 3833 return bit_cast<float, int32_t>(result_bits); |
3864 } | 3834 } |
3865 | 3835 |
3866 | 3836 |
3867 ASSEMBLER_TEST_GENERATE(Vrsqrteqs, assembler) { | 3837 ASSEMBLER_TEST_GENERATE(Vrsqrteqs, assembler) { |
3868 if (TargetCPUFeatures::neon_supported()) { | 3838 if (TargetCPUFeatures::neon_supported()) { |
3869 __ LoadSImmediate(S4, 147.0); | 3839 __ LoadSImmediate(S4, 147.0); |
3870 __ vmovs(S5, S4); | 3840 __ vmovs(S5, S4); |
3871 __ vmovs(S6, S4); | 3841 __ vmovs(S6, S4); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3903 } | 3873 } |
3904 __ bx(LR); | 3874 __ bx(LR); |
3905 } | 3875 } |
3906 | 3876 |
3907 | 3877 |
3908 ASSEMBLER_TEST_RUN(Vrsqrtsqs, test) { | 3878 ASSEMBLER_TEST_RUN(Vrsqrtsqs, test) { |
3909 EXPECT(test != NULL); | 3879 EXPECT(test != NULL); |
3910 if (TargetCPUFeatures::neon_supported()) { | 3880 if (TargetCPUFeatures::neon_supported()) { |
3911 typedef float (*Vrsqrtsqs)() DART_UNUSED; | 3881 typedef float (*Vrsqrtsqs)() DART_UNUSED; |
3912 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrtsqs, test->entry()); | 3882 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrtsqs, test->entry()); |
3913 EXPECT_FLOAT_EQ((3.0 - 10.0 * 5.0)/2.0, res, 0.0001f); | 3883 EXPECT_FLOAT_EQ((3.0 - 10.0 * 5.0) / 2.0, res, 0.0001f); |
3914 } | 3884 } |
3915 } | 3885 } |
3916 | 3886 |
3917 | 3887 |
3918 ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) { | 3888 ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) { |
3919 if (TargetCPUFeatures::neon_supported()) { | 3889 if (TargetCPUFeatures::neon_supported()) { |
3920 __ LoadSImmediate(S4, 147000.0); | 3890 __ LoadSImmediate(S4, 147000.0); |
3921 __ vmovs(S5, S4); | 3891 __ vmovs(S5, S4); |
3922 __ vmovs(S6, S4); | 3892 __ vmovs(S6, S4); |
3923 __ vmovs(S7, S4); | 3893 __ vmovs(S7, S4); |
3924 | 3894 |
3925 // Reciprocal square root estimate. | 3895 // Reciprocal square root estimate. |
3926 __ vrsqrteqs(Q0, Q1); | 3896 __ vrsqrteqs(Q0, Q1); |
3927 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 3897 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
3928 // First step. | 3898 // First step. |
3929 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 3899 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
3930 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. | 3900 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. |
3931 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 | 3901 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 |
3932 // Second step. | 3902 // Second step. |
3933 __ vmulqs(Q2, Q0, Q0); | 3903 __ vmulqs(Q2, Q0, Q0); |
3934 __ vrsqrtsqs(Q2, Q1, Q2); | 3904 __ vrsqrtsqs(Q2, Q1, Q2); |
3935 __ vmulqs(Q0, Q0, Q2); | 3905 __ vmulqs(Q0, Q0, Q2); |
3936 } | 3906 } |
3937 __ bx(LR); | 3907 __ bx(LR); |
3938 } | 3908 } |
3939 | 3909 |
3940 | 3910 |
3941 ASSEMBLER_TEST_RUN(ReciprocalSqrt, test) { | 3911 ASSEMBLER_TEST_RUN(ReciprocalSqrt, test) { |
3942 EXPECT(test != NULL); | 3912 EXPECT(test != NULL); |
3943 if (TargetCPUFeatures::neon_supported()) { | 3913 if (TargetCPUFeatures::neon_supported()) { |
3944 typedef float (*ReciprocalSqrt)() DART_UNUSED; | 3914 typedef float (*ReciprocalSqrt)() DART_UNUSED; |
3945 float res = EXECUTE_TEST_CODE_FLOAT(ReciprocalSqrt, test->entry()); | 3915 float res = EXECUTE_TEST_CODE_FLOAT(ReciprocalSqrt, test->entry()); |
3946 EXPECT_FLOAT_EQ(1.0/sqrt(147000.0), res, 0.0001f); | 3916 EXPECT_FLOAT_EQ(1.0 / sqrt(147000.0), res, 0.0001f); |
3947 } | 3917 } |
3948 } | 3918 } |
3949 | 3919 |
3950 | 3920 |
3951 ASSEMBLER_TEST_GENERATE(SIMDSqrt, assembler) { | 3921 ASSEMBLER_TEST_GENERATE(SIMDSqrt, assembler) { |
3952 if (TargetCPUFeatures::neon_supported()) { | 3922 if (TargetCPUFeatures::neon_supported()) { |
3953 __ LoadSImmediate(S4, 147000.0); | 3923 __ LoadSImmediate(S4, 147000.0); |
3954 __ vmovs(S5, S4); | 3924 __ vmovs(S5, S4); |
3955 __ vmovs(S6, S4); | 3925 __ vmovs(S6, S4); |
3956 __ vmovs(S7, S4); | 3926 __ vmovs(S7, S4); |
3957 | 3927 |
3958 // Reciprocal square root estimate. | 3928 // Reciprocal square root estimate. |
3959 __ vrsqrteqs(Q0, Q1); | 3929 __ vrsqrteqs(Q0, Q1); |
3960 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 3930 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
3961 // First step. | 3931 // First step. |
3962 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 3932 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
3963 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. | 3933 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. |
3964 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 | 3934 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 |
3965 // Second step. | 3935 // Second step. |
3966 __ vmulqs(Q2, Q0, Q0); | 3936 __ vmulqs(Q2, Q0, Q0); |
3967 __ vrsqrtsqs(Q2, Q1, Q2); | 3937 __ vrsqrtsqs(Q2, Q1, Q2); |
3968 __ vmulqs(Q0, Q0, Q2); | 3938 __ vmulqs(Q0, Q0, Q2); |
3969 | 3939 |
3970 // Reciprocal. | 3940 // Reciprocal. |
3971 __ vmovq(Q1, Q0); | 3941 __ vmovq(Q1, Q0); |
3972 // Reciprocal estimate. | 3942 // Reciprocal estimate. |
3973 __ vrecpeqs(Q0, Q1); | 3943 __ vrecpeqs(Q0, Q1); |
3974 // 2 Newton-Raphson steps. | 3944 // 2 Newton-Raphson steps. |
(...skipping 20 matching lines...) Expand all Loading... |
3995 if (TargetCPUFeatures::neon_supported()) { | 3965 if (TargetCPUFeatures::neon_supported()) { |
3996 __ LoadSImmediate(S4, 1.0); | 3966 __ LoadSImmediate(S4, 1.0); |
3997 __ LoadSImmediate(S5, 4.0); | 3967 __ LoadSImmediate(S5, 4.0); |
3998 __ LoadSImmediate(S6, 9.0); | 3968 __ LoadSImmediate(S6, 9.0); |
3999 __ LoadSImmediate(S7, 16.0); | 3969 __ LoadSImmediate(S7, 16.0); |
4000 | 3970 |
4001 // Reciprocal square root estimate. | 3971 // Reciprocal square root estimate. |
4002 __ vrsqrteqs(Q0, Q1); | 3972 __ vrsqrteqs(Q0, Q1); |
4003 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 3973 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
4004 // First step. | 3974 // First step. |
4005 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 3975 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
4006 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. | 3976 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. |
4007 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 | 3977 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 |
4008 // Second step. | 3978 // Second step. |
4009 __ vmulqs(Q2, Q0, Q0); | 3979 __ vmulqs(Q2, Q0, Q0); |
4010 __ vrsqrtsqs(Q2, Q1, Q2); | 3980 __ vrsqrtsqs(Q2, Q1, Q2); |
4011 __ vmulqs(Q0, Q0, Q2); | 3981 __ vmulqs(Q0, Q0, Q2); |
4012 | 3982 |
4013 // Reciprocal. | 3983 // Reciprocal. |
4014 __ vmovq(Q1, Q0); | 3984 __ vmovq(Q1, Q0); |
4015 // Reciprocal estimate. | 3985 // Reciprocal estimate. |
4016 __ vrecpeqs(Q0, Q1); | 3986 __ vrecpeqs(Q0, Q1); |
4017 // 2 Newton-Raphson steps. | 3987 // 2 Newton-Raphson steps. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4132 | 4102 |
4133 | 4103 |
4134 // Called from assembler_test.cc. | 4104 // Called from assembler_test.cc. |
4135 // LR: return address. | 4105 // LR: return address. |
4136 // R0: value. | 4106 // R0: value. |
4137 // R1: growable array. | 4107 // R1: growable array. |
4138 // R2: current thread. | 4108 // R2: current thread. |
4139 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { | 4109 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { |
4140 __ PushList((1 << LR) | (1 << THR)); | 4110 __ PushList((1 << LR) | (1 << THR)); |
4141 __ mov(THR, Operand(R2)); | 4111 __ mov(THR, Operand(R2)); |
4142 __ StoreIntoObject(R1, | 4112 __ StoreIntoObject(R1, FieldAddress(R1, GrowableObjectArray::data_offset()), |
4143 FieldAddress(R1, GrowableObjectArray::data_offset()), | |
4144 R0); | 4113 R0); |
4145 __ PopList((1 << LR) | (1 << THR)); | 4114 __ PopList((1 << LR) | (1 << THR)); |
4146 __ Ret(); | 4115 __ Ret(); |
4147 } | 4116 } |
4148 | 4117 |
4149 } // namespace dart | 4118 } // namespace dart |
4150 | 4119 |
4151 #endif // defined TARGET_ARCH_ARM | 4120 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |