Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
assembler_arm_test.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/globals.h"
6#if defined(TARGET_ARCH_ARM)
7
10#include "vm/cpu.h"
11#include "vm/os.h"
12#include "vm/unit_test.h"
13#include "vm/virtual_memory.h"
14
15namespace dart {
16namespace compiler {
17
18TEST_CASE(ReciprocalOps) {
19 EXPECT_EQ(true, isinf(ReciprocalEstimate(-0.0f)));
20 EXPECT_EQ(true, signbit(ReciprocalEstimate(-0.0f)));
21 EXPECT_EQ(true, isinf(ReciprocalEstimate(0.0f)));
22 EXPECT_EQ(true, !signbit(ReciprocalEstimate(0.0f)));
23 EXPECT_EQ(true, isnan(ReciprocalEstimate(NAN)));
24
25#define AS_UINT32(v) (bit_cast<uint32_t, float>(v))
26#define EXPECT_BITWISE_EQ(a, b) EXPECT_EQ(AS_UINT32(a), AS_UINT32(b))
27
28 EXPECT_BITWISE_EQ(0.0f, ReciprocalEstimate(kPosInfinity));
29 EXPECT_BITWISE_EQ(-0.0f, ReciprocalEstimate(kNegInfinity));
30 EXPECT_BITWISE_EQ(2.0f, ReciprocalStep(0.0f, kPosInfinity));
31 EXPECT_BITWISE_EQ(2.0f, ReciprocalStep(0.0f, kNegInfinity));
32 EXPECT_BITWISE_EQ(2.0f, ReciprocalStep(-0.0f, kPosInfinity));
33 EXPECT_BITWISE_EQ(2.0f, ReciprocalStep(-0.0f, kNegInfinity));
34 EXPECT_BITWISE_EQ(2.0f, ReciprocalStep(kPosInfinity, 0.0f));
35 EXPECT_BITWISE_EQ(2.0f, ReciprocalStep(kNegInfinity, 0.0f));
36 EXPECT_BITWISE_EQ(2.0f, ReciprocalStep(kPosInfinity, -0.0f));
37 EXPECT_BITWISE_EQ(2.0f, ReciprocalStep(kNegInfinity, -0.0f));
38 EXPECT_EQ(true, isnan(ReciprocalStep(NAN, 1.0f)));
39 EXPECT_EQ(true, isnan(ReciprocalStep(1.0f, NAN)));
40
41 EXPECT_EQ(true, isnan(ReciprocalSqrtEstimate(-1.0f)));
42 EXPECT_EQ(true, isnan(ReciprocalSqrtEstimate(kNegInfinity)));
43 EXPECT_EQ(true, isnan(ReciprocalSqrtEstimate(-1.0f)));
44 EXPECT_EQ(true, isinf(ReciprocalSqrtEstimate(-0.0f)));
45 EXPECT_EQ(true, signbit(ReciprocalSqrtEstimate(-0.0f)));
46 EXPECT_EQ(true, isinf(ReciprocalSqrtEstimate(0.0f)));
47 EXPECT_EQ(true, !signbit(ReciprocalSqrtEstimate(0.0f)));
48 EXPECT_EQ(true, isnan(ReciprocalSqrtEstimate(NAN)));
49 EXPECT_BITWISE_EQ(0.0f, ReciprocalSqrtEstimate(kPosInfinity));
50
51 EXPECT_BITWISE_EQ(1.5f, ReciprocalSqrtStep(0.0f, kPosInfinity));
52 EXPECT_BITWISE_EQ(1.5f, ReciprocalSqrtStep(0.0f, kNegInfinity));
53 EXPECT_BITWISE_EQ(1.5f, ReciprocalSqrtStep(-0.0f, kPosInfinity));
54 EXPECT_BITWISE_EQ(1.5f, ReciprocalSqrtStep(-0.0f, kNegInfinity));
55 EXPECT_BITWISE_EQ(1.5f, ReciprocalSqrtStep(kPosInfinity, 0.0f));
56 EXPECT_BITWISE_EQ(1.5f, ReciprocalSqrtStep(kNegInfinity, 0.0f));
57 EXPECT_BITWISE_EQ(1.5f, ReciprocalSqrtStep(kPosInfinity, -0.0f));
58 EXPECT_BITWISE_EQ(1.5f, ReciprocalSqrtStep(kNegInfinity, -0.0f));
59 EXPECT_EQ(true, isnan(ReciprocalSqrtStep(NAN, 1.0f)));
60 EXPECT_EQ(true, isnan(ReciprocalSqrtStep(1.0f, NAN)));
61
62#undef AS_UINT32
63#undef EXPECT_BITWISE_EQ
64}
65
66#define __ assembler->
67
68#if defined(PRODUCT)
69#define EXPECT_DISASSEMBLY(expected)
70#else
71#define EXPECT_DISASSEMBLY(expected) \
72 EXPECT_STREQ(expected, test->RelativeDisassembly())
73#endif
74
75ASSEMBLER_TEST_GENERATE(Simple, assembler) {
76 __ mov(R0, Operand(42));
77 __ Ret();
78}
79
80ASSEMBLER_TEST_RUN(Simple, test) {
81 typedef int (*SimpleCode)() DART_UNUSED;
82 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
83}
84
85ASSEMBLER_TEST_GENERATE(MoveNegated, assembler) {
86 __ mvn_(R0, Operand(42));
87 __ Ret();
88}
89
90ASSEMBLER_TEST_RUN(MoveNegated, test) {
91 EXPECT(test != nullptr);
92 typedef int (*MoveNegated)() DART_UNUSED;
93 EXPECT_EQ(~42, EXECUTE_TEST_CODE_INT32(MoveNegated, test->entry()));
94}
95
96ASSEMBLER_TEST_GENERATE(MoveRotImm, assembler) {
97 Operand o;
98 EXPECT(Operand::CanHold(0x00550000, &o));
99 __ mov(R0, o);
100 EXPECT(Operand::CanHold(0x30000003, &o));
101 __ add(R0, R0, o);
102 __ Ret();
103}
104
105ASSEMBLER_TEST_RUN(MoveRotImm, test) {
106 EXPECT(test != nullptr);
107 typedef int (*MoveRotImm)() DART_UNUSED;
108 EXPECT_EQ(0x30550003, EXECUTE_TEST_CODE_INT32(MoveRotImm, test->entry()));
109}
110
111ASSEMBLER_TEST_GENERATE(MovImm16, assembler) {
112 __ LoadPatchableImmediate(R0, 0x12345678);
113 __ Ret();
114}
115
116ASSEMBLER_TEST_RUN(MovImm16, test) {
117 EXPECT(test != nullptr);
118 typedef int (*MovImm16)() DART_UNUSED;
119 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INT32(MovImm16, test->entry()));
120}
121
122ASSEMBLER_TEST_GENERATE(LoadImmediate, assembler) {
123 __ mov(R0, Operand(0));
124 __ cmp(R0, Operand(0));
125 __ LoadImmediate(R0, 0x12345678, EQ);
126 __ LoadImmediate(R0, 0x87654321, NE);
127 __ Ret();
128}
129
130ASSEMBLER_TEST_RUN(LoadImmediate, test) {
131 EXPECT(test != nullptr);
132 typedef int (*LoadImmediate)() DART_UNUSED;
133 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INT32(LoadImmediate, test->entry()));
134}
135
136ASSEMBLER_TEST_GENERATE(LoadHalfWordUnaligned, assembler) {
137 __ LoadHalfWordUnaligned(R1, R0, TMP);
138 __ mov(R0, Operand(R1));
139 __ Ret();
140}
141
142ASSEMBLER_TEST_RUN(LoadHalfWordUnaligned, test) {
143 EXPECT(test != nullptr);
144 typedef intptr_t (*LoadHalfWordUnaligned)(intptr_t) DART_UNUSED;
145 uint8_t buffer[4] = {
146 0x89,
147 0xAB,
148 0xCD,
149 0xEF,
150 };
151
152 EXPECT_EQ(
153 static_cast<int16_t>(static_cast<uint16_t>(0xAB89)),
154 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadHalfWordUnaligned, test->entry(),
155 reinterpret_cast<intptr_t>(&buffer[0])));
156 EXPECT_EQ(
157 static_cast<int16_t>(static_cast<uint16_t>(0xCDAB)),
158 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadHalfWordUnaligned, test->entry(),
159 reinterpret_cast<intptr_t>(&buffer[1])));
160}
161
162ASSEMBLER_TEST_GENERATE(LoadHalfWordUnsignedUnaligned, assembler) {
163 __ LoadHalfWordUnsignedUnaligned(R1, R0, TMP);
164 __ mov(R0, Operand(R1));
165 __ Ret();
166}
167
168ASSEMBLER_TEST_RUN(LoadHalfWordUnsignedUnaligned, test) {
169 EXPECT(test != nullptr);
170 typedef intptr_t (*LoadHalfWordUnsignedUnaligned)(intptr_t) DART_UNUSED;
171 uint8_t buffer[4] = {
172 0x89,
173 0xAB,
174 0xCD,
175 0xEF,
176 };
177
178 EXPECT_EQ(0xAB89, EXECUTE_TEST_CODE_INTPTR_INTPTR(
179 LoadHalfWordUnsignedUnaligned, test->entry(),
180 reinterpret_cast<intptr_t>(&buffer[0])));
181 EXPECT_EQ(0xCDAB, EXECUTE_TEST_CODE_INTPTR_INTPTR(
182 LoadHalfWordUnsignedUnaligned, test->entry(),
183 reinterpret_cast<intptr_t>(&buffer[1])));
184}
185
186ASSEMBLER_TEST_GENERATE(StoreHalfWordUnaligned, assembler) {
187 __ LoadImmediate(R1, 0x1111ABCD);
188 __ StoreHalfWordUnaligned(R1, R0, TMP);
189 __ mov(R0, Operand(R1));
190 __ Ret();
191}
192
193ASSEMBLER_TEST_RUN(StoreHalfWordUnaligned, test) {
194 EXPECT(test != nullptr);
195 typedef intptr_t (*StoreHalfWordUnaligned)(intptr_t) DART_UNUSED;
196 uint8_t buffer[4] = {
197 0,
198 0,
199 0,
200 0,
201 };
202
203 EXPECT_EQ(0x1111ABCD, EXECUTE_TEST_CODE_INTPTR_INTPTR(
204 StoreHalfWordUnaligned, test->entry(),
205 reinterpret_cast<intptr_t>(&buffer[0])));
206 EXPECT_EQ(0xCD, buffer[0]);
207 EXPECT_EQ(0xAB, buffer[1]);
208 EXPECT_EQ(0, buffer[2]);
209
210 EXPECT_EQ(0x1111ABCD, EXECUTE_TEST_CODE_INTPTR_INTPTR(
211 StoreHalfWordUnaligned, test->entry(),
212 reinterpret_cast<intptr_t>(&buffer[1])));
213 EXPECT_EQ(0xCD, buffer[1]);
214 EXPECT_EQ(0xAB, buffer[2]);
215 EXPECT_EQ(0, buffer[3]);
216}
217
218ASSEMBLER_TEST_GENERATE(LoadWordUnaligned, assembler) {
219 __ LoadWordUnaligned(R1, R0, TMP);
220 __ mov(R0, Operand(R1));
221 __ Ret();
222}
223
224ASSEMBLER_TEST_RUN(LoadWordUnaligned, test) {
225 EXPECT(test != nullptr);
226 typedef intptr_t (*LoadWordUnaligned)(intptr_t) DART_UNUSED;
227 uint8_t buffer[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0};
228
229 EXPECT_EQ(
230 static_cast<intptr_t>(0x78563412),
231 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadWordUnaligned, test->entry(),
232 reinterpret_cast<intptr_t>(&buffer[0])));
233 EXPECT_EQ(
234 static_cast<intptr_t>(0x9A785634),
235 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadWordUnaligned, test->entry(),
236 reinterpret_cast<intptr_t>(&buffer[1])));
237 EXPECT_EQ(
238 static_cast<intptr_t>(0xBC9A7856),
239 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadWordUnaligned, test->entry(),
240 reinterpret_cast<intptr_t>(&buffer[2])));
241 EXPECT_EQ(
242 static_cast<intptr_t>(0xDEBC9A78),
243 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadWordUnaligned, test->entry(),
244 reinterpret_cast<intptr_t>(&buffer[3])));
245}
246
247ASSEMBLER_TEST_GENERATE(StoreWordUnaligned, assembler) {
248 __ LoadImmediate(R1, 0x12345678);
249 __ StoreWordUnaligned(R1, R0, TMP);
250 __ mov(R0, Operand(R1));
251 __ Ret();
252}
253
254ASSEMBLER_TEST_RUN(StoreWordUnaligned, test) {
255 EXPECT(test != nullptr);
256 typedef intptr_t (*StoreWordUnaligned)(intptr_t) DART_UNUSED;
257 uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
258
259 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR(
260 StoreWordUnaligned, test->entry(),
261 reinterpret_cast<intptr_t>(&buffer[0])));
262 EXPECT_EQ(0x78, buffer[0]);
263 EXPECT_EQ(0x56, buffer[1]);
264 EXPECT_EQ(0x34, buffer[2]);
265 EXPECT_EQ(0x12, buffer[3]);
266
267 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR(
268 StoreWordUnaligned, test->entry(),
269 reinterpret_cast<intptr_t>(&buffer[1])));
270 EXPECT_EQ(0x78, buffer[1]);
271 EXPECT_EQ(0x56, buffer[2]);
272 EXPECT_EQ(0x34, buffer[3]);
273 EXPECT_EQ(0x12, buffer[4]);
274
275 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR(
276 StoreWordUnaligned, test->entry(),
277 reinterpret_cast<intptr_t>(&buffer[2])));
278 EXPECT_EQ(0x78, buffer[2]);
279 EXPECT_EQ(0x56, buffer[3]);
280 EXPECT_EQ(0x34, buffer[4]);
281 EXPECT_EQ(0x12, buffer[5]);
282
283 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR(
284 StoreWordUnaligned, test->entry(),
285 reinterpret_cast<intptr_t>(&buffer[3])));
286 EXPECT_EQ(0x78, buffer[3]);
287 EXPECT_EQ(0x56, buffer[4]);
288 EXPECT_EQ(0x34, buffer[5]);
289 EXPECT_EQ(0x12, buffer[6]);
290}
291
292ASSEMBLER_TEST_GENERATE(Vmov, assembler) {
293 __ mov(R3, Operand(43));
294 __ mov(R1, Operand(41));
295 __ vmovsrr(S1, R1, R3); // S1:S2 = 41:43
296 __ vmovs(S0, S2); // S0 = S2, S0:S1 == 43:41
297 __ vmovd(D2, D0); // D2 = D0, S4:S5 == 43:41
298 __ vmovrs(R3, S5); // R3 = S5, R3 == 41
299 __ vmovrrs(R1, R2, S4); // R1:R2 = S4:S5, R1:R2 == 43:41
300 __ vmovdrr(D3, R3, R2); // D3 = R3:R2, S6:S7 == 41:41
301 __ vmovdr(D3, 1, R1); // D3[1] == S7 = R1, S6:S7 == 41:43
302 __ vmovrrd(R0, R1, D3); // R0:R1 = D3, R0:R1 == 41:43
303 __ sub(R0, R1, Operand(R0)); // 43-41
304 __ Ret();
305}
306
308 EXPECT(test != nullptr);
309 typedef int (*Vmov)() DART_UNUSED;
310 EXPECT_EQ(2, EXECUTE_TEST_CODE_INT32(Vmov, test->entry()));
311}
312
313ASSEMBLER_TEST_GENERATE(SingleVLoadStore, assembler) {
314 __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f));
315 __ mov(R2, Operand(SP));
316 __ str(R0, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
317 __ vldrs(S0, Address(R2, (-target::kWordSize * 30)));
318 __ vadds(S0, S0, S0);
319 __ vstrs(S0, Address(R2, (-target::kWordSize * 30)));
320 __ ldr(R0, Address(SP, (target::kWordSize * 30), Address::PostIndex));
321 __ Ret();
322}
323
324ASSEMBLER_TEST_RUN(SingleVLoadStore, test) {
325 EXPECT(test != nullptr);
326 typedef float (*SingleVLoadStore)() DART_UNUSED;
327 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry());
328 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
329}
330
331ASSEMBLER_TEST_GENERATE(SingleVShiftLoadStore, assembler) {
332 __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f));
333 __ mov(R2, Operand(SP));
334 // Expressing __str(R0, Address(SP, (-kWordSize * 32), Address::PreIndex));
335 // as:
336 __ mov(R1, Operand(target::kWordSize));
337 __ str(R0, Address(SP, R1, LSL, 5, Address::NegPreIndex));
338 __ vldrs(S0, Address(R2, (-target::kWordSize * 32)));
339 __ vadds(S0, S0, S0);
340 __ vstrs(S0, Address(R2, (-target::kWordSize * 32)));
341 // Expressing __ldr(R0, Address(SP, (kWordSize * 32), Address::PostIndex));
342 // as:
343 __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex));
344 __ Ret();
345}
346
347ASSEMBLER_TEST_RUN(SingleVShiftLoadStore, test) {
348 EXPECT(test != nullptr);
349 typedef float (*SingleVLoadStore)() DART_UNUSED;
350 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry());
351 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
352}
353
354ASSEMBLER_TEST_GENERATE(DoubleVLoadStore, assembler) {
355 int64_t value = bit_cast<int64_t, double>(12.3);
356 __ LoadImmediate(R0, Utils::Low32Bits(value));
357 __ LoadImmediate(R1, Utils::High32Bits(value));
358 __ mov(R2, Operand(SP));
359 __ str(R0, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
360 __ str(R1, Address(R2, (-target::kWordSize * 29)));
361 __ vldrd(D0, Address(R2, (-target::kWordSize * 30)));
362 __ vaddd(D0, D0, D0);
363 __ vstrd(D0, Address(R2, (-target::kWordSize * 30)));
364 __ ldr(R1, Address(R2, (-target::kWordSize * 29)));
365 __ ldr(R0, Address(SP, (target::kWordSize * 30), Address::PostIndex));
366 __ Ret();
367}
368
369ASSEMBLER_TEST_RUN(DoubleVLoadStore, test) {
370 EXPECT(test != nullptr);
371 typedef double (*DoubleVLoadStore)() DART_UNUSED;
372 float res = EXECUTE_TEST_CODE_DOUBLE(DoubleVLoadStore, test->entry());
373 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
374}
375
376ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) {
377 __ LoadSImmediate(S0, 12.3f);
378 __ LoadSImmediate(S1, 3.4f);
379 __ vnegs(S0, S0); // -12.3f
380 __ vabss(S0, S0); // 12.3f
381 __ vadds(S0, S0, S1); // 15.7f
382 __ vmuls(S0, S0, S1); // 53.38f
383 __ vsubs(S0, S0, S1); // 49.98f
384 __ vdivs(S0, S0, S1); // 14.7f
385 __ vsqrts(S0, S0); // 3.8340579f
386 __ Ret();
387}
388
389ASSEMBLER_TEST_RUN(SingleFPOperations, test) {
390 EXPECT(test != nullptr);
391 typedef float (*SingleFPOperations)() DART_UNUSED;
392 float res = EXECUTE_TEST_CODE_FLOAT(SingleFPOperations, test->entry());
393 EXPECT_FLOAT_EQ(3.8340579f, res, 0.001f);
394}
395
396ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) {
397 __ LoadDImmediate(D0, 12.3, R0);
398 __ LoadDImmediate(D1, 3.4, R0);
399 __ vnegd(D0, D0); // -12.3
400 __ vabsd(D0, D0); // 12.3
401 __ vaddd(D0, D0, D1); // 15.7
402 __ vmuld(D0, D0, D1); // 53.38
403 __ vsubd(D0, D0, D1); // 49.98
404 __ vdivd(D0, D0, D1); // 14.7
405 __ vsqrtd(D0, D0); // 3.8340579
406 __ Ret();
407}
408
409ASSEMBLER_TEST_RUN(DoubleFPOperations, test) {
410 EXPECT(test != nullptr);
411 typedef double (*DoubleFPOperations)() DART_UNUSED;
412 double res = EXECUTE_TEST_CODE_DOUBLE(DoubleFPOperations, test->entry());
413 EXPECT_FLOAT_EQ(3.8340579, res, 0.001);
414}
415
416ASSEMBLER_TEST_GENERATE(DoubleSqrtNeg, assembler) {
417 // Check that sqrt of a negative double gives NaN.
418 __ LoadDImmediate(D1, -1.0, R0);
419 __ vsqrtd(D0, D1);
420 __ vcmpd(D0, D0);
421 __ vmstat();
422 __ mov(R0, Operand(1), VS);
423 __ mov(R0, Operand(0), VC);
424 __ Ret();
425}
426
427ASSEMBLER_TEST_RUN(DoubleSqrtNeg, test) {
428 EXPECT(test != nullptr);
429 typedef int (*DoubleSqrtNeg)() DART_UNUSED;
430 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(DoubleSqrtNeg, test->entry()));
431}
432
433ASSEMBLER_TEST_GENERATE(IntToDoubleConversion, assembler) {
434 __ mov(R3, Operand(6));
435 __ vmovsr(S3, R3);
436 __ vcvtdi(D0, S3);
437 __ Ret();
438}
439
440ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) {
441 EXPECT(test != nullptr);
442 typedef double (*IntToDoubleConversionCode)() DART_UNUSED;
443 double res =
444 EXECUTE_TEST_CODE_DOUBLE(IntToDoubleConversionCode, test->entry());
445 EXPECT_FLOAT_EQ(6.0, res, 0.001);
446}
447
448ASSEMBLER_TEST_GENERATE(LongToDoubleConversion, assembler) {
449 int64_t value = 60000000000LL;
450 __ LoadImmediate(R0, Utils::Low32Bits(value));
451 __ LoadImmediate(R1, Utils::High32Bits(value));
452 __ vmovsr(S0, R0);
453 __ vmovsr(S2, R1);
454 __ vcvtdu(D0, S0);
455 __ vcvtdi(D1, S2);
456 __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0);
457 __ vmlad(D0, D1, D2);
458 __ Ret();
459}
460
461ASSEMBLER_TEST_RUN(LongToDoubleConversion, test) {
462 EXPECT(test != nullptr);
463 typedef double (*LongToDoubleConversionCode)() DART_UNUSED;
464 double res =
465 EXECUTE_TEST_CODE_DOUBLE(LongToDoubleConversionCode, test->entry());
466 EXPECT_FLOAT_EQ(60000000000.0, res, 0.001);
467}
468
469ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) {
470 __ mov(R3, Operand(6));
471 __ vmovsr(S3, R3);
472 __ vcvtsi(S0, S3);
473 __ Ret();
474}
475
476ASSEMBLER_TEST_RUN(IntToFloatConversion, test) {
477 EXPECT(test != nullptr);
478 typedef float (*IntToFloatConversionCode)() DART_UNUSED;
479 float res = EXECUTE_TEST_CODE_FLOAT(IntToFloatConversionCode, test->entry());
480 EXPECT_FLOAT_EQ(6.0, res, 0.001);
481}
482
483ASSEMBLER_TEST_GENERATE(FloatToIntConversion, assembler) {
484 __ vcvtis(S1, S0);
485 __ vmovrs(R0, S1);
486 __ Ret();
487}
488
489ASSEMBLER_TEST_RUN(FloatToIntConversion, test) {
490 EXPECT(test != nullptr);
491 typedef int (*FloatToIntConversion)(float arg) DART_UNUSED;
492 EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(),
493 12.8f));
494 EXPECT_EQ(INT32_MIN, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion,
495 test->entry(), -FLT_MAX));
496 EXPECT_EQ(INT32_MAX, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion,
497 test->entry(), FLT_MAX));
498}
499
500ASSEMBLER_TEST_GENERATE(DoubleToIntConversion, assembler) {
501 __ vcvtid(S0, D0);
502 __ vmovrs(R0, S0);
503 __ Ret();
504}
505
506ASSEMBLER_TEST_RUN(DoubleToIntConversion, test) {
507 typedef int (*DoubleToIntConversion)(double arg) DART_UNUSED;
508 EXPECT(test != nullptr);
509 EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(),
510 12.8));
511 EXPECT_EQ(INT32_MIN, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion,
512 test->entry(), -DBL_MAX));
513 EXPECT_EQ(INT32_MAX, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion,
514 test->entry(), DBL_MAX));
515}
516
517ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) {
518 __ LoadSImmediate(S2, 12.8f);
519 __ vcvtds(D0, S2);
520 __ Ret();
521}
522
523ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) {
524 typedef double (*FloatToDoubleConversionCode)() DART_UNUSED;
525 EXPECT(test != nullptr);
526 double res =
527 EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, test->entry());
528 EXPECT_FLOAT_EQ(12.8, res, 0.001);
529}
530
531ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) {
532 __ LoadDImmediate(D1, 12.8, R0);
533 __ vcvtsd(S0, D1);
534 __ Ret();
535}
536
537ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) {
538 EXPECT(test != nullptr);
539 typedef float (*DoubleToFloatConversionCode)() DART_UNUSED;
540 float res =
541 EXECUTE_TEST_CODE_FLOAT(DoubleToFloatConversionCode, test->entry());
542 EXPECT_FLOAT_EQ(12.8, res, 0.001);
543}
544
545ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) {
546 // Test 12.3f vs 12.5f.
547 __ LoadSImmediate(S0, 12.3f);
548 __ LoadSImmediate(S1, 12.5f);
549
550 // Count errors in R0. R0 is zero if no errors found.
551 __ mov(R0, Operand(0));
552 __ vcmps(S0, S1);
553 __ vmstat();
554 __ add(R0, R0, Operand(1), VS); // Error if unordered (Nan).
555 __ add(R0, R0, Operand(2), GT); // Error if greater.
556 __ add(R0, R0, Operand(4), EQ); // Error if equal.
557 __ add(R0, R0, Operand(8), PL); // Error if not less.
558
559 // Test NaN.
560 // Create NaN by dividing 0.0f/0.0f.
561 __ LoadSImmediate(S1, 0.0f);
562 __ vdivs(S1, S1, S1);
563 __ vcmps(S1, S1);
564 __ vmstat();
565 // Error if not unordered (not Nan).
566 __ add(R0, R0, Operand(16), VC);
567 // R0 is 0 if all tests passed.
568 __ Ret();
569}
570
571ASSEMBLER_TEST_RUN(FloatCompare, test) {
572 EXPECT(test != nullptr);
573 typedef int (*FloatCompare)() DART_UNUSED;
574 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(FloatCompare, test->entry()));
575}
576
577ASSEMBLER_TEST_GENERATE(DoubleCompare, assembler) {
578 // Test 12.3 vs 12.5.
579 __ LoadDImmediate(D0, 12.3, R1);
580 __ LoadDImmediate(D1, 12.5, R1);
581
582 // Count errors in R0. R0 is zero if no errors found.
583 __ mov(R0, Operand(0));
584 __ vcmpd(D0, D1);
585 __ vmstat();
586 __ add(R0, R0, Operand(1), VS); // Error if unordered (Nan).
587 __ add(R0, R0, Operand(2), GT); // Error if greater.
588 __ add(R0, R0, Operand(4), EQ); // Error if equal.
589 __ add(R0, R0, Operand(8), PL); // Error if not less.
590
591 // Test NaN.
592 // Create NaN by dividing 0.0/0.0.
593 __ LoadDImmediate(D1, 0.0, R1);
594 __ vdivd(D1, D1, D1);
595 __ vcmpd(D1, D1);
596 __ vmstat();
597 // Error if not unordered (not Nan).
598 __ add(R0, R0, Operand(16), VC);
599 // R0 is 0 if all tests passed.
600 __ Ret();
601}
602
603ASSEMBLER_TEST_RUN(DoubleCompare, test) {
604 EXPECT(test != nullptr);
605 typedef int (*DoubleCompare)() DART_UNUSED;
606 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(DoubleCompare, test->entry()));
607}
608
609ASSEMBLER_TEST_GENERATE(Loop, assembler) {
610 Label loop_entry;
611 __ mov(R0, Operand(1));
612 __ mov(R1, Operand(2));
613 __ Bind(&loop_entry);
614 __ mov(R0, Operand(R0, LSL, 1));
615 __ movs(R1, Operand(R1, LSR, 1));
616 __ b(&loop_entry, NE);
617 __ Ret();
618}
619
621 EXPECT(test != nullptr);
622 typedef int (*Loop)() DART_UNUSED;
623 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Loop, test->entry()));
624}
625
626ASSEMBLER_TEST_GENERATE(ForwardBranch, assembler) {
627 Label skip;
628 __ mov(R0, Operand(42));
629 __ b(&skip);
630 __ mov(R0, Operand(11));
631 __ Bind(&skip);
632 __ Ret();
633}
634
635ASSEMBLER_TEST_RUN(ForwardBranch, test) {
636 EXPECT(test != nullptr);
637 typedef int (*ForwardBranch)() DART_UNUSED;
638 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(ForwardBranch, test->entry()));
639}
640
641ASSEMBLER_TEST_GENERATE(Loop2, assembler) {
642 Label loop_entry;
643 __ set_use_far_branches(true);
644 __ mov(R0, Operand(1));
645 __ mov(R1, Operand(2));
646 __ Bind(&loop_entry);
647 __ mov(R0, Operand(R0, LSL, 1));
648 __ movs(R1, Operand(R1, LSR, 1));
649 __ b(&loop_entry, NE);
650 __ Ret();
651}
652
653ASSEMBLER_TEST_RUN(Loop2, test) {
654 EXPECT(test != nullptr);
655 typedef int (*Loop)() DART_UNUSED;
656 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Loop, test->entry()));
657}
658
659ASSEMBLER_TEST_GENERATE(Loop3, assembler) {
660 Label loop_entry;
661 __ set_use_far_branches(true);
662 __ mov(R0, Operand(1));
663 __ mov(R1, Operand(2));
664 __ Bind(&loop_entry);
665 for (int i = 0; i < (1 << 22); i++) {
666 __ nop();
667 }
668 __ mov(R0, Operand(R0, LSL, 1));
669 __ movs(R1, Operand(R1, LSR, 1));
670 __ b(&loop_entry, NE);
671 __ Ret();
672}
673
674ASSEMBLER_TEST_RUN(Loop3, test) {
675 EXPECT(test != nullptr);
676 typedef int (*Loop)() DART_UNUSED;
677 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Loop, test->entry()));
678}
679
680ASSEMBLER_TEST_GENERATE(LoadStore, assembler) {
681 __ mov(R1, Operand(123));
682 __ Push(R1);
683 __ Pop(R0);
684 __ Ret();
685}
686
687ASSEMBLER_TEST_RUN(LoadStore, test) {
688 EXPECT(test != nullptr);
689 typedef int (*LoadStore)() DART_UNUSED;
690 EXPECT_EQ(123, EXECUTE_TEST_CODE_INT32(LoadStore, test->entry()));
691}
692
693ASSEMBLER_TEST_GENERATE(PushRegisterPair, assembler) {
694 __ mov(R2, Operand(12));
695 __ mov(R3, Operand(21));
696 __ PushRegisterPair(R2, R3);
697 __ Pop(R0);
698 __ Pop(R1);
699 __ Ret();
700}
701
702ASSEMBLER_TEST_RUN(PushRegisterPair, test) {
703 EXPECT(test != nullptr);
704 typedef int (*PushRegisterPair)() DART_UNUSED;
705 EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32(PushRegisterPair, test->entry()));
706}
707
708ASSEMBLER_TEST_GENERATE(PushRegisterPairReversed, assembler) {
709 __ mov(R3, Operand(12));
710 __ mov(R2, Operand(21));
711 __ PushRegisterPair(R3, R2);
712 __ Pop(R0);
713 __ Pop(R1);
714 __ Ret();
715}
716
717ASSEMBLER_TEST_RUN(PushRegisterPairReversed, test) {
718 EXPECT(test != nullptr);
719 typedef int (*PushRegisterPairReversed)() DART_UNUSED;
720 EXPECT_EQ(12,
721 EXECUTE_TEST_CODE_INT32(PushRegisterPairReversed, test->entry()));
722}
723
724ASSEMBLER_TEST_GENERATE(PopRegisterPair, assembler) {
725 __ mov(R2, Operand(12));
726 __ mov(R3, Operand(21));
727 __ Push(R3);
728 __ Push(R2);
729 __ PopRegisterPair(R0, R1);
730 __ Ret();
731}
732
733ASSEMBLER_TEST_RUN(PopRegisterPair, test) {
734 EXPECT(test != nullptr);
735 typedef int (*PopRegisterPair)() DART_UNUSED;
736 EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32(PopRegisterPair, test->entry()));
737}
738
739ASSEMBLER_TEST_GENERATE(PopRegisterPairReversed, assembler) {
740 __ mov(R3, Operand(12));
741 __ mov(R2, Operand(21));
742 __ Push(R3);
743 __ Push(R2);
744 __ PopRegisterPair(R1, R0);
745 __ Ret();
746}
747
748ASSEMBLER_TEST_RUN(PopRegisterPairReversed, test) {
749 EXPECT(test != nullptr);
750 typedef int (*PopRegisterPairReversed)() DART_UNUSED;
751 EXPECT_EQ(12,
752 EXECUTE_TEST_CODE_INT32(PopRegisterPairReversed, test->entry()));
753}
754
755ASSEMBLER_TEST_GENERATE(Semaphore, assembler) {
756 __ mov(R0, Operand(40));
757 __ mov(R1, Operand(42));
758 __ Push(R0);
759 Label retry;
760 __ Bind(&retry);
761 __ ldrex(R0, SP);
762 __ strex(IP, R1, SP); // IP == 0, success
763 __ tst(IP, Operand(0));
764 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex.
765 __ Pop(R0); // 42
766 __ Ret();
767}
768
769ASSEMBLER_TEST_RUN(Semaphore, test) {
770 EXPECT(test != nullptr);
771 typedef int (*Semaphore)() DART_UNUSED;
772 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Semaphore, test->entry()));
773}
774
775ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) {
776 __ mov(R0, Operand(40));
777 __ mov(R1, Operand(42));
778 __ Push(R0);
779 __ ldrex(R0, SP);
780 __ clrex(); // Simulate a context switch.
781 __ strex(IP, R1, SP); // IP == 1, failure
782 __ Pop(R0); // 40
783 __ add(R0, R0, Operand(IP));
784 __ Ret();
785}
786
787ASSEMBLER_TEST_RUN(FailedSemaphore, test) {
788 EXPECT(test != nullptr);
789 typedef int (*FailedSemaphore)() DART_UNUSED;
790 EXPECT_EQ(41, EXECUTE_TEST_CODE_INT32(FailedSemaphore, test->entry()));
791}
792
793ASSEMBLER_TEST_GENERATE(AddSub, assembler) {
794 __ mov(R1, Operand(40));
795 __ sub(R1, R1, Operand(2));
796 __ add(R0, R1, Operand(4));
797 __ rsbs(R0, R0, Operand(100));
798 __ rsc(R0, R0, Operand(100));
799 __ Ret();
800}
801
802ASSEMBLER_TEST_RUN(AddSub, test) {
803 EXPECT(test != nullptr);
804 typedef int (*AddSub)() DART_UNUSED;
805 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(AddSub, test->entry()));
806}
807
808ASSEMBLER_TEST_GENERATE(AddCarry, assembler) {
809 __ LoadImmediate(R2, 0xFFFFFFFF);
810 __ mov(R1, Operand(1));
811 __ mov(R0, Operand(0));
812 __ adds(R2, R2, Operand(R1));
813 __ adcs(R0, R0, Operand(R0));
814 __ Ret();
815}
816
817ASSEMBLER_TEST_RUN(AddCarry, test) {
818 EXPECT(test != nullptr);
819 typedef int (*AddCarry)() DART_UNUSED;
820 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarry, test->entry()));
821}
822
823ASSEMBLER_TEST_GENERATE(AddCarryInOut, assembler) {
824 __ LoadImmediate(R2, 0xFFFFFFFF);
825 __ mov(R1, Operand(1));
826 __ mov(R0, Operand(0));
827 __ adds(IP, R2, Operand(R1)); // c_out = 1.
828 __ adcs(IP, R2, Operand(R0)); // c_in = 1, c_out = 1.
829 __ adc(R0, R0, Operand(R0)); // c_in = 1.
830 __ Ret();
831}
832
833ASSEMBLER_TEST_RUN(AddCarryInOut, test) {
834 EXPECT(test != nullptr);
835 typedef int (*AddCarryInOut)() DART_UNUSED;
836 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarryInOut, test->entry()));
837}
838
839ASSEMBLER_TEST_GENERATE(SubCarry, assembler) {
840 __ LoadImmediate(R2, 0x0);
841 __ mov(R1, Operand(1));
842 __ mov(R0, Operand(0));
843 __ subs(R2, R2, Operand(R1));
844 __ sbcs(R0, R0, Operand(R0));
845 __ Ret();
846}
847
848ASSEMBLER_TEST_RUN(SubCarry, test) {
849 EXPECT(test != nullptr);
850 typedef int (*SubCarry)() DART_UNUSED;
851 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarry, test->entry()));
852}
853
854ASSEMBLER_TEST_GENERATE(SubCarryInOut, assembler) {
855 __ mov(R1, Operand(1));
856 __ mov(R0, Operand(0));
857 __ subs(IP, R0, Operand(R1)); // c_out = 1.
858 __ sbcs(IP, R0, Operand(R0)); // c_in = 1, c_out = 1.
859 __ sbc(R0, R0, Operand(R0)); // c_in = 1.
860 __ Ret();
861}
862
863ASSEMBLER_TEST_RUN(SubCarryInOut, test) {
864 EXPECT(test != nullptr);
865 typedef int (*SubCarryInOut)() DART_UNUSED;
866 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarryInOut, test->entry()));
867}
868
869ASSEMBLER_TEST_GENERATE(Overflow, assembler) {
870 __ LoadImmediate(R0, 0xFFFFFFFF);
871 __ LoadImmediate(R1, 0x7FFFFFFF);
872 __ adds(IP, R0, Operand(1)); // c_out = 1.
873 __ adcs(IP, R1, Operand(0)); // c_in = 1, c_out = 1, v = 1.
874 __ mov(R0, Operand(1), VS);
875 __ Ret();
876}
877
878ASSEMBLER_TEST_RUN(Overflow, test) {
879 EXPECT(test != nullptr);
880 typedef int (*Overflow)() DART_UNUSED;
881 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Overflow, test->entry()));
882}
883
884ASSEMBLER_TEST_GENERATE(AndOrr, assembler) {
885 __ mov(R1, Operand(40));
886 __ mov(R2, Operand(0));
887 __ and_(R1, R2, Operand(R1));
888 __ mov(R3, Operand(42));
889 __ orr(R0, R1, Operand(R3));
890 __ Ret();
891}
892
893ASSEMBLER_TEST_RUN(AndOrr, test) {
894 EXPECT(test != nullptr);
895 typedef int (*AndOrr)() DART_UNUSED;
896 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(AndOrr, test->entry()));
897}
898
899ASSEMBLER_TEST_GENERATE(Orrs, assembler) {
900 __ mov(R0, Operand(0));
901 __ tst(R0, Operand(R1)); // Set zero-flag.
902 __ orrs(R0, R0, Operand(1)); // Clear zero-flag.
903 __ Ret(EQ);
904 __ mov(R0, Operand(42));
905 __ Ret(NE); // Only this return should fire.
906 __ mov(R0, Operand(2));
907 __ Ret();
908}
909
911 EXPECT(test != nullptr);
912 typedef int (*Orrs)() DART_UNUSED;
913 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Orrs, test->entry()));
914}
915
916ASSEMBLER_TEST_GENERATE(Multiply, assembler) {
917 __ mov(R1, Operand(20));
918 __ mov(R2, Operand(40));
919 __ mul(R3, R2, R1);
920 __ mov(R0, Operand(R3));
921 __ Ret();
922}
923
924ASSEMBLER_TEST_RUN(Multiply, test) {
925 EXPECT(test != nullptr);
926 typedef int (*Multiply)() DART_UNUSED;
927 EXPECT_EQ(800, EXECUTE_TEST_CODE_INT32(Multiply, test->entry()));
928}
929
930ASSEMBLER_TEST_GENERATE(QuotientRemainder, assembler) {
931 __ vmovsr(S2, R0);
932 __ vmovsr(S4, R2);
933 __ vcvtdi(D1, S2);
934 __ vcvtdi(D2, S4);
935 __ vdivd(D0, D1, D2);
936 __ vcvtid(S0, D0);
937 __ vmovrs(R1, S0); // r1 = r0/r2
938 __ mls(R0, R1, R2, R0); // r0 = r0 - r1*r2
939 __ Ret();
940}
941
942ASSEMBLER_TEST_RUN(QuotientRemainder, test) {
943 EXPECT(test != nullptr);
944 typedef int64_t (*QuotientRemainder)(int64_t dividend, int64_t divisor)
946 EXPECT_EQ(0x1000400000da8LL,
947 EXECUTE_TEST_CODE_INT64_LL(QuotientRemainder, test->entry(),
948 0x12345678, 0x1234));
949}
950
951ASSEMBLER_TEST_GENERATE(Multiply64To64, assembler) {
952 __ Push(R4);
953 __ mov(IP, Operand(R0));
954 __ mul(R4, R2, R1);
955 __ umull(R0, R1, R2, IP);
956 __ mla(R2, IP, R3, R4);
957 __ add(R1, R2, Operand(R1));
958 __ Pop(R4);
959 __ Ret();
960}
961
962ASSEMBLER_TEST_RUN(Multiply64To64, test) {
963 EXPECT(test != nullptr);
964 typedef int64_t (*Multiply64To64)(int64_t operand0, int64_t operand1)
966 EXPECT_EQ(6,
967 EXECUTE_TEST_CODE_INT64_LL(Multiply64To64, test->entry(), -3, -2));
968}
969
970ASSEMBLER_TEST_GENERATE(Multiply32To64, assembler) {
971 __ smull(R0, R1, R0, R2);
972 __ Ret();
973}
974
975ASSEMBLER_TEST_RUN(Multiply32To64, test) {
976 EXPECT(test != nullptr);
977 typedef int64_t (*Multiply32To64)(int64_t operand0, int64_t operand1)
979 EXPECT_EQ(6,
980 EXECUTE_TEST_CODE_INT64_LL(Multiply32To64, test->entry(), -3, -2));
981}
982
983ASSEMBLER_TEST_GENERATE(MultiplyAccumAccum32To64, assembler) {
984 __ umaal(R0, R1, R2, R3);
985 __ Ret();
986}
987
988ASSEMBLER_TEST_RUN(MultiplyAccumAccum32To64, test) {
989 EXPECT(test != nullptr);
990 typedef int64_t (*MultiplyAccumAccum32To64)(int64_t operand0,
991 int64_t operand1) DART_UNUSED;
992 EXPECT_EQ(3 + 7 + 5 * 11,
993 EXECUTE_TEST_CODE_INT64_LL(MultiplyAccumAccum32To64, test->entry(),
994 (3LL << 32) + 7, (5LL << 32) + 11));
995}
996
997ASSEMBLER_TEST_GENERATE(Clz, assembler) {
998 Label error;
999
1000 __ mov(R0, Operand(0));
1001 __ clz(R1, R0);
1002 __ cmp(R1, Operand(32));
1003 __ b(&error, NE);
1004 __ mov(R2, Operand(42));
1005 __ clz(R2, R2);
1006 __ cmp(R2, Operand(26));
1007 __ b(&error, NE);
1008 __ mvn_(R0, Operand(0));
1009 __ clz(R1, R0);
1010 __ cmp(R1, Operand(0));
1011 __ b(&error, NE);
1012 __ Lsr(R0, R0, Operand(3));
1013 __ clz(R1, R0);
1014 __ cmp(R1, Operand(3));
1015 __ b(&error, NE);
1016 __ mov(R0, Operand(0));
1017 __ Ret();
1018 __ Bind(&error);
1019 __ mov(R0, Operand(1));
1020 __ Ret();
1021}
1022
1024 EXPECT(test != nullptr);
1025 typedef int (*Clz)() DART_UNUSED;
1026 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Clz, test->entry()));
1027}
1028
1029ASSEMBLER_TEST_GENERATE(Rbit, assembler) {
1030 __ mov(R0, Operand(0x15));
1031 __ rbit(R0, R0);
1032 __ Ret();
1033}
1034
1035ASSEMBLER_TEST_RUN(Rbit, test) {
1036 EXPECT(test != nullptr);
1037 typedef int (*Rbit)() DART_UNUSED;
1038 const int32_t expected = 0xa8000000;
1039 EXPECT_EQ(expected, EXECUTE_TEST_CODE_INT32(Rbit, test->entry()));
1040}
1041
1042ASSEMBLER_TEST_GENERATE(Tst, assembler) {
1043 Label skip;
1044
1045 __ mov(R0, Operand(42));
1046 __ mov(R1, Operand(40));
1047 __ tst(R1, Operand(0));
1048 __ b(&skip, NE);
1049 __ mov(R0, Operand(0));
1050 __ Bind(&skip);
1051 __ Ret();
1052}
1053
1055 EXPECT(test != nullptr);
1056 typedef int (*Tst)() DART_UNUSED;
1057 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1058}
1059
1060ASSEMBLER_TEST_GENERATE(Lsl, assembler) {
1061 Label skip;
1062
1063 __ mov(R0, Operand(1));
1064 __ mov(R0, Operand(R0, LSL, 1));
1065 __ mov(R1, Operand(1));
1066 __ mov(R0, Operand(R0, LSL, R1));
1067 __ Ret();
1068}
1069
1071 EXPECT(test != nullptr);
1072 typedef int (*Tst)() DART_UNUSED;
1073 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1074}
1075
1076ASSEMBLER_TEST_GENERATE(Lsr, assembler) {
1077 Label skip;
1078
1079 __ mov(R0, Operand(4));
1080 __ mov(R0, Operand(R0, LSR, 1));
1081 __ mov(R1, Operand(1));
1082 __ mov(R0, Operand(R0, LSR, R1));
1083 __ Ret();
1084}
1085
1087 EXPECT(test != nullptr);
1088 typedef int (*Tst)() DART_UNUSED;
1089 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1090}
1091
1092ASSEMBLER_TEST_GENERATE(Lsr1, assembler) {
1093 Label skip;
1094
1095 __ mov(R0, Operand(1));
1096 __ Lsl(R0, R0, Operand(31));
1097 __ Lsr(R0, R0, Operand(31));
1098 __ Ret();
1099}
1100
1101ASSEMBLER_TEST_RUN(Lsr1, test) {
1102 EXPECT(test != nullptr);
1103 typedef int (*Tst)() DART_UNUSED;
1104 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1105}
1106
1107ASSEMBLER_TEST_GENERATE(Asr1, assembler) {
1108 Label skip;
1109
1110 __ mov(R0, Operand(1));
1111 __ Lsl(R0, R0, Operand(31));
1112 __ Asr(R0, R0, Operand(31));
1113 __ Ret();
1114}
1115
1116ASSEMBLER_TEST_RUN(Asr1, test) {
1117 EXPECT(test != nullptr);
1118 typedef int (*Tst)() DART_UNUSED;
1119 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1120}
1121
1122ASSEMBLER_TEST_GENERATE(Rsb, assembler) {
1123 __ mov(R3, Operand(10));
1124 __ rsb(R0, R3, Operand(42));
1125 __ Ret();
1126}
1127
1129 EXPECT(test != nullptr);
1130 typedef int (*Rsb)() DART_UNUSED;
1131 EXPECT_EQ(32, EXECUTE_TEST_CODE_INT32(Rsb, test->entry()));
1132}
1133
1134ASSEMBLER_TEST_GENERATE(Ldrh, assembler) {
1135 Label Test1, Test2, Test3, Done;
1136
1137 __ mov(R1, Operand(0x11));
1138 __ mov(R2, Operand(SP));
1139 __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
1140 __ ldrh(R0, Address(R2, (-target::kWordSize * 30)));
1141 __ cmp(R0, Operand(0x11));
1142 __ b(&Test1, EQ);
1143 __ mov(R0, Operand(1));
1144 __ b(&Done);
1145 __ Bind(&Test1);
1146
1147 __ mov(R0, Operand(0x22));
1148 __ strh(R0, Address(R2, (-target::kWordSize * 30)));
1149 __ ldrh(R1, Address(R2, (-target::kWordSize * 30)));
1150 __ cmp(R1, Operand(0x22));
1151 __ b(&Test2, EQ);
1152 __ mov(R0, Operand(1));
1153 __ b(&Done);
1154 __ Bind(&Test2);
1155
1156 __ mov(R0, Operand(0));
1157 __ AddImmediate(R2, (-target::kWordSize * 30));
1158 __ strh(R0, Address(R2));
1159 __ ldrh(R1, Address(R2));
1160 __ cmp(R1, Operand(0));
1161 __ b(&Test3, EQ);
1162 __ mov(R0, Operand(1));
1163 __ b(&Done);
1164 __ Bind(&Test3);
1165
1166 __ mov(R0, Operand(0));
1167 __ Bind(&Done);
1168 __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
1169 __ Ret();
1170}
1171
1172ASSEMBLER_TEST_RUN(Ldrh, test) {
1173 EXPECT(test != nullptr);
1174 typedef int (*Tst)() DART_UNUSED;
1175 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1176}
1177
1178ASSEMBLER_TEST_GENERATE(Ldrsb, assembler) {
1179 __ mov(R1, Operand(0xFF));
1180 __ mov(R2, Operand(SP));
1181 __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
1182 __ ldrsb(R0, Address(R2, (-target::kWordSize * 30)));
1183 __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
1184 __ Ret();
1185}
1186
1187ASSEMBLER_TEST_RUN(Ldrsb, test) {
1188 EXPECT(test != nullptr);
1189 typedef int (*Tst)() DART_UNUSED;
1190 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1191}
1192
1193ASSEMBLER_TEST_GENERATE(Ldrb, assembler) {
1194 __ mov(R1, Operand(0xFF));
1195 __ mov(R2, Operand(SP));
1196 __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
1197 __ ldrb(R0, Address(R2, (-target::kWordSize * 30)));
1198 __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
1199 __ Ret();
1200}
1201
1202ASSEMBLER_TEST_RUN(Ldrb, test) {
1203 EXPECT(test != nullptr);
1204 typedef int (*Tst)() DART_UNUSED;
1205 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1206}
1207
1208ASSEMBLER_TEST_GENERATE(Ldrsh, assembler) {
1209 __ mov(R1, Operand(0xFF));
1210 __ mov(R2, Operand(SP));
1211 __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
1212 __ ldrsh(R0, Address(R2, (-target::kWordSize * 30)));
1213 __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
1214 __ Ret();
1215}
1216
1217ASSEMBLER_TEST_RUN(Ldrsh, test) {
1218 EXPECT(test != nullptr);
1219 typedef int (*Tst)() DART_UNUSED;
1220 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1221}
1222
1223ASSEMBLER_TEST_GENERATE(Ldrh1, assembler) {
1224 __ mov(R1, Operand(0xFF));
1225 __ mov(R2, Operand(SP));
1226 __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
1227 __ ldrh(R0, Address(R2, (-target::kWordSize * 30)));
1228 __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
1229 __ Ret();
1230}
1231
1232ASSEMBLER_TEST_RUN(Ldrh1, test) {
1233 EXPECT(test != nullptr);
1234 typedef int (*Tst)() DART_UNUSED;
1235 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1236}
1237
1238ASSEMBLER_TEST_GENERATE(Ldrd, assembler) {
1239 __ mov(IP, Operand(SP));
1240 __ sub(SP, SP, Operand(target::kWordSize * 30));
1241 __ strd(R2, R3, SP, 0);
1242 __ strd(R0, R1, IP, (-target::kWordSize * 28));
1243 __ ldrd(R2, R3, IP, (-target::kWordSize * 28));
1244 __ ldrd(R0, R1, SP, 0);
1245 __ add(SP, SP, Operand(target::kWordSize * 30));
1246 __ sub(R0, R0, Operand(R2));
1247 __ add(R1, R1, Operand(R3));
1248 __ Ret();
1249}
1250
1251ASSEMBLER_TEST_RUN(Ldrd, test) {
1252 EXPECT(test != nullptr);
1253 typedef int64_t (*Tst)(int64_t r0r1, int64_t r2r3) DART_UNUSED;
1254 EXPECT_EQ(0x0000444400002222LL,
1255 EXECUTE_TEST_CODE_INT64_LL(Tst, test->entry(), 0x0000111100000000LL,
1256 0x0000333300002222LL));
1257}
1258
1259ASSEMBLER_TEST_GENERATE(Ldm_stm_da, assembler) {
1260 __ mov(R0, Operand(1));
1261 __ mov(R1, Operand(7));
1262 __ mov(R2, Operand(11));
1263 __ mov(R3, Operand(31));
1264 __ Push(R9); // We use R9 as accumulator.
1265 __ Push(R9);
1266 __ Push(R9);
1267 __ Push(R9);
1268 __ Push(R9);
1269 __ Push(R0); // Make room, so we can decrement after.
1270 __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
1271 __ str(R2, Address(SP)); // Should be a free slot.
1272 __ ldr(R9, Address(SP, 1 * target::kWordSize)); // R0. R9 = +1.
1273 __ ldr(IP, Address(SP, 2 * target::kWordSize)); // R1.
1274 __ sub(R9, R9, Operand(IP)); // -R1. R9 = -6.
1275 __ ldr(IP, Address(SP, 3 * target::kWordSize)); // R2.
1276 __ add(R9, R9, Operand(IP)); // +R2. R9 = +5.
1277 __ ldr(IP, Address(SP, 4 * target::kWordSize)); // R3.
1278 __ sub(R9, R9, Operand(IP)); // -R3. R9 = -26.
1279 __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
1280 // Same operations again. But this time from the restore registers.
1281 __ add(R9, R9, Operand(R0));
1282 __ sub(R9, R9, Operand(R1));
1283 __ add(R9, R9, Operand(R2));
1284 __ sub(R0, R9, Operand(R3)); // R0 = result = -52.
1285 __ Pop(R1); // Remove storage slot.
1286 __ Pop(R9); // Restore R9.
1287 __ Pop(R9); // Restore R9.
1288 __ Pop(R9); // Restore R9.
1289 __ Pop(R9); // Restore R9.
1290 __ Pop(R9); // Restore R9.
1291 __ Ret();
1292}
1293
1294ASSEMBLER_TEST_RUN(Ldm_stm_da, test) {
1295 EXPECT(test != nullptr);
1296 typedef int (*Tst)() DART_UNUSED;
1297 EXPECT_EQ(-52, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1298}
1299
1300ASSEMBLER_TEST_GENERATE(AddressShiftStrLSL1NegOffset, assembler) {
1301 __ mov(R2, Operand(42));
1302 __ mov(R1, Operand(target::kWordSize));
1303 __ str(R2, Address(SP, R1, LSL, 1, Address::NegOffset));
1304 __ ldr(R0, Address(SP, (-target::kWordSize * 2), Address::Offset));
1305 __ Ret();
1306}
1307
1308ASSEMBLER_TEST_RUN(AddressShiftStrLSL1NegOffset, test) {
1309 EXPECT(test != nullptr);
1310 typedef int (*Tst)() DART_UNUSED;
1311 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1312}
1313
1314ASSEMBLER_TEST_GENERATE(AddressShiftLdrLSL5NegOffset, assembler) {
1315 __ mov(R2, Operand(42));
1316 __ mov(R1, Operand(target::kWordSize));
1317 __ str(R2, Address(SP, (-target::kWordSize * 32), Address::Offset));
1318 __ ldr(R0, Address(SP, R1, LSL, 5, Address::NegOffset));
1319 __ Ret();
1320}
1321
1322ASSEMBLER_TEST_RUN(AddressShiftLdrLSL5NegOffset, test) {
1323 EXPECT(test != nullptr);
1324 typedef int (*Tst)() DART_UNUSED;
1325 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1326}
1327
1328ASSEMBLER_TEST_GENERATE(AddressShiftStrLRS1NegOffset, assembler) {
1329 __ mov(R2, Operand(42));
1330 __ mov(R1, Operand(target::kWordSize * 2));
1331 __ str(R2, Address(SP, R1, LSR, 1, Address::NegOffset));
1332 __ ldr(R0, Address(SP, -target::kWordSize, Address::Offset));
1333 __ Ret();
1334}
1335
1336ASSEMBLER_TEST_RUN(AddressShiftStrLRS1NegOffset, test) {
1337 EXPECT(test != nullptr);
1338 typedef int (*Tst)() DART_UNUSED;
1339 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1340}
1341
1342ASSEMBLER_TEST_GENERATE(AddressShiftLdrLRS1NegOffset, assembler) {
1343 __ mov(R2, Operand(42));
1344 __ mov(R1, Operand(target::kWordSize * 2));
1345 __ str(R2, Address(SP, -target::kWordSize, Address::Offset));
1346 __ ldr(R0, Address(SP, R1, LSR, 1, Address::NegOffset));
1347 __ Ret();
1348}
1349
1350ASSEMBLER_TEST_RUN(AddressShiftLdrLRS1NegOffset, test) {
1351 EXPECT(test != nullptr);
1352 typedef int (*Tst)() DART_UNUSED;
1353 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1354}
1355
1356ASSEMBLER_TEST_GENERATE(AddressShiftStrLSLNegPreIndex, assembler) {
1357 __ mov(R2, Operand(42));
1358 __ mov(R1, Operand(target::kWordSize));
1359 __ mov(R3, Operand(SP));
1360 __ str(R2, Address(SP, R1, LSL, 5, Address::NegPreIndex));
1361 __ ldr(R0, Address(R3, (-target::kWordSize * 32), Address::Offset));
1362 __ mov(SP, Operand(R3));
1363 __ Ret();
1364}
1365
1366ASSEMBLER_TEST_RUN(AddressShiftStrLSLNegPreIndex, test) {
1367 EXPECT(test != nullptr);
1368 typedef int (*Tst)() DART_UNUSED;
1369 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1370}
1371
1372ASSEMBLER_TEST_GENERATE(AddressShiftLdrLSLNegPreIndex, assembler) {
1373 __ mov(R2, Operand(42));
1374 __ mov(R1, Operand(target::kWordSize));
1375 __ str(R2, Address(SP, (-target::kWordSize * 32), Address::PreIndex));
1376 __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex));
1377 __ Ret();
1378}
1379
1380ASSEMBLER_TEST_RUN(AddressShiftLdrLSLNegPreIndex, test) {
1381 EXPECT(test != nullptr);
1382 typedef int (*Tst)() DART_UNUSED;
1383 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1384}
1385
1386// Make sure we can store and reload the D registers using vstmd and vldmd
1387ASSEMBLER_TEST_GENERATE(VstmdVldmd, assembler) {
1388 __ LoadDImmediate(D0, 0.0, R0);
1389 __ LoadDImmediate(D1, 1.0, R0);
1390 __ LoadDImmediate(D2, 2.0, R0);
1391 __ LoadDImmediate(D3, 3.0, R0);
1392 __ LoadDImmediate(D4, 4.0, R0);
1393 __ vstmd(DB_W, SP, D0, 5); // Push D0 - D4 onto the stack, dec SP
1394 __ LoadDImmediate(D0, 0.0, R0);
1395 __ LoadDImmediate(D1, 0.0, R0);
1396 __ LoadDImmediate(D2, 0.0, R0);
1397 __ LoadDImmediate(D3, 0.0, R0);
1398 __ LoadDImmediate(D4, 0.0, R0);
1399 __ vldmd(IA_W, SP, D0, 5); // Pop stack into D0 - D4, inc SP
1400
1401 // Load success value into R0
1402 __ mov(R0, Operand(42));
1403
1404 // Check that 4.0 is back in D4
1405 __ LoadDImmediate(D5, 4.0, R1);
1406 __ vcmpd(D4, D5);
1407 __ vmstat();
1408 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1409
1410 // Check that 3.0 is back in D3
1411 __ LoadDImmediate(D5, 3.0, R1);
1412 __ vcmpd(D3, D5);
1413 __ vmstat();
1414 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1415
1416 // Check that 2.0 is back in D2
1417 __ LoadDImmediate(D5, 2.0, R1);
1418 __ vcmpd(D2, D5);
1419 __ vmstat();
1420 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1421
1422 // Check that 1.0 is back in D1
1423 __ LoadDImmediate(D5, 1.0, R1);
1424 __ vcmpd(D1, D5);
1425 __ vmstat();
1426 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1427 __ Ret();
1428}
1429
1430ASSEMBLER_TEST_RUN(VstmdVldmd, test) {
1431 EXPECT(test != nullptr);
1432 typedef int (*Tst)() DART_UNUSED;
1433 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1434}
1435
1436// Make sure we can store and reload the S registers using vstms and vldms
1437ASSEMBLER_TEST_GENERATE(VstmsVldms, assembler) {
1438 __ LoadSImmediate(S0, 0.0);
1439 __ LoadSImmediate(S1, 1.0);
1440 __ LoadSImmediate(S2, 2.0);
1441 __ LoadSImmediate(S3, 3.0);
1442 __ LoadSImmediate(S4, 4.0);
1443 __ vstms(DB_W, SP, S0, S4); // Push S0 - S4 onto the stack, dec SP
1444 __ LoadSImmediate(S0, 0.0);
1445 __ LoadSImmediate(S1, 0.0);
1446 __ LoadSImmediate(S2, 0.0);
1447 __ LoadSImmediate(S3, 0.0);
1448 __ LoadSImmediate(S4, 0.0);
1449 __ vldms(IA_W, SP, S0, S4); // Pop stack into S0 - S4, inc SP
1450
1451 // Load success value into R0
1452 __ mov(R0, Operand(42));
1453
1454 // Check that 4.0 is back in S4
1455 __ LoadSImmediate(S5, 4.0);
1456 __ vcmps(S4, S5);
1457 __ vmstat();
1458 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1459
1460 // Check that 3.0 is back in S3
1461 __ LoadSImmediate(S5, 3.0);
1462 __ vcmps(S3, S5);
1463 __ vmstat();
1464 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1465
1466 // Check that 2.0 is back in S2
1467 __ LoadSImmediate(S5, 2.0);
1468 __ vcmps(S2, S5);
1469 __ vmstat();
1470 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1471
1472 // Check that 1.0 is back in S1
1473 __ LoadSImmediate(S5, 1.0);
1474 __ vcmps(S1, S5);
1475 __ vmstat();
1476 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1477 __ Ret();
1478}
1479
1480ASSEMBLER_TEST_RUN(VstmsVldms, test) {
1481 EXPECT(test != nullptr);
1482 typedef int (*Tst)() DART_UNUSED;
1483 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1484}
1485
1486// Make sure we can start somewhere other than D0
1487ASSEMBLER_TEST_GENERATE(VstmdVldmd1, assembler) {
1488 __ LoadDImmediate(D1, 1.0, R0);
1489 __ LoadDImmediate(D2, 2.0, R0);
1490 __ LoadDImmediate(D3, 3.0, R0);
1491 __ LoadDImmediate(D4, 4.0, R0);
1492 __ vstmd(DB_W, SP, D1, 4); // Push D1 - D4 onto the stack, dec SP
1493 __ LoadDImmediate(D1, 0.0, R0);
1494 __ LoadDImmediate(D2, 0.0, R0);
1495 __ LoadDImmediate(D3, 0.0, R0);
1496 __ LoadDImmediate(D4, 0.0, R0);
1497 __ vldmd(IA_W, SP, D1, 4); // Pop stack into D1 - D4, inc SP
1498
1499 // Load success value into R0
1500 __ mov(R0, Operand(42));
1501
1502 // Check that 4.0 is back in D4
1503 __ LoadDImmediate(D5, 4.0, R1);
1504 __ vcmpd(D4, D5);
1505 __ vmstat();
1506 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1507
1508 // Check that 3.0 is back in D3
1509 __ LoadDImmediate(D5, 3.0, R1);
1510 __ vcmpd(D3, D5);
1511 __ vmstat();
1512 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1513
1514 // Check that 2.0 is back in D2
1515 __ LoadDImmediate(D5, 2.0, R1);
1516 __ vcmpd(D2, D5);
1517 __ vmstat();
1518 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1519
1520 // Check that 1.0 is back in D1
1521 __ LoadDImmediate(D5, 1.0, R1);
1522 __ vcmpd(D1, D5);
1523 __ vmstat();
1524 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1525 __ Ret();
1526}
1527
1528ASSEMBLER_TEST_RUN(VstmdVldmd1, test) {
1529 EXPECT(test != nullptr);
1530 typedef int (*Tst)() DART_UNUSED;
1531 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1532}
1533
1534// Make sure we can start somewhere other than S0
1535ASSEMBLER_TEST_GENERATE(VstmsVldms1, assembler) {
1536 __ LoadSImmediate(S1, 1.0);
1537 __ LoadSImmediate(S2, 2.0);
1538 __ LoadSImmediate(S3, 3.0);
1539 __ LoadSImmediate(S4, 4.0);
1540 __ vstms(DB_W, SP, S1, S4); // Push S0 - S4 onto the stack, dec SP
1541 __ LoadSImmediate(S1, 0.0);
1542 __ LoadSImmediate(S2, 0.0);
1543 __ LoadSImmediate(S3, 0.0);
1544 __ LoadSImmediate(S4, 0.0);
1545 __ vldms(IA_W, SP, S1, S4); // Pop stack into S0 - S4, inc SP
1546
1547 // Load success value into R0
1548 __ mov(R0, Operand(42));
1549
1550 // Check that 4.0 is back in S4
1551 __ LoadSImmediate(S5, 4.0);
1552 __ vcmps(S4, S5);
1553 __ vmstat();
1554 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1555
1556 // Check that 3.0 is back in S3
1557 __ LoadSImmediate(S5, 3.0);
1558 __ vcmps(S3, S5);
1559 __ vmstat();
1560 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1561
1562 // Check that 2.0 is back in S2
1563 __ LoadSImmediate(S5, 2.0);
1564 __ vcmps(S2, S5);
1565 __ vmstat();
1566 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1567
1568 // Check that 1.0 is back in S1
1569 __ LoadSImmediate(S5, 1.0);
1570 __ vcmps(S1, S5);
1571 __ vmstat();
1572 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1573 __ Ret();
1574}
1575
1576ASSEMBLER_TEST_RUN(VstmsVldms1, test) {
1577 EXPECT(test != nullptr);
1578 typedef int (*Tst)() DART_UNUSED;
1579 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1580}
1581
1582// Make sure we can store the D registers using vstmd and
1583// load them into a different set using vldmd
1584ASSEMBLER_TEST_GENERATE(VstmdVldmd_off, assembler) {
1585 // Save used callee-saved FPU registers.
1586 __ vstmd(DB_W, SP, D8, 3);
1587 __ LoadDImmediate(D0, 0.0, R0);
1588 __ LoadDImmediate(D1, 1.0, R0);
1589 __ LoadDImmediate(D2, 2.0, R0);
1590 __ LoadDImmediate(D3, 3.0, R0);
1591 __ LoadDImmediate(D4, 4.0, R0);
1592 __ LoadDImmediate(D5, 5.0, R0);
1593 __ vstmd(DB_W, SP, D0, 5); // Push D0 - D4 onto the stack, dec SP
1594 __ vldmd(IA_W, SP, D5, 5); // Pop stack into D5 - D9, inc SP
1595
1596 // Load success value into R0
1597 __ mov(R0, Operand(42));
1598
1599 // Check that 4.0 is in D9
1600 __ LoadDImmediate(D10, 4.0, R1);
1601 __ vcmpd(D9, D10);
1602 __ vmstat();
1603 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1604
1605 // Check that 3.0 is in D8
1606 __ LoadDImmediate(D10, 3.0, R1);
1607 __ vcmpd(D8, D10);
1608 __ vmstat();
1609 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1610
1611 // Check that 2.0 is in D7
1612 __ LoadDImmediate(D10, 2.0, R1);
1613 __ vcmpd(D7, D10);
1614 __ vmstat();
1615 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1616
1617 // Check that 1.0 is in D6
1618 __ LoadDImmediate(D10, 1.0, R1);
1619 __ vcmpd(D6, D10);
1620 __ vmstat();
1621 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1622
1623 // Check that 0.0 is in D5
1624 __ LoadDImmediate(D10, 0.0, R1);
1625 __ vcmpd(D5, D10);
1626 __ vmstat();
1627 __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
1628
1629 // Restore used callee-saved FPU registers.
1630 __ vldmd(IA_W, SP, D8, 3);
1631 __ Ret();
1632}
1633
1634ASSEMBLER_TEST_RUN(VstmdVldmd_off, test) {
1635 EXPECT(test != nullptr);
1636 typedef int (*Tst)() DART_UNUSED;
1637 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1638}
1639
1640// Make sure we can start somewhere other than S0
1641ASSEMBLER_TEST_GENERATE(VstmsVldms_off, assembler) {
1642 __ LoadSImmediate(S0, 0.0);
1643 __ LoadSImmediate(S1, 1.0);
1644 __ LoadSImmediate(S2, 2.0);
1645 __ LoadSImmediate(S3, 3.0);
1646 __ LoadSImmediate(S4, 4.0);
1647 __ LoadSImmediate(S5, 5.0);
1648 __ vstms(DB_W, SP, S0, S4); // Push S0 - S4 onto the stack, dec SP
1649 __ vldms(IA_W, SP, S5, S9); // Pop stack into S5 - S9, inc SP
1650
1651 // Load success value into R0
1652 __ mov(R0, Operand(42));
1653
1654 // Check that 4.0 is in S9
1655 __ LoadSImmediate(S10, 4.0);
1656 __ vcmps(S9, S10);
1657 __ vmstat();
1658 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1659
1660 // Check that 3.0 is in S8
1661 __ LoadSImmediate(S10, 3.0);
1662 __ vcmps(S8, S10);
1663 __ vmstat();
1664 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1665
1666 // Check that 2.0 is in S7
1667 __ LoadSImmediate(S10, 2.0);
1668 __ vcmps(S7, S10);
1669 __ vmstat();
1670 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1671
1672 // Check that 1.0 is back in S6
1673 __ LoadSImmediate(S10, 1.0);
1674 __ vcmps(S6, S10);
1675 __ vmstat();
1676 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1677
1678 // Check that 0.0 is back in S5
1679 __ LoadSImmediate(S10, 0.0);
1680 __ vcmps(S5, S10);
1681 __ vmstat();
1682 __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
1683 __ Ret();
1684}
1685
1686ASSEMBLER_TEST_RUN(VstmsVldms_off, test) {
1687 EXPECT(test != nullptr);
1688 typedef int (*Tst)() DART_UNUSED;
1689 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1690}
1691
1692// 3 2 1 0
1693// 10987654321098765432109876543210
1694static constexpr uint32_t kBfxTestBits = 0b00010000001000001000010001001011;
1695
1696static int32_t ExpectedUbfxBitPattern(uint8_t lsb, uint8_t width) {
1697 ASSERT(width >= 1);
1698 ASSERT(width < 32);
1699 ASSERT(lsb < 32);
1700 ASSERT(lsb + width <= 32);
1701 return (kBfxTestBits & (Utils::NBitMask(width) << lsb)) >> lsb;
1702}
1703
1704static int32_t ExpectedSbfxBitPattern(uint8_t lsb, uint8_t width) {
1705 const uint32_t no_extension = ExpectedUbfxBitPattern(lsb, width);
1706 const uint32_t sign_extension =
1707 Utils::TestBit(no_extension, width - 1) ? ~Utils::NBitMask(width) : 0;
1708 return no_extension | sign_extension;
1709}
1710
1711// (lsb, width, extracted bit field is signed)
1712#define BFX_TEST_CASES(V) \
1713 V(0, 1, true) \
1714 V(0, 8, false) \
1715 V(0, 11, true) V(0, 19, false) V(3, 20, false) V(10, 19, true) V(31, 1, false)
1716
1717#define GENERATE_BFX_TEST(L, W, S) \
1718 ASSEMBLER_TEST_GENERATE(UbfxLSB##L##Width##W, assembler) { \
1719 __ LoadImmediate(R1, kBfxTestBits); \
1720 __ ubfx(R0, R1, L, W); \
1721 __ Ret(); \
1722 } \
1723 ASSEMBLER_TEST_RUN(UbfxLSB##L##Width##W, test) { \
1724 EXPECT(test != nullptr); \
1725 typedef int (*Tst)() DART_UNUSED; \
1726 ASSERT((ExpectedUbfxBitPattern(L, W) == ExpectedSbfxBitPattern(L, W)) != \
1727 S); \
1728 EXPECT_EQ(ExpectedUbfxBitPattern(L, W), \
1729 EXECUTE_TEST_CODE_INT32(Tst, test->entry())); \
1730 } \
1731 ASSEMBLER_TEST_GENERATE(SbfxLSB##L##Width##W, assembler) { \
1732 __ LoadImmediate(R1, kBfxTestBits); \
1733 __ sbfx(R0, R1, L, W); \
1734 __ Ret(); \
1735 } \
1736 ASSEMBLER_TEST_RUN(SbfxLSB##L##Width##W, test) { \
1737 EXPECT(test != nullptr); \
1738 typedef int (*Tst)() DART_UNUSED; \
1739 ASSERT((ExpectedUbfxBitPattern(L, W) == ExpectedSbfxBitPattern(L, W)) != \
1740 S); \
1741 EXPECT_EQ(ExpectedSbfxBitPattern(L, W), \
1742 EXECUTE_TEST_CODE_INT32(Tst, test->entry())); \
1743 }
1744
1745BFX_TEST_CASES(GENERATE_BFX_TEST)
1746
1747#undef GENERATE_BFX_TEST
1748#undef BFX_TEST_CASES
1749
1750ASSEMBLER_TEST_GENERATE(Udiv, assembler) {
1752 __ mov(R0, Operand(27));
1753 __ mov(R1, Operand(9));
1754 __ udiv(R2, R0, R1);
1755 __ mov(R0, Operand(R2));
1756 }
1757 __ Ret();
1758}
1759
1760ASSEMBLER_TEST_RUN(Udiv, test) {
1761 EXPECT(test != nullptr);
1763 typedef int (*Tst)() DART_UNUSED;
1764 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1765 EXPECT_DISASSEMBLY(
1766 "e3a0001b mov r0, #27\n"
1767 "e3a01009 mov r1, #9\n"
1768 "e732f110 udiv r2, r0, r1\n"
1769 "e1a00002 mov r0, r2\n"
1770 "e12fff1e bx lr\n");
1771 }
1772}
1773
1774ASSEMBLER_TEST_GENERATE(Sdiv, assembler) {
1776 __ mov(R0, Operand(27));
1777 __ LoadImmediate(R1, -9);
1778 __ sdiv(R2, R0, R1);
1779 __ mov(R0, Operand(R2));
1780 }
1781 __ Ret();
1782}
1783
1784ASSEMBLER_TEST_RUN(Sdiv, test) {
1785 EXPECT(test != nullptr);
1787 typedef int (*Tst)() DART_UNUSED;
1788 EXPECT_EQ(-3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1789 EXPECT_DISASSEMBLY(
1790 "e3a0001b mov r0, #27\n"
1791 "e3e01008 mvn r1, #8\n"
1792 "e712f110 sdiv r2, r0, r1\n"
1793 "e1a00002 mov r0, r2\n"
1794 "e12fff1e bx lr\n");
1795 }
1796}
1797
1798ASSEMBLER_TEST_GENERATE(Udiv_zero, assembler) {
1800 __ mov(R0, Operand(27));
1801 __ mov(R1, Operand(0));
1802 __ udiv(R2, R0, R1);
1803 __ mov(R0, Operand(R2));
1804 }
1805 __ Ret();
1806}
1807
1808ASSEMBLER_TEST_RUN(Udiv_zero, test) {
1809 EXPECT(test != nullptr);
1811 typedef int (*Tst)() DART_UNUSED;
1812 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1813 }
1814}
1815
1816ASSEMBLER_TEST_GENERATE(Sdiv_zero, assembler) {
1818 __ mov(R0, Operand(27));
1819 __ mov(R1, Operand(0));
1820 __ sdiv(R2, R0, R1);
1821 __ mov(R0, Operand(R2));
1822 }
1823 __ Ret();
1824}
1825
1826ASSEMBLER_TEST_RUN(Sdiv_zero, test) {
1827 EXPECT(test != nullptr);
1829 typedef int (*Tst)() DART_UNUSED;
1830 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1831 }
1832}
1833
1834ASSEMBLER_TEST_GENERATE(Udiv_corner, assembler) {
1836 __ LoadImmediate(R0, 0x80000000);
1837 __ LoadImmediate(R1, 0xffffffff);
1838 __ udiv(R2, R0, R1);
1839 __ mov(R0, Operand(R2));
1840 }
1841 __ Ret();
1842}
1843
1844ASSEMBLER_TEST_RUN(Udiv_corner, test) {
1845 EXPECT(test != nullptr);
1847 typedef int (*Tst)() DART_UNUSED;
1848 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1849 }
1850}
1851
1852ASSEMBLER_TEST_GENERATE(Sdiv_corner, assembler) {
1854 __ LoadImmediate(R0, 0x80000000);
1855 __ LoadImmediate(R1, 0xffffffff);
1856 __ sdiv(R2, R0, R1);
1857 __ mov(R0, Operand(R2));
1858 }
1859 __ Ret();
1860}
1861
1862ASSEMBLER_TEST_RUN(Sdiv_corner, test) {
1863 EXPECT(test != nullptr);
1865 typedef int (*Tst)() DART_UNUSED;
1866 EXPECT_EQ(static_cast<int32_t>(0x80000000),
1867 EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1868 }
1869}
1870
1871ASSEMBLER_TEST_GENERATE(IntDiv_supported, assembler) {
1872#if defined(USING_SIMULATOR)
1875 __ mov(R0, Operand(27));
1876 __ mov(R1, Operand(9));
1877 __ IntegerDivide(R0, R0, R1, D0, D1);
1879 __ Ret();
1880#else
1881 __ mov(R0, Operand(27));
1882 __ mov(R1, Operand(9));
1883 __ IntegerDivide(R0, R0, R1, D0, D1);
1884 __ Ret();
1885#endif
1886}
1887
1888ASSEMBLER_TEST_RUN(IntDiv_supported, test) {
1889 EXPECT(test != nullptr);
1890#if defined(USING_SIMULATOR)
1893 typedef int (*Tst)() DART_UNUSED;
1894 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1896#else
1897 typedef int (*Tst)() DART_UNUSED;
1898 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1899#endif
1900}
1901
1902ASSEMBLER_TEST_GENERATE(IntDiv_unsupported, assembler) {
1903#if defined(USING_SIMULATOR)
1906 __ mov(R0, Operand(27));
1907 __ mov(R1, Operand(9));
1908 __ IntegerDivide(R0, R0, R1, D0, D1);
1910 __ Ret();
1911#else
1912 __ mov(R0, Operand(27));
1913 __ mov(R1, Operand(9));
1914 __ IntegerDivide(R0, R0, R1, D0, D1);
1915 __ Ret();
1916#endif
1917}
1918
1919ASSEMBLER_TEST_RUN(IntDiv_unsupported, test) {
1920 EXPECT(test != nullptr);
1921#if defined(USING_SIMULATOR)
1924 typedef int (*Tst)() DART_UNUSED;
1925 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1927#else
1928 typedef int (*Tst)() DART_UNUSED;
1929 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1930#endif
1931}
1932
1933ASSEMBLER_TEST_GENERATE(Muls, assembler) {
1934 __ mov(R0, Operand(3));
1935 __ LoadImmediate(R1, -9);
1936 __ muls(R2, R0, R1);
1937 __ mov(R0, Operand(42), MI);
1938 __ Ret();
1939}
1940
1941ASSEMBLER_TEST_RUN(Muls, test) {
1942 EXPECT(test != nullptr);
1943 typedef int (*Tst)() DART_UNUSED;
1944 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1945}
1946
1947ASSEMBLER_TEST_GENERATE(Vaddqi8, assembler) {
1949 __ mov(R0, Operand(1));
1950 __ vmovsr(S0, R0);
1951 __ mov(R0, Operand(2));
1952 __ vmovsr(S1, R0);
1953 __ mov(R0, Operand(3));
1954 __ vmovsr(S2, R0);
1955 __ mov(R0, Operand(4));
1956 __ vmovsr(S3, R0);
1957 __ mov(R0, Operand(5));
1958 __ vmovsr(S4, R0);
1959 __ mov(R0, Operand(6));
1960 __ vmovsr(S5, R0);
1961 __ mov(R0, Operand(7));
1962 __ vmovsr(S6, R0);
1963 __ mov(R0, Operand(8));
1964 __ vmovsr(S7, R0);
1965
1966 __ vaddqi(kByte, Q2, Q0, Q1);
1967
1968 __ vmovrs(R0, S8);
1969 __ vmovrs(R1, S9);
1970 __ vmovrs(R2, S10);
1971 __ vmovrs(R3, S11);
1972
1973 __ add(R0, R0, Operand(R1));
1974 __ add(R0, R0, Operand(R2));
1975 __ add(R0, R0, Operand(R3));
1976 }
1977 __ Ret();
1978}
1979
1980ASSEMBLER_TEST_RUN(Vaddqi8, test) {
1981 EXPECT(test != nullptr);
1983 typedef int (*Tst)() DART_UNUSED;
1984 EXPECT_EQ(36, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
1985 }
1986}
1987
1988ASSEMBLER_TEST_GENERATE(Vaddqi16, assembler) {
1990 __ mov(R0, Operand(1));
1991 __ vmovsr(S0, R0);
1992 __ mov(R0, Operand(2));
1993 __ vmovsr(S1, R0);
1994 __ mov(R0, Operand(3));
1995 __ vmovsr(S2, R0);
1996 __ mov(R0, Operand(4));
1997 __ vmovsr(S3, R0);
1998 __ mov(R0, Operand(5));
1999 __ vmovsr(S4, R0);
2000 __ mov(R0, Operand(6));
2001 __ vmovsr(S5, R0);
2002 __ mov(R0, Operand(7));
2003 __ vmovsr(S6, R0);
2004 __ mov(R0, Operand(8));
2005 __ vmovsr(S7, R0);
2006
2007 __ vaddqi(kTwoBytes, Q2, Q0, Q1);
2008
2009 __ vmovrs(R0, S8);
2010 __ vmovrs(R1, S9);
2011 __ vmovrs(R2, S10);
2012 __ vmovrs(R3, S11);
2013
2014 __ add(R0, R0, Operand(R1));
2015 __ add(R0, R0, Operand(R2));
2016 __ add(R0, R0, Operand(R3));
2017 }
2018 __ Ret();
2019}
2020
2021ASSEMBLER_TEST_RUN(Vaddqi16, test) {
2022 EXPECT(test != nullptr);
2024 typedef int (*Tst)() DART_UNUSED;
2025 EXPECT_EQ(36, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2026 }
2027}
2028
2029ASSEMBLER_TEST_GENERATE(Vaddqi32, assembler) {
2031 __ mov(R0, Operand(1));
2032 __ vmovsr(S0, R0);
2033 __ mov(R0, Operand(2));
2034 __ vmovsr(S1, R0);
2035 __ mov(R0, Operand(3));
2036 __ vmovsr(S2, R0);
2037 __ mov(R0, Operand(4));
2038 __ vmovsr(S3, R0);
2039 __ mov(R0, Operand(5));
2040 __ vmovsr(S4, R0);
2041 __ mov(R0, Operand(6));
2042 __ vmovsr(S5, R0);
2043 __ mov(R0, Operand(7));
2044 __ vmovsr(S6, R0);
2045 __ mov(R0, Operand(8));
2046 __ vmovsr(S7, R0);
2047
2048 __ vaddqi(kFourBytes, Q2, Q0, Q1);
2049
2050 __ vmovrs(R0, S8);
2051 __ vmovrs(R1, S9);
2052 __ vmovrs(R2, S10);
2053 __ vmovrs(R3, S11);
2054
2055 __ add(R0, R0, Operand(R1));
2056 __ add(R0, R0, Operand(R2));
2057 __ add(R0, R0, Operand(R3));
2058 }
2059 __ Ret();
2060}
2061
2062ASSEMBLER_TEST_RUN(Vaddqi32, test) {
2063 EXPECT(test != nullptr);
2065 typedef int (*Tst)() DART_UNUSED;
2066 EXPECT_EQ(36, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2067 }
2068}
2069
2070ASSEMBLER_TEST_GENERATE(Vaddqi64, assembler) {
2072 __ mov(R0, Operand(1));
2073 __ vmovsr(S0, R0);
2074 __ mov(R0, Operand(2));
2075 __ vmovsr(S2, R0);
2076 __ mov(R0, Operand(3));
2077 __ vmovsr(S4, R0);
2078 __ mov(R0, Operand(4));
2079 __ vmovsr(S6, R0);
2080
2081 __ vaddqi(kWordPair, Q2, Q0, Q1);
2082
2083 __ vmovrs(R0, S8);
2084 __ vmovrs(R2, S10);
2085
2086 __ add(R0, R0, Operand(R2));
2087 }
2088 __ Ret();
2089}
2090
2091ASSEMBLER_TEST_RUN(Vaddqi64, test) {
2092 EXPECT(test != nullptr);
2094 typedef int (*Tst)() DART_UNUSED;
2095 EXPECT_EQ(10, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2096 }
2097}
2098
2099ASSEMBLER_TEST_GENERATE(Vshlqu64, assembler) {
2101 Label fail;
2102 __ LoadImmediate(R1, 21);
2103 __ LoadImmediate(R0, 1);
2104 __ vmovsr(S0, R1);
2105 __ vmovsr(S2, R1);
2106 __ vmovsr(S4, R0);
2107 __ vmovsr(S6, R0);
2108
2109 __ vshlqu(kWordPair, Q2, Q0, Q1);
2110
2111 __ vmovrs(R0, S8);
2112 __ vmovrs(R1, S10);
2113 __ CompareImmediate(R0, 42);
2114 __ LoadImmediate(R0, 0);
2115 __ b(&fail, NE);
2116 __ CompareImmediate(R1, 42);
2117 __ LoadImmediate(R0, 0);
2118 __ b(&fail, NE);
2119
2120 __ LoadImmediate(R0, 1);
2121 __ Bind(&fail);
2122 }
2123 __ Ret();
2124}
2125
2126ASSEMBLER_TEST_RUN(Vshlqu64, test) {
2127 EXPECT(test != nullptr);
2129 typedef int (*Tst)() DART_UNUSED;
2130 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2131 }
2132}
2133
2134ASSEMBLER_TEST_GENERATE(Vshlqi64, assembler) {
2136 Label fail;
2137 __ LoadImmediate(R1, -84);
2138 __ LoadImmediate(R0, -1);
2139 __ vmovdrr(D0, R1, R0);
2140 __ vmovdrr(D1, R1, R0);
2141 __ vmovsr(S4, R0);
2142 __ vmovsr(S6, R0);
2143
2144 __ vshlqi(kWordPair, Q2, Q0, Q1);
2145
2146 __ vmovrs(R0, S8);
2147 __ vmovrs(R1, S10);
2148 __ CompareImmediate(R0, -42);
2149 __ LoadImmediate(R0, 0);
2150 __ b(&fail, NE);
2151 __ CompareImmediate(R1, -42);
2152 __ LoadImmediate(R0, 0);
2153 __ b(&fail, NE);
2154
2155 __ LoadImmediate(R0, 1);
2156 __ Bind(&fail);
2157 }
2158 __ Ret();
2159}
2160
2161ASSEMBLER_TEST_RUN(Vshlqi64, test) {
2162 EXPECT(test != nullptr);
2164 typedef int (*Tst)() DART_UNUSED;
2165 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2166 }
2167}
2168
2169ASSEMBLER_TEST_GENERATE(Mint_shl_ok, assembler) {
2171 const QRegister value = Q0;
2172 const QRegister temp = Q1;
2173 const QRegister out = Q2;
2174 const Register shift = R1;
2175 const DRegister dtemp0 = EvenDRegisterOf(temp);
2176 const SRegister stemp0 = EvenSRegisterOf(dtemp0);
2177 const DRegister dout0 = EvenDRegisterOf(out);
2178 const SRegister sout0 = EvenSRegisterOf(dout0);
2179 const SRegister sout1 = OddSRegisterOf(dout0);
2180 Label fail;
2181
2182 // Initialize.
2183 __ veorq(value, value, value);
2184 __ veorq(temp, temp, temp);
2185 __ veorq(out, out, out);
2186 __ LoadImmediate(shift, 32);
2187 __ LoadImmediate(R2, 1 << 7);
2188 __ vmovsr(S0, R2);
2189
2190 __ vmovsr(stemp0, shift); // Move the shift into the low S register.
2191 __ vshlqu(kWordPair, out, value, temp);
2192
2193 // check for overflow by shifting back and comparing.
2194 __ rsb(shift, shift, Operand(0));
2195 __ vmovsr(stemp0, shift);
2196 __ vshlqi(kWordPair, temp, out, temp);
2197 __ vceqqi(kFourBytes, out, temp, value);
2198 // Low 64 bits of temp should be all 1's, otherwise temp != value and
2199 // we deopt.
2200 __ vmovrs(shift, sout0);
2201 __ CompareImmediate(shift, -1);
2202 __ b(&fail, NE);
2203 __ vmovrs(shift, sout1);
2204 __ CompareImmediate(shift, -1);
2205 __ b(&fail, NE);
2206
2207 __ LoadImmediate(R0, 1);
2208 __ Ret();
2209
2210 __ Bind(&fail);
2211 __ LoadImmediate(R0, 0);
2212 }
2213 __ Ret();
2214}
2215
2216ASSEMBLER_TEST_RUN(Mint_shl_ok, test) {
2217 EXPECT(test != nullptr);
2219 typedef int (*Tst)() DART_UNUSED;
2220 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2221 }
2222}
2223
2224ASSEMBLER_TEST_GENERATE(Mint_shl_overflow, assembler) {
2226 const QRegister value = Q0;
2227 const QRegister temp = Q1;
2228 const QRegister out = Q2;
2229 const Register shift = R1;
2230 const DRegister dtemp0 = EvenDRegisterOf(temp);
2231 const SRegister stemp0 = EvenSRegisterOf(dtemp0);
2232 const DRegister dout0 = EvenDRegisterOf(out);
2233 const SRegister sout0 = EvenSRegisterOf(dout0);
2234 const SRegister sout1 = OddSRegisterOf(dout0);
2235 Label fail;
2236
2237 // Initialize.
2238 __ veorq(value, value, value);
2239 __ veorq(temp, temp, temp);
2240 __ veorq(out, out, out);
2241 __ LoadImmediate(shift, 60);
2242 __ LoadImmediate(R2, 1 << 7);
2243 __ vmovsr(S0, R2);
2244
2245 __ vmovsr(stemp0, shift); // Move the shift into the low S register.
2246 __ vshlqu(kWordPair, out, value, temp);
2247
2248 // check for overflow by shifting back and comparing.
2249 __ rsb(shift, shift, Operand(0));
2250 __ vmovsr(stemp0, shift);
2251 __ vshlqi(kWordPair, temp, out, temp);
2252 __ vceqqi(kFourBytes, out, temp, value);
2253 // Low 64 bits of temp should be all 1's, otherwise temp != value and
2254 // we deopt.
2255 __ vmovrs(shift, sout0);
2256 __ CompareImmediate(shift, -1);
2257 __ b(&fail, NE);
2258 __ vmovrs(shift, sout1);
2259 __ CompareImmediate(shift, -1);
2260 __ b(&fail, NE);
2261
2262 __ LoadImmediate(R0, 0);
2263 __ Ret();
2264
2265 __ Bind(&fail);
2266 __ LoadImmediate(R0, 1);
2267 }
2268 __ Ret();
2269}
2270
2271ASSEMBLER_TEST_RUN(Mint_shl_overflow, test) {
2272 EXPECT(test != nullptr);
2274 typedef int (*Tst)() DART_UNUSED;
2275 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2276 }
2277}
2278
2279ASSEMBLER_TEST_GENERATE(Vsubqi8, assembler) {
2281 __ mov(R0, Operand(1));
2282 __ vmovsr(S0, R0);
2283 __ mov(R0, Operand(2));
2284 __ vmovsr(S1, R0);
2285 __ mov(R0, Operand(3));
2286 __ vmovsr(S2, R0);
2287 __ mov(R0, Operand(4));
2288 __ vmovsr(S3, R0);
2289 __ mov(R0, Operand(2));
2290 __ vmovsr(S4, R0);
2291 __ mov(R0, Operand(4));
2292 __ vmovsr(S5, R0);
2293 __ mov(R0, Operand(6));
2294 __ vmovsr(S6, R0);
2295 __ mov(R0, Operand(8));
2296 __ vmovsr(S7, R0);
2297
2298 __ vsubqi(kByte, Q2, Q1, Q0);
2299
2300 __ vmovrs(R0, S8);
2301 __ vmovrs(R1, S9);
2302 __ vmovrs(R2, S10);
2303 __ vmovrs(R3, S11);
2304
2305 __ add(R0, R0, Operand(R1));
2306 __ add(R0, R0, Operand(R2));
2307 __ add(R0, R0, Operand(R3));
2308 }
2309 __ Ret();
2310}
2311
2312ASSEMBLER_TEST_RUN(Vsubqi8, test) {
2313 EXPECT(test != nullptr);
2315 typedef int (*Tst)() DART_UNUSED;
2316 EXPECT_EQ(10, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2317 }
2318}
2319
2320ASSEMBLER_TEST_GENERATE(Vsubqi16, assembler) {
2322 __ mov(R0, Operand(1));
2323 __ vmovsr(S0, R0);
2324 __ mov(R0, Operand(2));
2325 __ vmovsr(S1, R0);
2326 __ mov(R0, Operand(3));
2327 __ vmovsr(S2, R0);
2328 __ mov(R0, Operand(4));
2329 __ vmovsr(S3, R0);
2330 __ mov(R0, Operand(2));
2331 __ vmovsr(S4, R0);
2332 __ mov(R0, Operand(4));
2333 __ vmovsr(S5, R0);
2334 __ mov(R0, Operand(6));
2335 __ vmovsr(S6, R0);
2336 __ mov(R0, Operand(8));
2337 __ vmovsr(S7, R0);
2338
2339 __ vsubqi(kTwoBytes, Q2, Q1, Q0);
2340
2341 __ vmovrs(R0, S8);
2342 __ vmovrs(R1, S9);
2343 __ vmovrs(R2, S10);
2344 __ vmovrs(R3, S11);
2345
2346 __ add(R0, R0, Operand(R1));
2347 __ add(R0, R0, Operand(R2));
2348 __ add(R0, R0, Operand(R3));
2349 }
2350 __ Ret();
2351}
2352
2353ASSEMBLER_TEST_RUN(Vsubqi16, test) {
2354 EXPECT(test != nullptr);
2356 typedef int (*Tst)() DART_UNUSED;
2357 EXPECT_EQ(10, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2358 }
2359}
2360
2361ASSEMBLER_TEST_GENERATE(Vsubqi32, assembler) {
2363 __ mov(R0, Operand(1));
2364 __ vmovsr(S0, R0);
2365 __ mov(R0, Operand(2));
2366 __ vmovsr(S1, R0);
2367 __ mov(R0, Operand(3));
2368 __ vmovsr(S2, R0);
2369 __ mov(R0, Operand(4));
2370 __ vmovsr(S3, R0);
2371 __ mov(R0, Operand(2));
2372 __ vmovsr(S4, R0);
2373 __ mov(R0, Operand(4));
2374 __ vmovsr(S5, R0);
2375 __ mov(R0, Operand(6));
2376 __ vmovsr(S6, R0);
2377 __ mov(R0, Operand(8));
2378 __ vmovsr(S7, R0);
2379
2380 __ vsubqi(kFourBytes, Q2, Q1, Q0);
2381
2382 __ vmovrs(R0, S8);
2383 __ vmovrs(R1, S9);
2384 __ vmovrs(R2, S10);
2385 __ vmovrs(R3, S11);
2386
2387 __ add(R0, R0, Operand(R1));
2388 __ add(R0, R0, Operand(R2));
2389 __ add(R0, R0, Operand(R3));
2390 }
2391 __ Ret();
2392}
2393
2394ASSEMBLER_TEST_RUN(Vsubqi32, test) {
2395 EXPECT(test != nullptr);
2397 typedef int (*Tst)() DART_UNUSED;
2398 EXPECT_EQ(10, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2399 }
2400}
2401
2402ASSEMBLER_TEST_GENERATE(Vsubqi64, assembler) {
2404 __ mov(R0, Operand(1));
2405 __ vmovsr(S0, R0);
2406 __ mov(R0, Operand(2));
2407 __ vmovsr(S2, R0);
2408 __ mov(R0, Operand(2));
2409 __ vmovsr(S4, R0);
2410 __ mov(R0, Operand(4));
2411 __ vmovsr(S6, R0);
2412
2413 __ vsubqi(kWordPair, Q2, Q1, Q0);
2414
2415 __ vmovrs(R0, S8);
2416 __ vmovrs(R2, S10);
2417
2418 __ add(R0, R0, Operand(R2));
2419 }
2420 __ Ret();
2421}
2422
2423ASSEMBLER_TEST_RUN(Vsubqi64, test) {
2424 EXPECT(test != nullptr);
2426 typedef int (*Tst)() DART_UNUSED;
2427 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2428 }
2429}
2430
2431ASSEMBLER_TEST_GENERATE(Vmulqi8, assembler) {
2433 __ mov(R0, Operand(1));
2434 __ vmovsr(S0, R0);
2435 __ mov(R0, Operand(2));
2436 __ vmovsr(S1, R0);
2437 __ mov(R0, Operand(3));
2438 __ vmovsr(S2, R0);
2439 __ mov(R0, Operand(4));
2440 __ vmovsr(S3, R0);
2441 __ mov(R0, Operand(5));
2442 __ vmovsr(S4, R0);
2443 __ mov(R0, Operand(6));
2444 __ vmovsr(S5, R0);
2445 __ mov(R0, Operand(7));
2446 __ vmovsr(S6, R0);
2447 __ mov(R0, Operand(8));
2448 __ vmovsr(S7, R0);
2449
2450 __ vmulqi(kByte, Q2, Q1, Q0);
2451
2452 __ vmovrs(R0, S8);
2453 __ vmovrs(R1, S9);
2454 __ vmovrs(R2, S10);
2455 __ vmovrs(R3, S11);
2456
2457 __ add(R0, R0, Operand(R1));
2458 __ add(R0, R0, Operand(R2));
2459 __ add(R0, R0, Operand(R3));
2460 }
2461 __ Ret();
2462}
2463
2464ASSEMBLER_TEST_RUN(Vmulqi8, test) {
2465 EXPECT(test != nullptr);
2467 typedef int (*Tst)() DART_UNUSED;
2468 EXPECT_EQ(70, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2469 }
2470}
2471
2472ASSEMBLER_TEST_GENERATE(Vmulqi16, assembler) {
2474 __ mov(R0, Operand(1));
2475 __ vmovsr(S0, R0);
2476 __ mov(R0, Operand(2));
2477 __ vmovsr(S1, R0);
2478 __ mov(R0, Operand(3));
2479 __ vmovsr(S2, R0);
2480 __ mov(R0, Operand(4));
2481 __ vmovsr(S3, R0);
2482 __ mov(R0, Operand(5));
2483 __ vmovsr(S4, R0);
2484 __ mov(R0, Operand(6));
2485 __ vmovsr(S5, R0);
2486 __ mov(R0, Operand(7));
2487 __ vmovsr(S6, R0);
2488 __ mov(R0, Operand(8));
2489 __ vmovsr(S7, R0);
2490
2491 __ vmulqi(kTwoBytes, Q2, Q1, Q0);
2492
2493 __ vmovrs(R0, S8);
2494 __ vmovrs(R1, S9);
2495 __ vmovrs(R2, S10);
2496 __ vmovrs(R3, S11);
2497
2498 __ add(R0, R0, Operand(R1));
2499 __ add(R0, R0, Operand(R2));
2500 __ add(R0, R0, Operand(R3));
2501 }
2502 __ Ret();
2503}
2504
2505ASSEMBLER_TEST_RUN(Vmulqi16, test) {
2506 EXPECT(test != nullptr);
2508 typedef int (*Tst)() DART_UNUSED;
2509 EXPECT_EQ(70, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2510 }
2511}
2512
2513ASSEMBLER_TEST_GENERATE(Vmulqi32, assembler) {
2515 __ mov(R0, Operand(1));
2516 __ vmovsr(S0, R0);
2517 __ mov(R0, Operand(2));
2518 __ vmovsr(S1, R0);
2519 __ mov(R0, Operand(3));
2520 __ vmovsr(S2, R0);
2521 __ mov(R0, Operand(4));
2522 __ vmovsr(S3, R0);
2523 __ mov(R0, Operand(5));
2524 __ vmovsr(S4, R0);
2525 __ mov(R0, Operand(6));
2526 __ vmovsr(S5, R0);
2527 __ mov(R0, Operand(7));
2528 __ vmovsr(S6, R0);
2529 __ mov(R0, Operand(8));
2530 __ vmovsr(S7, R0);
2531
2532 __ vmulqi(kFourBytes, Q2, Q1, Q0);
2533
2534 __ vmovrs(R0, S8);
2535 __ vmovrs(R1, S9);
2536 __ vmovrs(R2, S10);
2537 __ vmovrs(R3, S11);
2538
2539 __ add(R0, R0, Operand(R1));
2540 __ add(R0, R0, Operand(R2));
2541 __ add(R0, R0, Operand(R3));
2542 }
2543 __ Ret();
2544}
2545
2546ASSEMBLER_TEST_RUN(Vmulqi32, test) {
2547 EXPECT(test != nullptr);
2549 typedef int (*Tst)() DART_UNUSED;
2550 EXPECT_EQ(70, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2551 }
2552}
2553
2554ASSEMBLER_TEST_GENERATE(Vaddqs, assembler) {
2556 __ LoadSImmediate(S0, 1.0);
2557 __ LoadSImmediate(S1, 2.0);
2558 __ LoadSImmediate(S2, 3.0);
2559 __ LoadSImmediate(S3, 4.0);
2560 __ LoadSImmediate(S4, 5.0);
2561 __ LoadSImmediate(S5, 6.0);
2562 __ LoadSImmediate(S6, 7.0);
2563 __ LoadSImmediate(S7, 8.0);
2564
2565 __ vaddqs(Q2, Q0, Q1);
2566
2567 __ vadds(S8, S8, S9);
2568 __ vadds(S8, S8, S10);
2569 __ vadds(S8, S8, S11);
2570
2571 __ vcvtis(S0, S8);
2572 __ vmovrs(R0, S0);
2573 }
2574 __ Ret();
2575}
2576
2577ASSEMBLER_TEST_RUN(Vaddqs, test) {
2578 EXPECT(test != nullptr);
2580 typedef int (*Tst)() DART_UNUSED;
2581 EXPECT_EQ(36, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2582 }
2583}
2584
2585ASSEMBLER_TEST_GENERATE(Vsubqs, assembler) {
2587 __ LoadSImmediate(S0, 1.0);
2588 __ LoadSImmediate(S1, 2.0);
2589 __ LoadSImmediate(S2, 3.0);
2590 __ LoadSImmediate(S3, 4.0);
2591 __ LoadSImmediate(S4, 2.0);
2592 __ LoadSImmediate(S5, 4.0);
2593 __ LoadSImmediate(S6, 6.0);
2594 __ LoadSImmediate(S7, 8.0);
2595
2596 __ vsubqs(Q2, Q1, Q0);
2597
2598 __ vadds(S8, S8, S9);
2599 __ vadds(S8, S8, S10);
2600 __ vadds(S8, S8, S11);
2601
2602 __ vcvtis(S0, S8);
2603 __ vmovrs(R0, S0);
2604 }
2605 __ Ret();
2606}
2607
2608ASSEMBLER_TEST_RUN(Vsubqs, test) {
2609 EXPECT(test != nullptr);
2611 typedef int (*Tst)() DART_UNUSED;
2612 EXPECT_EQ(10, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2613 }
2614}
2615
2616ASSEMBLER_TEST_GENERATE(Vmulqs, assembler) {
2618 __ LoadSImmediate(S0, 1.0);
2619 __ LoadSImmediate(S1, 2.0);
2620 __ LoadSImmediate(S2, 3.0);
2621 __ LoadSImmediate(S3, 4.0);
2622 __ LoadSImmediate(S4, 5.0);
2623 __ LoadSImmediate(S5, 6.0);
2624 __ LoadSImmediate(S6, 7.0);
2625 __ LoadSImmediate(S7, 8.0);
2626
2627 __ vmulqs(Q2, Q1, Q0);
2628
2629 __ vadds(S8, S8, S9);
2630 __ vadds(S8, S8, S10);
2631 __ vadds(S8, S8, S11);
2632
2633 __ vcvtis(S0, S8);
2634 __ vmovrs(R0, S0);
2635 }
2636 __ Ret();
2637}
2638
2639ASSEMBLER_TEST_RUN(Vmulqs, test) {
2640 EXPECT(test != nullptr);
2642 typedef int (*Tst)() DART_UNUSED;
2643 EXPECT_EQ(70, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2644 }
2645}
2646
2647ASSEMBLER_TEST_GENERATE(VtblX, assembler) {
2649 // Index.
2650 __ LoadImmediate(R0, 0x03020100);
2651 __ vmovsr(S0, R0);
2652 __ vmovsr(S1, R0);
2653
2654 // Table.
2655 __ LoadSImmediate(S2, 1.0);
2656 __ LoadSImmediate(S3, 2.0);
2657 __ LoadSImmediate(S4, 3.0);
2658 __ LoadSImmediate(S5, 4.0);
2659
2660 // Select.
2661 __ vtbl(D3, D1, 2, D0);
2662
2663 // Check that S6, S7 are both 1.0
2664 __ vcvtis(S0, S6);
2665 __ vcvtis(S1, S7);
2666 __ vmovrs(R2, S0);
2667 __ vmovrs(R3, S1);
2668
2669 __ LoadImmediate(R0, 0);
2670 __ CompareImmediate(R2, 1);
2671 __ Ret(NE);
2672 __ CompareImmediate(R3, 1);
2673 __ Ret(NE);
2674 __ LoadImmediate(R0, 42);
2675 }
2676 __ Ret();
2677}
2678
2679ASSEMBLER_TEST_RUN(VtblX, test) {
2680 EXPECT(test != nullptr);
2682 typedef int (*Tst)() DART_UNUSED;
2683 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2684 }
2685}
2686
2687ASSEMBLER_TEST_GENERATE(VtblY, assembler) {
2689 // Index.
2690 __ LoadImmediate(R0, 0x07060504);
2691 __ vmovsr(S0, R0);
2692 __ vmovsr(S1, R0);
2693
2694 // Table.
2695 __ LoadSImmediate(S2, 2.0);
2696 __ LoadSImmediate(S3, 1.0);
2697 __ LoadSImmediate(S4, 3.0);
2698 __ LoadSImmediate(S5, 4.0);
2699
2700 // Select.
2701 __ vtbl(D3, D1, 2, D0);
2702
2703 // Check that S6, S7 are both 1.0
2704 __ vcvtis(S0, S6);
2705 __ vcvtis(S1, S7);
2706 __ vmovrs(R2, S0);
2707 __ vmovrs(R3, S1);
2708
2709 __ LoadImmediate(R0, 0);
2710 __ CompareImmediate(R2, 1);
2711 __ Ret(NE);
2712 __ CompareImmediate(R3, 1);
2713 __ Ret(NE);
2714 __ LoadImmediate(R0, 42);
2715 }
2716 __ Ret();
2717}
2718
2719ASSEMBLER_TEST_RUN(VtblY, test) {
2720 EXPECT(test != nullptr);
2722 typedef int (*Tst)() DART_UNUSED;
2723 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2724 }
2725}
2726
2727ASSEMBLER_TEST_GENERATE(VtblZ, assembler) {
2729 // Index.
2730 __ LoadImmediate(R0, 0x0b0a0908);
2731 __ vmovsr(S0, R0);
2732 __ vmovsr(S1, R0);
2733
2734 // Table.
2735 __ LoadSImmediate(S2, 2.0);
2736 __ LoadSImmediate(S3, 3.0);
2737 __ LoadSImmediate(S4, 1.0);
2738 __ LoadSImmediate(S5, 4.0);
2739
2740 // Select.
2741 __ vtbl(D3, D1, 2, D0);
2742
2743 // Check that S6, S7 are both 1.0
2744 __ vcvtis(S0, S6);
2745 __ vcvtis(S1, S7);
2746 __ vmovrs(R2, S0);
2747 __ vmovrs(R3, S1);
2748
2749 __ LoadImmediate(R0, 0);
2750 __ CompareImmediate(R2, 1);
2751 __ Ret(NE);
2752 __ CompareImmediate(R3, 1);
2753 __ Ret(NE);
2754 __ LoadImmediate(R0, 42);
2755 }
2756 __ Ret();
2757}
2758
2759ASSEMBLER_TEST_RUN(VtblZ, test) {
2760 EXPECT(test != nullptr);
2762 typedef int (*Tst)() DART_UNUSED;
2763 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2764 }
2765}
2766
2767ASSEMBLER_TEST_GENERATE(VtblW, assembler) {
2769 // Index.
2770 __ LoadImmediate(R0, 0x0f0e0d0c);
2771 __ vmovsr(S0, R0);
2772 __ vmovsr(S1, R0);
2773
2774 // Table.
2775 __ LoadSImmediate(S2, 2.0);
2776 __ LoadSImmediate(S3, 3.0);
2777 __ LoadSImmediate(S4, 4.0);
2778 __ LoadSImmediate(S5, 1.0);
2779
2780 // Select.
2781 __ vtbl(D3, D1, 2, D0);
2782
2783 // Check that S6, S7 are both 1.0
2784 __ vcvtis(S0, S6);
2785 __ vcvtis(S1, S7);
2786 __ vmovrs(R2, S0);
2787 __ vmovrs(R3, S1);
2788
2789 __ LoadImmediate(R0, 0);
2790 __ CompareImmediate(R2, 1);
2791 __ Ret(NE);
2792 __ CompareImmediate(R3, 1);
2793 __ Ret(NE);
2794 __ LoadImmediate(R0, 42);
2795 }
2796 __ Ret();
2797}
2798
2799ASSEMBLER_TEST_RUN(VtblW, test) {
2800 EXPECT(test != nullptr);
2802 typedef int (*Tst)() DART_UNUSED;
2803 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2804 }
2805}
2806
2807ASSEMBLER_TEST_GENERATE(Veorq, assembler) {
2809 // Q0
2810 __ LoadImmediate(R0, 0xaaaaaaab);
2811 __ vmovsr(S0, R0);
2812 __ vmovsr(S1, R0);
2813 __ vmovsr(S2, R0);
2814 __ vmovsr(S3, R0);
2815
2816 // Q1
2817 __ LoadImmediate(R0, 0x55555555);
2818 __ vmovsr(S4, R0);
2819 __ vmovsr(S5, R0);
2820 __ vmovsr(S6, R0);
2821 __ vmovsr(S7, R0);
2822
2823 // Q2 = -2 -2 -2 -2
2824 __ veorq(Q2, Q1, Q0);
2825
2826 __ vmovrs(R0, S8);
2827 __ vmovrs(R1, S9);
2828 __ vmovrs(R2, S10);
2829 __ vmovrs(R3, S11);
2830
2831 __ add(R0, R0, Operand(R1));
2832 __ add(R0, R0, Operand(R2));
2833 __ add(R0, R0, Operand(R3));
2834 }
2835 __ Ret();
2836}
2837
2838ASSEMBLER_TEST_RUN(Veorq, test) {
2839 EXPECT(test != nullptr);
2841 typedef int (*Tst)() DART_UNUSED;
2842 EXPECT_EQ(-8, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2843 }
2844}
2845
2846ASSEMBLER_TEST_GENERATE(Vornq, assembler) {
2848 // Q0
2849 __ LoadImmediate(R0, 0xfffffff0);
2850 __ vmovsr(S0, R0);
2851 __ vmovsr(S1, R0);
2852 __ vmovsr(S2, R0);
2853 __ vmovsr(S3, R0);
2854
2855 // Q1
2856 __ LoadImmediate(R0, 0);
2857 __ vmovsr(S4, R0);
2858 __ vmovsr(S5, R0);
2859 __ vmovsr(S6, R0);
2860 __ vmovsr(S7, R0);
2861
2862 // Q2 = 15 15 15 15
2863 __ vornq(Q2, Q1, Q0);
2864
2865 __ vmovrs(R0, S8);
2866 __ vmovrs(R1, S9);
2867 __ vmovrs(R2, S10);
2868 __ vmovrs(R3, S11);
2869
2870 __ add(R0, R0, Operand(R1));
2871 __ add(R0, R0, Operand(R2));
2872 __ add(R0, R0, Operand(R3));
2873 }
2874 __ Ret();
2875}
2876
2877ASSEMBLER_TEST_RUN(Vornq, test) {
2878 EXPECT(test != nullptr);
2880 typedef int (*Tst)() DART_UNUSED;
2881 EXPECT_EQ(60, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2882 }
2883}
2884
2885ASSEMBLER_TEST_GENERATE(Vorrq, assembler) {
2887 // Q0
2888 __ LoadImmediate(R0, 0xaaaaaaaa);
2889 __ vmovsr(S0, R0);
2890 __ vmovsr(S1, R0);
2891 __ vmovsr(S2, R0);
2892 __ vmovsr(S3, R0);
2893
2894 // Q1
2895 __ LoadImmediate(R0, 0x55555555);
2896 __ vmovsr(S4, R0);
2897 __ vmovsr(S5, R0);
2898 __ vmovsr(S6, R0);
2899 __ vmovsr(S7, R0);
2900
2901 // Q2 = -1 -1 -1 -1
2902 __ vorrq(Q2, Q1, Q0);
2903
2904 __ vmovrs(R0, S8);
2905 __ vmovrs(R1, S9);
2906 __ vmovrs(R2, S10);
2907 __ vmovrs(R3, S11);
2908
2909 __ add(R0, R0, Operand(R1));
2910 __ add(R0, R0, Operand(R2));
2911 __ add(R0, R0, Operand(R3));
2912 }
2913 __ Ret();
2914}
2915
2916ASSEMBLER_TEST_RUN(Vorrq, test) {
2917 EXPECT(test != nullptr);
2919 typedef int (*Tst)() DART_UNUSED;
2920 EXPECT_EQ(-4, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2921 }
2922}
2923
2924ASSEMBLER_TEST_GENERATE(Vandq, assembler) {
2926 // Q0
2927 __ LoadImmediate(R0, 0xaaaaaaab);
2928 __ vmovsr(S0, R0);
2929 __ vmovsr(S1, R0);
2930 __ vmovsr(S2, R0);
2931 __ vmovsr(S3, R0);
2932
2933 // Q1
2934 __ LoadImmediate(R0, 0x55555555);
2935 __ vmovsr(S4, R0);
2936 __ vmovsr(S5, R0);
2937 __ vmovsr(S6, R0);
2938 __ vmovsr(S7, R0);
2939
2940 // Q2 = 1 1 1 1
2941 __ vandq(Q2, Q1, Q0);
2942
2943 __ vmovrs(R0, S8);
2944 __ vmovrs(R1, S9);
2945 __ vmovrs(R2, S10);
2946 __ vmovrs(R3, S11);
2947
2948 __ add(R0, R0, Operand(R1));
2949 __ add(R0, R0, Operand(R2));
2950 __ add(R0, R0, Operand(R3));
2951 }
2952 __ Ret();
2953}
2954
2955ASSEMBLER_TEST_RUN(Vandq, test) {
2956 EXPECT(test != nullptr);
2958 typedef int (*Tst)() DART_UNUSED;
2959 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2960 }
2961}
2962
2963ASSEMBLER_TEST_GENERATE(Vmovq, assembler) {
2965 // Q0
2966 __ LoadSImmediate(S0, 1.0);
2967 __ vmovs(S1, S0);
2968 __ vmovs(S2, S0);
2969 __ vmovs(S3, S0);
2970
2971 // Q0
2972 __ LoadSImmediate(S4, -1.0);
2973 __ vmovs(S5, S0);
2974 __ vmovs(S6, S0);
2975 __ vmovs(S7, S0);
2976
2977 // Q1 = Q2
2978 __ vmovq(Q1, Q0);
2979
2980 __ vadds(S4, S4, S5);
2981 __ vadds(S4, S4, S6);
2982 __ vadds(S4, S4, S7);
2983 __ vcvtis(S0, S4);
2984 __ vmovrs(R0, S0);
2985 }
2986 __ Ret();
2987}
2988
2989ASSEMBLER_TEST_RUN(Vmovq, test) {
2990 EXPECT(test != nullptr);
2992 typedef int (*Tst)() DART_UNUSED;
2993 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2994 }
2995}
2996
2997ASSEMBLER_TEST_GENERATE(Vmvnq, assembler) {
2999 __ LoadImmediate(R1, 42); // R1 <- 42.
3000 __ vmovsr(S2, R1); // S2 <- R1.
3001 __ vmvnq(Q1, Q0); // Q1 <- ~Q0.
3002 __ vmvnq(Q2, Q1); // Q2 <- ~Q1.
3003 __ vmovrs(R0, S10); // Now R0 should be 42 again.
3004 }
3005 __ Ret();
3006}
3007
3008ASSEMBLER_TEST_RUN(Vmvnq, test) {
3009 EXPECT(test != nullptr);
3011 typedef int (*Tst)() DART_UNUSED;
3012 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3013 }
3014}
3015
3016ASSEMBLER_TEST_GENERATE(Vdupb, assembler) {
3018 __ LoadImmediate(R0, 0x00000000);
3019 __ LoadImmediate(R1, 0x00ff0000);
3020 __ vmovsr(S4, R0);
3021 __ vmovsr(S5, R1);
3022
3023 // Should copy 0xff to each byte of Q0.
3024 __ vdup(kByte, Q0, D2, 6);
3025
3026 __ vmovrs(R0, S0);
3027 __ vmovrs(R1, S1);
3028 __ vmovrs(R2, S2);
3029 __ vmovrs(R3, S3);
3030
3031 __ add(R0, R0, Operand(R1));
3032 __ add(R0, R0, Operand(R2));
3033 __ add(R0, R0, Operand(R3));
3034 }
3035 __ Ret();
3036}
3037
3038ASSEMBLER_TEST_RUN(Vdupb, test) {
3039 EXPECT(test != nullptr);
3041 typedef int (*Tst)() DART_UNUSED;
3042 EXPECT_EQ(-4, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3043 }
3044}
3045
3046ASSEMBLER_TEST_GENERATE(Vduph, assembler) {
3048 __ LoadImmediate(R0, 0xffff0000);
3049 __ LoadImmediate(R1, 0x00000000);
3050 __ vmovsr(S4, R0);
3051 __ vmovsr(S5, R1);
3052
3053 // Should copy 0xff to each byte of Q0.
3054 __ vdup(kTwoBytes, Q0, D2, 1);
3055
3056 __ vmovrs(R0, S0);
3057 __ vmovrs(R1, S1);
3058 __ vmovrs(R2, S2);
3059 __ vmovrs(R3, S3);
3060
3061 __ add(R0, R0, Operand(R1));
3062 __ add(R0, R0, Operand(R2));
3063 __ add(R0, R0, Operand(R3));
3064 }
3065 __ Ret();
3066}
3067
3068ASSEMBLER_TEST_RUN(Vduph, test) {
3069 EXPECT(test != nullptr);
3071 typedef int (*Tst)() DART_UNUSED;
3072 EXPECT_EQ(-4, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3073 }
3074}
3075
3076ASSEMBLER_TEST_GENERATE(Vdupw, assembler) {
3078 __ LoadImmediate(R0, 0x00000000);
3079 __ LoadImmediate(R1, 0xffffffff);
3080 __ vmovsr(S4, R0);
3081 __ vmovsr(S5, R1);
3082
3083 // Should copy 0xff to each byte of Q0.
3084 __ vdup(kFourBytes, Q0, D2, 1);
3085
3086 __ vmovrs(R0, S0);
3087 __ vmovrs(R1, S1);
3088 __ vmovrs(R2, S2);
3089 __ vmovrs(R3, S3);
3090
3091 __ add(R0, R0, Operand(R1));
3092 __ add(R0, R0, Operand(R2));
3093 __ add(R0, R0, Operand(R3));
3094 }
3095 __ Ret();
3096}
3097
3098ASSEMBLER_TEST_RUN(Vdupw, test) {
3099 EXPECT(test != nullptr);
3101 typedef int (*Tst)() DART_UNUSED;
3102 EXPECT_EQ(-4, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3103 }
3104}
3105
3106ASSEMBLER_TEST_GENERATE(Vzipqw, assembler) {
3108 __ LoadSImmediate(S0, 0.0);
3109 __ LoadSImmediate(S1, 1.0);
3110 __ LoadSImmediate(S2, 2.0);
3111 __ LoadSImmediate(S3, 3.0);
3112 __ LoadSImmediate(S4, 4.0);
3113 __ LoadSImmediate(S5, 5.0);
3114 __ LoadSImmediate(S6, 6.0);
3115 __ LoadSImmediate(S7, 7.0);
3116
3117 __ vzipqw(Q0, Q1);
3118
3119 __ vsubqs(Q0, Q1, Q0);
3120
3121 __ vadds(S0, S0, S1);
3122 __ vadds(S0, S0, S2);
3123 __ vadds(S0, S0, S3);
3124 }
3125 __ Ret();
3126}
3127
3128ASSEMBLER_TEST_RUN(Vzipqw, test) {
3129 EXPECT(test != nullptr);
3131 typedef float (*Vzipqw)() DART_UNUSED;
3132 float res = EXECUTE_TEST_CODE_FLOAT(Vzipqw, test->entry());
3133 EXPECT_FLOAT_EQ(8.0, res, 0.0001f);
3134 }
3135}
3136
3137ASSEMBLER_TEST_GENERATE(Vceqqi32, assembler) {
3139 __ mov(R0, Operand(1));
3140 __ vmovsr(S0, R0);
3141 __ mov(R0, Operand(2));
3142 __ vmovsr(S1, R0);
3143 __ mov(R0, Operand(3));
3144 __ vmovsr(S2, R0);
3145 __ mov(R0, Operand(4));
3146 __ vmovsr(S3, R0);
3147 __ mov(R0, Operand(1));
3148 __ vmovsr(S4, R0);
3149 __ mov(R0, Operand(20));
3150 __ vmovsr(S5, R0);
3151 __ mov(R0, Operand(3));
3152 __ vmovsr(S6, R0);
3153 __ mov(R0, Operand(40));
3154 __ vmovsr(S7, R0);
3155
3156 __ vceqqi(kFourBytes, Q2, Q1, Q0);
3157
3158 __ vmovrs(R0, S8);
3159 __ vmovrs(R1, S9);
3160 __ vmovrs(R2, S10);
3161 __ vmovrs(R3, S11);
3162
3163 __ add(R0, R0, Operand(R1));
3164 __ add(R0, R0, Operand(R2));
3165 __ add(R0, R0, Operand(R3));
3166 }
3167 __ Ret();
3168}
3169
3170ASSEMBLER_TEST_RUN(Vceqqi32, test) {
3171 EXPECT(test != nullptr);
3173 typedef int (*Tst)() DART_UNUSED;
3174 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3175 }
3176}
3177
3178ASSEMBLER_TEST_GENERATE(Vceqqs, assembler) {
3180 __ LoadSImmediate(S0, 1.0);
3181 __ LoadSImmediate(S1, 2.0);
3182 __ LoadSImmediate(S2, 3.0);
3183 __ LoadSImmediate(S3, 4.0);
3184 __ LoadSImmediate(S4, 1.0);
3185 __ LoadSImmediate(S5, 4.0);
3186 __ LoadSImmediate(S6, 3.0);
3187 __ LoadSImmediate(S7, 8.0);
3188
3189 __ vceqqs(Q2, Q1, Q0);
3190
3191 __ vmovrs(R0, S8);
3192 __ vmovrs(R1, S9);
3193 __ vmovrs(R2, S10);
3194 __ vmovrs(R3, S11);
3195
3196 __ add(R0, R0, Operand(R1));
3197 __ add(R0, R0, Operand(R2));
3198 __ add(R0, R0, Operand(R3));
3199 }
3200 __ Ret();
3201}
3202
3203ASSEMBLER_TEST_RUN(Vceqqs, test) {
3204 EXPECT(test != nullptr);
3206 typedef int (*Tst)() DART_UNUSED;
3207 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3208 }
3209}
3210
3211ASSEMBLER_TEST_GENERATE(Vcgeqi32, assembler) {
3213 __ mov(R0, Operand(1));
3214 __ vmovsr(S0, R0);
3215 __ mov(R0, Operand(2));
3216 __ vmovsr(S1, R0);
3217 __ mov(R0, Operand(3));
3218 __ vmovsr(S2, R0);
3219 __ mov(R0, Operand(4));
3220 __ vmovsr(S3, R0);
3221 __ mov(R0, Operand(1));
3222 __ vmovsr(S4, R0);
3223 __ mov(R0, Operand(1));
3224 __ vmovsr(S5, R0);
3225 __ mov(R0, Operand(3));
3226 __ vmovsr(S6, R0);
3227 __ mov(R0, Operand(1));
3228 __ vmovsr(S7, R0);
3229
3230 __ vcgeqi(kFourBytes, Q2, Q1, Q0);
3231
3232 __ vmovrs(R0, S8);
3233 __ vmovrs(R1, S9);
3234 __ vmovrs(R2, S10);
3235 __ vmovrs(R3, S11);
3236
3237 __ add(R0, R0, Operand(R1));
3238 __ add(R0, R0, Operand(R2));
3239 __ add(R0, R0, Operand(R3));
3240 }
3241 __ Ret();
3242}
3243
3244ASSEMBLER_TEST_RUN(Vcgeqi32, test) {
3245 EXPECT(test != nullptr);
3247 typedef int (*Tst)() DART_UNUSED;
3248 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3249 }
3250}
3251
3252ASSEMBLER_TEST_GENERATE(Vcugeqi32, assembler) {
3254 __ mov(R0, Operand(1));
3255 __ vmovsr(S0, R0);
3256 __ mov(R0, Operand(2));
3257 __ vmovsr(S1, R0);
3258 __ mov(R0, Operand(3));
3259 __ vmovsr(S2, R0);
3260 __ mov(R0, Operand(4));
3261 __ vmovsr(S3, R0);
3262 __ LoadImmediate(R0, -1);
3263 __ vmovsr(S4, R0);
3264 __ mov(R0, Operand(1));
3265 __ vmovsr(S5, R0);
3266 __ LoadImmediate(R0, -3);
3267 __ vmovsr(S6, R0);
3268 __ mov(R0, Operand(1));
3269 __ vmovsr(S7, R0);
3270
3271 __ vcugeqi(kFourBytes, Q2, Q1, Q0);
3272
3273 __ vmovrs(R0, S8);
3274 __ vmovrs(R1, S9);
3275 __ vmovrs(R2, S10);
3276 __ vmovrs(R3, S11);
3277
3278 __ add(R0, R0, Operand(R1));
3279 __ add(R0, R0, Operand(R2));
3280 __ add(R0, R0, Operand(R3));
3281 }
3282 __ Ret();
3283}
3284
3285ASSEMBLER_TEST_RUN(Vcugeqi32, test) {
3286 EXPECT(test != nullptr);
3288 typedef int (*Tst)() DART_UNUSED;
3289 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3290 }
3291}
3292
3293ASSEMBLER_TEST_GENERATE(Vcgeqs, assembler) {
3295 __ LoadSImmediate(S0, 1.0);
3296 __ LoadSImmediate(S1, 2.0);
3297 __ LoadSImmediate(S2, 3.0);
3298 __ LoadSImmediate(S3, 4.0);
3299 __ LoadSImmediate(S4, 1.0);
3300 __ LoadSImmediate(S5, 1.0);
3301 __ LoadSImmediate(S6, 3.0);
3302 __ LoadSImmediate(S7, 1.0);
3303
3304 __ vcgeqs(Q2, Q1, Q0);
3305
3306 __ vmovrs(R0, S8);
3307 __ vmovrs(R1, S9);
3308 __ vmovrs(R2, S10);
3309 __ vmovrs(R3, S11);
3310
3311 __ add(R0, R0, Operand(R1));
3312 __ add(R0, R0, Operand(R2));
3313 __ add(R0, R0, Operand(R3));
3314 }
3315 __ Ret();
3316}
3317
3318ASSEMBLER_TEST_RUN(Vcgeqs, test) {
3319 EXPECT(test != nullptr);
3321 typedef int (*Tst)() DART_UNUSED;
3322 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3323 }
3324}
3325
3326ASSEMBLER_TEST_GENERATE(Vcgtqi32, assembler) {
3328 __ mov(R0, Operand(1));
3329 __ vmovsr(S0, R0);
3330 __ mov(R0, Operand(2));
3331 __ vmovsr(S1, R0);
3332 __ mov(R0, Operand(3));
3333 __ vmovsr(S2, R0);
3334 __ mov(R0, Operand(4));
3335 __ vmovsr(S3, R0);
3336 __ mov(R0, Operand(2));
3337 __ vmovsr(S4, R0);
3338 __ mov(R0, Operand(1));
3339 __ vmovsr(S5, R0);
3340 __ mov(R0, Operand(4));
3341 __ vmovsr(S6, R0);
3342 __ mov(R0, Operand(1));
3343 __ vmovsr(S7, R0);
3344
3345 __ vcgtqi(kFourBytes, Q2, Q1, Q0);
3346
3347 __ vmovrs(R0, S8);
3348 __ vmovrs(R1, S9);
3349 __ vmovrs(R2, S10);
3350 __ vmovrs(R3, S11);
3351
3352 __ add(R0, R0, Operand(R1));
3353 __ add(R0, R0, Operand(R2));
3354 __ add(R0, R0, Operand(R3));
3355 }
3356 __ Ret();
3357}
3358
3359ASSEMBLER_TEST_RUN(Vcgtqi32, test) {
3360 EXPECT(test != nullptr);
3362 typedef int (*Tst)() DART_UNUSED;
3363 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3364 }
3365}
3366
3367ASSEMBLER_TEST_GENERATE(Vcugtqi32, assembler) {
3369 __ mov(R0, Operand(1));
3370 __ vmovsr(S0, R0);
3371 __ mov(R0, Operand(2));
3372 __ vmovsr(S1, R0);
3373 __ mov(R0, Operand(3));
3374 __ vmovsr(S2, R0);
3375 __ mov(R0, Operand(4));
3376 __ vmovsr(S3, R0);
3377 __ LoadImmediate(R0, -1);
3378 __ vmovsr(S4, R0);
3379 __ mov(R0, Operand(1));
3380 __ vmovsr(S5, R0);
3381 __ LoadImmediate(R0, -3);
3382 __ vmovsr(S6, R0);
3383 __ mov(R0, Operand(1));
3384 __ vmovsr(S7, R0);
3385
3386 __ vcugtqi(kFourBytes, Q2, Q1, Q0);
3387
3388 __ vmovrs(R0, S8);
3389 __ vmovrs(R1, S9);
3390 __ vmovrs(R2, S10);
3391 __ vmovrs(R3, S11);
3392
3393 __ add(R0, R0, Operand(R1));
3394 __ add(R0, R0, Operand(R2));
3395 __ add(R0, R0, Operand(R3));
3396 }
3397 __ Ret();
3398}
3399
3400ASSEMBLER_TEST_RUN(Vcugtqi32, test) {
3401 EXPECT(test != nullptr);
3403 typedef int (*Tst)() DART_UNUSED;
3404 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3405 }
3406}
3407
3408ASSEMBLER_TEST_GENERATE(Vcgtqs, assembler) {
3410 __ LoadSImmediate(S0, 1.0);
3411 __ LoadSImmediate(S1, 2.0);
3412 __ LoadSImmediate(S2, 3.0);
3413 __ LoadSImmediate(S3, 4.0);
3414 __ LoadSImmediate(S4, 2.0);
3415 __ LoadSImmediate(S5, 1.0);
3416 __ LoadSImmediate(S6, 4.0);
3417 __ LoadSImmediate(S7, 1.0);
3418
3419 __ vcgtqs(Q2, Q1, Q0);
3420
3421 __ vmovrs(R0, S8);
3422 __ vmovrs(R1, S9);
3423 __ vmovrs(R2, S10);
3424 __ vmovrs(R3, S11);
3425
3426 __ add(R0, R0, Operand(R1));
3427 __ add(R0, R0, Operand(R2));
3428 __ add(R0, R0, Operand(R3));
3429 }
3430 __ Ret();
3431}
3432
3433ASSEMBLER_TEST_RUN(Vcgtqs, test) {
3434 EXPECT(test != nullptr);
3436 typedef int (*Tst)() DART_UNUSED;
3437 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3438 }
3439}
3440
3441// Verify that vmins(-0.0, 0.0) = -0.0
3442ASSEMBLER_TEST_GENERATE(Vminqs_zero, assembler) {
3444 __ veorq(Q1, Q1, Q1);
3445 __ vnegqs(Q2, Q1);
3446 __ vminqs(Q0, Q1, Q2);
3447 }
3448 __ Ret();
3449}
3450
3451ASSEMBLER_TEST_RUN(Vminqs_zero, test) {
3452 EXPECT(test != nullptr);
3454 typedef float (*Tst)() DART_UNUSED;
3455 float res = EXECUTE_TEST_CODE_FLOAT(Tst, test->entry());
3456 EXPECT_EQ(true, signbit(res) && (res == 0.0));
3457 }
3458}
3459
3460ASSEMBLER_TEST_GENERATE(Vminqs, assembler) {
3462 __ LoadSImmediate(S0, 1.0);
3463 __ LoadSImmediate(S1, 2.0);
3464 __ LoadSImmediate(S2, 3.0);
3465 __ LoadSImmediate(S3, 4.0);
3466
3467 __ LoadSImmediate(S4, 2.0);
3468 __ LoadSImmediate(S5, 1.0);
3469 __ LoadSImmediate(S6, 6.0);
3470 __ LoadSImmediate(S7, 3.0);
3471
3472 __ vminqs(Q2, Q1, Q0);
3473
3474 __ vadds(S8, S8, S9);
3475 __ vadds(S8, S8, S10);
3476 __ vadds(S8, S8, S11);
3477
3478 __ vcvtis(S0, S8);
3479 __ vmovrs(R0, S0);
3480 }
3481 __ Ret();
3482}
3483
3484ASSEMBLER_TEST_RUN(Vminqs, test) {
3485 EXPECT(test != nullptr);
3487 typedef int (*Tst)() DART_UNUSED;
3488 EXPECT_EQ(8, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3489 }
3490}
3491
3492ASSEMBLER_TEST_GENERATE(Vmaxqs_zero, assembler) {
3494 __ veorq(Q1, Q1, Q1);
3495 __ vnegqs(Q2, Q1);
3496 __ vmaxqs(Q0, Q2, Q1);
3497 }
3498 __ Ret();
3499}
3500
3501// Verify that vmaxqs(-0.0, 0.0) = 0.0
3502ASSEMBLER_TEST_RUN(Vmaxqs_zero, test) {
3503 EXPECT(test != nullptr);
3505 typedef float (*Tst)() DART_UNUSED;
3506 float res = EXECUTE_TEST_CODE_FLOAT(Tst, test->entry());
3507 EXPECT_EQ(true, !signbit(res) && (res == 0.0));
3508 }
3509}
3510
3511ASSEMBLER_TEST_GENERATE(Vmaxqs, assembler) {
3513 __ LoadSImmediate(S0, 1.0);
3514 __ LoadSImmediate(S1, 2.0);
3515 __ LoadSImmediate(S2, 3.0);
3516 __ LoadSImmediate(S3, 4.0);
3517
3518 __ LoadSImmediate(S4, 2.0);
3519 __ LoadSImmediate(S5, 1.0);
3520 __ LoadSImmediate(S6, 6.0);
3521 __ LoadSImmediate(S7, 3.0);
3522
3523 __ vmaxqs(Q2, Q1, Q0);
3524
3525 __ vadds(S8, S8, S9);
3526 __ vadds(S8, S8, S10);
3527 __ vadds(S8, S8, S11);
3528
3529 __ vcvtis(S0, S8);
3530 __ vmovrs(R0, S0);
3531 }
3532 __ Ret();
3533}
3534
3535ASSEMBLER_TEST_RUN(Vmaxqs, test) {
3536 EXPECT(test != nullptr);
3538 typedef int (*Tst)() DART_UNUSED;
3539 EXPECT_EQ(14, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
3540 }
3541}
3542
3543ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) {
3545 __ LoadSImmediate(S4, 147.0);
3546 __ vmovs(S5, S4);
3547 __ vmovs(S6, S4);
3548 __ vmovs(S7, S4);
3549 __ vrecpeqs(Q0, Q1);
3550 }
3551 __ Ret();
3552}
3553
3554ASSEMBLER_TEST_RUN(Vrecpeqs, test) {
3555 EXPECT(test != nullptr);
3557 typedef float (*Vrecpeqs)() DART_UNUSED;
3558 float res = EXECUTE_TEST_CODE_FLOAT(Vrecpeqs, test->entry());
3559 EXPECT_FLOAT_EQ(ReciprocalEstimate(147.0), res, 0.0001f);
3560 }
3561}
3562
3563ASSEMBLER_TEST_GENERATE(Vrecpsqs, assembler) {
3565 __ LoadSImmediate(S4, 5.0);
3566 __ LoadSImmediate(S5, 2.0);
3567 __ LoadSImmediate(S6, 3.0);
3568 __ LoadSImmediate(S7, 4.0);
3569
3570 __ LoadSImmediate(S8, 10.0);
3571 __ LoadSImmediate(S9, 1.0);
3572 __ LoadSImmediate(S10, 6.0);
3573 __ LoadSImmediate(S11, 3.0);
3574
3575 __ vrecpsqs(Q0, Q1, Q2);
3576 }
3577 __ Ret();
3578}
3579
3580ASSEMBLER_TEST_RUN(Vrecpsqs, test) {
3581 EXPECT(test != nullptr);
3583 typedef float (*Vrecpsqs)() DART_UNUSED;
3584 float res = EXECUTE_TEST_CODE_FLOAT(Vrecpsqs, test->entry());
3585 EXPECT_FLOAT_EQ(2.0 - 10.0 * 5.0, res, 0.0001f);
3586 }
3587}
3588
3589ASSEMBLER_TEST_GENERATE(Reciprocal, assembler) {
3591 __ LoadSImmediate(S4, 147000.0);
3592 __ vmovs(S5, S4);
3593 __ vmovs(S6, S4);
3594 __ vmovs(S7, S4);
3595
3596 // Reciprocal estimate.
3597 __ vrecpeqs(Q0, Q1);
3598 // 2 Newton-Raphson steps.
3599 __ vrecpsqs(Q2, Q1, Q0);
3600 __ vmulqs(Q0, Q0, Q2);
3601 __ vrecpsqs(Q2, Q1, Q0);
3602 __ vmulqs(Q0, Q0, Q2);
3603 }
3604 __ Ret();
3605}
3606
3607ASSEMBLER_TEST_RUN(Reciprocal, test) {
3608 EXPECT(test != nullptr);
3610 typedef float (*Reciprocal)() DART_UNUSED;
3611 float res = EXECUTE_TEST_CODE_FLOAT(Reciprocal, test->entry());
3612 EXPECT_FLOAT_EQ(1.0 / 147000.0, res, 0.0001f);
3613 }
3614}
3615
3616ASSEMBLER_TEST_GENERATE(Vrsqrteqs, assembler) {
3618 __ LoadSImmediate(S4, 147.0);
3619 __ vmovs(S5, S4);
3620 __ vmovs(S6, S4);
3621 __ vmovs(S7, S4);
3622
3623 __ vrsqrteqs(Q0, Q1);
3624 }
3625 __ Ret();
3626}
3627
3628ASSEMBLER_TEST_RUN(Vrsqrteqs, test) {
3629 EXPECT(test != nullptr);
3631 typedef float (*Vrsqrteqs)() DART_UNUSED;
3632 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrteqs, test->entry());
3633 EXPECT_FLOAT_EQ(ReciprocalSqrtEstimate(147.0), res, 0.0001f);
3634 }
3635}
3636
3637ASSEMBLER_TEST_GENERATE(Vrsqrtsqs, assembler) {
3639 __ LoadSImmediate(S4, 5.0);
3640 __ LoadSImmediate(S5, 2.0);
3641 __ LoadSImmediate(S6, 3.0);
3642 __ LoadSImmediate(S7, 4.0);
3643
3644 __ LoadSImmediate(S8, 10.0);
3645 __ LoadSImmediate(S9, 1.0);
3646 __ LoadSImmediate(S10, 6.0);
3647 __ LoadSImmediate(S11, 3.0);
3648
3649 __ vrsqrtsqs(Q0, Q1, Q2);
3650 }
3651 __ Ret();
3652}
3653
3654ASSEMBLER_TEST_RUN(Vrsqrtsqs, test) {
3655 EXPECT(test != nullptr);
3657 typedef float (*Vrsqrtsqs)() DART_UNUSED;
3658 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrtsqs, test->entry());
3659 EXPECT_FLOAT_EQ((3.0 - 10.0 * 5.0) / 2.0, res, 0.0001f);
3660 }
3661}
3662
3663ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) {
3665 __ LoadSImmediate(S4, 147000.0);
3666 __ vmovs(S5, S4);
3667 __ vmovs(S6, S4);
3668 __ vmovs(S7, S4);
3669
3670 // Reciprocal square root estimate.
3671 __ vrsqrteqs(Q0, Q1);
3672 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2.
3673 // First step.
3674 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2
3675 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2.
3676 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2
3677 // Second step.
3678 __ vmulqs(Q2, Q0, Q0);
3679 __ vrsqrtsqs(Q2, Q1, Q2);
3680 __ vmulqs(Q0, Q0, Q2);
3681 }
3682 __ Ret();
3683}
3684
3685ASSEMBLER_TEST_RUN(ReciprocalSqrt, test) {
3686 EXPECT(test != nullptr);
3688 typedef float (*ReciprocalSqrt)() DART_UNUSED;
3689 float res = EXECUTE_TEST_CODE_FLOAT(ReciprocalSqrt, test->entry());
3690 EXPECT_FLOAT_EQ(1.0 / sqrt(147000.0), res, 0.0001f);
3691 }
3692}
3693
3694ASSEMBLER_TEST_GENERATE(SIMDSqrt, assembler) {
3696 __ LoadSImmediate(S4, 147000.0);
3697 __ vmovs(S5, S4);
3698 __ vmovs(S6, S4);
3699 __ vmovs(S7, S4);
3700
3701 // Reciprocal square root estimate.
3702 __ vrsqrteqs(Q0, Q1);
3703 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2.
3704 // First step.
3705 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2
3706 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2.
3707 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2
3708 // Second step.
3709 __ vmulqs(Q2, Q0, Q0);
3710 __ vrsqrtsqs(Q2, Q1, Q2);
3711 __ vmulqs(Q0, Q0, Q2);
3712
3713 // Reciprocal.
3714 __ vmovq(Q1, Q0);
3715 // Reciprocal estimate.
3716 __ vrecpeqs(Q0, Q1);
3717 // 2 Newton-Raphson steps.
3718 __ vrecpsqs(Q2, Q1, Q0);
3719 __ vmulqs(Q0, Q0, Q2);
3720 __ vrecpsqs(Q2, Q1, Q0);
3721 __ vmulqs(Q0, Q0, Q2);
3722 }
3723 __ Ret();
3724}
3725
3726ASSEMBLER_TEST_RUN(SIMDSqrt, test) {
3727 EXPECT(test != nullptr);
3729 typedef float (*SIMDSqrt)() DART_UNUSED;
3730 float res = EXECUTE_TEST_CODE_FLOAT(SIMDSqrt, test->entry());
3731 EXPECT_FLOAT_EQ(sqrt(147000.0), res, 0.0001f);
3732 }
3733}
3734
3735ASSEMBLER_TEST_GENERATE(SIMDSqrt2, assembler) {
3737 __ LoadSImmediate(S4, 1.0);
3738 __ LoadSImmediate(S5, 4.0);
3739 __ LoadSImmediate(S6, 9.0);
3740 __ LoadSImmediate(S7, 16.0);
3741
3742 // Reciprocal square root estimate.
3743 __ vrsqrteqs(Q0, Q1);
3744 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2.
3745 // First step.
3746 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2
3747 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2.
3748 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2
3749 // Second step.
3750 __ vmulqs(Q2, Q0, Q0);
3751 __ vrsqrtsqs(Q2, Q1, Q2);
3752 __ vmulqs(Q0, Q0, Q2);
3753
3754 // Reciprocal.
3755 __ vmovq(Q1, Q0);
3756 // Reciprocal estimate.
3757 __ vrecpeqs(Q0, Q1);
3758 // 2 Newton-Raphson steps.
3759 __ vrecpsqs(Q2, Q1, Q0);
3760 __ vmulqs(Q0, Q0, Q2);
3761 __ vrecpsqs(Q2, Q1, Q0);
3762 __ vmulqs(Q0, Q0, Q2);
3763
3764 __ vadds(S0, S0, S1);
3765 __ vadds(S0, S0, S2);
3766 __ vadds(S0, S0, S3);
3767 }
3768 __ Ret();
3769}
3770
3771ASSEMBLER_TEST_RUN(SIMDSqrt2, test) {
3772 EXPECT(test != nullptr);
3774 typedef float (*SIMDSqrt2)() DART_UNUSED;
3775 float res = EXECUTE_TEST_CODE_FLOAT(SIMDSqrt2, test->entry());
3776 EXPECT_FLOAT_EQ(10.0, res, 0.0001f);
3777 }
3778}
3779
3780ASSEMBLER_TEST_GENERATE(SIMDDiv, assembler) {
3782 __ LoadSImmediate(S4, 1.0);
3783 __ LoadSImmediate(S5, 4.0);
3784 __ LoadSImmediate(S6, 9.0);
3785 __ LoadSImmediate(S7, 16.0);
3786
3787 __ LoadSImmediate(S12, 4.0);
3788 __ LoadSImmediate(S13, 16.0);
3789 __ LoadSImmediate(S14, 36.0);
3790 __ LoadSImmediate(S15, 64.0);
3791
3792 // Reciprocal estimate.
3793 __ vrecpeqs(Q0, Q1);
3794 // 2 Newton-Raphson steps.
3795 __ vrecpsqs(Q2, Q1, Q0);
3796 __ vmulqs(Q0, Q0, Q2);
3797 __ vrecpsqs(Q2, Q1, Q0);
3798 __ vmulqs(Q0, Q0, Q2);
3799
3800 __ vmulqs(Q0, Q3, Q0);
3801 __ vadds(S0, S0, S1);
3802 __ vadds(S0, S0, S2);
3803 __ vadds(S0, S0, S3);
3804 }
3805 __ Ret();
3806}
3807
3808ASSEMBLER_TEST_RUN(SIMDDiv, test) {
3809 EXPECT(test != nullptr);
3811 typedef float (*SIMDDiv)() DART_UNUSED;
3812 float res = EXECUTE_TEST_CODE_FLOAT(SIMDDiv, test->entry());
3813 EXPECT_FLOAT_EQ(16.0, res, 0.0001f);
3814 }
3815}
3816
3817ASSEMBLER_TEST_GENERATE(Vabsqs, assembler) {
3819 __ LoadSImmediate(S4, 1.0);
3820 __ LoadSImmediate(S5, -1.0);
3821 __ LoadSImmediate(S6, 1.0);
3822 __ LoadSImmediate(S7, -1.0);
3823
3824 __ vabsqs(Q0, Q1);
3825
3826 __ vadds(S0, S0, S1);
3827 __ vadds(S0, S0, S2);
3828 __ vadds(S0, S0, S3);
3829 }
3830 __ Ret();
3831}
3832
3833ASSEMBLER_TEST_RUN(Vabsqs, test) {
3834 EXPECT(test != nullptr);
3836 typedef float (*Vabsqs)() DART_UNUSED;
3837 float res = EXECUTE_TEST_CODE_FLOAT(Vabsqs, test->entry());
3838 EXPECT_FLOAT_EQ(4.0, res, 0.0001f);
3839 }
3840}
3841
3842ASSEMBLER_TEST_GENERATE(Vnegqs, assembler) {
3844 __ LoadSImmediate(S4, 1.0);
3845 __ LoadSImmediate(S5, -2.0);
3846 __ LoadSImmediate(S6, 1.0);
3847 __ LoadSImmediate(S7, -2.0);
3848
3849 __ vnegqs(Q0, Q1);
3850
3851 __ vadds(S0, S0, S1);
3852 __ vadds(S0, S0, S2);
3853 __ vadds(S0, S0, S3);
3854 }
3855 __ Ret();
3856}
3857
3858ASSEMBLER_TEST_RUN(Vnegqs, test) {
3859 EXPECT(test != nullptr);
3861 typedef float (*Vnegqs)() DART_UNUSED;
3862 float res = EXECUTE_TEST_CODE_FLOAT(Vnegqs, test->entry());
3863 EXPECT_FLOAT_EQ(2.0, res, 0.0001f);
3864 }
3865}
3866
3867// Called from assembler_test.cc.
3868// LR: return address.
3869// R0: value.
3870// R1: growable array.
3871// R2: current thread.
3872ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
3873 SPILLS_LR_TO_FRAME(__ PushList((1 << LR) | (1 << THR)));
3874 __ mov(THR, Operand(R2));
3875 __ StoreIntoObject(R1, FieldAddress(R1, GrowableObjectArray::data_offset()),
3876 R0);
3877 RESTORES_LR_FROM_FRAME(__ PopList((1 << LR) | (1 << THR)));
3878 __ Ret();
3879}
3880
3881static void RangeCheck(Assembler* assembler, Register value, Register temp) {
3882 const Register return_reg = CallingConventions::kReturnReg;
3883 Label in_range;
3884 __ RangeCheck(value, temp, kFirstErrorCid, kLastErrorCid,
3885 AssemblerBase::kIfInRange, &in_range);
3886 __ LoadImmediate(return_reg, Immediate(0));
3887 __ Ret();
3888 __ Bind(&in_range);
3889 __ LoadImmediate(return_reg, Immediate(1));
3890 __ Ret();
3891}
3892
3893ASSEMBLER_TEST_GENERATE(RangeCheckNoTemp, assembler) {
3895 const Register temp = kNoRegister;
3896 RangeCheck(assembler, value, temp);
3897}
3898
3899ASSEMBLER_TEST_RUN(RangeCheckNoTemp, test) {
3900 intptr_t result;
3901 result = test->Invoke<intptr_t, intptr_t>(kErrorCid);
3902 EXPECT_EQ(1, result);
3903 result = test->Invoke<intptr_t, intptr_t>(kUnwindErrorCid);
3904 EXPECT_EQ(1, result);
3905 result = test->Invoke<intptr_t, intptr_t>(kFunctionCid);
3906 EXPECT_EQ(0, result);
3907 result = test->Invoke<intptr_t, intptr_t>(kMintCid);
3908 EXPECT_EQ(0, result);
3909}
3910
3911ASSEMBLER_TEST_GENERATE(RangeCheckWithTemp, assembler) {
3914 RangeCheck(assembler, value, temp);
3915}
3916
3917ASSEMBLER_TEST_RUN(RangeCheckWithTemp, test) {
3918 intptr_t result;
3919 result = test->Invoke<intptr_t, intptr_t>(kErrorCid);
3920 EXPECT_EQ(1, result);
3921 result = test->Invoke<intptr_t, intptr_t>(kUnwindErrorCid);
3922 EXPECT_EQ(1, result);
3923 result = test->Invoke<intptr_t, intptr_t>(kFunctionCid);
3924 EXPECT_EQ(0, result);
3925 result = test->Invoke<intptr_t, intptr_t>(kMintCid);
3926 EXPECT_EQ(0, result);
3927}
3928
3929ASSEMBLER_TEST_GENERATE(RangeCheckWithTempReturnValue, assembler) {
3932 const Register return_reg = CallingConventions::kReturnReg;
3933 Label in_range;
3934 __ RangeCheck(value, temp, kFirstErrorCid, kLastErrorCid,
3935 AssemblerBase::kIfInRange, &in_range);
3936 __ Bind(&in_range);
3937 __ mov(return_reg, Operand(value));
3938 __ Ret();
3939}
3940
3941ASSEMBLER_TEST_RUN(RangeCheckWithTempReturnValue, test) {
3942 intptr_t result;
3943 result = test->Invoke<intptr_t, intptr_t>(kErrorCid);
3944 EXPECT_EQ(kErrorCid, result);
3945 result = test->Invoke<intptr_t, intptr_t>(kUnwindErrorCid);
3946 EXPECT_EQ(kUnwindErrorCid, result);
3947 result = test->Invoke<intptr_t, intptr_t>(kFunctionCid);
3948 EXPECT_EQ(kFunctionCid, result);
3949 result = test->Invoke<intptr_t, intptr_t>(kMintCid);
3950 EXPECT_EQ(kMintCid, result);
3951}
3952
3953void EnterTestFrame(Assembler* assembler) {
3954 __ EnterFrame(1 << THR | 1 << PP | 1 << CODE_REG, 0);
3955 __ MoveRegister(CODE_REG, R0);
3956 __ MoveRegister(THR, R1);
3957 __ LoadPoolPointer(PP);
3958}
3959
3960void LeaveTestFrame(Assembler* assembler) {
3961 __ LeaveFrame(1 << THR | 1 << PP | 1 << CODE_REG);
3962}
3963
3964// Tests that BranchLink only clobbers CODE_REG in JIT mode and does not
3965// clobber any allocatable registers in AOT mode.
3966ASSEMBLER_TEST_GENERATE(BranchLinkPreservesRegisters, assembler) {
3967 const auto& do_nothing_just_return =
3968 AssemblerTest::Generate("DoNothing", [](auto assembler) { __ Ret(); });
3969
3970 EnterTestFrame(assembler);
3971 SPILLS_LR_TO_FRAME({ __ PushRegister(LR); });
3972
3973 const RegisterSet clobbered_regs(
3974 kDartAvailableCpuRegs & ~(static_cast<RegList>(1) << R0),
3975 /*fpu_register_mask=*/0);
3976 __ PushRegisters(clobbered_regs);
3977
3978 Label done;
3979
3980 const auto check_all_allocatable_registers_are_preserved_by_call = [&]() {
3981 for (auto reg : RegisterRange(kDartAvailableCpuRegs)) {
3982 __ LoadImmediate(reg, static_cast<int32_t>(reg));
3983 }
3984 __ BranchLink(do_nothing_just_return);
3985 for (auto reg : RegisterRange(kDartAvailableCpuRegs)) {
3986 // We expect CODE_REG to be clobbered in JIT mode.
3987 if (!FLAG_precompiled_mode && reg == CODE_REG) continue;
3988
3989 __ CompareImmediate(reg, static_cast<int32_t>(reg));
3990 __ LoadImmediate(R0, reg, NE);
3991 __ b(&done, NE);
3992 }
3993 };
3994
3995 check_all_allocatable_registers_are_preserved_by_call();
3996
3997 FLAG_precompiled_mode = true;
3998 check_all_allocatable_registers_are_preserved_by_call();
3999 FLAG_precompiled_mode = false;
4000
4001 __ LoadImmediate(R0, 42); // 42 is SUCCESS.
4002 __ Bind(&done);
4003 __ PopRegisters(clobbered_regs);
4004 RESTORES_LR_FROM_FRAME({ __ PopRegister(LR); });
4005 LeaveTestFrame(assembler);
4006 __ Ret();
4007}
4008
4009ASSEMBLER_TEST_RUN(BranchLinkPreservesRegisters, test) {
4010 const intptr_t result = test->InvokeWithCodeAndThread<int64_t>();
4011 EXPECT_EQ(42, result);
4012}
4013
4014} // namespace compiler
4015} // namespace dart
4016
4017#endif // defined TARGET_ARCH_ARM
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
Definition DM.cpp:263
static void fail(const SkString &err)
Definition DM.cpp:234
static bool skip(SkStream *stream, size_t amount)
#define EXPECT(type, expectedAlignment, expectedSize)
#define __
Type::kYUV Type::kRGBA() int(0.7 *637)
static const Code & Generate(const char *name, const std::function< void(compiler::Assembler *assembler)> &generator)
Definition unit_test.cc:756
static const Register ArgumentRegisters[]
static constexpr Register kReturnReg
static intptr_t data_offset()
Definition object.h:11110
static void set_integer_division_supported(bool supported)
Definition cpu_arm.h:48
static bool neon_supported()
Definition cpu_arm.h:76
static bool integer_division_supported()
Definition cpu_arm.h:73
static int32_t Low32Bits(int64_t value)
Definition utils.h:354
static constexpr T NBitMask(size_t n)
Definition utils.h:533
static int32_t High32Bits(int64_t value)
Definition utils.h:358
static constexpr bool TestBit(T mask, size_t position)
Definition utils.h:549
static bool CanHold(uint32_t immediate, Operand *o)
#define ASSERT(E)
static bool b
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
void LeaveTestFrame(Assembler *assembler)
void EnterTestFrame(Assembler *assembler)
float ReciprocalSqrtEstimate(float op)
const Register THR
static DRegister EvenDRegisterOf(QRegister q)
static Utils::BitsRange< Register > RegisterRange(uint32_t regs)
Definition constants.h:110
float ReciprocalStep(float op1, float op2)
uint16_t RegList
static const ClassId kLastErrorCid
Definition class_id.h:311
static const ClassId kFirstErrorCid
Definition class_id.h:310
const Register CODE_REG
static SRegister OddSRegisterOf(DRegister d)
@ kNoRegister
constexpr RegList kDartAvailableCpuRegs
const Register TMP
float ReciprocalSqrtStep(float op1, float op2)
const Register PP
float ReciprocalEstimate(float op)
static SRegister EvenSRegisterOf(DRegister d)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition SkVx.h:706
#define DART_UNUSED
Definition globals.h:269
int32_t width
#define ASSEMBLER_TEST_GENERATE(name, assembler)
Definition unit_test.h:89
#define TEST_CASE(name)
Definition unit_test.h:85
#define ASSEMBLER_TEST_RUN(name, test)
Definition unit_test.h:127
#define kPosInfinity
Definition globals.h:65
#define kNegInfinity
Definition globals.h:66