Flutter Engine
The Flutter Engine
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 __
static const Code & Generate(const char *name, const std::function< void(compiler::Assembler *assembler)> &generator)
Definition: unit_test.cc:770
static const Register ArgumentRegisters[]
static constexpr Register kReturnReg
static intptr_t data_offset()
Definition: object.h:11136
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:369
static constexpr T NBitMask(size_t n)
Definition: utils.h:548
static int32_t High32Bits(int64_t value)
Definition: utils.h:373
static constexpr bool TestBit(T mask, size_t position)
Definition: utils.h:564
static bool CanHold(uint32_t immediate, Operand *o)
#define ASSERT(E)
static bool b
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
static constexpr intptr_t kWordSize
Definition: runtime_api.h:274
void LeaveTestFrame(Assembler *assembler)
ASSEMBLER_TEST_GENERATE(InstantiateTypeArgumentsHashKeys, assembler)
void EnterTestFrame(Assembler *assembler)
Definition: dart_vm.cc:33
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
Definition: constants_arm.h:99
constexpr RegList kDartAvailableCpuRegs
const Register TMP
ASSEMBLER_TEST_RUN(StoreIntoObject, test)
TEST_CASE(DirectoryCurrent)
float ReciprocalSqrtStep(float op1, float op2)
const Register PP
float ReciprocalEstimate(float op)
static SRegister EvenSRegisterOf(DRegister d)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
static bool Bind(PassBindingsCacheMTL &pass, ShaderStage stage, size_t bind_index, const BufferView &view)
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 kPosInfinity
Definition: globals.h:65
#define kNegInfinity
Definition: globals.h:66