1 // Copyright 2013, ARM Limited
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright notice,
8 // this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright notice,
10 // this list of conditions and the following disclaimer in the documentation
11 // and/or other materials provided with the distribution.
12 // * Neither the name of ARM Limited nor the names of its contributors may be
13 // used to endorse or promote products derived from this software without
14 // specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <math.h>
31 #include <float.h>
32
33 #include "cctest.h"
34 #include "test-utils-a64.h"
35 #include "a64/macro-assembler-a64.h"
36 #include "a64/simulator-a64.h"
37 #include "a64/debugger-a64.h"
38 #include "a64/disasm-a64.h"
39 #include "a64/cpu-a64.h"
40
41 namespace vixl {
42
43 // Test infrastructure.
44 //
45 // Tests are functions which accept no parameters and have no return values.
46 // The testing code should not perform an explicit return once completed. For
47 // example to test the mov immediate instruction a very simple test would be:
48 //
49 // TEST(mov_x0_one) {
50 // SETUP();
51 //
52 // START();
53 // __ mov(x0, Operand(1));
54 // END();
55 //
56 // RUN();
57 //
58 // ASSERT_EQUAL_64(1, x0);
59 //
60 // TEARDOWN();
61 // }
62 //
63 // Within a START ... END block all registers but sp can be modified. sp has to
64 // be explicitly saved/restored. The END() macro replaces the function return
65 // so it may appear multiple times in a test if the test has multiple exit
66 // points.
67 //
68 // Once the test has been run all integer and floating point registers as well
69 // as flags are accessible through a RegisterDump instance, see
70 // utils-a64.cc for more info on RegisterDump.
71 //
72 // We provide some helper assert to handle common cases:
73 //
74 // ASSERT_EQUAL_32(int32_t, int_32t)
75 // ASSERT_EQUAL_FP32(float, float)
76 // ASSERT_EQUAL_32(int32_t, W register)
77 // ASSERT_EQUAL_FP32(float, S register)
78 // ASSERT_EQUAL_64(int64_t, int_64t)
79 // ASSERT_EQUAL_FP64(double, double)
80 // ASSERT_EQUAL_64(int64_t, X register)
81 // ASSERT_EQUAL_64(X register, X register)
82 // ASSERT_EQUAL_FP64(double, D register)
83 //
84 // e.g. ASSERT_EQUAL_64(0.5, d30);
85 //
86 // If more advanced computation is required before the assert then access the
87 // RegisterDump named core directly:
88 //
89 // ASSERT_EQUAL_64(0x1234, core->reg_x0() & 0xffff);
90
91
92 #define __ masm.
93 #define TEST(name) TEST_(ASM_##name)
94
95 #define BUF_SIZE (4096)
96
97 #define SETUP() SETUP_SIZE(BUF_SIZE)
98
99 #ifdef USE_SIMULATOR
100
101 // Run tests with the simulator.
102 #define SETUP_SIZE(buf_size) \
103 byte* buf = new byte[buf_size]; \
104 MacroAssembler masm(buf, buf_size); \
105 Decoder decoder; \
106 Simulator* simulator = NULL; \
107 if (Cctest::run_debugger()) { \
108 simulator = new Debugger(&decoder); \
109 } else { \
110 simulator = new Simulator(&decoder); \
111 simulator->set_disasm_trace(Cctest::trace_sim()); \
112 } \
113 simulator->set_coloured_trace(Cctest::coloured_trace()); \
114 simulator->set_instruction_stats(Cctest::instruction_stats()); \
115 RegisterDump core
116
117 #define START() \
118 masm.Reset(); \
119 simulator->ResetState(); \
120 __ PushCalleeSavedRegisters(); \
121 if (Cctest::run_debugger()) { \
122 if (Cctest::trace_reg()) { \
123 __ Trace(LOG_STATE, TRACE_ENABLE); \
124 } \
125 if (Cctest::trace_sim()) { \
126 __ Trace(LOG_DISASM, TRACE_ENABLE); \
127 } \
128 } \
129 if (Cctest::instruction_stats()) { \
130 __ EnableInstrumentation(); \
131 }
132
133 #define END() \
134 if (Cctest::instruction_stats()) { \
135 __ DisableInstrumentation(); \
136 } \
137 if (Cctest::run_debugger()) { \
138 __ Trace(LOG_ALL, TRACE_DISABLE); \
139 } \
140 core.Dump(&masm); \
141 __ PopCalleeSavedRegisters(); \
142 __ Ret(); \
143 masm.FinalizeCode()
144
145 #define RUN() \
146 simulator->RunFrom(reinterpret_cast<Instruction*>(buf))
147
148 #define TEARDOWN() \
149 delete simulator; \
150 delete[] buf;
151
152 #else // ifdef USE_SIMULATOR.
153 // Run the test on real hardware or models.
154 #define SETUP_SIZE(size) \
155 size_t buf_size = size; \
156 byte* buf = new byte[buf_size]; \
157 MacroAssembler masm(buf, buf_size); \
158 RegisterDump core; \
159 CPU::SetUp()
160
161 #define START() \
162 masm.Reset(); \
163 __ PushCalleeSavedRegisters()
164
165 #define END() \
166 core.Dump(&masm); \
167 __ PopCalleeSavedRegisters(); \
168 __ Ret(); \
169 masm.FinalizeCode()
170
171 #define RUN() \
172 CPU::EnsureIAndDCacheCoherency(buf, buf_size); \
173 { \
174 void (*test_function)(void); \
175 VIXL_ASSERT(sizeof(buf) == sizeof(test_function)); \
176 memcpy(&test_function, &buf, sizeof(buf)); \
177 test_function(); \
178 }
179
180 #define TEARDOWN() \
181 delete[] buf;
182
183 #endif // ifdef USE_SIMULATOR.
184
185 #define ASSERT_EQUAL_NZCV(expected) \
186 assert(EqualNzcv(expected, core.flags_nzcv()))
187
188 #define ASSERT_EQUAL_REGISTERS(expected) \
189 assert(EqualRegisters(&expected, &core))
190
191 #define ASSERT_EQUAL_32(expected, result) \
192 assert(Equal32(static_cast<uint32_t>(expected), &core, result))
193
194 #define ASSERT_EQUAL_FP32(expected, result) \
195 assert(EqualFP32(expected, &core, result))
196
197 #define ASSERT_EQUAL_64(expected, result) \
198 assert(Equal64(expected, &core, result))
199
200 #define ASSERT_EQUAL_FP64(expected, result) \
201 assert(EqualFP64(expected, &core, result))
202
203 #define ASSERT_LITERAL_POOL_SIZE(expected) \
204 assert((expected) == (__ LiteralPoolSize()))
205
206
TEST(stack_ops)207 TEST(stack_ops) {
208 SETUP();
209
210 START();
211 // save sp.
212 __ Mov(x29, sp);
213
214 // Set the sp to a known value.
215 __ Mov(sp, 0x1004);
216 __ Mov(x0, sp);
217
218 // Add immediate to the sp, and move the result to a normal register.
219 __ Add(sp, sp, 0x50);
220 __ Mov(x1, sp);
221
222 // Add extended to the sp, and move the result to a normal register.
223 __ Mov(x17, 0xfff);
224 __ Add(sp, sp, Operand(x17, SXTB));
225 __ Mov(x2, sp);
226
227 // Create an sp using a logical instruction, and move to normal register.
228 __ Orr(sp, xzr, 0x1fff);
229 __ Mov(x3, sp);
230
231 // Write wsp using a logical instruction.
232 __ Orr(wsp, wzr, 0xfffffff8);
233 __ Mov(x4, sp);
234
235 // Write sp, and read back wsp.
236 __ Orr(sp, xzr, 0xfffffff8);
237 __ Mov(w5, wsp);
238
239 // restore sp.
240 __ Mov(sp, x29);
241 END();
242
243 RUN();
244
245 ASSERT_EQUAL_64(0x1004, x0);
246 ASSERT_EQUAL_64(0x1054, x1);
247 ASSERT_EQUAL_64(0x1053, x2);
248 ASSERT_EQUAL_64(0x1fff, x3);
249 ASSERT_EQUAL_64(0xfffffff8, x4);
250 ASSERT_EQUAL_64(0xfffffff8, x5);
251
252 TEARDOWN();
253 }
254
255
TEST(mvn)256 TEST(mvn) {
257 SETUP();
258
259 START();
260 __ Mvn(w0, 0xfff);
261 __ Mvn(x1, 0xfff);
262 __ Mvn(w2, Operand(w0, LSL, 1));
263 __ Mvn(x3, Operand(x1, LSL, 2));
264 __ Mvn(w4, Operand(w0, LSR, 3));
265 __ Mvn(x5, Operand(x1, LSR, 4));
266 __ Mvn(w6, Operand(w0, ASR, 11));
267 __ Mvn(x7, Operand(x1, ASR, 12));
268 __ Mvn(w8, Operand(w0, ROR, 13));
269 __ Mvn(x9, Operand(x1, ROR, 14));
270 __ Mvn(w10, Operand(w2, UXTB));
271 __ Mvn(x11, Operand(x2, SXTB, 1));
272 __ Mvn(w12, Operand(w2, UXTH, 2));
273 __ Mvn(x13, Operand(x2, SXTH, 3));
274 __ Mvn(x14, Operand(w2, UXTW, 4));
275 __ Mvn(x15, Operand(w2, SXTW, 4));
276 END();
277
278 RUN();
279
280 ASSERT_EQUAL_64(0xfffff000, x0);
281 ASSERT_EQUAL_64(0xfffffffffffff000, x1);
282 ASSERT_EQUAL_64(0x00001fff, x2);
283 ASSERT_EQUAL_64(0x0000000000003fff, x3);
284 ASSERT_EQUAL_64(0xe00001ff, x4);
285 ASSERT_EQUAL_64(0xf0000000000000ff, x5);
286 ASSERT_EQUAL_64(0x00000001, x6);
287 ASSERT_EQUAL_64(0x0000000000000000, x7);
288 ASSERT_EQUAL_64(0x7ff80000, x8);
289 ASSERT_EQUAL_64(0x3ffc000000000000, x9);
290 ASSERT_EQUAL_64(0xffffff00, x10);
291 ASSERT_EQUAL_64(0x0000000000000001, x11);
292 ASSERT_EQUAL_64(0xffff8003, x12);
293 ASSERT_EQUAL_64(0xffffffffffff0007, x13);
294 ASSERT_EQUAL_64(0xfffffffffffe000f, x14);
295 ASSERT_EQUAL_64(0xfffffffffffe000f, x15);
296
297 TEARDOWN();
298 }
299
300
TEST(mov_imm_w)301 TEST(mov_imm_w) {
302 SETUP();
303
304 START();
305 __ Mov(w0, 0xffffffff);
306 __ Mov(w1, 0xffff1234);
307 __ Mov(w2, 0x1234ffff);
308 __ Mov(w3, 0x00000000);
309 __ Mov(w4, 0x00001234);
310 __ Mov(w5, 0x12340000);
311 __ Mov(w6, 0x12345678);
312 END();
313
314 RUN();
315
316 ASSERT_EQUAL_64(0xffffffff, x0);
317 ASSERT_EQUAL_64(0xffff1234, x1);
318 ASSERT_EQUAL_64(0x1234ffff, x2);
319 ASSERT_EQUAL_64(0x00000000, x3);
320 ASSERT_EQUAL_64(0x00001234, x4);
321 ASSERT_EQUAL_64(0x12340000, x5);
322 ASSERT_EQUAL_64(0x12345678, x6);
323
324 TEARDOWN();
325 }
326
327
TEST(mov_imm_x)328 TEST(mov_imm_x) {
329 SETUP();
330
331 START();
332 __ Mov(x0, 0xffffffffffffffff);
333 __ Mov(x1, 0xffffffffffff1234);
334 __ Mov(x2, 0xffffffff12345678);
335 __ Mov(x3, 0xffff1234ffff5678);
336 __ Mov(x4, 0x1234ffffffff5678);
337 __ Mov(x5, 0x1234ffff5678ffff);
338 __ Mov(x6, 0x12345678ffffffff);
339 __ Mov(x7, 0x1234ffffffffffff);
340 __ Mov(x8, 0x123456789abcffff);
341 __ Mov(x9, 0x12345678ffff9abc);
342 __ Mov(x10, 0x1234ffff56789abc);
343 __ Mov(x11, 0xffff123456789abc);
344 __ Mov(x12, 0x0000000000000000);
345 __ Mov(x13, 0x0000000000001234);
346 __ Mov(x14, 0x0000000012345678);
347 __ Mov(x15, 0x0000123400005678);
348 __ Mov(x18, 0x1234000000005678);
349 __ Mov(x19, 0x1234000056780000);
350 __ Mov(x20, 0x1234567800000000);
351 __ Mov(x21, 0x1234000000000000);
352 __ Mov(x22, 0x123456789abc0000);
353 __ Mov(x23, 0x1234567800009abc);
354 __ Mov(x24, 0x1234000056789abc);
355 __ Mov(x25, 0x0000123456789abc);
356 __ Mov(x26, 0x123456789abcdef0);
357 __ Mov(x27, 0xffff000000000001);
358 __ Mov(x28, 0x8000ffff00000000);
359 END();
360
361 RUN();
362
363 ASSERT_EQUAL_64(0xffffffffffff1234, x1);
364 ASSERT_EQUAL_64(0xffffffff12345678, x2);
365 ASSERT_EQUAL_64(0xffff1234ffff5678, x3);
366 ASSERT_EQUAL_64(0x1234ffffffff5678, x4);
367 ASSERT_EQUAL_64(0x1234ffff5678ffff, x5);
368 ASSERT_EQUAL_64(0x12345678ffffffff, x6);
369 ASSERT_EQUAL_64(0x1234ffffffffffff, x7);
370 ASSERT_EQUAL_64(0x123456789abcffff, x8);
371 ASSERT_EQUAL_64(0x12345678ffff9abc, x9);
372 ASSERT_EQUAL_64(0x1234ffff56789abc, x10);
373 ASSERT_EQUAL_64(0xffff123456789abc, x11);
374 ASSERT_EQUAL_64(0x0000000000000000, x12);
375 ASSERT_EQUAL_64(0x0000000000001234, x13);
376 ASSERT_EQUAL_64(0x0000000012345678, x14);
377 ASSERT_EQUAL_64(0x0000123400005678, x15);
378 ASSERT_EQUAL_64(0x1234000000005678, x18);
379 ASSERT_EQUAL_64(0x1234000056780000, x19);
380 ASSERT_EQUAL_64(0x1234567800000000, x20);
381 ASSERT_EQUAL_64(0x1234000000000000, x21);
382 ASSERT_EQUAL_64(0x123456789abc0000, x22);
383 ASSERT_EQUAL_64(0x1234567800009abc, x23);
384 ASSERT_EQUAL_64(0x1234000056789abc, x24);
385 ASSERT_EQUAL_64(0x0000123456789abc, x25);
386 ASSERT_EQUAL_64(0x123456789abcdef0, x26);
387 ASSERT_EQUAL_64(0xffff000000000001, x27);
388 ASSERT_EQUAL_64(0x8000ffff00000000, x28);
389
390
391 TEARDOWN();
392 }
393
394
TEST(mov)395 TEST(mov) {
396 SETUP();
397
398 START();
399 __ Mov(x0, 0xffffffffffffffff);
400 __ Mov(x1, 0xffffffffffffffff);
401 __ Mov(x2, 0xffffffffffffffff);
402 __ Mov(x3, 0xffffffffffffffff);
403
404 __ Mov(x0, 0x0123456789abcdef);
405
406 __ movz(x1, UINT64_C(0xabcd) << 16);
407 __ movk(x2, UINT64_C(0xabcd) << 32);
408 __ movn(x3, UINT64_C(0xabcd) << 48);
409
410 __ Mov(x4, 0x0123456789abcdef);
411 __ Mov(x5, x4);
412
413 __ Mov(w6, -1);
414
415 // Test that moves back to the same register have the desired effect. This
416 // is a no-op for X registers, and a truncation for W registers.
417 __ Mov(x7, 0x0123456789abcdef);
418 __ Mov(x7, x7);
419 __ Mov(x8, 0x0123456789abcdef);
420 __ Mov(w8, w8);
421 __ Mov(x9, 0x0123456789abcdef);
422 __ Mov(x9, Operand(x9));
423 __ Mov(x10, 0x0123456789abcdef);
424 __ Mov(w10, Operand(w10));
425
426 __ Mov(w11, 0xfff);
427 __ Mov(x12, 0xfff);
428 __ Mov(w13, Operand(w11, LSL, 1));
429 __ Mov(x14, Operand(x12, LSL, 2));
430 __ Mov(w15, Operand(w11, LSR, 3));
431 __ Mov(x18, Operand(x12, LSR, 4));
432 __ Mov(w19, Operand(w11, ASR, 11));
433 __ Mov(x20, Operand(x12, ASR, 12));
434 __ Mov(w21, Operand(w11, ROR, 13));
435 __ Mov(x22, Operand(x12, ROR, 14));
436 __ Mov(w23, Operand(w13, UXTB));
437 __ Mov(x24, Operand(x13, SXTB, 1));
438 __ Mov(w25, Operand(w13, UXTH, 2));
439 __ Mov(x26, Operand(x13, SXTH, 3));
440 __ Mov(x27, Operand(w13, UXTW, 4));
441
442 __ Mov(x28, 0x0123456789abcdef);
443 __ Mov(w28, w28, kDiscardForSameWReg);
444 END();
445
446 RUN();
447
448 ASSERT_EQUAL_64(0x0123456789abcdef, x0);
449 ASSERT_EQUAL_64(0x00000000abcd0000, x1);
450 ASSERT_EQUAL_64(0xffffabcdffffffff, x2);
451 ASSERT_EQUAL_64(0x5432ffffffffffff, x3);
452 ASSERT_EQUAL_64(x4, x5);
453 ASSERT_EQUAL_32(-1, w6);
454 ASSERT_EQUAL_64(0x0123456789abcdef, x7);
455 ASSERT_EQUAL_32(0x89abcdef, w8);
456 ASSERT_EQUAL_64(0x0123456789abcdef, x9);
457 ASSERT_EQUAL_32(0x89abcdef, w10);
458 ASSERT_EQUAL_64(0x00000fff, x11);
459 ASSERT_EQUAL_64(0x0000000000000fff, x12);
460 ASSERT_EQUAL_64(0x00001ffe, x13);
461 ASSERT_EQUAL_64(0x0000000000003ffc, x14);
462 ASSERT_EQUAL_64(0x000001ff, x15);
463 ASSERT_EQUAL_64(0x00000000000000ff, x18);
464 ASSERT_EQUAL_64(0x00000001, x19);
465 ASSERT_EQUAL_64(0x0000000000000000, x20);
466 ASSERT_EQUAL_64(0x7ff80000, x21);
467 ASSERT_EQUAL_64(0x3ffc000000000000, x22);
468 ASSERT_EQUAL_64(0x000000fe, x23);
469 ASSERT_EQUAL_64(0xfffffffffffffffc, x24);
470 ASSERT_EQUAL_64(0x00007ff8, x25);
471 ASSERT_EQUAL_64(0x000000000000fff0, x26);
472 ASSERT_EQUAL_64(0x000000000001ffe0, x27);
473 ASSERT_EQUAL_64(0x0123456789abcdef, x28);
474
475 TEARDOWN();
476 }
477
478
TEST(orr)479 TEST(orr) {
480 SETUP();
481
482 START();
483 __ Mov(x0, 0xf0f0);
484 __ Mov(x1, 0xf00000ff);
485
486 __ Orr(x2, x0, Operand(x1));
487 __ Orr(w3, w0, Operand(w1, LSL, 28));
488 __ Orr(x4, x0, Operand(x1, LSL, 32));
489 __ Orr(x5, x0, Operand(x1, LSR, 4));
490 __ Orr(w6, w0, Operand(w1, ASR, 4));
491 __ Orr(x7, x0, Operand(x1, ASR, 4));
492 __ Orr(w8, w0, Operand(w1, ROR, 12));
493 __ Orr(x9, x0, Operand(x1, ROR, 12));
494 __ Orr(w10, w0, 0xf);
495 __ Orr(x11, x0, 0xf0000000f0000000);
496 END();
497
498 RUN();
499
500 ASSERT_EQUAL_64(0x00000000f000f0ff, x2);
501 ASSERT_EQUAL_64(0xf000f0f0, x3);
502 ASSERT_EQUAL_64(0xf00000ff0000f0f0, x4);
503 ASSERT_EQUAL_64(0x000000000f00f0ff, x5);
504 ASSERT_EQUAL_64(0xff00f0ff, x6);
505 ASSERT_EQUAL_64(0x000000000f00f0ff, x7);
506 ASSERT_EQUAL_64(0x0ffff0f0, x8);
507 ASSERT_EQUAL_64(0x0ff00000000ff0f0, x9);
508 ASSERT_EQUAL_64(0x0000f0ff, x10);
509 ASSERT_EQUAL_64(0xf0000000f000f0f0, x11);
510
511 TEARDOWN();
512 }
513
514
TEST(orr_extend)515 TEST(orr_extend) {
516 SETUP();
517
518 START();
519 __ Mov(x0, 1);
520 __ Mov(x1, 0x8000000080008080);
521 __ Orr(w6, w0, Operand(w1, UXTB));
522 __ Orr(x7, x0, Operand(x1, UXTH, 1));
523 __ Orr(w8, w0, Operand(w1, UXTW, 2));
524 __ Orr(x9, x0, Operand(x1, UXTX, 3));
525 __ Orr(w10, w0, Operand(w1, SXTB));
526 __ Orr(x11, x0, Operand(x1, SXTH, 1));
527 __ Orr(x12, x0, Operand(x1, SXTW, 2));
528 __ Orr(x13, x0, Operand(x1, SXTX, 3));
529 END();
530
531 RUN();
532
533 ASSERT_EQUAL_64(0x00000081, x6);
534 ASSERT_EQUAL_64(0x0000000000010101, x7);
535 ASSERT_EQUAL_64(0x00020201, x8);
536 ASSERT_EQUAL_64(0x0000000400040401, x9);
537 ASSERT_EQUAL_64(0xffffff81, x10);
538 ASSERT_EQUAL_64(0xffffffffffff0101, x11);
539 ASSERT_EQUAL_64(0xfffffffe00020201, x12);
540 ASSERT_EQUAL_64(0x0000000400040401, x13);
541
542 TEARDOWN();
543 }
544
545
TEST(bitwise_wide_imm)546 TEST(bitwise_wide_imm) {
547 SETUP();
548
549 START();
550 __ Mov(x0, 0);
551 __ Mov(x1, 0xf0f0f0f0f0f0f0f0);
552
553 __ Orr(x10, x0, 0x1234567890abcdef);
554 __ Orr(w11, w1, 0x90abcdef);
555 END();
556
557 RUN();
558
559 ASSERT_EQUAL_64(0, x0);
560 ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0, x1);
561 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
562 ASSERT_EQUAL_64(0x00000000f0fbfdff, x11);
563
564 TEARDOWN();
565 }
566
567
TEST(orn)568 TEST(orn) {
569 SETUP();
570
571 START();
572 __ Mov(x0, 0xf0f0);
573 __ Mov(x1, 0xf00000ff);
574
575 __ Orn(x2, x0, Operand(x1));
576 __ Orn(w3, w0, Operand(w1, LSL, 4));
577 __ Orn(x4, x0, Operand(x1, LSL, 4));
578 __ Orn(x5, x0, Operand(x1, LSR, 1));
579 __ Orn(w6, w0, Operand(w1, ASR, 1));
580 __ Orn(x7, x0, Operand(x1, ASR, 1));
581 __ Orn(w8, w0, Operand(w1, ROR, 16));
582 __ Orn(x9, x0, Operand(x1, ROR, 16));
583 __ Orn(w10, w0, 0x0000ffff);
584 __ Orn(x11, x0, 0x0000ffff0000ffff);
585 END();
586
587 RUN();
588
589 ASSERT_EQUAL_64(0xffffffff0ffffff0, x2);
590 ASSERT_EQUAL_64(0xfffff0ff, x3);
591 ASSERT_EQUAL_64(0xfffffff0fffff0ff, x4);
592 ASSERT_EQUAL_64(0xffffffff87fffff0, x5);
593 ASSERT_EQUAL_64(0x07fffff0, x6);
594 ASSERT_EQUAL_64(0xffffffff87fffff0, x7);
595 ASSERT_EQUAL_64(0xff00ffff, x8);
596 ASSERT_EQUAL_64(0xff00ffffffffffff, x9);
597 ASSERT_EQUAL_64(0xfffff0f0, x10);
598 ASSERT_EQUAL_64(0xffff0000fffff0f0, x11);
599
600 TEARDOWN();
601 }
602
603
TEST(orn_extend)604 TEST(orn_extend) {
605 SETUP();
606
607 START();
608 __ Mov(x0, 1);
609 __ Mov(x1, 0x8000000080008081);
610 __ Orn(w6, w0, Operand(w1, UXTB));
611 __ Orn(x7, x0, Operand(x1, UXTH, 1));
612 __ Orn(w8, w0, Operand(w1, UXTW, 2));
613 __ Orn(x9, x0, Operand(x1, UXTX, 3));
614 __ Orn(w10, w0, Operand(w1, SXTB));
615 __ Orn(x11, x0, Operand(x1, SXTH, 1));
616 __ Orn(x12, x0, Operand(x1, SXTW, 2));
617 __ Orn(x13, x0, Operand(x1, SXTX, 3));
618 END();
619
620 RUN();
621
622 ASSERT_EQUAL_64(0xffffff7f, x6);
623 ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
624 ASSERT_EQUAL_64(0xfffdfdfb, x8);
625 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
626 ASSERT_EQUAL_64(0x0000007f, x10);
627 ASSERT_EQUAL_64(0x000000000000fefd, x11);
628 ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
629 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
630
631 TEARDOWN();
632 }
633
634
TEST(and_)635 TEST(and_) {
636 SETUP();
637
638 START();
639 __ Mov(x0, 0xfff0);
640 __ Mov(x1, 0xf00000ff);
641
642 __ And(x2, x0, Operand(x1));
643 __ And(w3, w0, Operand(w1, LSL, 4));
644 __ And(x4, x0, Operand(x1, LSL, 4));
645 __ And(x5, x0, Operand(x1, LSR, 1));
646 __ And(w6, w0, Operand(w1, ASR, 20));
647 __ And(x7, x0, Operand(x1, ASR, 20));
648 __ And(w8, w0, Operand(w1, ROR, 28));
649 __ And(x9, x0, Operand(x1, ROR, 28));
650 __ And(w10, w0, Operand(0xff00));
651 __ And(x11, x0, Operand(0xff));
652 END();
653
654 RUN();
655
656 ASSERT_EQUAL_64(0x000000f0, x2);
657 ASSERT_EQUAL_64(0x00000ff0, x3);
658 ASSERT_EQUAL_64(0x00000ff0, x4);
659 ASSERT_EQUAL_64(0x00000070, x5);
660 ASSERT_EQUAL_64(0x0000ff00, x6);
661 ASSERT_EQUAL_64(0x00000f00, x7);
662 ASSERT_EQUAL_64(0x00000ff0, x8);
663 ASSERT_EQUAL_64(0x00000000, x9);
664 ASSERT_EQUAL_64(0x0000ff00, x10);
665 ASSERT_EQUAL_64(0x000000f0, x11);
666
667 TEARDOWN();
668 }
669
670
TEST(and_extend)671 TEST(and_extend) {
672 SETUP();
673
674 START();
675 __ Mov(x0, 0xffffffffffffffff);
676 __ Mov(x1, 0x8000000080008081);
677 __ And(w6, w0, Operand(w1, UXTB));
678 __ And(x7, x0, Operand(x1, UXTH, 1));
679 __ And(w8, w0, Operand(w1, UXTW, 2));
680 __ And(x9, x0, Operand(x1, UXTX, 3));
681 __ And(w10, w0, Operand(w1, SXTB));
682 __ And(x11, x0, Operand(x1, SXTH, 1));
683 __ And(x12, x0, Operand(x1, SXTW, 2));
684 __ And(x13, x0, Operand(x1, SXTX, 3));
685 END();
686
687 RUN();
688
689 ASSERT_EQUAL_64(0x00000081, x6);
690 ASSERT_EQUAL_64(0x0000000000010102, x7);
691 ASSERT_EQUAL_64(0x00020204, x8);
692 ASSERT_EQUAL_64(0x0000000400040408, x9);
693 ASSERT_EQUAL_64(0xffffff81, x10);
694 ASSERT_EQUAL_64(0xffffffffffff0102, x11);
695 ASSERT_EQUAL_64(0xfffffffe00020204, x12);
696 ASSERT_EQUAL_64(0x0000000400040408, x13);
697
698 TEARDOWN();
699 }
700
701
TEST(ands)702 TEST(ands) {
703 SETUP();
704
705 START();
706 __ Mov(x1, 0xf00000ff);
707 __ Ands(w0, w1, Operand(w1));
708 END();
709
710 RUN();
711
712 ASSERT_EQUAL_NZCV(NFlag);
713 ASSERT_EQUAL_64(0xf00000ff, x0);
714
715 START();
716 __ Mov(x0, 0xfff0);
717 __ Mov(x1, 0xf00000ff);
718 __ Ands(w0, w0, Operand(w1, LSR, 4));
719 END();
720
721 RUN();
722
723 ASSERT_EQUAL_NZCV(ZFlag);
724 ASSERT_EQUAL_64(0x00000000, x0);
725
726 START();
727 __ Mov(x0, 0x8000000000000000);
728 __ Mov(x1, 0x00000001);
729 __ Ands(x0, x0, Operand(x1, ROR, 1));
730 END();
731
732 RUN();
733
734 ASSERT_EQUAL_NZCV(NFlag);
735 ASSERT_EQUAL_64(0x8000000000000000, x0);
736
737 START();
738 __ Mov(x0, 0xfff0);
739 __ Ands(w0, w0, Operand(0xf));
740 END();
741
742 RUN();
743
744 ASSERT_EQUAL_NZCV(ZFlag);
745 ASSERT_EQUAL_64(0x00000000, x0);
746
747 START();
748 __ Mov(x0, 0xff000000);
749 __ Ands(w0, w0, Operand(0x80000000));
750 END();
751
752 RUN();
753
754 ASSERT_EQUAL_NZCV(NFlag);
755 ASSERT_EQUAL_64(0x80000000, x0);
756
757 TEARDOWN();
758 }
759
760
TEST(bic)761 TEST(bic) {
762 SETUP();
763
764 START();
765 __ Mov(x0, 0xfff0);
766 __ Mov(x1, 0xf00000ff);
767
768 __ Bic(x2, x0, Operand(x1));
769 __ Bic(w3, w0, Operand(w1, LSL, 4));
770 __ Bic(x4, x0, Operand(x1, LSL, 4));
771 __ Bic(x5, x0, Operand(x1, LSR, 1));
772 __ Bic(w6, w0, Operand(w1, ASR, 20));
773 __ Bic(x7, x0, Operand(x1, ASR, 20));
774 __ Bic(w8, w0, Operand(w1, ROR, 28));
775 __ Bic(x9, x0, Operand(x1, ROR, 24));
776 __ Bic(x10, x0, Operand(0x1f));
777 __ Bic(x11, x0, Operand(0x100));
778
779 // Test bic into sp when the constant cannot be encoded in the immediate
780 // field.
781 // Use x20 to preserve sp. We check for the result via x21 because the
782 // test infrastructure requires that sp be restored to its original value.
783 __ Mov(x20, sp);
784 __ Mov(x0, 0xffffff);
785 __ Bic(sp, x0, Operand(0xabcdef));
786 __ Mov(x21, sp);
787 __ Mov(sp, x20);
788 END();
789
790 RUN();
791
792 ASSERT_EQUAL_64(0x0000ff00, x2);
793 ASSERT_EQUAL_64(0x0000f000, x3);
794 ASSERT_EQUAL_64(0x0000f000, x4);
795 ASSERT_EQUAL_64(0x0000ff80, x5);
796 ASSERT_EQUAL_64(0x000000f0, x6);
797 ASSERT_EQUAL_64(0x0000f0f0, x7);
798 ASSERT_EQUAL_64(0x0000f000, x8);
799 ASSERT_EQUAL_64(0x0000ff00, x9);
800 ASSERT_EQUAL_64(0x0000ffe0, x10);
801 ASSERT_EQUAL_64(0x0000fef0, x11);
802
803 ASSERT_EQUAL_64(0x543210, x21);
804
805 TEARDOWN();
806 }
807
808
TEST(bic_extend)809 TEST(bic_extend) {
810 SETUP();
811
812 START();
813 __ Mov(x0, 0xffffffffffffffff);
814 __ Mov(x1, 0x8000000080008081);
815 __ Bic(w6, w0, Operand(w1, UXTB));
816 __ Bic(x7, x0, Operand(x1, UXTH, 1));
817 __ Bic(w8, w0, Operand(w1, UXTW, 2));
818 __ Bic(x9, x0, Operand(x1, UXTX, 3));
819 __ Bic(w10, w0, Operand(w1, SXTB));
820 __ Bic(x11, x0, Operand(x1, SXTH, 1));
821 __ Bic(x12, x0, Operand(x1, SXTW, 2));
822 __ Bic(x13, x0, Operand(x1, SXTX, 3));
823 END();
824
825 RUN();
826
827 ASSERT_EQUAL_64(0xffffff7e, x6);
828 ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
829 ASSERT_EQUAL_64(0xfffdfdfb, x8);
830 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
831 ASSERT_EQUAL_64(0x0000007e, x10);
832 ASSERT_EQUAL_64(0x000000000000fefd, x11);
833 ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
834 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
835
836 TEARDOWN();
837 }
838
839
TEST(bics)840 TEST(bics) {
841 SETUP();
842
843 START();
844 __ Mov(x1, 0xffff);
845 __ Bics(w0, w1, Operand(w1));
846 END();
847
848 RUN();
849
850 ASSERT_EQUAL_NZCV(ZFlag);
851 ASSERT_EQUAL_64(0x00000000, x0);
852
853 START();
854 __ Mov(x0, 0xffffffff);
855 __ Bics(w0, w0, Operand(w0, LSR, 1));
856 END();
857
858 RUN();
859
860 ASSERT_EQUAL_NZCV(NFlag);
861 ASSERT_EQUAL_64(0x80000000, x0);
862
863 START();
864 __ Mov(x0, 0x8000000000000000);
865 __ Mov(x1, 0x00000001);
866 __ Bics(x0, x0, Operand(x1, ROR, 1));
867 END();
868
869 RUN();
870
871 ASSERT_EQUAL_NZCV(ZFlag);
872 ASSERT_EQUAL_64(0x00000000, x0);
873
874 START();
875 __ Mov(x0, 0xffffffffffffffff);
876 __ Bics(x0, x0, 0x7fffffffffffffff);
877 END();
878
879 RUN();
880
881 ASSERT_EQUAL_NZCV(NFlag);
882 ASSERT_EQUAL_64(0x8000000000000000, x0);
883
884 START();
885 __ Mov(w0, 0xffff0000);
886 __ Bics(w0, w0, 0xfffffff0);
887 END();
888
889 RUN();
890
891 ASSERT_EQUAL_NZCV(ZFlag);
892 ASSERT_EQUAL_64(0x00000000, x0);
893
894 TEARDOWN();
895 }
896
897
TEST(eor)898 TEST(eor) {
899 SETUP();
900
901 START();
902 __ Mov(x0, 0xfff0);
903 __ Mov(x1, 0xf00000ff);
904
905 __ Eor(x2, x0, Operand(x1));
906 __ Eor(w3, w0, Operand(w1, LSL, 4));
907 __ Eor(x4, x0, Operand(x1, LSL, 4));
908 __ Eor(x5, x0, Operand(x1, LSR, 1));
909 __ Eor(w6, w0, Operand(w1, ASR, 20));
910 __ Eor(x7, x0, Operand(x1, ASR, 20));
911 __ Eor(w8, w0, Operand(w1, ROR, 28));
912 __ Eor(x9, x0, Operand(x1, ROR, 28));
913 __ Eor(w10, w0, 0xff00ff00);
914 __ Eor(x11, x0, 0xff00ff00ff00ff00);
915 END();
916
917 RUN();
918
919 ASSERT_EQUAL_64(0x00000000f000ff0f, x2);
920 ASSERT_EQUAL_64(0x0000f000, x3);
921 ASSERT_EQUAL_64(0x0000000f0000f000, x4);
922 ASSERT_EQUAL_64(0x000000007800ff8f, x5);
923 ASSERT_EQUAL_64(0xffff00f0, x6);
924 ASSERT_EQUAL_64(0x000000000000f0f0, x7);
925 ASSERT_EQUAL_64(0x0000f00f, x8);
926 ASSERT_EQUAL_64(0x00000ff00000ffff, x9);
927 ASSERT_EQUAL_64(0xff0000f0, x10);
928 ASSERT_EQUAL_64(0xff00ff00ff0000f0, x11);
929
930 TEARDOWN();
931 }
932
TEST(eor_extend)933 TEST(eor_extend) {
934 SETUP();
935
936 START();
937 __ Mov(x0, 0x1111111111111111);
938 __ Mov(x1, 0x8000000080008081);
939 __ Eor(w6, w0, Operand(w1, UXTB));
940 __ Eor(x7, x0, Operand(x1, UXTH, 1));
941 __ Eor(w8, w0, Operand(w1, UXTW, 2));
942 __ Eor(x9, x0, Operand(x1, UXTX, 3));
943 __ Eor(w10, w0, Operand(w1, SXTB));
944 __ Eor(x11, x0, Operand(x1, SXTH, 1));
945 __ Eor(x12, x0, Operand(x1, SXTW, 2));
946 __ Eor(x13, x0, Operand(x1, SXTX, 3));
947 END();
948
949 RUN();
950
951 ASSERT_EQUAL_64(0x11111190, x6);
952 ASSERT_EQUAL_64(0x1111111111101013, x7);
953 ASSERT_EQUAL_64(0x11131315, x8);
954 ASSERT_EQUAL_64(0x1111111511151519, x9);
955 ASSERT_EQUAL_64(0xeeeeee90, x10);
956 ASSERT_EQUAL_64(0xeeeeeeeeeeee1013, x11);
957 ASSERT_EQUAL_64(0xeeeeeeef11131315, x12);
958 ASSERT_EQUAL_64(0x1111111511151519, x13);
959
960 TEARDOWN();
961 }
962
963
TEST(eon)964 TEST(eon) {
965 SETUP();
966
967 START();
968 __ Mov(x0, 0xfff0);
969 __ Mov(x1, 0xf00000ff);
970
971 __ Eon(x2, x0, Operand(x1));
972 __ Eon(w3, w0, Operand(w1, LSL, 4));
973 __ Eon(x4, x0, Operand(x1, LSL, 4));
974 __ Eon(x5, x0, Operand(x1, LSR, 1));
975 __ Eon(w6, w0, Operand(w1, ASR, 20));
976 __ Eon(x7, x0, Operand(x1, ASR, 20));
977 __ Eon(w8, w0, Operand(w1, ROR, 28));
978 __ Eon(x9, x0, Operand(x1, ROR, 28));
979 __ Eon(w10, w0, 0x03c003c0);
980 __ Eon(x11, x0, 0x0000100000001000);
981 END();
982
983 RUN();
984
985 ASSERT_EQUAL_64(0xffffffff0fff00f0, x2);
986 ASSERT_EQUAL_64(0xffff0fff, x3);
987 ASSERT_EQUAL_64(0xfffffff0ffff0fff, x4);
988 ASSERT_EQUAL_64(0xffffffff87ff0070, x5);
989 ASSERT_EQUAL_64(0x0000ff0f, x6);
990 ASSERT_EQUAL_64(0xffffffffffff0f0f, x7);
991 ASSERT_EQUAL_64(0xffff0ff0, x8);
992 ASSERT_EQUAL_64(0xfffff00fffff0000, x9);
993 ASSERT_EQUAL_64(0xfc3f03cf, x10);
994 ASSERT_EQUAL_64(0xffffefffffff100f, x11);
995
996 TEARDOWN();
997 }
998
999
TEST(eon_extend)1000 TEST(eon_extend) {
1001 SETUP();
1002
1003 START();
1004 __ Mov(x0, 0x1111111111111111);
1005 __ Mov(x1, 0x8000000080008081);
1006 __ Eon(w6, w0, Operand(w1, UXTB));
1007 __ Eon(x7, x0, Operand(x1, UXTH, 1));
1008 __ Eon(w8, w0, Operand(w1, UXTW, 2));
1009 __ Eon(x9, x0, Operand(x1, UXTX, 3));
1010 __ Eon(w10, w0, Operand(w1, SXTB));
1011 __ Eon(x11, x0, Operand(x1, SXTH, 1));
1012 __ Eon(x12, x0, Operand(x1, SXTW, 2));
1013 __ Eon(x13, x0, Operand(x1, SXTX, 3));
1014 END();
1015
1016 RUN();
1017
1018 ASSERT_EQUAL_64(0xeeeeee6f, x6);
1019 ASSERT_EQUAL_64(0xeeeeeeeeeeefefec, x7);
1020 ASSERT_EQUAL_64(0xeeececea, x8);
1021 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x9);
1022 ASSERT_EQUAL_64(0x1111116f, x10);
1023 ASSERT_EQUAL_64(0x111111111111efec, x11);
1024 ASSERT_EQUAL_64(0x11111110eeececea, x12);
1025 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x13);
1026
1027 TEARDOWN();
1028 }
1029
1030
TEST(mul)1031 TEST(mul) {
1032 SETUP();
1033
1034 START();
1035 __ Mov(x16, 0);
1036 __ Mov(x17, 1);
1037 __ Mov(x18, 0xffffffff);
1038 __ Mov(x19, 0xffffffffffffffff);
1039
1040 __ Mul(w0, w16, w16);
1041 __ Mul(w1, w16, w17);
1042 __ Mul(w2, w17, w18);
1043 __ Mul(w3, w18, w19);
1044 __ Mul(x4, x16, x16);
1045 __ Mul(x5, x17, x18);
1046 __ Mul(x6, x18, x19);
1047 __ Mul(x7, x19, x19);
1048 __ Smull(x8, w17, w18);
1049 __ Smull(x9, w18, w18);
1050 __ Smull(x10, w19, w19);
1051 __ Mneg(w11, w16, w16);
1052 __ Mneg(w12, w16, w17);
1053 __ Mneg(w13, w17, w18);
1054 __ Mneg(w14, w18, w19);
1055 __ Mneg(x20, x16, x16);
1056 __ Mneg(x21, x17, x18);
1057 __ Mneg(x22, x18, x19);
1058 __ Mneg(x23, x19, x19);
1059 END();
1060
1061 RUN();
1062
1063 ASSERT_EQUAL_64(0, x0);
1064 ASSERT_EQUAL_64(0, x1);
1065 ASSERT_EQUAL_64(0xffffffff, x2);
1066 ASSERT_EQUAL_64(1, x3);
1067 ASSERT_EQUAL_64(0, x4);
1068 ASSERT_EQUAL_64(0xffffffff, x5);
1069 ASSERT_EQUAL_64(0xffffffff00000001, x6);
1070 ASSERT_EQUAL_64(1, x7);
1071 ASSERT_EQUAL_64(0xffffffffffffffff, x8);
1072 ASSERT_EQUAL_64(1, x9);
1073 ASSERT_EQUAL_64(1, x10);
1074 ASSERT_EQUAL_64(0, x11);
1075 ASSERT_EQUAL_64(0, x12);
1076 ASSERT_EQUAL_64(1, x13);
1077 ASSERT_EQUAL_64(0xffffffff, x14);
1078 ASSERT_EQUAL_64(0, x20);
1079 ASSERT_EQUAL_64(0xffffffff00000001, x21);
1080 ASSERT_EQUAL_64(0xffffffff, x22);
1081 ASSERT_EQUAL_64(0xffffffffffffffff, x23);
1082
1083 TEARDOWN();
1084 }
1085
1086
SmullHelper(int64_t expected,int64_t a,int64_t b)1087 static void SmullHelper(int64_t expected, int64_t a, int64_t b) {
1088 SETUP();
1089 START();
1090 __ Mov(w0, a);
1091 __ Mov(w1, b);
1092 __ Smull(x2, w0, w1);
1093 END();
1094 RUN();
1095 ASSERT_EQUAL_64(expected, x2);
1096 TEARDOWN();
1097 }
1098
1099
TEST(smull)1100 TEST(smull) {
1101 SmullHelper(0, 0, 0);
1102 SmullHelper(1, 1, 1);
1103 SmullHelper(-1, -1, 1);
1104 SmullHelper(1, -1, -1);
1105 SmullHelper(0xffffffff80000000, 0x80000000, 1);
1106 SmullHelper(0x0000000080000000, 0x00010000, 0x00008000);
1107 }
1108
1109
TEST(madd)1110 TEST(madd) {
1111 SETUP();
1112
1113 START();
1114 __ Mov(x16, 0);
1115 __ Mov(x17, 1);
1116 __ Mov(x18, 0xffffffff);
1117 __ Mov(x19, 0xffffffffffffffff);
1118
1119 __ Madd(w0, w16, w16, w16);
1120 __ Madd(w1, w16, w16, w17);
1121 __ Madd(w2, w16, w16, w18);
1122 __ Madd(w3, w16, w16, w19);
1123 __ Madd(w4, w16, w17, w17);
1124 __ Madd(w5, w17, w17, w18);
1125 __ Madd(w6, w17, w17, w19);
1126 __ Madd(w7, w17, w18, w16);
1127 __ Madd(w8, w17, w18, w18);
1128 __ Madd(w9, w18, w18, w17);
1129 __ Madd(w10, w18, w19, w18);
1130 __ Madd(w11, w19, w19, w19);
1131
1132 __ Madd(x12, x16, x16, x16);
1133 __ Madd(x13, x16, x16, x17);
1134 __ Madd(x14, x16, x16, x18);
1135 __ Madd(x15, x16, x16, x19);
1136 __ Madd(x20, x16, x17, x17);
1137 __ Madd(x21, x17, x17, x18);
1138 __ Madd(x22, x17, x17, x19);
1139 __ Madd(x23, x17, x18, x16);
1140 __ Madd(x24, x17, x18, x18);
1141 __ Madd(x25, x18, x18, x17);
1142 __ Madd(x26, x18, x19, x18);
1143 __ Madd(x27, x19, x19, x19);
1144
1145 END();
1146
1147 RUN();
1148
1149 ASSERT_EQUAL_64(0, x0);
1150 ASSERT_EQUAL_64(1, x1);
1151 ASSERT_EQUAL_64(0xffffffff, x2);
1152 ASSERT_EQUAL_64(0xffffffff, x3);
1153 ASSERT_EQUAL_64(1, x4);
1154 ASSERT_EQUAL_64(0, x5);
1155 ASSERT_EQUAL_64(0, x6);
1156 ASSERT_EQUAL_64(0xffffffff, x7);
1157 ASSERT_EQUAL_64(0xfffffffe, x8);
1158 ASSERT_EQUAL_64(2, x9);
1159 ASSERT_EQUAL_64(0, x10);
1160 ASSERT_EQUAL_64(0, x11);
1161
1162 ASSERT_EQUAL_64(0, x12);
1163 ASSERT_EQUAL_64(1, x13);
1164 ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1165 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1166 ASSERT_EQUAL_64(1, x20);
1167 ASSERT_EQUAL_64(0x0000000100000000, x21);
1168 ASSERT_EQUAL_64(0, x22);
1169 ASSERT_EQUAL_64(0x00000000ffffffff, x23);
1170 ASSERT_EQUAL_64(0x00000001fffffffe, x24);
1171 ASSERT_EQUAL_64(0xfffffffe00000002, x25);
1172 ASSERT_EQUAL_64(0, x26);
1173 ASSERT_EQUAL_64(0, x27);
1174
1175 TEARDOWN();
1176 }
1177
1178
TEST(msub)1179 TEST(msub) {
1180 SETUP();
1181
1182 START();
1183 __ Mov(x16, 0);
1184 __ Mov(x17, 1);
1185 __ Mov(x18, 0xffffffff);
1186 __ Mov(x19, 0xffffffffffffffff);
1187
1188 __ Msub(w0, w16, w16, w16);
1189 __ Msub(w1, w16, w16, w17);
1190 __ Msub(w2, w16, w16, w18);
1191 __ Msub(w3, w16, w16, w19);
1192 __ Msub(w4, w16, w17, w17);
1193 __ Msub(w5, w17, w17, w18);
1194 __ Msub(w6, w17, w17, w19);
1195 __ Msub(w7, w17, w18, w16);
1196 __ Msub(w8, w17, w18, w18);
1197 __ Msub(w9, w18, w18, w17);
1198 __ Msub(w10, w18, w19, w18);
1199 __ Msub(w11, w19, w19, w19);
1200
1201 __ Msub(x12, x16, x16, x16);
1202 __ Msub(x13, x16, x16, x17);
1203 __ Msub(x14, x16, x16, x18);
1204 __ Msub(x15, x16, x16, x19);
1205 __ Msub(x20, x16, x17, x17);
1206 __ Msub(x21, x17, x17, x18);
1207 __ Msub(x22, x17, x17, x19);
1208 __ Msub(x23, x17, x18, x16);
1209 __ Msub(x24, x17, x18, x18);
1210 __ Msub(x25, x18, x18, x17);
1211 __ Msub(x26, x18, x19, x18);
1212 __ Msub(x27, x19, x19, x19);
1213
1214 END();
1215
1216 RUN();
1217
1218 ASSERT_EQUAL_64(0, x0);
1219 ASSERT_EQUAL_64(1, x1);
1220 ASSERT_EQUAL_64(0xffffffff, x2);
1221 ASSERT_EQUAL_64(0xffffffff, x3);
1222 ASSERT_EQUAL_64(1, x4);
1223 ASSERT_EQUAL_64(0xfffffffe, x5);
1224 ASSERT_EQUAL_64(0xfffffffe, x6);
1225 ASSERT_EQUAL_64(1, x7);
1226 ASSERT_EQUAL_64(0, x8);
1227 ASSERT_EQUAL_64(0, x9);
1228 ASSERT_EQUAL_64(0xfffffffe, x10);
1229 ASSERT_EQUAL_64(0xfffffffe, x11);
1230
1231 ASSERT_EQUAL_64(0, x12);
1232 ASSERT_EQUAL_64(1, x13);
1233 ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1234 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1235 ASSERT_EQUAL_64(1, x20);
1236 ASSERT_EQUAL_64(0x00000000fffffffe, x21);
1237 ASSERT_EQUAL_64(0xfffffffffffffffe, x22);
1238 ASSERT_EQUAL_64(0xffffffff00000001, x23);
1239 ASSERT_EQUAL_64(0, x24);
1240 ASSERT_EQUAL_64(0x0000000200000000, x25);
1241 ASSERT_EQUAL_64(0x00000001fffffffe, x26);
1242 ASSERT_EQUAL_64(0xfffffffffffffffe, x27);
1243
1244 TEARDOWN();
1245 }
1246
1247
TEST(smulh)1248 TEST(smulh) {
1249 SETUP();
1250
1251 START();
1252 __ Mov(x20, 0);
1253 __ Mov(x21, 1);
1254 __ Mov(x22, 0x0000000100000000);
1255 __ Mov(x23, 0x0000000012345678);
1256 __ Mov(x24, 0x0123456789abcdef);
1257 __ Mov(x25, 0x0000000200000000);
1258 __ Mov(x26, 0x8000000000000000);
1259 __ Mov(x27, 0xffffffffffffffff);
1260 __ Mov(x28, 0x5555555555555555);
1261 __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
1262
1263 __ Smulh(x0, x20, x24);
1264 __ Smulh(x1, x21, x24);
1265 __ Smulh(x2, x22, x23);
1266 __ Smulh(x3, x22, x24);
1267 __ Smulh(x4, x24, x25);
1268 __ Smulh(x5, x23, x27);
1269 __ Smulh(x6, x26, x26);
1270 __ Smulh(x7, x26, x27);
1271 __ Smulh(x8, x27, x27);
1272 __ Smulh(x9, x28, x28);
1273 __ Smulh(x10, x28, x29);
1274 __ Smulh(x11, x29, x29);
1275 END();
1276
1277 RUN();
1278
1279 ASSERT_EQUAL_64(0, x0);
1280 ASSERT_EQUAL_64(0, x1);
1281 ASSERT_EQUAL_64(0, x2);
1282 ASSERT_EQUAL_64(0x0000000001234567, x3);
1283 ASSERT_EQUAL_64(0x0000000002468acf, x4);
1284 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
1285 ASSERT_EQUAL_64(0x4000000000000000, x6);
1286 ASSERT_EQUAL_64(0, x7);
1287 ASSERT_EQUAL_64(0, x8);
1288 ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1289 ASSERT_EQUAL_64(0xe38e38e38e38e38e, x10);
1290 ASSERT_EQUAL_64(0x1c71c71c71c71c72, x11);
1291
1292 TEARDOWN();
1293 }
1294
1295
TEST(smaddl_umaddl)1296 TEST(smaddl_umaddl) {
1297 SETUP();
1298
1299 START();
1300 __ Mov(x17, 1);
1301 __ Mov(x18, 0x00000000ffffffff);
1302 __ Mov(x19, 0xffffffffffffffff);
1303 __ Mov(x20, 4);
1304 __ Mov(x21, 0x0000000200000000);
1305
1306 __ Smaddl(x9, w17, w18, x20);
1307 __ Smaddl(x10, w18, w18, x20);
1308 __ Smaddl(x11, w19, w19, x20);
1309 __ Smaddl(x12, w19, w19, x21);
1310 __ Umaddl(x13, w17, w18, x20);
1311 __ Umaddl(x14, w18, w18, x20);
1312 __ Umaddl(x15, w19, w19, x20);
1313 __ Umaddl(x22, w19, w19, x21);
1314 END();
1315
1316 RUN();
1317
1318 ASSERT_EQUAL_64(3, x9);
1319 ASSERT_EQUAL_64(5, x10);
1320 ASSERT_EQUAL_64(5, x11);
1321 ASSERT_EQUAL_64(0x0000000200000001, x12);
1322 ASSERT_EQUAL_64(0x0000000100000003, x13);
1323 ASSERT_EQUAL_64(0xfffffffe00000005, x14);
1324 ASSERT_EQUAL_64(0xfffffffe00000005, x15);
1325 ASSERT_EQUAL_64(1, x22);
1326
1327 TEARDOWN();
1328 }
1329
1330
TEST(smsubl_umsubl)1331 TEST(smsubl_umsubl) {
1332 SETUP();
1333
1334 START();
1335 __ Mov(x17, 1);
1336 __ Mov(x18, 0x00000000ffffffff);
1337 __ Mov(x19, 0xffffffffffffffff);
1338 __ Mov(x20, 4);
1339 __ Mov(x21, 0x0000000200000000);
1340
1341 __ Smsubl(x9, w17, w18, x20);
1342 __ Smsubl(x10, w18, w18, x20);
1343 __ Smsubl(x11, w19, w19, x20);
1344 __ Smsubl(x12, w19, w19, x21);
1345 __ Umsubl(x13, w17, w18, x20);
1346 __ Umsubl(x14, w18, w18, x20);
1347 __ Umsubl(x15, w19, w19, x20);
1348 __ Umsubl(x22, w19, w19, x21);
1349 END();
1350
1351 RUN();
1352
1353 ASSERT_EQUAL_64(5, x9);
1354 ASSERT_EQUAL_64(3, x10);
1355 ASSERT_EQUAL_64(3, x11);
1356 ASSERT_EQUAL_64(0x00000001ffffffff, x12);
1357 ASSERT_EQUAL_64(0xffffffff00000005, x13);
1358 ASSERT_EQUAL_64(0x0000000200000003, x14);
1359 ASSERT_EQUAL_64(0x0000000200000003, x15);
1360 ASSERT_EQUAL_64(0x00000003ffffffff, x22);
1361
1362 TEARDOWN();
1363 }
1364
1365
TEST(div)1366 TEST(div) {
1367 SETUP();
1368
1369 START();
1370 __ Mov(x16, 1);
1371 __ Mov(x17, 0xffffffff);
1372 __ Mov(x18, 0xffffffffffffffff);
1373 __ Mov(x19, 0x80000000);
1374 __ Mov(x20, 0x8000000000000000);
1375 __ Mov(x21, 2);
1376
1377 __ Udiv(w0, w16, w16);
1378 __ Udiv(w1, w17, w16);
1379 __ Sdiv(w2, w16, w16);
1380 __ Sdiv(w3, w16, w17);
1381 __ Sdiv(w4, w17, w18);
1382
1383 __ Udiv(x5, x16, x16);
1384 __ Udiv(x6, x17, x18);
1385 __ Sdiv(x7, x16, x16);
1386 __ Sdiv(x8, x16, x17);
1387 __ Sdiv(x9, x17, x18);
1388
1389 __ Udiv(w10, w19, w21);
1390 __ Sdiv(w11, w19, w21);
1391 __ Udiv(x12, x19, x21);
1392 __ Sdiv(x13, x19, x21);
1393 __ Udiv(x14, x20, x21);
1394 __ Sdiv(x15, x20, x21);
1395
1396 __ Udiv(w22, w19, w17);
1397 __ Sdiv(w23, w19, w17);
1398 __ Udiv(x24, x20, x18);
1399 __ Sdiv(x25, x20, x18);
1400
1401 __ Udiv(x26, x16, x21);
1402 __ Sdiv(x27, x16, x21);
1403 __ Udiv(x28, x18, x21);
1404 __ Sdiv(x29, x18, x21);
1405
1406 __ Mov(x17, 0);
1407 __ Udiv(w18, w16, w17);
1408 __ Sdiv(w19, w16, w17);
1409 __ Udiv(x20, x16, x17);
1410 __ Sdiv(x21, x16, x17);
1411 END();
1412
1413 RUN();
1414
1415 ASSERT_EQUAL_64(1, x0);
1416 ASSERT_EQUAL_64(0xffffffff, x1);
1417 ASSERT_EQUAL_64(1, x2);
1418 ASSERT_EQUAL_64(0xffffffff, x3);
1419 ASSERT_EQUAL_64(1, x4);
1420 ASSERT_EQUAL_64(1, x5);
1421 ASSERT_EQUAL_64(0, x6);
1422 ASSERT_EQUAL_64(1, x7);
1423 ASSERT_EQUAL_64(0, x8);
1424 ASSERT_EQUAL_64(0xffffffff00000001, x9);
1425 ASSERT_EQUAL_64(0x40000000, x10);
1426 ASSERT_EQUAL_64(0xC0000000, x11);
1427 ASSERT_EQUAL_64(0x0000000040000000, x12);
1428 ASSERT_EQUAL_64(0x0000000040000000, x13);
1429 ASSERT_EQUAL_64(0x4000000000000000, x14);
1430 ASSERT_EQUAL_64(0xC000000000000000, x15);
1431 ASSERT_EQUAL_64(0, x22);
1432 ASSERT_EQUAL_64(0x80000000, x23);
1433 ASSERT_EQUAL_64(0, x24);
1434 ASSERT_EQUAL_64(0x8000000000000000, x25);
1435 ASSERT_EQUAL_64(0, x26);
1436 ASSERT_EQUAL_64(0, x27);
1437 ASSERT_EQUAL_64(0x7fffffffffffffff, x28);
1438 ASSERT_EQUAL_64(0, x29);
1439 ASSERT_EQUAL_64(0, x18);
1440 ASSERT_EQUAL_64(0, x19);
1441 ASSERT_EQUAL_64(0, x20);
1442 ASSERT_EQUAL_64(0, x21);
1443
1444 TEARDOWN();
1445 }
1446
1447
TEST(rbit_rev)1448 TEST(rbit_rev) {
1449 SETUP();
1450
1451 START();
1452 __ Mov(x24, 0xfedcba9876543210);
1453 __ Rbit(w0, w24);
1454 __ Rbit(x1, x24);
1455 __ Rev16(w2, w24);
1456 __ Rev16(x3, x24);
1457 __ Rev(w4, w24);
1458 __ Rev32(x5, x24);
1459 __ Rev(x6, x24);
1460 END();
1461
1462 RUN();
1463
1464 ASSERT_EQUAL_64(0x084c2a6e, x0);
1465 ASSERT_EQUAL_64(0x084c2a6e195d3b7f, x1);
1466 ASSERT_EQUAL_64(0x54761032, x2);
1467 ASSERT_EQUAL_64(0xdcfe98ba54761032, x3);
1468 ASSERT_EQUAL_64(0x10325476, x4);
1469 ASSERT_EQUAL_64(0x98badcfe10325476, x5);
1470 ASSERT_EQUAL_64(0x1032547698badcfe, x6);
1471
1472 TEARDOWN();
1473 }
1474
1475
TEST(clz_cls)1476 TEST(clz_cls) {
1477 SETUP();
1478
1479 START();
1480 __ Mov(x24, 0x0008000000800000);
1481 __ Mov(x25, 0xff800000fff80000);
1482 __ Mov(x26, 0);
1483 __ Clz(w0, w24);
1484 __ Clz(x1, x24);
1485 __ Clz(w2, w25);
1486 __ Clz(x3, x25);
1487 __ Clz(w4, w26);
1488 __ Clz(x5, x26);
1489 __ Cls(w6, w24);
1490 __ Cls(x7, x24);
1491 __ Cls(w8, w25);
1492 __ Cls(x9, x25);
1493 __ Cls(w10, w26);
1494 __ Cls(x11, x26);
1495 END();
1496
1497 RUN();
1498
1499 ASSERT_EQUAL_64(8, x0);
1500 ASSERT_EQUAL_64(12, x1);
1501 ASSERT_EQUAL_64(0, x2);
1502 ASSERT_EQUAL_64(0, x3);
1503 ASSERT_EQUAL_64(32, x4);
1504 ASSERT_EQUAL_64(64, x5);
1505 ASSERT_EQUAL_64(7, x6);
1506 ASSERT_EQUAL_64(11, x7);
1507 ASSERT_EQUAL_64(12, x8);
1508 ASSERT_EQUAL_64(8, x9);
1509 ASSERT_EQUAL_64(31, x10);
1510 ASSERT_EQUAL_64(63, x11);
1511
1512 TEARDOWN();
1513 }
1514
1515
TEST(label)1516 TEST(label) {
1517 SETUP();
1518
1519 Label label_1, label_2, label_3, label_4;
1520
1521 START();
1522 __ Mov(x0, 0x1);
1523 __ Mov(x1, 0x0);
1524 __ Mov(x22, lr); // Save lr.
1525
1526 __ B(&label_1);
1527 __ B(&label_1);
1528 __ B(&label_1); // Multiple branches to the same label.
1529 __ Mov(x0, 0x0);
1530 __ Bind(&label_2);
1531 __ B(&label_3); // Forward branch.
1532 __ Mov(x0, 0x0);
1533 __ Bind(&label_1);
1534 __ B(&label_2); // Backward branch.
1535 __ Mov(x0, 0x0);
1536 __ Bind(&label_3);
1537 __ Bl(&label_4);
1538 END();
1539
1540 __ Bind(&label_4);
1541 __ Mov(x1, 0x1);
1542 __ Mov(lr, x22);
1543 END();
1544
1545 RUN();
1546
1547 ASSERT_EQUAL_64(0x1, x0);
1548 ASSERT_EQUAL_64(0x1, x1);
1549
1550 TEARDOWN();
1551 }
1552
1553
TEST(adr)1554 TEST(adr) {
1555 SETUP();
1556
1557 Label label_1, label_2, label_3, label_4;
1558
1559 START();
1560 __ Mov(x0, 0x0); // Set to non-zero to indicate failure.
1561 __ Adr(x1, &label_3); // Set to zero to indicate success.
1562
1563 __ Adr(x2, &label_1); // Multiple forward references to the same label.
1564 __ Adr(x3, &label_1);
1565 __ Adr(x4, &label_1);
1566
1567 __ Bind(&label_2);
1568 __ Eor(x5, x2, Operand(x3)); // Ensure that x2,x3 and x4 are identical.
1569 __ Eor(x6, x2, Operand(x4));
1570 __ Orr(x0, x0, Operand(x5));
1571 __ Orr(x0, x0, Operand(x6));
1572 __ Br(x2); // label_1, label_3
1573
1574 __ Bind(&label_3);
1575 __ Adr(x2, &label_3); // Self-reference (offset 0).
1576 __ Eor(x1, x1, Operand(x2));
1577 __ Adr(x2, &label_4); // Simple forward reference.
1578 __ Br(x2); // label_4
1579
1580 __ Bind(&label_1);
1581 __ Adr(x2, &label_3); // Multiple reverse references to the same label.
1582 __ Adr(x3, &label_3);
1583 __ Adr(x4, &label_3);
1584 __ Adr(x5, &label_2); // Simple reverse reference.
1585 __ Br(x5); // label_2
1586
1587 __ Bind(&label_4);
1588 END();
1589
1590 RUN();
1591
1592 ASSERT_EQUAL_64(0x0, x0);
1593 ASSERT_EQUAL_64(0x0, x1);
1594
1595 TEARDOWN();
1596 }
1597
1598
TEST(branch_cond)1599 TEST(branch_cond) {
1600 SETUP();
1601
1602 Label wrong;
1603
1604 START();
1605 __ Mov(x0, 0x1);
1606 __ Mov(x1, 0x1);
1607 __ Mov(x2, 0x8000000000000000);
1608
1609 // For each 'cmp' instruction below, condition codes other than the ones
1610 // following it would branch.
1611
1612 __ Cmp(x1, 0);
1613 __ B(&wrong, eq);
1614 __ B(&wrong, lo);
1615 __ B(&wrong, mi);
1616 __ B(&wrong, vs);
1617 __ B(&wrong, ls);
1618 __ B(&wrong, lt);
1619 __ B(&wrong, le);
1620 Label ok_1;
1621 __ B(&ok_1, ne);
1622 __ Mov(x0, 0x0);
1623 __ Bind(&ok_1);
1624
1625 __ Cmp(x1, 1);
1626 __ B(&wrong, ne);
1627 __ B(&wrong, lo);
1628 __ B(&wrong, mi);
1629 __ B(&wrong, vs);
1630 __ B(&wrong, hi);
1631 __ B(&wrong, lt);
1632 __ B(&wrong, gt);
1633 Label ok_2;
1634 __ B(&ok_2, pl);
1635 __ Mov(x0, 0x0);
1636 __ Bind(&ok_2);
1637
1638 __ Cmp(x1, 2);
1639 __ B(&wrong, eq);
1640 __ B(&wrong, hs);
1641 __ B(&wrong, pl);
1642 __ B(&wrong, vs);
1643 __ B(&wrong, hi);
1644 __ B(&wrong, ge);
1645 __ B(&wrong, gt);
1646 Label ok_3;
1647 __ B(&ok_3, vc);
1648 __ Mov(x0, 0x0);
1649 __ Bind(&ok_3);
1650
1651 __ Cmp(x2, 1);
1652 __ B(&wrong, eq);
1653 __ B(&wrong, lo);
1654 __ B(&wrong, mi);
1655 __ B(&wrong, vc);
1656 __ B(&wrong, ls);
1657 __ B(&wrong, ge);
1658 __ B(&wrong, gt);
1659 Label ok_4;
1660 __ B(&ok_4, le);
1661 __ Mov(x0, 0x0);
1662 __ Bind(&ok_4);
1663
1664 Label ok_5;
1665 __ b(&ok_5, al);
1666 __ Mov(x0, 0x0);
1667 __ Bind(&ok_5);
1668
1669 Label ok_6;
1670 __ b(&ok_6, nv);
1671 __ Mov(x0, 0x0);
1672 __ Bind(&ok_6);
1673
1674 END();
1675
1676 __ Bind(&wrong);
1677 __ Mov(x0, 0x0);
1678 END();
1679
1680 RUN();
1681
1682 ASSERT_EQUAL_64(0x1, x0);
1683
1684 TEARDOWN();
1685 }
1686
1687
TEST(branch_to_reg)1688 TEST(branch_to_reg) {
1689 SETUP();
1690
1691 // Test br.
1692 Label fn1, after_fn1;
1693
1694 START();
1695 __ Mov(x29, lr);
1696
1697 __ Mov(x1, 0);
1698 __ B(&after_fn1);
1699
1700 __ Bind(&fn1);
1701 __ Mov(x0, lr);
1702 __ Mov(x1, 42);
1703 __ Br(x0);
1704
1705 __ Bind(&after_fn1);
1706 __ Bl(&fn1);
1707
1708 // Test blr.
1709 Label fn2, after_fn2;
1710
1711 __ Mov(x2, 0);
1712 __ B(&after_fn2);
1713
1714 __ Bind(&fn2);
1715 __ Mov(x0, lr);
1716 __ Mov(x2, 84);
1717 __ Blr(x0);
1718
1719 __ Bind(&after_fn2);
1720 __ Bl(&fn2);
1721 __ Mov(x3, lr);
1722
1723 __ Mov(lr, x29);
1724 END();
1725
1726 RUN();
1727
1728 ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
1729 ASSERT_EQUAL_64(42, x1);
1730 ASSERT_EQUAL_64(84, x2);
1731
1732 TEARDOWN();
1733 }
1734
1735
TEST(compare_branch)1736 TEST(compare_branch) {
1737 SETUP();
1738
1739 START();
1740 __ Mov(x0, 0);
1741 __ Mov(x1, 0);
1742 __ Mov(x2, 0);
1743 __ Mov(x3, 0);
1744 __ Mov(x4, 0);
1745 __ Mov(x5, 0);
1746 __ Mov(x16, 0);
1747 __ Mov(x17, 42);
1748
1749 Label zt, zt_end;
1750 __ Cbz(w16, &zt);
1751 __ B(&zt_end);
1752 __ Bind(&zt);
1753 __ Mov(x0, 1);
1754 __ Bind(&zt_end);
1755
1756 Label zf, zf_end;
1757 __ Cbz(x17, &zf);
1758 __ B(&zf_end);
1759 __ Bind(&zf);
1760 __ Mov(x1, 1);
1761 __ Bind(&zf_end);
1762
1763 Label nzt, nzt_end;
1764 __ Cbnz(w17, &nzt);
1765 __ B(&nzt_end);
1766 __ Bind(&nzt);
1767 __ Mov(x2, 1);
1768 __ Bind(&nzt_end);
1769
1770 Label nzf, nzf_end;
1771 __ Cbnz(x16, &nzf);
1772 __ B(&nzf_end);
1773 __ Bind(&nzf);
1774 __ Mov(x3, 1);
1775 __ Bind(&nzf_end);
1776
1777 __ Mov(x18, 0xffffffff00000000);
1778
1779 Label a, a_end;
1780 __ Cbz(w18, &a);
1781 __ B(&a_end);
1782 __ Bind(&a);
1783 __ Mov(x4, 1);
1784 __ Bind(&a_end);
1785
1786 Label b, b_end;
1787 __ Cbnz(w18, &b);
1788 __ B(&b_end);
1789 __ Bind(&b);
1790 __ Mov(x5, 1);
1791 __ Bind(&b_end);
1792
1793 END();
1794
1795 RUN();
1796
1797 ASSERT_EQUAL_64(1, x0);
1798 ASSERT_EQUAL_64(0, x1);
1799 ASSERT_EQUAL_64(1, x2);
1800 ASSERT_EQUAL_64(0, x3);
1801 ASSERT_EQUAL_64(1, x4);
1802 ASSERT_EQUAL_64(0, x5);
1803
1804 TEARDOWN();
1805 }
1806
1807
TEST(test_branch)1808 TEST(test_branch) {
1809 SETUP();
1810
1811 START();
1812 __ Mov(x0, 0);
1813 __ Mov(x1, 0);
1814 __ Mov(x2, 0);
1815 __ Mov(x3, 0);
1816 __ Mov(x16, 0xaaaaaaaaaaaaaaaa);
1817
1818 Label bz, bz_end;
1819 __ Tbz(w16, 0, &bz);
1820 __ B(&bz_end);
1821 __ Bind(&bz);
1822 __ Mov(x0, 1);
1823 __ Bind(&bz_end);
1824
1825 Label bo, bo_end;
1826 __ Tbz(x16, 63, &bo);
1827 __ B(&bo_end);
1828 __ Bind(&bo);
1829 __ Mov(x1, 1);
1830 __ Bind(&bo_end);
1831
1832 Label nbz, nbz_end;
1833 __ Tbnz(x16, 61, &nbz);
1834 __ B(&nbz_end);
1835 __ Bind(&nbz);
1836 __ Mov(x2, 1);
1837 __ Bind(&nbz_end);
1838
1839 Label nbo, nbo_end;
1840 __ Tbnz(w16, 2, &nbo);
1841 __ B(&nbo_end);
1842 __ Bind(&nbo);
1843 __ Mov(x3, 1);
1844 __ Bind(&nbo_end);
1845 END();
1846
1847 RUN();
1848
1849 ASSERT_EQUAL_64(1, x0);
1850 ASSERT_EQUAL_64(0, x1);
1851 ASSERT_EQUAL_64(1, x2);
1852 ASSERT_EQUAL_64(0, x3);
1853
1854 TEARDOWN();
1855 }
1856
1857
TEST(branch_type)1858 TEST(branch_type) {
1859 SETUP();
1860
1861 Label fail, done;
1862
1863 START();
1864 __ Mov(x0, 0x0);
1865 __ Mov(x10, 0x7);
1866 __ Mov(x11, 0x0);
1867
1868 // Test non taken branches.
1869 __ Cmp(x10, 0x7);
1870 __ B(&fail, ne);
1871 __ B(&fail, never);
1872 __ B(&fail, reg_zero, x10);
1873 __ B(&fail, reg_not_zero, x11);
1874 __ B(&fail, reg_bit_clear, x10, 0);
1875 __ B(&fail, reg_bit_set, x10, 3);
1876
1877 // Test taken branches.
1878 Label l1, l2, l3, l4, l5;
1879 __ Cmp(x10, 0x7);
1880 __ B(&l1, eq);
1881 __ B(&fail);
1882 __ Bind(&l1);
1883 __ B(&l2, always);
1884 __ B(&fail);
1885 __ Bind(&l2);
1886 __ B(&l3, reg_not_zero, x10);
1887 __ B(&fail);
1888 __ Bind(&l3);
1889 __ B(&l4, reg_bit_clear, x10, 15);
1890 __ B(&fail);
1891 __ Bind(&l4);
1892 __ B(&l5, reg_bit_set, x10, 1);
1893 __ B(&fail);
1894 __ Bind(&l5);
1895
1896 __ B(&done);
1897
1898 __ Bind(&fail);
1899 __ Mov(x0, 0x1);
1900
1901 __ Bind(&done);
1902
1903 END();
1904
1905 RUN();
1906
1907 ASSERT_EQUAL_64(0x0, x0);
1908
1909 TEARDOWN();
1910 }
1911
1912
TEST(ldr_str_offset)1913 TEST(ldr_str_offset) {
1914 SETUP();
1915
1916 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
1917 uint64_t dst[5] = {0, 0, 0, 0, 0};
1918 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1919 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
1920
1921 START();
1922 __ Mov(x17, src_base);
1923 __ Mov(x18, dst_base);
1924 __ Ldr(w0, MemOperand(x17));
1925 __ Str(w0, MemOperand(x18));
1926 __ Ldr(w1, MemOperand(x17, 4));
1927 __ Str(w1, MemOperand(x18, 12));
1928 __ Ldr(x2, MemOperand(x17, 8));
1929 __ Str(x2, MemOperand(x18, 16));
1930 __ Ldrb(w3, MemOperand(x17, 1));
1931 __ Strb(w3, MemOperand(x18, 25));
1932 __ Ldrh(w4, MemOperand(x17, 2));
1933 __ Strh(w4, MemOperand(x18, 33));
1934 END();
1935
1936 RUN();
1937
1938 ASSERT_EQUAL_64(0x76543210, x0);
1939 ASSERT_EQUAL_64(0x76543210, dst[0]);
1940 ASSERT_EQUAL_64(0xfedcba98, x1);
1941 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
1942 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
1943 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
1944 ASSERT_EQUAL_64(0x32, x3);
1945 ASSERT_EQUAL_64(0x3200, dst[3]);
1946 ASSERT_EQUAL_64(0x7654, x4);
1947 ASSERT_EQUAL_64(0x765400, dst[4]);
1948 ASSERT_EQUAL_64(src_base, x17);
1949 ASSERT_EQUAL_64(dst_base, x18);
1950
1951 TEARDOWN();
1952 }
1953
1954
TEST(ldr_str_wide)1955 TEST(ldr_str_wide) {
1956 SETUP();
1957
1958 uint32_t src[8192];
1959 uint32_t dst[8192];
1960 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1961 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
1962 memset(src, 0xaa, 8192 * sizeof(src[0]));
1963 memset(dst, 0xaa, 8192 * sizeof(dst[0]));
1964 src[0] = 0;
1965 src[6144] = 6144;
1966 src[8191] = 8191;
1967
1968 START();
1969 __ Mov(x22, src_base);
1970 __ Mov(x23, dst_base);
1971 __ Mov(x24, src_base);
1972 __ Mov(x25, dst_base);
1973 __ Mov(x26, src_base);
1974 __ Mov(x27, dst_base);
1975
1976 __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
1977 __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
1978 __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
1979 __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
1980 __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
1981 __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
1982 END();
1983
1984 RUN();
1985
1986 ASSERT_EQUAL_32(8191, w0);
1987 ASSERT_EQUAL_32(8191, dst[8191]);
1988 ASSERT_EQUAL_64(src_base, x22);
1989 ASSERT_EQUAL_64(dst_base, x23);
1990 ASSERT_EQUAL_32(0, w1);
1991 ASSERT_EQUAL_32(0, dst[0]);
1992 ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
1993 ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
1994 ASSERT_EQUAL_32(6144, w2);
1995 ASSERT_EQUAL_32(6144, dst[6144]);
1996 ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
1997 ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
1998
1999 TEARDOWN();
2000 }
2001
2002
TEST(ldr_str_preindex)2003 TEST(ldr_str_preindex) {
2004 SETUP();
2005
2006 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
2007 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2008 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2009 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2010
2011 START();
2012 __ Mov(x17, src_base);
2013 __ Mov(x18, dst_base);
2014 __ Mov(x19, src_base);
2015 __ Mov(x20, dst_base);
2016 __ Mov(x21, src_base + 16);
2017 __ Mov(x22, dst_base + 40);
2018 __ Mov(x23, src_base);
2019 __ Mov(x24, dst_base);
2020 __ Mov(x25, src_base);
2021 __ Mov(x26, dst_base);
2022 __ Ldr(w0, MemOperand(x17, 4, PreIndex));
2023 __ Str(w0, MemOperand(x18, 12, PreIndex));
2024 __ Ldr(x1, MemOperand(x19, 8, PreIndex));
2025 __ Str(x1, MemOperand(x20, 16, PreIndex));
2026 __ Ldr(w2, MemOperand(x21, -4, PreIndex));
2027 __ Str(w2, MemOperand(x22, -4, PreIndex));
2028 __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
2029 __ Strb(w3, MemOperand(x24, 25, PreIndex));
2030 __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
2031 __ Strh(w4, MemOperand(x26, 41, PreIndex));
2032 END();
2033
2034 RUN();
2035
2036 ASSERT_EQUAL_64(0xfedcba98, x0);
2037 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2038 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2039 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
2040 ASSERT_EQUAL_64(0x01234567, x2);
2041 ASSERT_EQUAL_64(0x0123456700000000, dst[4]);
2042 ASSERT_EQUAL_64(0x32, x3);
2043 ASSERT_EQUAL_64(0x3200, dst[3]);
2044 ASSERT_EQUAL_64(0x9876, x4);
2045 ASSERT_EQUAL_64(0x987600, dst[5]);
2046 ASSERT_EQUAL_64(src_base + 4, x17);
2047 ASSERT_EQUAL_64(dst_base + 12, x18);
2048 ASSERT_EQUAL_64(src_base + 8, x19);
2049 ASSERT_EQUAL_64(dst_base + 16, x20);
2050 ASSERT_EQUAL_64(src_base + 12, x21);
2051 ASSERT_EQUAL_64(dst_base + 36, x22);
2052 ASSERT_EQUAL_64(src_base + 1, x23);
2053 ASSERT_EQUAL_64(dst_base + 25, x24);
2054 ASSERT_EQUAL_64(src_base + 3, x25);
2055 ASSERT_EQUAL_64(dst_base + 41, x26);
2056
2057 TEARDOWN();
2058 }
2059
2060
TEST(ldr_str_postindex)2061 TEST(ldr_str_postindex) {
2062 SETUP();
2063
2064 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
2065 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2066 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2067 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2068
2069 START();
2070 __ Mov(x17, src_base + 4);
2071 __ Mov(x18, dst_base + 12);
2072 __ Mov(x19, src_base + 8);
2073 __ Mov(x20, dst_base + 16);
2074 __ Mov(x21, src_base + 8);
2075 __ Mov(x22, dst_base + 32);
2076 __ Mov(x23, src_base + 1);
2077 __ Mov(x24, dst_base + 25);
2078 __ Mov(x25, src_base + 3);
2079 __ Mov(x26, dst_base + 41);
2080 __ Ldr(w0, MemOperand(x17, 4, PostIndex));
2081 __ Str(w0, MemOperand(x18, 12, PostIndex));
2082 __ Ldr(x1, MemOperand(x19, 8, PostIndex));
2083 __ Str(x1, MemOperand(x20, 16, PostIndex));
2084 __ Ldr(x2, MemOperand(x21, -8, PostIndex));
2085 __ Str(x2, MemOperand(x22, -32, PostIndex));
2086 __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
2087 __ Strb(w3, MemOperand(x24, 5, PostIndex));
2088 __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
2089 __ Strh(w4, MemOperand(x26, -41, PostIndex));
2090 END();
2091
2092 RUN();
2093
2094 ASSERT_EQUAL_64(0xfedcba98, x0);
2095 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2096 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2097 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
2098 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2099 ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
2100 ASSERT_EQUAL_64(0x32, x3);
2101 ASSERT_EQUAL_64(0x3200, dst[3]);
2102 ASSERT_EQUAL_64(0x9876, x4);
2103 ASSERT_EQUAL_64(0x987600, dst[5]);
2104 ASSERT_EQUAL_64(src_base + 8, x17);
2105 ASSERT_EQUAL_64(dst_base + 24, x18);
2106 ASSERT_EQUAL_64(src_base + 16, x19);
2107 ASSERT_EQUAL_64(dst_base + 32, x20);
2108 ASSERT_EQUAL_64(src_base, x21);
2109 ASSERT_EQUAL_64(dst_base, x22);
2110 ASSERT_EQUAL_64(src_base + 2, x23);
2111 ASSERT_EQUAL_64(dst_base + 30, x24);
2112 ASSERT_EQUAL_64(src_base, x25);
2113 ASSERT_EQUAL_64(dst_base, x26);
2114
2115 TEARDOWN();
2116 }
2117
2118
TEST(ldr_str_largeindex)2119 TEST(ldr_str_largeindex) {
2120 SETUP();
2121
2122 // This value won't fit in the immediate offset field of ldr/str instructions.
2123 int largeoffset = 0xabcdef;
2124
2125 int64_t data[3] = { 0x1122334455667788, 0, 0 };
2126 uint64_t base_addr = reinterpret_cast<uintptr_t>(data);
2127 uint64_t drifted_addr = base_addr - largeoffset;
2128
2129 // This test checks that we we can use large immediate offsets when
2130 // using PreIndex or PostIndex addressing mode of the MacroAssembler
2131 // Ldr/Str instructions.
2132
2133 START();
2134 __ Mov(x19, drifted_addr);
2135 __ Ldr(x0, MemOperand(x19, largeoffset, PreIndex));
2136
2137 __ Mov(x20, base_addr);
2138 __ Ldr(x1, MemOperand(x20, largeoffset, PostIndex));
2139
2140 __ Mov(x21, drifted_addr);
2141 __ Str(x0, MemOperand(x21, largeoffset + 8, PreIndex));
2142
2143 __ Mov(x22, base_addr + 16);
2144 __ Str(x0, MemOperand(x22, largeoffset, PostIndex));
2145 END();
2146
2147 RUN();
2148
2149 ASSERT_EQUAL_64(0x1122334455667788, data[0]);
2150 ASSERT_EQUAL_64(0x1122334455667788, data[1]);
2151 ASSERT_EQUAL_64(0x1122334455667788, data[2]);
2152 ASSERT_EQUAL_64(0x1122334455667788, x0);
2153 ASSERT_EQUAL_64(0x1122334455667788, x1);
2154
2155 ASSERT_EQUAL_64(base_addr, x19);
2156 ASSERT_EQUAL_64(base_addr + largeoffset, x20);
2157 ASSERT_EQUAL_64(base_addr + 8, x21);
2158 ASSERT_EQUAL_64(base_addr + 16 + largeoffset, x22);
2159
2160 TEARDOWN();
2161 }
2162
2163
TEST(load_signed)2164 TEST(load_signed) {
2165 SETUP();
2166
2167 uint32_t src[2] = {0x80008080, 0x7fff7f7f};
2168 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2169
2170 START();
2171 __ Mov(x24, src_base);
2172 __ Ldrsb(w0, MemOperand(x24));
2173 __ Ldrsb(w1, MemOperand(x24, 4));
2174 __ Ldrsh(w2, MemOperand(x24));
2175 __ Ldrsh(w3, MemOperand(x24, 4));
2176 __ Ldrsb(x4, MemOperand(x24));
2177 __ Ldrsb(x5, MemOperand(x24, 4));
2178 __ Ldrsh(x6, MemOperand(x24));
2179 __ Ldrsh(x7, MemOperand(x24, 4));
2180 __ Ldrsw(x8, MemOperand(x24));
2181 __ Ldrsw(x9, MemOperand(x24, 4));
2182 END();
2183
2184 RUN();
2185
2186 ASSERT_EQUAL_64(0xffffff80, x0);
2187 ASSERT_EQUAL_64(0x0000007f, x1);
2188 ASSERT_EQUAL_64(0xffff8080, x2);
2189 ASSERT_EQUAL_64(0x00007f7f, x3);
2190 ASSERT_EQUAL_64(0xffffffffffffff80, x4);
2191 ASSERT_EQUAL_64(0x000000000000007f, x5);
2192 ASSERT_EQUAL_64(0xffffffffffff8080, x6);
2193 ASSERT_EQUAL_64(0x0000000000007f7f, x7);
2194 ASSERT_EQUAL_64(0xffffffff80008080, x8);
2195 ASSERT_EQUAL_64(0x000000007fff7f7f, x9);
2196
2197 TEARDOWN();
2198 }
2199
2200
TEST(load_store_regoffset)2201 TEST(load_store_regoffset) {
2202 SETUP();
2203
2204 uint32_t src[3] = {1, 2, 3};
2205 uint32_t dst[4] = {0, 0, 0, 0};
2206 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2207 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2208
2209 START();
2210 __ Mov(x16, src_base);
2211 __ Mov(x17, dst_base);
2212 __ Mov(x18, src_base + 3 * sizeof(src[0]));
2213 __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
2214 __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
2215 __ Mov(x24, 0);
2216 __ Mov(x25, 4);
2217 __ Mov(x26, -4);
2218 __ Mov(x27, 0xfffffffc); // 32-bit -4.
2219 __ Mov(x28, 0xfffffffe); // 32-bit -2.
2220 __ Mov(x29, 0xffffffff); // 32-bit -1.
2221
2222 __ Ldr(w0, MemOperand(x16, x24));
2223 __ Ldr(x1, MemOperand(x16, x25));
2224 __ Ldr(w2, MemOperand(x18, x26));
2225 __ Ldr(w3, MemOperand(x18, x27, SXTW));
2226 __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
2227 __ Str(w0, MemOperand(x17, x24));
2228 __ Str(x1, MemOperand(x17, x25));
2229 __ Str(w2, MemOperand(x20, x29, SXTW, 2));
2230 END();
2231
2232 RUN();
2233
2234 ASSERT_EQUAL_64(1, x0);
2235 ASSERT_EQUAL_64(0x0000000300000002, x1);
2236 ASSERT_EQUAL_64(3, x2);
2237 ASSERT_EQUAL_64(3, x3);
2238 ASSERT_EQUAL_64(2, x4);
2239 ASSERT_EQUAL_32(1, dst[0]);
2240 ASSERT_EQUAL_32(2, dst[1]);
2241 ASSERT_EQUAL_32(3, dst[2]);
2242 ASSERT_EQUAL_32(3, dst[3]);
2243
2244 TEARDOWN();
2245 }
2246
2247
TEST(load_store_float)2248 TEST(load_store_float) {
2249 SETUP();
2250
2251 float src[3] = {1.0, 2.0, 3.0};
2252 float dst[3] = {0.0, 0.0, 0.0};
2253 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2254 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2255
2256 START();
2257 __ Mov(x17, src_base);
2258 __ Mov(x18, dst_base);
2259 __ Mov(x19, src_base);
2260 __ Mov(x20, dst_base);
2261 __ Mov(x21, src_base);
2262 __ Mov(x22, dst_base);
2263 __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
2264 __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2265 __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
2266 __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2267 __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2268 __ Str(s2, MemOperand(x22, sizeof(dst[0])));
2269 END();
2270
2271 RUN();
2272
2273 ASSERT_EQUAL_FP32(2.0, s0);
2274 ASSERT_EQUAL_FP32(2.0, dst[0]);
2275 ASSERT_EQUAL_FP32(1.0, s1);
2276 ASSERT_EQUAL_FP32(1.0, dst[2]);
2277 ASSERT_EQUAL_FP32(3.0, s2);
2278 ASSERT_EQUAL_FP32(3.0, dst[1]);
2279 ASSERT_EQUAL_64(src_base, x17);
2280 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2281 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2282 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2283 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2284 ASSERT_EQUAL_64(dst_base, x22);
2285
2286 TEARDOWN();
2287 }
2288
2289
TEST(load_store_double)2290 TEST(load_store_double) {
2291 SETUP();
2292
2293 double src[3] = {1.0, 2.0, 3.0};
2294 double dst[3] = {0.0, 0.0, 0.0};
2295 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2296 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2297
2298 START();
2299 __ Mov(x17, src_base);
2300 __ Mov(x18, dst_base);
2301 __ Mov(x19, src_base);
2302 __ Mov(x20, dst_base);
2303 __ Mov(x21, src_base);
2304 __ Mov(x22, dst_base);
2305 __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
2306 __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2307 __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
2308 __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2309 __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2310 __ Str(d2, MemOperand(x22, sizeof(dst[0])));
2311 END();
2312
2313 RUN();
2314
2315 ASSERT_EQUAL_FP64(2.0, d0);
2316 ASSERT_EQUAL_FP64(2.0, dst[0]);
2317 ASSERT_EQUAL_FP64(1.0, d1);
2318 ASSERT_EQUAL_FP64(1.0, dst[2]);
2319 ASSERT_EQUAL_FP64(3.0, d2);
2320 ASSERT_EQUAL_FP64(3.0, dst[1]);
2321 ASSERT_EQUAL_64(src_base, x17);
2322 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2323 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2324 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2325 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2326 ASSERT_EQUAL_64(dst_base, x22);
2327
2328 TEARDOWN();
2329 }
2330
2331
TEST(ldp_stp_float)2332 TEST(ldp_stp_float) {
2333 SETUP();
2334
2335 float src[2] = {1.0, 2.0};
2336 float dst[3] = {0.0, 0.0, 0.0};
2337 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2338 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2339
2340 START();
2341 __ Mov(x16, src_base);
2342 __ Mov(x17, dst_base);
2343 __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2344 __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2345 END();
2346
2347 RUN();
2348
2349 ASSERT_EQUAL_FP32(1.0, s31);
2350 ASSERT_EQUAL_FP32(2.0, s0);
2351 ASSERT_EQUAL_FP32(0.0, dst[0]);
2352 ASSERT_EQUAL_FP32(2.0, dst[1]);
2353 ASSERT_EQUAL_FP32(1.0, dst[2]);
2354 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2355 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2356
2357 TEARDOWN();
2358 }
2359
2360
TEST(ldp_stp_double)2361 TEST(ldp_stp_double) {
2362 SETUP();
2363
2364 double src[2] = {1.0, 2.0};
2365 double dst[3] = {0.0, 0.0, 0.0};
2366 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2367 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2368
2369 START();
2370 __ Mov(x16, src_base);
2371 __ Mov(x17, dst_base);
2372 __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2373 __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2374 END();
2375
2376 RUN();
2377
2378 ASSERT_EQUAL_FP64(1.0, d31);
2379 ASSERT_EQUAL_FP64(2.0, d0);
2380 ASSERT_EQUAL_FP64(0.0, dst[0]);
2381 ASSERT_EQUAL_FP64(2.0, dst[1]);
2382 ASSERT_EQUAL_FP64(1.0, dst[2]);
2383 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2384 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2385
2386 TEARDOWN();
2387 }
2388
2389
TEST(ldp_stp_offset)2390 TEST(ldp_stp_offset) {
2391 SETUP();
2392
2393 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2394 0xffeeddccbbaa9988};
2395 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2396 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2397 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2398
2399 START();
2400 __ Mov(x16, src_base);
2401 __ Mov(x17, dst_base);
2402 __ Mov(x18, src_base + 24);
2403 __ Mov(x19, dst_base + 56);
2404 __ Ldp(w0, w1, MemOperand(x16));
2405 __ Ldp(w2, w3, MemOperand(x16, 4));
2406 __ Ldp(x4, x5, MemOperand(x16, 8));
2407 __ Ldp(w6, w7, MemOperand(x18, -12));
2408 __ Ldp(x8, x9, MemOperand(x18, -16));
2409 __ Stp(w0, w1, MemOperand(x17));
2410 __ Stp(w2, w3, MemOperand(x17, 8));
2411 __ Stp(x4, x5, MemOperand(x17, 16));
2412 __ Stp(w6, w7, MemOperand(x19, -24));
2413 __ Stp(x8, x9, MemOperand(x19, -16));
2414 END();
2415
2416 RUN();
2417
2418 ASSERT_EQUAL_64(0x44556677, x0);
2419 ASSERT_EQUAL_64(0x00112233, x1);
2420 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
2421 ASSERT_EQUAL_64(0x00112233, x2);
2422 ASSERT_EQUAL_64(0xccddeeff, x3);
2423 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
2424 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2425 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
2426 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2427 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
2428 ASSERT_EQUAL_64(0x8899aabb, x6);
2429 ASSERT_EQUAL_64(0xbbaa9988, x7);
2430 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
2431 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
2432 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
2433 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
2434 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
2435 ASSERT_EQUAL_64(src_base, x16);
2436 ASSERT_EQUAL_64(dst_base, x17);
2437 ASSERT_EQUAL_64(src_base + 24, x18);
2438 ASSERT_EQUAL_64(dst_base + 56, x19);
2439
2440 TEARDOWN();
2441 }
2442
2443
TEST(ldnp_stnp_offset)2444 TEST(ldnp_stnp_offset) {
2445 SETUP();
2446
2447 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2448 0xffeeddccbbaa9988};
2449 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2450 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2451 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2452
2453 START();
2454 __ Mov(x16, src_base);
2455 __ Mov(x17, dst_base);
2456 __ Mov(x18, src_base + 24);
2457 __ Mov(x19, dst_base + 56);
2458 __ Ldnp(w0, w1, MemOperand(x16));
2459 __ Ldnp(w2, w3, MemOperand(x16, 4));
2460 __ Ldnp(x4, x5, MemOperand(x16, 8));
2461 __ Ldnp(w6, w7, MemOperand(x18, -12));
2462 __ Ldnp(x8, x9, MemOperand(x18, -16));
2463 __ Stnp(w0, w1, MemOperand(x17));
2464 __ Stnp(w2, w3, MemOperand(x17, 8));
2465 __ Stnp(x4, x5, MemOperand(x17, 16));
2466 __ Stnp(w6, w7, MemOperand(x19, -24));
2467 __ Stnp(x8, x9, MemOperand(x19, -16));
2468 END();
2469
2470 RUN();
2471
2472 ASSERT_EQUAL_64(0x44556677, x0);
2473 ASSERT_EQUAL_64(0x00112233, x1);
2474 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
2475 ASSERT_EQUAL_64(0x00112233, x2);
2476 ASSERT_EQUAL_64(0xccddeeff, x3);
2477 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
2478 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2479 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
2480 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2481 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
2482 ASSERT_EQUAL_64(0x8899aabb, x6);
2483 ASSERT_EQUAL_64(0xbbaa9988, x7);
2484 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
2485 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
2486 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
2487 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
2488 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
2489 ASSERT_EQUAL_64(src_base, x16);
2490 ASSERT_EQUAL_64(dst_base, x17);
2491 ASSERT_EQUAL_64(src_base + 24, x18);
2492 ASSERT_EQUAL_64(dst_base + 56, x19);
2493
2494 TEARDOWN();
2495 }
2496
2497
TEST(ldp_stp_preindex)2498 TEST(ldp_stp_preindex) {
2499 SETUP();
2500
2501 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2502 0xffeeddccbbaa9988};
2503 uint64_t dst[5] = {0, 0, 0, 0, 0};
2504 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2505 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2506
2507 START();
2508 __ Mov(x16, src_base);
2509 __ Mov(x17, dst_base);
2510 __ Mov(x18, dst_base + 16);
2511 __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
2512 __ Mov(x19, x16);
2513 __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
2514 __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
2515 __ Mov(x20, x17);
2516 __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
2517 __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
2518 __ Mov(x21, x16);
2519 __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
2520 __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
2521 __ Mov(x22, x18);
2522 __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
2523 END();
2524
2525 RUN();
2526
2527 ASSERT_EQUAL_64(0x00112233, x0);
2528 ASSERT_EQUAL_64(0xccddeeff, x1);
2529 ASSERT_EQUAL_64(0x44556677, x2);
2530 ASSERT_EQUAL_64(0x00112233, x3);
2531 ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
2532 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
2533 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2534 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2535 ASSERT_EQUAL_64(0x0011223344556677, x6);
2536 ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
2537 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
2538 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
2539 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
2540 ASSERT_EQUAL_64(src_base, x16);
2541 ASSERT_EQUAL_64(dst_base, x17);
2542 ASSERT_EQUAL_64(dst_base + 16, x18);
2543 ASSERT_EQUAL_64(src_base + 4, x19);
2544 ASSERT_EQUAL_64(dst_base + 4, x20);
2545 ASSERT_EQUAL_64(src_base + 8, x21);
2546 ASSERT_EQUAL_64(dst_base + 24, x22);
2547
2548 TEARDOWN();
2549 }
2550
2551
TEST(ldp_stp_postindex)2552 TEST(ldp_stp_postindex) {
2553 SETUP();
2554
2555 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
2556 0xffeeddccbbaa9988, 0x7766554433221100};
2557 uint64_t dst[5] = {0, 0, 0, 0, 0};
2558 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2559 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2560
2561 START();
2562 __ Mov(x16, src_base);
2563 __ Mov(x17, dst_base);
2564 __ Mov(x18, dst_base + 16);
2565 __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
2566 __ Mov(x19, x16);
2567 __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
2568 __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
2569 __ Mov(x20, x17);
2570 __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
2571 __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
2572 __ Mov(x21, x16);
2573 __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
2574 __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
2575 __ Mov(x22, x18);
2576 __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
2577 END();
2578
2579 RUN();
2580
2581 ASSERT_EQUAL_64(0x44556677, x0);
2582 ASSERT_EQUAL_64(0x00112233, x1);
2583 ASSERT_EQUAL_64(0x00112233, x2);
2584 ASSERT_EQUAL_64(0xccddeeff, x3);
2585 ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
2586 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
2587 ASSERT_EQUAL_64(0x0011223344556677, x4);
2588 ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
2589 ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
2590 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
2591 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
2592 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
2593 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
2594 ASSERT_EQUAL_64(src_base, x16);
2595 ASSERT_EQUAL_64(dst_base, x17);
2596 ASSERT_EQUAL_64(dst_base + 16, x18);
2597 ASSERT_EQUAL_64(src_base + 4, x19);
2598 ASSERT_EQUAL_64(dst_base + 4, x20);
2599 ASSERT_EQUAL_64(src_base + 8, x21);
2600 ASSERT_EQUAL_64(dst_base + 24, x22);
2601
2602 TEARDOWN();
2603 }
2604
2605
TEST(ldp_sign_extend)2606 TEST(ldp_sign_extend) {
2607 SETUP();
2608
2609 uint32_t src[2] = {0x80000000, 0x7fffffff};
2610 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2611
2612 START();
2613 __ Mov(x24, src_base);
2614 __ Ldpsw(x0, x1, MemOperand(x24));
2615 END();
2616
2617 RUN();
2618
2619 ASSERT_EQUAL_64(0xffffffff80000000, x0);
2620 ASSERT_EQUAL_64(0x000000007fffffff, x1);
2621
2622 TEARDOWN();
2623 }
2624
2625
TEST(ldur_stur)2626 TEST(ldur_stur) {
2627 SETUP();
2628
2629 int64_t src[2] = {0x0123456789abcdef, 0x0123456789abcdef};
2630 int64_t dst[5] = {0, 0, 0, 0, 0};
2631 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2632 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2633
2634 START();
2635 __ Mov(x17, src_base);
2636 __ Mov(x18, dst_base);
2637 __ Mov(x19, src_base + 16);
2638 __ Mov(x20, dst_base + 32);
2639 __ Mov(x21, dst_base + 40);
2640 __ Ldr(w0, MemOperand(x17, 1));
2641 __ Str(w0, MemOperand(x18, 2));
2642 __ Ldr(x1, MemOperand(x17, 3));
2643 __ Str(x1, MemOperand(x18, 9));
2644 __ Ldr(w2, MemOperand(x19, -9));
2645 __ Str(w2, MemOperand(x20, -5));
2646 __ Ldrb(w3, MemOperand(x19, -1));
2647 __ Strb(w3, MemOperand(x21, -1));
2648 END();
2649
2650 RUN();
2651
2652 ASSERT_EQUAL_64(0x6789abcd, x0);
2653 ASSERT_EQUAL_64(0x00006789abcd0000, dst[0]);
2654 ASSERT_EQUAL_64(0xabcdef0123456789, x1);
2655 ASSERT_EQUAL_64(0xcdef012345678900, dst[1]);
2656 ASSERT_EQUAL_64(0x000000ab, dst[2]);
2657 ASSERT_EQUAL_64(0xabcdef01, x2);
2658 ASSERT_EQUAL_64(0x00abcdef01000000, dst[3]);
2659 ASSERT_EQUAL_64(0x00000001, x3);
2660 ASSERT_EQUAL_64(0x0100000000000000, dst[4]);
2661 ASSERT_EQUAL_64(src_base, x17);
2662 ASSERT_EQUAL_64(dst_base, x18);
2663 ASSERT_EQUAL_64(src_base + 16, x19);
2664 ASSERT_EQUAL_64(dst_base + 32, x20);
2665
2666 TEARDOWN();
2667 }
2668
2669
TEST(ldr_literal)2670 TEST(ldr_literal) {
2671 SETUP();
2672
2673 START();
2674 __ Ldr(x2, 0x1234567890abcdef);
2675 __ Ldr(w3, 0xfedcba09);
2676 __ Ldr(d13, 1.234);
2677 __ Ldr(s25, 2.5);
2678 END();
2679
2680 RUN();
2681
2682 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
2683 ASSERT_EQUAL_64(0xfedcba09, x3);
2684 ASSERT_EQUAL_FP64(1.234, d13);
2685 ASSERT_EQUAL_FP32(2.5, s25);
2686
2687 TEARDOWN();
2688 }
2689
2690
LdrLiteralRangeHelper(ptrdiff_t range_,LiteralPoolEmitOption option,bool expect_dump)2691 static void LdrLiteralRangeHelper(ptrdiff_t range_,
2692 LiteralPoolEmitOption option,
2693 bool expect_dump) {
2694 VIXL_ASSERT(range_ > 0);
2695 SETUP_SIZE(range_ + 1024);
2696
2697 Label label_1, label_2;
2698
2699 size_t range = static_cast<size_t>(range_);
2700 size_t code_size = 0;
2701 size_t pool_guard_size;
2702
2703 if (option == NoJumpRequired) {
2704 // Space for an explicit branch.
2705 pool_guard_size = sizeof(Instr);
2706 } else {
2707 pool_guard_size = 0;
2708 }
2709
2710 START();
2711 // Force a pool dump so the pool starts off empty.
2712 __ EmitLiteralPool(JumpRequired);
2713 ASSERT_LITERAL_POOL_SIZE(0);
2714
2715 __ Ldr(x0, 0x1234567890abcdef);
2716 __ Ldr(w1, 0xfedcba09);
2717 __ Ldr(d0, 1.234);
2718 __ Ldr(s1, 2.5);
2719 ASSERT_LITERAL_POOL_SIZE(24);
2720
2721 code_size += 4 * sizeof(Instr);
2722
2723 // Check that the requested range (allowing space for a branch over the pool)
2724 // can be handled by this test.
2725 VIXL_ASSERT((code_size + pool_guard_size) <= range);
2726
2727 // Emit NOPs up to 'range', leaving space for the pool guard.
2728 while ((code_size + pool_guard_size) < range) {
2729 __ Nop();
2730 code_size += sizeof(Instr);
2731 }
2732
2733 // Emit the guard sequence before the literal pool.
2734 if (option == NoJumpRequired) {
2735 __ B(&label_1);
2736 code_size += sizeof(Instr);
2737 }
2738
2739 VIXL_ASSERT(code_size == range);
2740 ASSERT_LITERAL_POOL_SIZE(24);
2741
2742 // Possibly generate a literal pool.
2743 __ CheckLiteralPool(option);
2744 __ Bind(&label_1);
2745 if (expect_dump) {
2746 ASSERT_LITERAL_POOL_SIZE(0);
2747 } else {
2748 ASSERT_LITERAL_POOL_SIZE(24);
2749 }
2750
2751 // Force a pool flush to check that a second pool functions correctly.
2752 __ EmitLiteralPool(JumpRequired);
2753 ASSERT_LITERAL_POOL_SIZE(0);
2754
2755 // These loads should be after the pool (and will require a new one).
2756 __ Ldr(x4, 0x34567890abcdef12);
2757 __ Ldr(w5, 0xdcba09fe);
2758 __ Ldr(d4, 123.4);
2759 __ Ldr(s5, 250.0);
2760 ASSERT_LITERAL_POOL_SIZE(24);
2761 END();
2762
2763 RUN();
2764
2765 // Check that the literals loaded correctly.
2766 ASSERT_EQUAL_64(0x1234567890abcdef, x0);
2767 ASSERT_EQUAL_64(0xfedcba09, x1);
2768 ASSERT_EQUAL_FP64(1.234, d0);
2769 ASSERT_EQUAL_FP32(2.5, s1);
2770 ASSERT_EQUAL_64(0x34567890abcdef12, x4);
2771 ASSERT_EQUAL_64(0xdcba09fe, x5);
2772 ASSERT_EQUAL_FP64(123.4, d4);
2773 ASSERT_EQUAL_FP32(250.0, s5);
2774
2775 TEARDOWN();
2776 }
2777
2778
TEST(ldr_literal_range_1)2779 TEST(ldr_literal_range_1) {
2780 LdrLiteralRangeHelper(kRecommendedLiteralPoolRange,
2781 NoJumpRequired,
2782 true);
2783 }
2784
2785
TEST(ldr_literal_range_2)2786 TEST(ldr_literal_range_2) {
2787 LdrLiteralRangeHelper(kRecommendedLiteralPoolRange-sizeof(Instr),
2788 NoJumpRequired,
2789 false);
2790 }
2791
2792
TEST(ldr_literal_range_3)2793 TEST(ldr_literal_range_3) {
2794 LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange,
2795 JumpRequired,
2796 true);
2797 }
2798
2799
TEST(ldr_literal_range_4)2800 TEST(ldr_literal_range_4) {
2801 LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange-sizeof(Instr),
2802 JumpRequired,
2803 false);
2804 }
2805
2806
TEST(ldr_literal_range_5)2807 TEST(ldr_literal_range_5) {
2808 LdrLiteralRangeHelper(kLiteralPoolCheckInterval,
2809 JumpRequired,
2810 false);
2811 }
2812
2813
TEST(ldr_literal_range_6)2814 TEST(ldr_literal_range_6) {
2815 LdrLiteralRangeHelper(kLiteralPoolCheckInterval-sizeof(Instr),
2816 JumpRequired,
2817 false);
2818 }
2819
2820
TEST(add_sub_imm)2821 TEST(add_sub_imm) {
2822 SETUP();
2823
2824 START();
2825 __ Mov(x0, 0x0);
2826 __ Mov(x1, 0x1111);
2827 __ Mov(x2, 0xffffffffffffffff);
2828 __ Mov(x3, 0x8000000000000000);
2829
2830 __ Add(x10, x0, Operand(0x123));
2831 __ Add(x11, x1, Operand(0x122000));
2832 __ Add(x12, x0, Operand(0xabc << 12));
2833 __ Add(x13, x2, Operand(1));
2834
2835 __ Add(w14, w0, Operand(0x123));
2836 __ Add(w15, w1, Operand(0x122000));
2837 __ Add(w16, w0, Operand(0xabc << 12));
2838 __ Add(w17, w2, Operand(1));
2839
2840 __ Sub(x20, x0, Operand(0x1));
2841 __ Sub(x21, x1, Operand(0x111));
2842 __ Sub(x22, x1, Operand(0x1 << 12));
2843 __ Sub(x23, x3, Operand(1));
2844
2845 __ Sub(w24, w0, Operand(0x1));
2846 __ Sub(w25, w1, Operand(0x111));
2847 __ Sub(w26, w1, Operand(0x1 << 12));
2848 __ Sub(w27, w3, Operand(1));
2849 END();
2850
2851 RUN();
2852
2853 ASSERT_EQUAL_64(0x123, x10);
2854 ASSERT_EQUAL_64(0x123111, x11);
2855 ASSERT_EQUAL_64(0xabc000, x12);
2856 ASSERT_EQUAL_64(0x0, x13);
2857
2858 ASSERT_EQUAL_32(0x123, w14);
2859 ASSERT_EQUAL_32(0x123111, w15);
2860 ASSERT_EQUAL_32(0xabc000, w16);
2861 ASSERT_EQUAL_32(0x0, w17);
2862
2863 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
2864 ASSERT_EQUAL_64(0x1000, x21);
2865 ASSERT_EQUAL_64(0x111, x22);
2866 ASSERT_EQUAL_64(0x7fffffffffffffff, x23);
2867
2868 ASSERT_EQUAL_32(0xffffffff, w24);
2869 ASSERT_EQUAL_32(0x1000, w25);
2870 ASSERT_EQUAL_32(0x111, w26);
2871 ASSERT_EQUAL_32(0xffffffff, w27);
2872
2873 TEARDOWN();
2874 }
2875
2876
TEST(add_sub_wide_imm)2877 TEST(add_sub_wide_imm) {
2878 SETUP();
2879
2880 START();
2881 __ Mov(x0, 0x0);
2882 __ Mov(x1, 0x1);
2883
2884 __ Add(x10, x0, Operand(0x1234567890abcdef));
2885 __ Add(x11, x1, Operand(0xffffffff));
2886
2887 __ Add(w12, w0, Operand(0x12345678));
2888 __ Add(w13, w1, Operand(0xffffffff));
2889
2890 __ Sub(x20, x0, Operand(0x1234567890abcdef));
2891
2892 __ Sub(w21, w0, Operand(0x12345678));
2893 END();
2894
2895 RUN();
2896
2897 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
2898 ASSERT_EQUAL_64(0x100000000, x11);
2899
2900 ASSERT_EQUAL_32(0x12345678, w12);
2901 ASSERT_EQUAL_64(0x0, x13);
2902
2903 ASSERT_EQUAL_64(-0x1234567890abcdef, x20);
2904
2905 ASSERT_EQUAL_32(-0x12345678, w21);
2906
2907 TEARDOWN();
2908 }
2909
2910
TEST(add_sub_shifted)2911 TEST(add_sub_shifted) {
2912 SETUP();
2913
2914 START();
2915 __ Mov(x0, 0);
2916 __ Mov(x1, 0x0123456789abcdef);
2917 __ Mov(x2, 0xfedcba9876543210);
2918 __ Mov(x3, 0xffffffffffffffff);
2919
2920 __ Add(x10, x1, Operand(x2));
2921 __ Add(x11, x0, Operand(x1, LSL, 8));
2922 __ Add(x12, x0, Operand(x1, LSR, 8));
2923 __ Add(x13, x0, Operand(x1, ASR, 8));
2924 __ Add(x14, x0, Operand(x2, ASR, 8));
2925 __ Add(w15, w0, Operand(w1, ASR, 8));
2926 __ Add(w18, w3, Operand(w1, ROR, 8));
2927 __ Add(x19, x3, Operand(x1, ROR, 8));
2928
2929 __ Sub(x20, x3, Operand(x2));
2930 __ Sub(x21, x3, Operand(x1, LSL, 8));
2931 __ Sub(x22, x3, Operand(x1, LSR, 8));
2932 __ Sub(x23, x3, Operand(x1, ASR, 8));
2933 __ Sub(x24, x3, Operand(x2, ASR, 8));
2934 __ Sub(w25, w3, Operand(w1, ASR, 8));
2935 __ Sub(w26, w3, Operand(w1, ROR, 8));
2936 __ Sub(x27, x3, Operand(x1, ROR, 8));
2937 END();
2938
2939 RUN();
2940
2941 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
2942 ASSERT_EQUAL_64(0x23456789abcdef00, x11);
2943 ASSERT_EQUAL_64(0x000123456789abcd, x12);
2944 ASSERT_EQUAL_64(0x000123456789abcd, x13);
2945 ASSERT_EQUAL_64(0xfffedcba98765432, x14);
2946 ASSERT_EQUAL_64(0xff89abcd, x15);
2947 ASSERT_EQUAL_64(0xef89abcc, x18);
2948 ASSERT_EQUAL_64(0xef0123456789abcc, x19);
2949
2950 ASSERT_EQUAL_64(0x0123456789abcdef, x20);
2951 ASSERT_EQUAL_64(0xdcba9876543210ff, x21);
2952 ASSERT_EQUAL_64(0xfffedcba98765432, x22);
2953 ASSERT_EQUAL_64(0xfffedcba98765432, x23);
2954 ASSERT_EQUAL_64(0x000123456789abcd, x24);
2955 ASSERT_EQUAL_64(0x00765432, x25);
2956 ASSERT_EQUAL_64(0x10765432, x26);
2957 ASSERT_EQUAL_64(0x10fedcba98765432, x27);
2958
2959 TEARDOWN();
2960 }
2961
2962
TEST(add_sub_extended)2963 TEST(add_sub_extended) {
2964 SETUP();
2965
2966 START();
2967 __ Mov(x0, 0);
2968 __ Mov(x1, 0x0123456789abcdef);
2969 __ Mov(x2, 0xfedcba9876543210);
2970 __ Mov(w3, 0x80);
2971
2972 __ Add(x10, x0, Operand(x1, UXTB, 0));
2973 __ Add(x11, x0, Operand(x1, UXTB, 1));
2974 __ Add(x12, x0, Operand(x1, UXTH, 2));
2975 __ Add(x13, x0, Operand(x1, UXTW, 4));
2976
2977 __ Add(x14, x0, Operand(x1, SXTB, 0));
2978 __ Add(x15, x0, Operand(x1, SXTB, 1));
2979 __ Add(x16, x0, Operand(x1, SXTH, 2));
2980 __ Add(x17, x0, Operand(x1, SXTW, 3));
2981 __ Add(x18, x0, Operand(x2, SXTB, 0));
2982 __ Add(x19, x0, Operand(x2, SXTB, 1));
2983 __ Add(x20, x0, Operand(x2, SXTH, 2));
2984 __ Add(x21, x0, Operand(x2, SXTW, 3));
2985
2986 __ Add(x22, x1, Operand(x2, SXTB, 1));
2987 __ Sub(x23, x1, Operand(x2, SXTB, 1));
2988
2989 __ Add(w24, w1, Operand(w2, UXTB, 2));
2990 __ Add(w25, w0, Operand(w1, SXTB, 0));
2991 __ Add(w26, w0, Operand(w1, SXTB, 1));
2992 __ Add(w27, w2, Operand(w1, SXTW, 3));
2993
2994 __ Add(w28, w0, Operand(w1, SXTW, 3));
2995 __ Add(x29, x0, Operand(w1, SXTW, 3));
2996
2997 __ Sub(x30, x0, Operand(w3, SXTB, 1));
2998 END();
2999
3000 RUN();
3001
3002 ASSERT_EQUAL_64(0xef, x10);
3003 ASSERT_EQUAL_64(0x1de, x11);
3004 ASSERT_EQUAL_64(0x337bc, x12);
3005 ASSERT_EQUAL_64(0x89abcdef0, x13);
3006
3007 ASSERT_EQUAL_64(0xffffffffffffffef, x14);
3008 ASSERT_EQUAL_64(0xffffffffffffffde, x15);
3009 ASSERT_EQUAL_64(0xffffffffffff37bc, x16);
3010 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x17);
3011 ASSERT_EQUAL_64(0x10, x18);
3012 ASSERT_EQUAL_64(0x20, x19);
3013 ASSERT_EQUAL_64(0xc840, x20);
3014 ASSERT_EQUAL_64(0x3b2a19080, x21);
3015
3016 ASSERT_EQUAL_64(0x0123456789abce0f, x22);
3017 ASSERT_EQUAL_64(0x0123456789abcdcf, x23);
3018
3019 ASSERT_EQUAL_32(0x89abce2f, w24);
3020 ASSERT_EQUAL_32(0xffffffef, w25);
3021 ASSERT_EQUAL_32(0xffffffde, w26);
3022 ASSERT_EQUAL_32(0xc3b2a188, w27);
3023
3024 ASSERT_EQUAL_32(0x4d5e6f78, w28);
3025 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x29);
3026
3027 ASSERT_EQUAL_64(256, x30);
3028
3029 TEARDOWN();
3030 }
3031
3032
TEST(add_sub_negative)3033 TEST(add_sub_negative) {
3034 SETUP();
3035
3036 START();
3037 __ Mov(x0, 0);
3038 __ Mov(x1, 4687);
3039 __ Mov(x2, 0x1122334455667788);
3040 __ Mov(w3, 0x11223344);
3041 __ Mov(w4, 400000);
3042
3043 __ Add(x10, x0, -42);
3044 __ Add(x11, x1, -687);
3045 __ Add(x12, x2, -0x88);
3046
3047 __ Sub(x13, x0, -600);
3048 __ Sub(x14, x1, -313);
3049 __ Sub(x15, x2, -0x555);
3050
3051 __ Add(w19, w3, -0x344);
3052 __ Add(w20, w4, -2000);
3053
3054 __ Sub(w21, w3, -0xbc);
3055 __ Sub(w22, w4, -2000);
3056 END();
3057
3058 RUN();
3059
3060 ASSERT_EQUAL_64(-42, x10);
3061 ASSERT_EQUAL_64(4000, x11);
3062 ASSERT_EQUAL_64(0x1122334455667700, x12);
3063
3064 ASSERT_EQUAL_64(600, x13);
3065 ASSERT_EQUAL_64(5000, x14);
3066 ASSERT_EQUAL_64(0x1122334455667cdd, x15);
3067
3068 ASSERT_EQUAL_32(0x11223000, w19);
3069 ASSERT_EQUAL_32(398000, w20);
3070
3071 ASSERT_EQUAL_32(0x11223400, w21);
3072 ASSERT_EQUAL_32(402000, w22);
3073
3074 TEARDOWN();
3075 }
3076
3077
TEST(add_sub_zero)3078 TEST(add_sub_zero) {
3079 SETUP();
3080
3081 START();
3082 __ Mov(x0, 0);
3083 __ Mov(x1, 0);
3084 __ Mov(x2, 0);
3085
3086 Label blob1;
3087 __ Bind(&blob1);
3088 __ Add(x0, x0, 0);
3089 __ Sub(x1, x1, 0);
3090 __ Sub(x2, x2, xzr);
3091 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob1) == 0);
3092
3093 Label blob2;
3094 __ Bind(&blob2);
3095 __ Add(w3, w3, 0);
3096 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob2) != 0);
3097
3098 Label blob3;
3099 __ Bind(&blob3);
3100 __ Sub(w3, w3, wzr);
3101 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob3) != 0);
3102
3103 END();
3104
3105 RUN();
3106
3107 ASSERT_EQUAL_64(0, x0);
3108 ASSERT_EQUAL_64(0, x1);
3109 ASSERT_EQUAL_64(0, x2);
3110
3111 TEARDOWN();
3112 }
3113
3114
TEST(claim_drop_zero)3115 TEST(claim_drop_zero) {
3116 SETUP();
3117
3118 START();
3119
3120 Label start;
3121 __ Bind(&start);
3122 __ Claim(Operand(0));
3123 __ Drop(Operand(0));
3124 __ Claim(Operand(xzr));
3125 __ Drop(Operand(xzr));
3126 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
3127
3128 END();
3129
3130 RUN();
3131
3132 TEARDOWN();
3133 }
3134
3135
TEST(neg)3136 TEST(neg) {
3137 SETUP();
3138
3139 START();
3140 __ Mov(x0, 0xf123456789abcdef);
3141
3142 // Immediate.
3143 __ Neg(x1, 0x123);
3144 __ Neg(w2, 0x123);
3145
3146 // Shifted.
3147 __ Neg(x3, Operand(x0, LSL, 1));
3148 __ Neg(w4, Operand(w0, LSL, 2));
3149 __ Neg(x5, Operand(x0, LSR, 3));
3150 __ Neg(w6, Operand(w0, LSR, 4));
3151 __ Neg(x7, Operand(x0, ASR, 5));
3152 __ Neg(w8, Operand(w0, ASR, 6));
3153
3154 // Extended.
3155 __ Neg(w9, Operand(w0, UXTB));
3156 __ Neg(x10, Operand(x0, SXTB, 1));
3157 __ Neg(w11, Operand(w0, UXTH, 2));
3158 __ Neg(x12, Operand(x0, SXTH, 3));
3159 __ Neg(w13, Operand(w0, UXTW, 4));
3160 __ Neg(x14, Operand(x0, SXTW, 4));
3161 END();
3162
3163 RUN();
3164
3165 ASSERT_EQUAL_64(0xfffffffffffffedd, x1);
3166 ASSERT_EQUAL_64(0xfffffedd, x2);
3167 ASSERT_EQUAL_64(0x1db97530eca86422, x3);
3168 ASSERT_EQUAL_64(0xd950c844, x4);
3169 ASSERT_EQUAL_64(0xe1db97530eca8643, x5);
3170 ASSERT_EQUAL_64(0xf7654322, x6);
3171 ASSERT_EQUAL_64(0x0076e5d4c3b2a191, x7);
3172 ASSERT_EQUAL_64(0x01d950c9, x8);
3173 ASSERT_EQUAL_64(0xffffff11, x9);
3174 ASSERT_EQUAL_64(0x0000000000000022, x10);
3175 ASSERT_EQUAL_64(0xfffcc844, x11);
3176 ASSERT_EQUAL_64(0x0000000000019088, x12);
3177 ASSERT_EQUAL_64(0x65432110, x13);
3178 ASSERT_EQUAL_64(0x0000000765432110, x14);
3179
3180 TEARDOWN();
3181 }
3182
3183
TEST(adc_sbc_shift)3184 TEST(adc_sbc_shift) {
3185 SETUP();
3186
3187 START();
3188 __ Mov(x0, 0);
3189 __ Mov(x1, 1);
3190 __ Mov(x2, 0x0123456789abcdef);
3191 __ Mov(x3, 0xfedcba9876543210);
3192 __ Mov(x4, 0xffffffffffffffff);
3193
3194 // Clear the C flag.
3195 __ Adds(x0, x0, Operand(0));
3196
3197 __ Adc(x5, x2, Operand(x3));
3198 __ Adc(x6, x0, Operand(x1, LSL, 60));
3199 __ Sbc(x7, x4, Operand(x3, LSR, 4));
3200 __ Adc(x8, x2, Operand(x3, ASR, 4));
3201 __ Adc(x9, x2, Operand(x3, ROR, 8));
3202
3203 __ Adc(w10, w2, Operand(w3));
3204 __ Adc(w11, w0, Operand(w1, LSL, 30));
3205 __ Sbc(w12, w4, Operand(w3, LSR, 4));
3206 __ Adc(w13, w2, Operand(w3, ASR, 4));
3207 __ Adc(w14, w2, Operand(w3, ROR, 8));
3208
3209 // Set the C flag.
3210 __ Cmp(w0, Operand(w0));
3211
3212 __ Adc(x18, x2, Operand(x3));
3213 __ Adc(x19, x0, Operand(x1, LSL, 60));
3214 __ Sbc(x20, x4, Operand(x3, LSR, 4));
3215 __ Adc(x21, x2, Operand(x3, ASR, 4));
3216 __ Adc(x22, x2, Operand(x3, ROR, 8));
3217
3218 __ Adc(w23, w2, Operand(w3));
3219 __ Adc(w24, w0, Operand(w1, LSL, 30));
3220 __ Sbc(w25, w4, Operand(w3, LSR, 4));
3221 __ Adc(w26, w2, Operand(w3, ASR, 4));
3222 __ Adc(w27, w2, Operand(w3, ROR, 8));
3223 END();
3224
3225 RUN();
3226
3227 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
3228 ASSERT_EQUAL_64(INT64_C(1) << 60, x6);
3229 ASSERT_EQUAL_64(0xf0123456789abcdd, x7);
3230 ASSERT_EQUAL_64(0x0111111111111110, x8);
3231 ASSERT_EQUAL_64(0x1222222222222221, x9);
3232
3233 ASSERT_EQUAL_32(0xffffffff, w10);
3234 ASSERT_EQUAL_32(INT32_C(1) << 30, w11);
3235 ASSERT_EQUAL_32(0xf89abcdd, w12);
3236 ASSERT_EQUAL_32(0x91111110, w13);
3237 ASSERT_EQUAL_32(0x9a222221, w14);
3238
3239 ASSERT_EQUAL_64(0xffffffffffffffff + 1, x18);
3240 ASSERT_EQUAL_64((INT64_C(1) << 60) + 1, x19);
3241 ASSERT_EQUAL_64(0xf0123456789abcdd + 1, x20);
3242 ASSERT_EQUAL_64(0x0111111111111110 + 1, x21);
3243 ASSERT_EQUAL_64(0x1222222222222221 + 1, x22);
3244
3245 ASSERT_EQUAL_32(0xffffffff + 1, w23);
3246 ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, w24);
3247 ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
3248 ASSERT_EQUAL_32(0x91111110 + 1, w26);
3249 ASSERT_EQUAL_32(0x9a222221 + 1, w27);
3250
3251 // Check that adc correctly sets the condition flags.
3252 START();
3253 __ Mov(x0, 1);
3254 __ Mov(x1, 0xffffffffffffffff);
3255 // Clear the C flag.
3256 __ Adds(x0, x0, Operand(0));
3257 __ Adcs(x10, x0, Operand(x1));
3258 END();
3259
3260 RUN();
3261
3262 ASSERT_EQUAL_NZCV(ZCFlag);
3263 ASSERT_EQUAL_64(0, x10);
3264
3265 START();
3266 __ Mov(x0, 1);
3267 __ Mov(x1, 0x8000000000000000);
3268 // Clear the C flag.
3269 __ Adds(x0, x0, Operand(0));
3270 __ Adcs(x10, x0, Operand(x1, ASR, 63));
3271 END();
3272
3273 RUN();
3274
3275 ASSERT_EQUAL_NZCV(ZCFlag);
3276 ASSERT_EQUAL_64(0, x10);
3277
3278 START();
3279 __ Mov(x0, 0x10);
3280 __ Mov(x1, 0x07ffffffffffffff);
3281 // Clear the C flag.
3282 __ Adds(x0, x0, Operand(0));
3283 __ Adcs(x10, x0, Operand(x1, LSL, 4));
3284 END();
3285
3286 RUN();
3287
3288 ASSERT_EQUAL_NZCV(NVFlag);
3289 ASSERT_EQUAL_64(0x8000000000000000, x10);
3290
3291 // Check that sbc correctly sets the condition flags.
3292 START();
3293 __ Mov(x0, 0);
3294 __ Mov(x1, 0xffffffffffffffff);
3295 // Clear the C flag.
3296 __ Adds(x0, x0, Operand(0));
3297 __ Sbcs(x10, x0, Operand(x1));
3298 END();
3299
3300 RUN();
3301
3302 ASSERT_EQUAL_NZCV(ZFlag);
3303 ASSERT_EQUAL_64(0, x10);
3304
3305 START();
3306 __ Mov(x0, 1);
3307 __ Mov(x1, 0xffffffffffffffff);
3308 // Clear the C flag.
3309 __ Adds(x0, x0, Operand(0));
3310 __ Sbcs(x10, x0, Operand(x1, LSR, 1));
3311 END();
3312
3313 RUN();
3314
3315 ASSERT_EQUAL_NZCV(NFlag);
3316 ASSERT_EQUAL_64(0x8000000000000001, x10);
3317
3318 START();
3319 __ Mov(x0, 0);
3320 // Clear the C flag.
3321 __ Adds(x0, x0, Operand(0));
3322 __ Sbcs(x10, x0, Operand(0xffffffffffffffff));
3323 END();
3324
3325 RUN();
3326
3327 ASSERT_EQUAL_NZCV(ZFlag);
3328 ASSERT_EQUAL_64(0, x10);
3329
3330 START();
3331 __ Mov(w0, 0x7fffffff);
3332 // Clear the C flag.
3333 __ Adds(x0, x0, Operand(0));
3334 __ Ngcs(w10, w0);
3335 END();
3336
3337 RUN();
3338
3339 ASSERT_EQUAL_NZCV(NFlag);
3340 ASSERT_EQUAL_64(0x80000000, x10);
3341
3342 START();
3343 // Clear the C flag.
3344 __ Adds(x0, x0, Operand(0));
3345 __ Ngcs(x10, 0x7fffffffffffffff);
3346 END();
3347
3348 RUN();
3349
3350 ASSERT_EQUAL_NZCV(NFlag);
3351 ASSERT_EQUAL_64(0x8000000000000000, x10);
3352
3353 START();
3354 __ Mov(x0, 0);
3355 // Set the C flag.
3356 __ Cmp(x0, Operand(x0));
3357 __ Sbcs(x10, x0, Operand(1));
3358 END();
3359
3360 RUN();
3361
3362 ASSERT_EQUAL_NZCV(NFlag);
3363 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
3364
3365 START();
3366 __ Mov(x0, 0);
3367 // Set the C flag.
3368 __ Cmp(x0, Operand(x0));
3369 __ Ngcs(x10, 0x7fffffffffffffff);
3370 END();
3371
3372 RUN();
3373
3374 ASSERT_EQUAL_NZCV(NFlag);
3375 ASSERT_EQUAL_64(0x8000000000000001, x10);
3376
3377 TEARDOWN();
3378 }
3379
3380
TEST(adc_sbc_extend)3381 TEST(adc_sbc_extend) {
3382 SETUP();
3383
3384 START();
3385 // Clear the C flag.
3386 __ Adds(x0, x0, Operand(0));
3387
3388 __ Mov(x0, 0);
3389 __ Mov(x1, 1);
3390 __ Mov(x2, 0x0123456789abcdef);
3391
3392 __ Adc(x10, x1, Operand(w2, UXTB, 1));
3393 __ Adc(x11, x1, Operand(x2, SXTH, 2));
3394 __ Sbc(x12, x1, Operand(w2, UXTW, 4));
3395 __ Adc(x13, x1, Operand(x2, UXTX, 4));
3396
3397 __ Adc(w14, w1, Operand(w2, UXTB, 1));
3398 __ Adc(w15, w1, Operand(w2, SXTH, 2));
3399 __ Adc(w9, w1, Operand(w2, UXTW, 4));
3400
3401 // Set the C flag.
3402 __ Cmp(w0, Operand(w0));
3403
3404 __ Adc(x20, x1, Operand(w2, UXTB, 1));
3405 __ Adc(x21, x1, Operand(x2, SXTH, 2));
3406 __ Sbc(x22, x1, Operand(w2, UXTW, 4));
3407 __ Adc(x23, x1, Operand(x2, UXTX, 4));
3408
3409 __ Adc(w24, w1, Operand(w2, UXTB, 1));
3410 __ Adc(w25, w1, Operand(w2, SXTH, 2));
3411 __ Adc(w26, w1, Operand(w2, UXTW, 4));
3412 END();
3413
3414 RUN();
3415
3416 ASSERT_EQUAL_64(0x1df, x10);
3417 ASSERT_EQUAL_64(0xffffffffffff37bd, x11);
3418 ASSERT_EQUAL_64(0xfffffff765432110, x12);
3419 ASSERT_EQUAL_64(0x123456789abcdef1, x13);
3420
3421 ASSERT_EQUAL_32(0x1df, w14);
3422 ASSERT_EQUAL_32(0xffff37bd, w15);
3423 ASSERT_EQUAL_32(0x9abcdef1, w9);
3424
3425 ASSERT_EQUAL_64(0x1df + 1, x20);
3426 ASSERT_EQUAL_64(0xffffffffffff37bd + 1, x21);
3427 ASSERT_EQUAL_64(0xfffffff765432110 + 1, x22);
3428 ASSERT_EQUAL_64(0x123456789abcdef1 + 1, x23);
3429
3430 ASSERT_EQUAL_32(0x1df + 1, w24);
3431 ASSERT_EQUAL_32(0xffff37bd + 1, w25);
3432 ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
3433
3434 // Check that adc correctly sets the condition flags.
3435 START();
3436 __ Mov(x0, 0xff);
3437 __ Mov(x1, 0xffffffffffffffff);
3438 // Clear the C flag.
3439 __ Adds(x0, x0, Operand(0));
3440 __ Adcs(x10, x0, Operand(x1, SXTX, 1));
3441 END();
3442
3443 RUN();
3444
3445 ASSERT_EQUAL_NZCV(CFlag);
3446
3447 START();
3448 __ Mov(x0, 0x7fffffffffffffff);
3449 __ Mov(x1, 1);
3450 // Clear the C flag.
3451 __ Adds(x0, x0, Operand(0));
3452 __ Adcs(x10, x0, Operand(x1, UXTB, 2));
3453 END();
3454
3455 RUN();
3456
3457 ASSERT_EQUAL_NZCV(NVFlag);
3458
3459 START();
3460 __ Mov(x0, 0x7fffffffffffffff);
3461 // Clear the C flag.
3462 __ Adds(x0, x0, Operand(0));
3463 __ Adcs(x10, x0, Operand(1));
3464 END();
3465
3466 RUN();
3467
3468 ASSERT_EQUAL_NZCV(NVFlag);
3469
3470 TEARDOWN();
3471 }
3472
3473
TEST(adc_sbc_wide_imm)3474 TEST(adc_sbc_wide_imm) {
3475 SETUP();
3476
3477 START();
3478 __ Mov(x0, 0);
3479
3480 // Clear the C flag.
3481 __ Adds(x0, x0, Operand(0));
3482
3483 __ Adc(x7, x0, Operand(0x1234567890abcdef));
3484 __ Adc(w8, w0, Operand(0xffffffff));
3485 __ Sbc(x9, x0, Operand(0x1234567890abcdef));
3486 __ Sbc(w10, w0, Operand(0xffffffff));
3487 __ Ngc(x11, Operand(0xffffffff00000000));
3488 __ Ngc(w12, Operand(0xffff0000));
3489
3490 // Set the C flag.
3491 __ Cmp(w0, Operand(w0));
3492
3493 __ Adc(x18, x0, Operand(0x1234567890abcdef));
3494 __ Adc(w19, w0, Operand(0xffffffff));
3495 __ Sbc(x20, x0, Operand(0x1234567890abcdef));
3496 __ Sbc(w21, w0, Operand(0xffffffff));
3497 __ Ngc(x22, Operand(0xffffffff00000000));
3498 __ Ngc(w23, Operand(0xffff0000));
3499 END();
3500
3501 RUN();
3502
3503 ASSERT_EQUAL_64(0x1234567890abcdef, x7);
3504 ASSERT_EQUAL_64(0xffffffff, x8);
3505 ASSERT_EQUAL_64(0xedcba9876f543210, x9);
3506 ASSERT_EQUAL_64(0, x10);
3507 ASSERT_EQUAL_64(0xffffffff, x11);
3508 ASSERT_EQUAL_64(0xffff, x12);
3509
3510 ASSERT_EQUAL_64(0x1234567890abcdef + 1, x18);
3511 ASSERT_EQUAL_64(0, x19);
3512 ASSERT_EQUAL_64(0xedcba9876f543211, x20);
3513 ASSERT_EQUAL_64(1, x21);
3514 ASSERT_EQUAL_64(0x0000000100000000, x22);
3515 ASSERT_EQUAL_64(0x0000000000010000, x23);
3516
3517 TEARDOWN();
3518 }
3519
TEST(flags)3520 TEST(flags) {
3521 SETUP();
3522
3523 START();
3524 __ Mov(x0, 0);
3525 __ Mov(x1, 0x1111111111111111);
3526 __ Neg(x10, Operand(x0));
3527 __ Neg(x11, Operand(x1));
3528 __ Neg(w12, Operand(w1));
3529 // Clear the C flag.
3530 __ Adds(x0, x0, Operand(0));
3531 __ Ngc(x13, Operand(x0));
3532 // Set the C flag.
3533 __ Cmp(x0, Operand(x0));
3534 __ Ngc(w14, Operand(w0));
3535 END();
3536
3537 RUN();
3538
3539 ASSERT_EQUAL_64(0, x10);
3540 ASSERT_EQUAL_64(-0x1111111111111111, x11);
3541 ASSERT_EQUAL_32(-0x11111111, w12);
3542 ASSERT_EQUAL_64(-1, x13);
3543 ASSERT_EQUAL_32(0, w14);
3544
3545 START();
3546 __ Mov(x0, 0);
3547 __ Cmp(x0, Operand(x0));
3548 END();
3549
3550 RUN();
3551
3552 ASSERT_EQUAL_NZCV(ZCFlag);
3553
3554 START();
3555 __ Mov(w0, 0);
3556 __ Cmp(w0, Operand(w0));
3557 END();
3558
3559 RUN();
3560
3561 ASSERT_EQUAL_NZCV(ZCFlag);
3562
3563 START();
3564 __ Mov(x0, 0);
3565 __ Mov(x1, 0x1111111111111111);
3566 __ Cmp(x0, Operand(x1));
3567 END();
3568
3569 RUN();
3570
3571 ASSERT_EQUAL_NZCV(NFlag);
3572
3573 START();
3574 __ Mov(w0, 0);
3575 __ Mov(w1, 0x11111111);
3576 __ Cmp(w0, Operand(w1));
3577 END();
3578
3579 RUN();
3580
3581 ASSERT_EQUAL_NZCV(NFlag);
3582
3583 START();
3584 __ Mov(x1, 0x1111111111111111);
3585 __ Cmp(x1, Operand(0));
3586 END();
3587
3588 RUN();
3589
3590 ASSERT_EQUAL_NZCV(CFlag);
3591
3592 START();
3593 __ Mov(w1, 0x11111111);
3594 __ Cmp(w1, Operand(0));
3595 END();
3596
3597 RUN();
3598
3599 ASSERT_EQUAL_NZCV(CFlag);
3600
3601 START();
3602 __ Mov(x0, 1);
3603 __ Mov(x1, 0x7fffffffffffffff);
3604 __ Cmn(x1, Operand(x0));
3605 END();
3606
3607 RUN();
3608
3609 ASSERT_EQUAL_NZCV(NVFlag);
3610
3611 START();
3612 __ Mov(w0, 1);
3613 __ Mov(w1, 0x7fffffff);
3614 __ Cmn(w1, Operand(w0));
3615 END();
3616
3617 RUN();
3618
3619 ASSERT_EQUAL_NZCV(NVFlag);
3620
3621 START();
3622 __ Mov(x0, 1);
3623 __ Mov(x1, 0xffffffffffffffff);
3624 __ Cmn(x1, Operand(x0));
3625 END();
3626
3627 RUN();
3628
3629 ASSERT_EQUAL_NZCV(ZCFlag);
3630
3631 START();
3632 __ Mov(w0, 1);
3633 __ Mov(w1, 0xffffffff);
3634 __ Cmn(w1, Operand(w0));
3635 END();
3636
3637 RUN();
3638
3639 ASSERT_EQUAL_NZCV(ZCFlag);
3640
3641 START();
3642 __ Mov(w0, 0);
3643 __ Mov(w1, 1);
3644 // Clear the C flag.
3645 __ Adds(w0, w0, Operand(0));
3646 __ Ngcs(w0, Operand(w1));
3647 END();
3648
3649 RUN();
3650
3651 ASSERT_EQUAL_NZCV(NFlag);
3652
3653 START();
3654 __ Mov(w0, 0);
3655 __ Mov(w1, 0);
3656 // Set the C flag.
3657 __ Cmp(w0, Operand(w0));
3658 __ Ngcs(w0, Operand(w1));
3659 END();
3660
3661 RUN();
3662
3663 ASSERT_EQUAL_NZCV(ZCFlag);
3664
3665 TEARDOWN();
3666 }
3667
3668
TEST(cmp_shift)3669 TEST(cmp_shift) {
3670 SETUP();
3671
3672 START();
3673 __ Mov(x18, 0xf0000000);
3674 __ Mov(x19, 0xf000000010000000);
3675 __ Mov(x20, 0xf0000000f0000000);
3676 __ Mov(x21, 0x7800000078000000);
3677 __ Mov(x22, 0x3c0000003c000000);
3678 __ Mov(x23, 0x8000000780000000);
3679 __ Mov(x24, 0x0000000f00000000);
3680 __ Mov(x25, 0x00000003c0000000);
3681 __ Mov(x26, 0x8000000780000000);
3682 __ Mov(x27, 0xc0000003);
3683
3684 __ Cmp(w20, Operand(w21, LSL, 1));
3685 __ Mrs(x0, NZCV);
3686
3687 __ Cmp(x20, Operand(x22, LSL, 2));
3688 __ Mrs(x1, NZCV);
3689
3690 __ Cmp(w19, Operand(w23, LSR, 3));
3691 __ Mrs(x2, NZCV);
3692
3693 __ Cmp(x18, Operand(x24, LSR, 4));
3694 __ Mrs(x3, NZCV);
3695
3696 __ Cmp(w20, Operand(w25, ASR, 2));
3697 __ Mrs(x4, NZCV);
3698
3699 __ Cmp(x20, Operand(x26, ASR, 3));
3700 __ Mrs(x5, NZCV);
3701
3702 __ Cmp(w27, Operand(w22, ROR, 28));
3703 __ Mrs(x6, NZCV);
3704
3705 __ Cmp(x20, Operand(x21, ROR, 31));
3706 __ Mrs(x7, NZCV);
3707 END();
3708
3709 RUN();
3710
3711 ASSERT_EQUAL_32(ZCFlag, w0);
3712 ASSERT_EQUAL_32(ZCFlag, w1);
3713 ASSERT_EQUAL_32(ZCFlag, w2);
3714 ASSERT_EQUAL_32(ZCFlag, w3);
3715 ASSERT_EQUAL_32(ZCFlag, w4);
3716 ASSERT_EQUAL_32(ZCFlag, w5);
3717 ASSERT_EQUAL_32(ZCFlag, w6);
3718 ASSERT_EQUAL_32(ZCFlag, w7);
3719
3720 TEARDOWN();
3721 }
3722
3723
TEST(cmp_extend)3724 TEST(cmp_extend) {
3725 SETUP();
3726
3727 START();
3728 __ Mov(w20, 0x2);
3729 __ Mov(w21, 0x1);
3730 __ Mov(x22, 0xffffffffffffffff);
3731 __ Mov(x23, 0xff);
3732 __ Mov(x24, 0xfffffffffffffffe);
3733 __ Mov(x25, 0xffff);
3734 __ Mov(x26, 0xffffffff);
3735
3736 __ Cmp(w20, Operand(w21, LSL, 1));
3737 __ Mrs(x0, NZCV);
3738
3739 __ Cmp(x22, Operand(x23, SXTB, 0));
3740 __ Mrs(x1, NZCV);
3741
3742 __ Cmp(x24, Operand(x23, SXTB, 1));
3743 __ Mrs(x2, NZCV);
3744
3745 __ Cmp(x24, Operand(x23, UXTB, 1));
3746 __ Mrs(x3, NZCV);
3747
3748 __ Cmp(w22, Operand(w25, UXTH));
3749 __ Mrs(x4, NZCV);
3750
3751 __ Cmp(x22, Operand(x25, SXTH));
3752 __ Mrs(x5, NZCV);
3753
3754 __ Cmp(x22, Operand(x26, UXTW));
3755 __ Mrs(x6, NZCV);
3756
3757 __ Cmp(x24, Operand(x26, SXTW, 1));
3758 __ Mrs(x7, NZCV);
3759 END();
3760
3761 RUN();
3762
3763 ASSERT_EQUAL_32(ZCFlag, w0);
3764 ASSERT_EQUAL_32(ZCFlag, w1);
3765 ASSERT_EQUAL_32(ZCFlag, w2);
3766 ASSERT_EQUAL_32(NCFlag, w3);
3767 ASSERT_EQUAL_32(NCFlag, w4);
3768 ASSERT_EQUAL_32(ZCFlag, w5);
3769 ASSERT_EQUAL_32(NCFlag, w6);
3770 ASSERT_EQUAL_32(ZCFlag, w7);
3771
3772 TEARDOWN();
3773 }
3774
3775
TEST(ccmp)3776 TEST(ccmp) {
3777 SETUP();
3778
3779 START();
3780 __ Mov(w16, 0);
3781 __ Mov(w17, 1);
3782 __ Cmp(w16, w16);
3783 __ Ccmp(w16, w17, NCFlag, eq);
3784 __ Mrs(x0, NZCV);
3785
3786 __ Cmp(w16, w16);
3787 __ Ccmp(w16, w17, NCFlag, ne);
3788 __ Mrs(x1, NZCV);
3789
3790 __ Cmp(x16, x16);
3791 __ Ccmn(x16, 2, NZCVFlag, eq);
3792 __ Mrs(x2, NZCV);
3793
3794 __ Cmp(x16, x16);
3795 __ Ccmn(x16, 2, NZCVFlag, ne);
3796 __ Mrs(x3, NZCV);
3797
3798 __ ccmp(x16, x16, NZCVFlag, al);
3799 __ Mrs(x4, NZCV);
3800
3801 __ ccmp(x16, x16, NZCVFlag, nv);
3802 __ Mrs(x5, NZCV);
3803
3804 END();
3805
3806 RUN();
3807
3808 ASSERT_EQUAL_32(NFlag, w0);
3809 ASSERT_EQUAL_32(NCFlag, w1);
3810 ASSERT_EQUAL_32(NoFlag, w2);
3811 ASSERT_EQUAL_32(NZCVFlag, w3);
3812 ASSERT_EQUAL_32(ZCFlag, w4);
3813 ASSERT_EQUAL_32(ZCFlag, w5);
3814
3815 TEARDOWN();
3816 }
3817
3818
TEST(ccmp_wide_imm)3819 TEST(ccmp_wide_imm) {
3820 SETUP();
3821
3822 START();
3823 __ Mov(w20, 0);
3824
3825 __ Cmp(w20, Operand(w20));
3826 __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
3827 __ Mrs(x0, NZCV);
3828
3829 __ Cmp(w20, Operand(w20));
3830 __ Ccmp(x20, Operand(0xffffffffffffffff), NZCVFlag, eq);
3831 __ Mrs(x1, NZCV);
3832 END();
3833
3834 RUN();
3835
3836 ASSERT_EQUAL_32(NFlag, w0);
3837 ASSERT_EQUAL_32(NoFlag, w1);
3838
3839 TEARDOWN();
3840 }
3841
3842
TEST(ccmp_shift_extend)3843 TEST(ccmp_shift_extend) {
3844 SETUP();
3845
3846 START();
3847 __ Mov(w20, 0x2);
3848 __ Mov(w21, 0x1);
3849 __ Mov(x22, 0xffffffffffffffff);
3850 __ Mov(x23, 0xff);
3851 __ Mov(x24, 0xfffffffffffffffe);
3852
3853 __ Cmp(w20, Operand(w20));
3854 __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
3855 __ Mrs(x0, NZCV);
3856
3857 __ Cmp(w20, Operand(w20));
3858 __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
3859 __ Mrs(x1, NZCV);
3860
3861 __ Cmp(w20, Operand(w20));
3862 __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
3863 __ Mrs(x2, NZCV);
3864
3865 __ Cmp(w20, Operand(w20));
3866 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
3867 __ Mrs(x3, NZCV);
3868
3869 __ Cmp(w20, Operand(w20));
3870 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
3871 __ Mrs(x4, NZCV);
3872 END();
3873
3874 RUN();
3875
3876 ASSERT_EQUAL_32(ZCFlag, w0);
3877 ASSERT_EQUAL_32(ZCFlag, w1);
3878 ASSERT_EQUAL_32(ZCFlag, w2);
3879 ASSERT_EQUAL_32(NCFlag, w3);
3880 ASSERT_EQUAL_32(NZCVFlag, w4);
3881
3882 TEARDOWN();
3883 }
3884
3885
TEST(csel)3886 TEST(csel) {
3887 SETUP();
3888
3889 START();
3890 __ Mov(x16, 0);
3891 __ Mov(x24, 0x0000000f0000000f);
3892 __ Mov(x25, 0x0000001f0000001f);
3893
3894 __ Cmp(w16, Operand(0));
3895 __ Csel(w0, w24, w25, eq);
3896 __ Csel(w1, w24, w25, ne);
3897 __ Csinc(w2, w24, w25, mi);
3898 __ Csinc(w3, w24, w25, pl);
3899
3900 __ csel(w13, w24, w25, al);
3901 __ csel(x14, x24, x25, nv);
3902
3903 __ Cmp(x16, Operand(1));
3904 __ Csinv(x4, x24, x25, gt);
3905 __ Csinv(x5, x24, x25, le);
3906 __ Csneg(x6, x24, x25, hs);
3907 __ Csneg(x7, x24, x25, lo);
3908
3909 __ Cset(w8, ne);
3910 __ Csetm(w9, ne);
3911 __ Cinc(x10, x25, ne);
3912 __ Cinv(x11, x24, ne);
3913 __ Cneg(x12, x24, ne);
3914
3915 __ csel(w15, w24, w25, al);
3916 __ csel(x17, x24, x25, nv);
3917
3918 END();
3919
3920 RUN();
3921
3922 ASSERT_EQUAL_64(0x0000000f, x0);
3923 ASSERT_EQUAL_64(0x0000001f, x1);
3924 ASSERT_EQUAL_64(0x00000020, x2);
3925 ASSERT_EQUAL_64(0x0000000f, x3);
3926 ASSERT_EQUAL_64(0xffffffe0ffffffe0, x4);
3927 ASSERT_EQUAL_64(0x0000000f0000000f, x5);
3928 ASSERT_EQUAL_64(0xffffffe0ffffffe1, x6);
3929 ASSERT_EQUAL_64(0x0000000f0000000f, x7);
3930 ASSERT_EQUAL_64(0x00000001, x8);
3931 ASSERT_EQUAL_64(0xffffffff, x9);
3932 ASSERT_EQUAL_64(0x0000001f00000020, x10);
3933 ASSERT_EQUAL_64(0xfffffff0fffffff0, x11);
3934 ASSERT_EQUAL_64(0xfffffff0fffffff1, x12);
3935 ASSERT_EQUAL_64(0x0000000f, x13);
3936 ASSERT_EQUAL_64(0x0000000f0000000f, x14);
3937 ASSERT_EQUAL_64(0x0000000f, x15);
3938 ASSERT_EQUAL_64(0x0000000f0000000f, x17);
3939
3940 TEARDOWN();
3941 }
3942
3943
TEST(csel_imm)3944 TEST(csel_imm) {
3945 SETUP();
3946
3947 START();
3948 __ Mov(x18, 0);
3949 __ Mov(x19, 0x80000000);
3950 __ Mov(x20, 0x8000000000000000);
3951
3952 __ Cmp(x18, Operand(0));
3953 __ Csel(w0, w19, -2, ne);
3954 __ Csel(w1, w19, -1, ne);
3955 __ Csel(w2, w19, 0, ne);
3956 __ Csel(w3, w19, 1, ne);
3957 __ Csel(w4, w19, 2, ne);
3958 __ Csel(w5, w19, Operand(w19, ASR, 31), ne);
3959 __ Csel(w6, w19, Operand(w19, ROR, 1), ne);
3960 __ Csel(w7, w19, 3, eq);
3961
3962 __ Csel(x8, x20, -2, ne);
3963 __ Csel(x9, x20, -1, ne);
3964 __ Csel(x10, x20, 0, ne);
3965 __ Csel(x11, x20, 1, ne);
3966 __ Csel(x12, x20, 2, ne);
3967 __ Csel(x13, x20, Operand(x20, ASR, 63), ne);
3968 __ Csel(x14, x20, Operand(x20, ROR, 1), ne);
3969 __ Csel(x15, x20, 3, eq);
3970
3971 END();
3972
3973 RUN();
3974
3975 ASSERT_EQUAL_32(-2, w0);
3976 ASSERT_EQUAL_32(-1, w1);
3977 ASSERT_EQUAL_32(0, w2);
3978 ASSERT_EQUAL_32(1, w3);
3979 ASSERT_EQUAL_32(2, w4);
3980 ASSERT_EQUAL_32(-1, w5);
3981 ASSERT_EQUAL_32(0x40000000, w6);
3982 ASSERT_EQUAL_32(0x80000000, w7);
3983
3984 ASSERT_EQUAL_64(-2, x8);
3985 ASSERT_EQUAL_64(-1, x9);
3986 ASSERT_EQUAL_64(0, x10);
3987 ASSERT_EQUAL_64(1, x11);
3988 ASSERT_EQUAL_64(2, x12);
3989 ASSERT_EQUAL_64(-1, x13);
3990 ASSERT_EQUAL_64(0x4000000000000000, x14);
3991 ASSERT_EQUAL_64(0x8000000000000000, x15);
3992
3993 TEARDOWN();
3994 }
3995
3996
TEST(lslv)3997 TEST(lslv) {
3998 SETUP();
3999
4000 uint64_t value = 0x0123456789abcdef;
4001 int shift[] = {1, 3, 5, 9, 17, 33};
4002
4003 START();
4004 __ Mov(x0, value);
4005 __ Mov(w1, shift[0]);
4006 __ Mov(w2, shift[1]);
4007 __ Mov(w3, shift[2]);
4008 __ Mov(w4, shift[3]);
4009 __ Mov(w5, shift[4]);
4010 __ Mov(w6, shift[5]);
4011
4012 __ lslv(x0, x0, xzr);
4013
4014 __ Lsl(x16, x0, x1);
4015 __ Lsl(x17, x0, x2);
4016 __ Lsl(x18, x0, x3);
4017 __ Lsl(x19, x0, x4);
4018 __ Lsl(x20, x0, x5);
4019 __ Lsl(x21, x0, x6);
4020
4021 __ Lsl(w22, w0, w1);
4022 __ Lsl(w23, w0, w2);
4023 __ Lsl(w24, w0, w3);
4024 __ Lsl(w25, w0, w4);
4025 __ Lsl(w26, w0, w5);
4026 __ Lsl(w27, w0, w6);
4027 END();
4028
4029 RUN();
4030
4031 ASSERT_EQUAL_64(value, x0);
4032 ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
4033 ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
4034 ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
4035 ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
4036 ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
4037 ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
4038 ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
4039 ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
4040 ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
4041 ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
4042 ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
4043 ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
4044
4045 TEARDOWN();
4046 }
4047
4048
TEST(lsrv)4049 TEST(lsrv) {
4050 SETUP();
4051
4052 uint64_t value = 0x0123456789abcdef;
4053 int shift[] = {1, 3, 5, 9, 17, 33};
4054
4055 START();
4056 __ Mov(x0, value);
4057 __ Mov(w1, shift[0]);
4058 __ Mov(w2, shift[1]);
4059 __ Mov(w3, shift[2]);
4060 __ Mov(w4, shift[3]);
4061 __ Mov(w5, shift[4]);
4062 __ Mov(w6, shift[5]);
4063
4064 __ lsrv(x0, x0, xzr);
4065
4066 __ Lsr(x16, x0, x1);
4067 __ Lsr(x17, x0, x2);
4068 __ Lsr(x18, x0, x3);
4069 __ Lsr(x19, x0, x4);
4070 __ Lsr(x20, x0, x5);
4071 __ Lsr(x21, x0, x6);
4072
4073 __ Lsr(w22, w0, w1);
4074 __ Lsr(w23, w0, w2);
4075 __ Lsr(w24, w0, w3);
4076 __ Lsr(w25, w0, w4);
4077 __ Lsr(w26, w0, w5);
4078 __ Lsr(w27, w0, w6);
4079 END();
4080
4081 RUN();
4082
4083 ASSERT_EQUAL_64(value, x0);
4084 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
4085 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
4086 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
4087 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
4088 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
4089 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
4090
4091 value &= 0xffffffff;
4092 ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
4093 ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
4094 ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
4095 ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
4096 ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
4097 ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
4098
4099 TEARDOWN();
4100 }
4101
4102
TEST(asrv)4103 TEST(asrv) {
4104 SETUP();
4105
4106 int64_t value = 0xfedcba98fedcba98;
4107 int shift[] = {1, 3, 5, 9, 17, 33};
4108
4109 START();
4110 __ Mov(x0, value);
4111 __ Mov(w1, shift[0]);
4112 __ Mov(w2, shift[1]);
4113 __ Mov(w3, shift[2]);
4114 __ Mov(w4, shift[3]);
4115 __ Mov(w5, shift[4]);
4116 __ Mov(w6, shift[5]);
4117
4118 __ asrv(x0, x0, xzr);
4119
4120 __ Asr(x16, x0, x1);
4121 __ Asr(x17, x0, x2);
4122 __ Asr(x18, x0, x3);
4123 __ Asr(x19, x0, x4);
4124 __ Asr(x20, x0, x5);
4125 __ Asr(x21, x0, x6);
4126
4127 __ Asr(w22, w0, w1);
4128 __ Asr(w23, w0, w2);
4129 __ Asr(w24, w0, w3);
4130 __ Asr(w25, w0, w4);
4131 __ Asr(w26, w0, w5);
4132 __ Asr(w27, w0, w6);
4133 END();
4134
4135 RUN();
4136
4137 ASSERT_EQUAL_64(value, x0);
4138 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
4139 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
4140 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
4141 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
4142 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
4143 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
4144
4145 int32_t value32 = static_cast<int32_t>(value & 0xffffffff);
4146 ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
4147 ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
4148 ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
4149 ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
4150 ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
4151 ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
4152
4153 TEARDOWN();
4154 }
4155
4156
TEST(rorv)4157 TEST(rorv) {
4158 SETUP();
4159
4160 uint64_t value = 0x0123456789abcdef;
4161 int shift[] = {4, 8, 12, 16, 24, 36};
4162
4163 START();
4164 __ Mov(x0, value);
4165 __ Mov(w1, shift[0]);
4166 __ Mov(w2, shift[1]);
4167 __ Mov(w3, shift[2]);
4168 __ Mov(w4, shift[3]);
4169 __ Mov(w5, shift[4]);
4170 __ Mov(w6, shift[5]);
4171
4172 __ rorv(x0, x0, xzr);
4173
4174 __ Ror(x16, x0, x1);
4175 __ Ror(x17, x0, x2);
4176 __ Ror(x18, x0, x3);
4177 __ Ror(x19, x0, x4);
4178 __ Ror(x20, x0, x5);
4179 __ Ror(x21, x0, x6);
4180
4181 __ Ror(w22, w0, w1);
4182 __ Ror(w23, w0, w2);
4183 __ Ror(w24, w0, w3);
4184 __ Ror(w25, w0, w4);
4185 __ Ror(w26, w0, w5);
4186 __ Ror(w27, w0, w6);
4187 END();
4188
4189 RUN();
4190
4191 ASSERT_EQUAL_64(value, x0);
4192 ASSERT_EQUAL_64(0xf0123456789abcde, x16);
4193 ASSERT_EQUAL_64(0xef0123456789abcd, x17);
4194 ASSERT_EQUAL_64(0xdef0123456789abc, x18);
4195 ASSERT_EQUAL_64(0xcdef0123456789ab, x19);
4196 ASSERT_EQUAL_64(0xabcdef0123456789, x20);
4197 ASSERT_EQUAL_64(0x789abcdef0123456, x21);
4198 ASSERT_EQUAL_32(0xf89abcde, w22);
4199 ASSERT_EQUAL_32(0xef89abcd, w23);
4200 ASSERT_EQUAL_32(0xdef89abc, w24);
4201 ASSERT_EQUAL_32(0xcdef89ab, w25);
4202 ASSERT_EQUAL_32(0xabcdef89, w26);
4203 ASSERT_EQUAL_32(0xf89abcde, w27);
4204
4205 TEARDOWN();
4206 }
4207
4208
TEST(bfm)4209 TEST(bfm) {
4210 SETUP();
4211
4212 START();
4213 __ Mov(x1, 0x0123456789abcdef);
4214
4215 __ Mov(x10, 0x8888888888888888);
4216 __ Mov(x11, 0x8888888888888888);
4217 __ Mov(x12, 0x8888888888888888);
4218 __ Mov(x13, 0x8888888888888888);
4219 __ Mov(w20, 0x88888888);
4220 __ Mov(w21, 0x88888888);
4221
4222 __ bfm(x10, x1, 16, 31);
4223 __ bfm(x11, x1, 32, 15);
4224
4225 __ bfm(w20, w1, 16, 23);
4226 __ bfm(w21, w1, 24, 15);
4227
4228 // Aliases.
4229 __ Bfi(x12, x1, 16, 8);
4230 __ Bfxil(x13, x1, 16, 8);
4231 END();
4232
4233 RUN();
4234
4235
4236 ASSERT_EQUAL_64(0x88888888888889ab, x10);
4237 ASSERT_EQUAL_64(0x8888cdef88888888, x11);
4238
4239 ASSERT_EQUAL_32(0x888888ab, w20);
4240 ASSERT_EQUAL_32(0x88cdef88, w21);
4241
4242 ASSERT_EQUAL_64(0x8888888888ef8888, x12);
4243 ASSERT_EQUAL_64(0x88888888888888ab, x13);
4244
4245 TEARDOWN();
4246 }
4247
4248
TEST(sbfm)4249 TEST(sbfm) {
4250 SETUP();
4251
4252 START();
4253 __ Mov(x1, 0x0123456789abcdef);
4254 __ Mov(x2, 0xfedcba9876543210);
4255
4256 __ sbfm(x10, x1, 16, 31);
4257 __ sbfm(x11, x1, 32, 15);
4258 __ sbfm(x12, x1, 32, 47);
4259 __ sbfm(x13, x1, 48, 35);
4260
4261 __ sbfm(w14, w1, 16, 23);
4262 __ sbfm(w15, w1, 24, 15);
4263 __ sbfm(w16, w2, 16, 23);
4264 __ sbfm(w17, w2, 24, 15);
4265
4266 // Aliases.
4267 __ Asr(x18, x1, 32);
4268 __ Asr(x19, x2, 32);
4269 __ Sbfiz(x20, x1, 8, 16);
4270 __ Sbfiz(x21, x2, 8, 16);
4271 __ Sbfx(x22, x1, 8, 16);
4272 __ Sbfx(x23, x2, 8, 16);
4273 __ Sxtb(x24, w1);
4274 __ Sxtb(x25, x2);
4275 __ Sxth(x26, w1);
4276 __ Sxth(x27, x2);
4277 __ Sxtw(x28, w1);
4278 __ Sxtw(x29, x2);
4279 END();
4280
4281 RUN();
4282
4283
4284 ASSERT_EQUAL_64(0xffffffffffff89ab, x10);
4285 ASSERT_EQUAL_64(0xffffcdef00000000, x11);
4286 ASSERT_EQUAL_64(0x0000000000004567, x12);
4287 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
4288
4289 ASSERT_EQUAL_32(0xffffffab, w14);
4290 ASSERT_EQUAL_32(0xffcdef00, w15);
4291 ASSERT_EQUAL_32(0x00000054, w16);
4292 ASSERT_EQUAL_32(0x00321000, w17);
4293
4294 ASSERT_EQUAL_64(0x0000000001234567, x18);
4295 ASSERT_EQUAL_64(0xfffffffffedcba98, x19);
4296 ASSERT_EQUAL_64(0xffffffffffcdef00, x20);
4297 ASSERT_EQUAL_64(0x0000000000321000, x21);
4298 ASSERT_EQUAL_64(0xffffffffffffabcd, x22);
4299 ASSERT_EQUAL_64(0x0000000000005432, x23);
4300 ASSERT_EQUAL_64(0xffffffffffffffef, x24);
4301 ASSERT_EQUAL_64(0x0000000000000010, x25);
4302 ASSERT_EQUAL_64(0xffffffffffffcdef, x26);
4303 ASSERT_EQUAL_64(0x0000000000003210, x27);
4304 ASSERT_EQUAL_64(0xffffffff89abcdef, x28);
4305 ASSERT_EQUAL_64(0x0000000076543210, x29);
4306
4307 TEARDOWN();
4308 }
4309
4310
TEST(ubfm)4311 TEST(ubfm) {
4312 SETUP();
4313
4314 START();
4315 __ Mov(x1, 0x0123456789abcdef);
4316 __ Mov(x2, 0xfedcba9876543210);
4317
4318 __ Mov(x10, 0x8888888888888888);
4319 __ Mov(x11, 0x8888888888888888);
4320
4321 __ ubfm(x10, x1, 16, 31);
4322 __ ubfm(x11, x1, 32, 15);
4323 __ ubfm(x12, x1, 32, 47);
4324 __ ubfm(x13, x1, 48, 35);
4325
4326 __ ubfm(w25, w1, 16, 23);
4327 __ ubfm(w26, w1, 24, 15);
4328 __ ubfm(w27, w2, 16, 23);
4329 __ ubfm(w28, w2, 24, 15);
4330
4331 // Aliases
4332 __ Lsl(x15, x1, 63);
4333 __ Lsl(x16, x1, 0);
4334 __ Lsr(x17, x1, 32);
4335 __ Ubfiz(x18, x1, 8, 16);
4336 __ Ubfx(x19, x1, 8, 16);
4337 __ Uxtb(x20, x1);
4338 __ Uxth(x21, x1);
4339 __ Uxtw(x22, x1);
4340 END();
4341
4342 RUN();
4343
4344 ASSERT_EQUAL_64(0x00000000000089ab, x10);
4345 ASSERT_EQUAL_64(0x0000cdef00000000, x11);
4346 ASSERT_EQUAL_64(0x0000000000004567, x12);
4347 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
4348
4349 ASSERT_EQUAL_32(0x000000ab, w25);
4350 ASSERT_EQUAL_32(0x00cdef00, w26);
4351 ASSERT_EQUAL_32(0x00000054, w27);
4352 ASSERT_EQUAL_32(0x00321000, w28);
4353
4354 ASSERT_EQUAL_64(0x8000000000000000, x15);
4355 ASSERT_EQUAL_64(0x0123456789abcdef, x16);
4356 ASSERT_EQUAL_64(0x0000000001234567, x17);
4357 ASSERT_EQUAL_64(0x0000000000cdef00, x18);
4358 ASSERT_EQUAL_64(0x000000000000abcd, x19);
4359 ASSERT_EQUAL_64(0x00000000000000ef, x20);
4360 ASSERT_EQUAL_64(0x000000000000cdef, x21);
4361 ASSERT_EQUAL_64(0x0000000089abcdef, x22);
4362
4363 TEARDOWN();
4364 }
4365
4366
TEST(extr)4367 TEST(extr) {
4368 SETUP();
4369
4370 START();
4371 __ Mov(x1, 0x0123456789abcdef);
4372 __ Mov(x2, 0xfedcba9876543210);
4373
4374 __ Extr(w10, w1, w2, 0);
4375 __ Extr(w11, w1, w2, 1);
4376 __ Extr(x12, x2, x1, 2);
4377
4378 __ Ror(w13, w1, 0);
4379 __ Ror(w14, w2, 17);
4380 __ Ror(w15, w1, 31);
4381 __ Ror(x18, x2, 1);
4382 __ Ror(x19, x1, 63);
4383 END();
4384
4385 RUN();
4386
4387 ASSERT_EQUAL_64(0x76543210, x10);
4388 ASSERT_EQUAL_64(0xbb2a1908, x11);
4389 ASSERT_EQUAL_64(0x0048d159e26af37b, x12);
4390 ASSERT_EQUAL_64(0x89abcdef, x13);
4391 ASSERT_EQUAL_64(0x19083b2a, x14);
4392 ASSERT_EQUAL_64(0x13579bdf, x15);
4393 ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908, x18);
4394 ASSERT_EQUAL_64(0x02468acf13579bde, x19);
4395
4396 TEARDOWN();
4397 }
4398
4399
TEST(fmov_imm)4400 TEST(fmov_imm) {
4401 SETUP();
4402
4403 START();
4404 __ Fmov(s11, 1.0);
4405 __ Fmov(d22, -13.0);
4406 __ Fmov(s1, 255.0);
4407 __ Fmov(d2, 12.34567);
4408 __ Fmov(s3, 0.0);
4409 __ Fmov(d4, 0.0);
4410 __ Fmov(s5, kFP32PositiveInfinity);
4411 __ Fmov(d6, kFP64NegativeInfinity);
4412 END();
4413
4414 RUN();
4415
4416 ASSERT_EQUAL_FP32(1.0, s11);
4417 ASSERT_EQUAL_FP64(-13.0, d22);
4418 ASSERT_EQUAL_FP32(255.0, s1);
4419 ASSERT_EQUAL_FP64(12.34567, d2);
4420 ASSERT_EQUAL_FP32(0.0, s3);
4421 ASSERT_EQUAL_FP64(0.0, d4);
4422 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
4423 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
4424
4425 TEARDOWN();
4426 }
4427
4428
TEST(fmov_reg)4429 TEST(fmov_reg) {
4430 SETUP();
4431
4432 START();
4433 __ Fmov(s20, 1.0);
4434 __ Fmov(w10, s20);
4435 __ Fmov(s30, w10);
4436 __ Fmov(s5, s20);
4437 __ Fmov(d1, -13.0);
4438 __ Fmov(x1, d1);
4439 __ Fmov(d2, x1);
4440 __ Fmov(d4, d1);
4441 __ Fmov(d6, rawbits_to_double(0x0123456789abcdef));
4442 __ Fmov(s6, s6);
4443 END();
4444
4445 RUN();
4446
4447 ASSERT_EQUAL_32(float_to_rawbits(1.0), w10);
4448 ASSERT_EQUAL_FP32(1.0, s30);
4449 ASSERT_EQUAL_FP32(1.0, s5);
4450 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1);
4451 ASSERT_EQUAL_FP64(-13.0, d2);
4452 ASSERT_EQUAL_FP64(-13.0, d4);
4453 ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
4454
4455 TEARDOWN();
4456 }
4457
4458
TEST(fadd)4459 TEST(fadd) {
4460 SETUP();
4461
4462 START();
4463 __ Fmov(s14, -0.0f);
4464 __ Fmov(s15, kFP32PositiveInfinity);
4465 __ Fmov(s16, kFP32NegativeInfinity);
4466 __ Fmov(s17, 3.25f);
4467 __ Fmov(s18, 1.0f);
4468 __ Fmov(s19, 0.0f);
4469
4470 __ Fmov(d26, -0.0);
4471 __ Fmov(d27, kFP64PositiveInfinity);
4472 __ Fmov(d28, kFP64NegativeInfinity);
4473 __ Fmov(d29, 0.0);
4474 __ Fmov(d30, -2.0);
4475 __ Fmov(d31, 2.25);
4476
4477 __ Fadd(s0, s17, s18);
4478 __ Fadd(s1, s18, s19);
4479 __ Fadd(s2, s14, s18);
4480 __ Fadd(s3, s15, s18);
4481 __ Fadd(s4, s16, s18);
4482 __ Fadd(s5, s15, s16);
4483 __ Fadd(s6, s16, s15);
4484
4485 __ Fadd(d7, d30, d31);
4486 __ Fadd(d8, d29, d31);
4487 __ Fadd(d9, d26, d31);
4488 __ Fadd(d10, d27, d31);
4489 __ Fadd(d11, d28, d31);
4490 __ Fadd(d12, d27, d28);
4491 __ Fadd(d13, d28, d27);
4492 END();
4493
4494 RUN();
4495
4496 ASSERT_EQUAL_FP32(4.25, s0);
4497 ASSERT_EQUAL_FP32(1.0, s1);
4498 ASSERT_EQUAL_FP32(1.0, s2);
4499 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
4500 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
4501 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4502 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4503 ASSERT_EQUAL_FP64(0.25, d7);
4504 ASSERT_EQUAL_FP64(2.25, d8);
4505 ASSERT_EQUAL_FP64(2.25, d9);
4506 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10);
4507 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11);
4508 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4509 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
4510
4511 TEARDOWN();
4512 }
4513
4514
TEST(fsub)4515 TEST(fsub) {
4516 SETUP();
4517
4518 START();
4519 __ Fmov(s14, -0.0f);
4520 __ Fmov(s15, kFP32PositiveInfinity);
4521 __ Fmov(s16, kFP32NegativeInfinity);
4522 __ Fmov(s17, 3.25f);
4523 __ Fmov(s18, 1.0f);
4524 __ Fmov(s19, 0.0f);
4525
4526 __ Fmov(d26, -0.0);
4527 __ Fmov(d27, kFP64PositiveInfinity);
4528 __ Fmov(d28, kFP64NegativeInfinity);
4529 __ Fmov(d29, 0.0);
4530 __ Fmov(d30, -2.0);
4531 __ Fmov(d31, 2.25);
4532
4533 __ Fsub(s0, s17, s18);
4534 __ Fsub(s1, s18, s19);
4535 __ Fsub(s2, s14, s18);
4536 __ Fsub(s3, s18, s15);
4537 __ Fsub(s4, s18, s16);
4538 __ Fsub(s5, s15, s15);
4539 __ Fsub(s6, s16, s16);
4540
4541 __ Fsub(d7, d30, d31);
4542 __ Fsub(d8, d29, d31);
4543 __ Fsub(d9, d26, d31);
4544 __ Fsub(d10, d31, d27);
4545 __ Fsub(d11, d31, d28);
4546 __ Fsub(d12, d27, d27);
4547 __ Fsub(d13, d28, d28);
4548 END();
4549
4550 RUN();
4551
4552 ASSERT_EQUAL_FP32(2.25, s0);
4553 ASSERT_EQUAL_FP32(1.0, s1);
4554 ASSERT_EQUAL_FP32(-1.0, s2);
4555 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
4556 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
4557 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4558 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4559 ASSERT_EQUAL_FP64(-4.25, d7);
4560 ASSERT_EQUAL_FP64(-2.25, d8);
4561 ASSERT_EQUAL_FP64(-2.25, d9);
4562 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
4563 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
4564 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4565 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
4566
4567 TEARDOWN();
4568 }
4569
4570
TEST(fmul)4571 TEST(fmul) {
4572 SETUP();
4573
4574 START();
4575 __ Fmov(s14, -0.0f);
4576 __ Fmov(s15, kFP32PositiveInfinity);
4577 __ Fmov(s16, kFP32NegativeInfinity);
4578 __ Fmov(s17, 3.25f);
4579 __ Fmov(s18, 2.0f);
4580 __ Fmov(s19, 0.0f);
4581 __ Fmov(s20, -2.0f);
4582
4583 __ Fmov(d26, -0.0);
4584 __ Fmov(d27, kFP64PositiveInfinity);
4585 __ Fmov(d28, kFP64NegativeInfinity);
4586 __ Fmov(d29, 0.0);
4587 __ Fmov(d30, -2.0);
4588 __ Fmov(d31, 2.25);
4589
4590 __ Fmul(s0, s17, s18);
4591 __ Fmul(s1, s18, s19);
4592 __ Fmul(s2, s14, s14);
4593 __ Fmul(s3, s15, s20);
4594 __ Fmul(s4, s16, s20);
4595 __ Fmul(s5, s15, s19);
4596 __ Fmul(s6, s19, s16);
4597
4598 __ Fmul(d7, d30, d31);
4599 __ Fmul(d8, d29, d31);
4600 __ Fmul(d9, d26, d26);
4601 __ Fmul(d10, d27, d30);
4602 __ Fmul(d11, d28, d30);
4603 __ Fmul(d12, d27, d29);
4604 __ Fmul(d13, d29, d28);
4605 END();
4606
4607 RUN();
4608
4609 ASSERT_EQUAL_FP32(6.5, s0);
4610 ASSERT_EQUAL_FP32(0.0, s1);
4611 ASSERT_EQUAL_FP32(0.0, s2);
4612 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
4613 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
4614 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4615 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4616 ASSERT_EQUAL_FP64(-4.5, d7);
4617 ASSERT_EQUAL_FP64(0.0, d8);
4618 ASSERT_EQUAL_FP64(0.0, d9);
4619 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
4620 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
4621 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4622 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
4623
4624 TEARDOWN();
4625 }
4626
4627
FmaddFmsubHelper(double n,double m,double a,double fmadd,double fmsub,double fnmadd,double fnmsub)4628 static void FmaddFmsubHelper(double n, double m, double a,
4629 double fmadd, double fmsub,
4630 double fnmadd, double fnmsub) {
4631 SETUP();
4632 START();
4633
4634 __ Fmov(d0, n);
4635 __ Fmov(d1, m);
4636 __ Fmov(d2, a);
4637 __ Fmadd(d28, d0, d1, d2);
4638 __ Fmsub(d29, d0, d1, d2);
4639 __ Fnmadd(d30, d0, d1, d2);
4640 __ Fnmsub(d31, d0, d1, d2);
4641
4642 END();
4643 RUN();
4644
4645 ASSERT_EQUAL_FP64(fmadd, d28);
4646 ASSERT_EQUAL_FP64(fmsub, d29);
4647 ASSERT_EQUAL_FP64(fnmadd, d30);
4648 ASSERT_EQUAL_FP64(fnmsub, d31);
4649
4650 TEARDOWN();
4651 }
4652
4653
TEST(fmadd_fmsub_double)4654 TEST(fmadd_fmsub_double) {
4655 // It's hard to check the result of fused operations because the only way to
4656 // calculate the result is using fma, which is what the simulator uses anyway.
4657 // TODO(jbramley): Add tests to check behaviour against a hardware trace.
4658
4659 // Basic operation.
4660 FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0);
4661 FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0);
4662
4663 // Check the sign of exact zeroes.
4664 // n m a fmadd fmsub fnmadd fnmsub
4665 FmaddFmsubHelper(-0.0, +0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
4666 FmaddFmsubHelper(+0.0, +0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
4667 FmaddFmsubHelper(+0.0, +0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
4668 FmaddFmsubHelper(-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
4669 FmaddFmsubHelper(+0.0, -0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
4670 FmaddFmsubHelper(-0.0, -0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
4671 FmaddFmsubHelper(-0.0, -0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
4672 FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
4673
4674 // Check NaN generation.
4675 FmaddFmsubHelper(kFP64PositiveInfinity, 0.0, 42.0,
4676 kFP64DefaultNaN, kFP64DefaultNaN,
4677 kFP64DefaultNaN, kFP64DefaultNaN);
4678 FmaddFmsubHelper(0.0, kFP64PositiveInfinity, 42.0,
4679 kFP64DefaultNaN, kFP64DefaultNaN,
4680 kFP64DefaultNaN, kFP64DefaultNaN);
4681 FmaddFmsubHelper(kFP64PositiveInfinity, 1.0, kFP64PositiveInfinity,
4682 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
4683 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
4684 kFP64NegativeInfinity, // -inf + (-inf * 1) = -inf
4685 kFP64DefaultNaN); // -inf + ( inf * 1) = NaN
4686 FmaddFmsubHelper(kFP64NegativeInfinity, 1.0, kFP64PositiveInfinity,
4687 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
4688 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
4689 kFP64DefaultNaN, // -inf + ( inf * 1) = NaN
4690 kFP64NegativeInfinity); // -inf + (-inf * 1) = -inf
4691 }
4692
4693
FmaddFmsubHelper(float n,float m,float a,float fmadd,float fmsub,float fnmadd,float fnmsub)4694 static void FmaddFmsubHelper(float n, float m, float a,
4695 float fmadd, float fmsub,
4696 float fnmadd, float fnmsub) {
4697 SETUP();
4698 START();
4699
4700 __ Fmov(s0, n);
4701 __ Fmov(s1, m);
4702 __ Fmov(s2, a);
4703 __ Fmadd(s28, s0, s1, s2);
4704 __ Fmsub(s29, s0, s1, s2);
4705 __ Fnmadd(s30, s0, s1, s2);
4706 __ Fnmsub(s31, s0, s1, s2);
4707
4708 END();
4709 RUN();
4710
4711 ASSERT_EQUAL_FP32(fmadd, s28);
4712 ASSERT_EQUAL_FP32(fmsub, s29);
4713 ASSERT_EQUAL_FP32(fnmadd, s30);
4714 ASSERT_EQUAL_FP32(fnmsub, s31);
4715
4716 TEARDOWN();
4717 }
4718
4719
TEST(fmadd_fmsub_float)4720 TEST(fmadd_fmsub_float) {
4721 // It's hard to check the result of fused operations because the only way to
4722 // calculate the result is using fma, which is what the simulator uses anyway.
4723 // TODO(jbramley): Add tests to check behaviour against a hardware trace.
4724
4725 // Basic operation.
4726 FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f);
4727 FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f);
4728
4729 // Check the sign of exact zeroes.
4730 // n m a fmadd fmsub fnmadd fnmsub
4731 FmaddFmsubHelper(-0.0f, +0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
4732 FmaddFmsubHelper(+0.0f, +0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
4733 FmaddFmsubHelper(+0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
4734 FmaddFmsubHelper(-0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
4735 FmaddFmsubHelper(+0.0f, -0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
4736 FmaddFmsubHelper(-0.0f, -0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
4737 FmaddFmsubHelper(-0.0f, -0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
4738 FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
4739
4740 // Check NaN generation.
4741 FmaddFmsubHelper(kFP32PositiveInfinity, 0.0f, 42.0f,
4742 kFP32DefaultNaN, kFP32DefaultNaN,
4743 kFP32DefaultNaN, kFP32DefaultNaN);
4744 FmaddFmsubHelper(0.0f, kFP32PositiveInfinity, 42.0f,
4745 kFP32DefaultNaN, kFP32DefaultNaN,
4746 kFP32DefaultNaN, kFP32DefaultNaN);
4747 FmaddFmsubHelper(kFP32PositiveInfinity, 1.0f, kFP32PositiveInfinity,
4748 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
4749 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
4750 kFP32NegativeInfinity, // -inf + (-inf * 1) = -inf
4751 kFP32DefaultNaN); // -inf + ( inf * 1) = NaN
4752 FmaddFmsubHelper(kFP32NegativeInfinity, 1.0f, kFP32PositiveInfinity,
4753 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
4754 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
4755 kFP32DefaultNaN, // -inf + ( inf * 1) = NaN
4756 kFP32NegativeInfinity); // -inf + (-inf * 1) = -inf
4757 }
4758
4759
TEST(fmadd_fmsub_double_nans)4760 TEST(fmadd_fmsub_double_nans) {
4761 // Make sure that NaN propagation works correctly.
4762 double s1 = rawbits_to_double(0x7ff5555511111111);
4763 double s2 = rawbits_to_double(0x7ff5555522222222);
4764 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
4765 double q1 = rawbits_to_double(0x7ffaaaaa11111111);
4766 double q2 = rawbits_to_double(0x7ffaaaaa22222222);
4767 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
4768 VIXL_ASSERT(IsSignallingNaN(s1));
4769 VIXL_ASSERT(IsSignallingNaN(s2));
4770 VIXL_ASSERT(IsSignallingNaN(sa));
4771 VIXL_ASSERT(IsQuietNaN(q1));
4772 VIXL_ASSERT(IsQuietNaN(q2));
4773 VIXL_ASSERT(IsQuietNaN(qa));
4774
4775 // The input NaNs after passing through ProcessNaN.
4776 double s1_proc = rawbits_to_double(0x7ffd555511111111);
4777 double s2_proc = rawbits_to_double(0x7ffd555522222222);
4778 double sa_proc = rawbits_to_double(0x7ffd5555aaaaaaaa);
4779 double q1_proc = q1;
4780 double q2_proc = q2;
4781 double qa_proc = qa;
4782 VIXL_ASSERT(IsQuietNaN(s1_proc));
4783 VIXL_ASSERT(IsQuietNaN(s2_proc));
4784 VIXL_ASSERT(IsQuietNaN(sa_proc));
4785 VIXL_ASSERT(IsQuietNaN(q1_proc));
4786 VIXL_ASSERT(IsQuietNaN(q2_proc));
4787 VIXL_ASSERT(IsQuietNaN(qa_proc));
4788
4789 // Negated NaNs as it would be done on ARMv8 hardware.
4790 double s1_proc_neg = rawbits_to_double(0xfffd555511111111);
4791 double sa_proc_neg = rawbits_to_double(0xfffd5555aaaaaaaa);
4792 double q1_proc_neg = rawbits_to_double(0xfffaaaaa11111111);
4793 double qa_proc_neg = rawbits_to_double(0xfffaaaaaaaaaaaaa);
4794 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
4795 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
4796 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
4797 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
4798
4799 // Quiet NaNs are propagated.
4800 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
4801 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
4802 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4803 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
4804 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4805 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4806 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4807
4808 // Signalling NaNs are propagated, and made quiet.
4809 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4810 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
4811 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4812 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4813 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4814 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4815 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4816
4817 // Signalling NaNs take precedence over quiet NaNs.
4818 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4819 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
4820 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4821 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4822 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4823 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4824 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4825
4826 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
4827 FmaddFmsubHelper(0, kFP64PositiveInfinity, qa,
4828 kFP64DefaultNaN, kFP64DefaultNaN,
4829 kFP64DefaultNaN, kFP64DefaultNaN);
4830 FmaddFmsubHelper(kFP64PositiveInfinity, 0, qa,
4831 kFP64DefaultNaN, kFP64DefaultNaN,
4832 kFP64DefaultNaN, kFP64DefaultNaN);
4833 FmaddFmsubHelper(0, kFP64NegativeInfinity, qa,
4834 kFP64DefaultNaN, kFP64DefaultNaN,
4835 kFP64DefaultNaN, kFP64DefaultNaN);
4836 FmaddFmsubHelper(kFP64NegativeInfinity, 0, qa,
4837 kFP64DefaultNaN, kFP64DefaultNaN,
4838 kFP64DefaultNaN, kFP64DefaultNaN);
4839 }
4840
4841
TEST(fmadd_fmsub_float_nans)4842 TEST(fmadd_fmsub_float_nans) {
4843 // Make sure that NaN propagation works correctly.
4844 float s1 = rawbits_to_float(0x7f951111);
4845 float s2 = rawbits_to_float(0x7f952222);
4846 float sa = rawbits_to_float(0x7f95aaaa);
4847 float q1 = rawbits_to_float(0x7fea1111);
4848 float q2 = rawbits_to_float(0x7fea2222);
4849 float qa = rawbits_to_float(0x7feaaaaa);
4850 VIXL_ASSERT(IsSignallingNaN(s1));
4851 VIXL_ASSERT(IsSignallingNaN(s2));
4852 VIXL_ASSERT(IsSignallingNaN(sa));
4853 VIXL_ASSERT(IsQuietNaN(q1));
4854 VIXL_ASSERT(IsQuietNaN(q2));
4855 VIXL_ASSERT(IsQuietNaN(qa));
4856
4857 // The input NaNs after passing through ProcessNaN.
4858 float s1_proc = rawbits_to_float(0x7fd51111);
4859 float s2_proc = rawbits_to_float(0x7fd52222);
4860 float sa_proc = rawbits_to_float(0x7fd5aaaa);
4861 float q1_proc = q1;
4862 float q2_proc = q2;
4863 float qa_proc = qa;
4864 VIXL_ASSERT(IsQuietNaN(s1_proc));
4865 VIXL_ASSERT(IsQuietNaN(s2_proc));
4866 VIXL_ASSERT(IsQuietNaN(sa_proc));
4867 VIXL_ASSERT(IsQuietNaN(q1_proc));
4868 VIXL_ASSERT(IsQuietNaN(q2_proc));
4869 VIXL_ASSERT(IsQuietNaN(qa_proc));
4870
4871 // Negated NaNs as it would be done on ARMv8 hardware.
4872 float s1_proc_neg = rawbits_to_float(0xffd51111);
4873 float sa_proc_neg = rawbits_to_float(0xffd5aaaa);
4874 float q1_proc_neg = rawbits_to_float(0xffea1111);
4875 float qa_proc_neg = rawbits_to_float(0xffeaaaaa);
4876 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
4877 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
4878 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
4879 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
4880
4881 // Quiet NaNs are propagated.
4882 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
4883 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
4884 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4885 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
4886 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4887 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4888 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4889
4890 // Signalling NaNs are propagated, and made quiet.
4891 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4892 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
4893 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4894 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4895 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4896 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4897 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4898
4899 // Signalling NaNs take precedence over quiet NaNs.
4900 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4901 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
4902 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4903 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4904 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4905 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4906 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4907
4908 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
4909 FmaddFmsubHelper(0, kFP32PositiveInfinity, qa,
4910 kFP32DefaultNaN, kFP32DefaultNaN,
4911 kFP32DefaultNaN, kFP32DefaultNaN);
4912 FmaddFmsubHelper(kFP32PositiveInfinity, 0, qa,
4913 kFP32DefaultNaN, kFP32DefaultNaN,
4914 kFP32DefaultNaN, kFP32DefaultNaN);
4915 FmaddFmsubHelper(0, kFP32NegativeInfinity, qa,
4916 kFP32DefaultNaN, kFP32DefaultNaN,
4917 kFP32DefaultNaN, kFP32DefaultNaN);
4918 FmaddFmsubHelper(kFP32NegativeInfinity, 0, qa,
4919 kFP32DefaultNaN, kFP32DefaultNaN,
4920 kFP32DefaultNaN, kFP32DefaultNaN);
4921 }
4922
4923
TEST(fdiv)4924 TEST(fdiv) {
4925 SETUP();
4926
4927 START();
4928 __ Fmov(s14, -0.0f);
4929 __ Fmov(s15, kFP32PositiveInfinity);
4930 __ Fmov(s16, kFP32NegativeInfinity);
4931 __ Fmov(s17, 3.25f);
4932 __ Fmov(s18, 2.0f);
4933 __ Fmov(s19, 2.0f);
4934 __ Fmov(s20, -2.0f);
4935
4936 __ Fmov(d26, -0.0);
4937 __ Fmov(d27, kFP64PositiveInfinity);
4938 __ Fmov(d28, kFP64NegativeInfinity);
4939 __ Fmov(d29, 0.0);
4940 __ Fmov(d30, -2.0);
4941 __ Fmov(d31, 2.25);
4942
4943 __ Fdiv(s0, s17, s18);
4944 __ Fdiv(s1, s18, s19);
4945 __ Fdiv(s2, s14, s18);
4946 __ Fdiv(s3, s18, s15);
4947 __ Fdiv(s4, s18, s16);
4948 __ Fdiv(s5, s15, s16);
4949 __ Fdiv(s6, s14, s14);
4950
4951 __ Fdiv(d7, d31, d30);
4952 __ Fdiv(d8, d29, d31);
4953 __ Fdiv(d9, d26, d31);
4954 __ Fdiv(d10, d31, d27);
4955 __ Fdiv(d11, d31, d28);
4956 __ Fdiv(d12, d28, d27);
4957 __ Fdiv(d13, d29, d29);
4958 END();
4959
4960 RUN();
4961
4962 ASSERT_EQUAL_FP32(1.625f, s0);
4963 ASSERT_EQUAL_FP32(1.0f, s1);
4964 ASSERT_EQUAL_FP32(-0.0f, s2);
4965 ASSERT_EQUAL_FP32(0.0f, s3);
4966 ASSERT_EQUAL_FP32(-0.0f, s4);
4967 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4968 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4969 ASSERT_EQUAL_FP64(-1.125, d7);
4970 ASSERT_EQUAL_FP64(0.0, d8);
4971 ASSERT_EQUAL_FP64(-0.0, d9);
4972 ASSERT_EQUAL_FP64(0.0, d10);
4973 ASSERT_EQUAL_FP64(-0.0, d11);
4974 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4975 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
4976
4977 TEARDOWN();
4978 }
4979
4980
MinMaxHelper(float n,float m,bool min,float quiet_nan_substitute=0.0)4981 static float MinMaxHelper(float n,
4982 float m,
4983 bool min,
4984 float quiet_nan_substitute = 0.0) {
4985 const uint64_t kFP32QuietNaNMask = 0x00400000;
4986 uint32_t raw_n = float_to_rawbits(n);
4987 uint32_t raw_m = float_to_rawbits(m);
4988
4989 if (isnan(n) && ((raw_n & kFP32QuietNaNMask) == 0)) {
4990 // n is signalling NaN.
4991 return rawbits_to_float(raw_n | kFP32QuietNaNMask);
4992 } else if (isnan(m) && ((raw_m & kFP32QuietNaNMask) == 0)) {
4993 // m is signalling NaN.
4994 return rawbits_to_float(raw_m | kFP32QuietNaNMask);
4995 } else if (quiet_nan_substitute == 0.0) {
4996 if (isnan(n)) {
4997 // n is quiet NaN.
4998 return n;
4999 } else if (isnan(m)) {
5000 // m is quiet NaN.
5001 return m;
5002 }
5003 } else {
5004 // Substitute n or m if one is quiet, but not both.
5005 if (isnan(n) && !isnan(m)) {
5006 // n is quiet NaN: replace with substitute.
5007 n = quiet_nan_substitute;
5008 } else if (!isnan(n) && isnan(m)) {
5009 // m is quiet NaN: replace with substitute.
5010 m = quiet_nan_substitute;
5011 }
5012 }
5013
5014 if ((n == 0.0) && (m == 0.0) &&
5015 (copysign(1.0, n) != copysign(1.0, m))) {
5016 return min ? -0.0 : 0.0;
5017 }
5018
5019 return min ? fminf(n, m) : fmaxf(n, m);
5020 }
5021
5022
MinMaxHelper(double n,double m,bool min,double quiet_nan_substitute=0.0)5023 static double MinMaxHelper(double n,
5024 double m,
5025 bool min,
5026 double quiet_nan_substitute = 0.0) {
5027 const uint64_t kFP64QuietNaNMask = 0x0008000000000000;
5028 uint64_t raw_n = double_to_rawbits(n);
5029 uint64_t raw_m = double_to_rawbits(m);
5030
5031 if (isnan(n) && ((raw_n & kFP64QuietNaNMask) == 0)) {
5032 // n is signalling NaN.
5033 return rawbits_to_double(raw_n | kFP64QuietNaNMask);
5034 } else if (isnan(m) && ((raw_m & kFP64QuietNaNMask) == 0)) {
5035 // m is signalling NaN.
5036 return rawbits_to_double(raw_m | kFP64QuietNaNMask);
5037 } else if (quiet_nan_substitute == 0.0) {
5038 if (isnan(n)) {
5039 // n is quiet NaN.
5040 return n;
5041 } else if (isnan(m)) {
5042 // m is quiet NaN.
5043 return m;
5044 }
5045 } else {
5046 // Substitute n or m if one is quiet, but not both.
5047 if (isnan(n) && !isnan(m)) {
5048 // n is quiet NaN: replace with substitute.
5049 n = quiet_nan_substitute;
5050 } else if (!isnan(n) && isnan(m)) {
5051 // m is quiet NaN: replace with substitute.
5052 m = quiet_nan_substitute;
5053 }
5054 }
5055
5056 if ((n == 0.0) && (m == 0.0) &&
5057 (copysign(1.0, n) != copysign(1.0, m))) {
5058 return min ? -0.0 : 0.0;
5059 }
5060
5061 return min ? fmin(n, m) : fmax(n, m);
5062 }
5063
5064
FminFmaxDoubleHelper(double n,double m,double min,double max,double minnm,double maxnm)5065 static void FminFmaxDoubleHelper(double n, double m, double min, double max,
5066 double minnm, double maxnm) {
5067 SETUP();
5068
5069 START();
5070 __ Fmov(d0, n);
5071 __ Fmov(d1, m);
5072 __ Fmin(d28, d0, d1);
5073 __ Fmax(d29, d0, d1);
5074 __ Fminnm(d30, d0, d1);
5075 __ Fmaxnm(d31, d0, d1);
5076 END();
5077
5078 RUN();
5079
5080 ASSERT_EQUAL_FP64(min, d28);
5081 ASSERT_EQUAL_FP64(max, d29);
5082 ASSERT_EQUAL_FP64(minnm, d30);
5083 ASSERT_EQUAL_FP64(maxnm, d31);
5084
5085 TEARDOWN();
5086 }
5087
5088
TEST(fmax_fmin_d)5089 TEST(fmax_fmin_d) {
5090 // Use non-standard NaNs to check that the payload bits are preserved.
5091 double snan = rawbits_to_double(0x7ff5555512345678);
5092 double qnan = rawbits_to_double(0x7ffaaaaa87654321);
5093
5094 double snan_processed = rawbits_to_double(0x7ffd555512345678);
5095 double qnan_processed = qnan;
5096
5097 VIXL_ASSERT(IsSignallingNaN(snan));
5098 VIXL_ASSERT(IsQuietNaN(qnan));
5099 VIXL_ASSERT(IsQuietNaN(snan_processed));
5100 VIXL_ASSERT(IsQuietNaN(qnan_processed));
5101
5102 // Bootstrap tests.
5103 FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0);
5104 FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1);
5105 FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity,
5106 kFP64NegativeInfinity, kFP64PositiveInfinity,
5107 kFP64NegativeInfinity, kFP64PositiveInfinity);
5108 FminFmaxDoubleHelper(snan, 0,
5109 snan_processed, snan_processed,
5110 snan_processed, snan_processed);
5111 FminFmaxDoubleHelper(0, snan,
5112 snan_processed, snan_processed,
5113 snan_processed, snan_processed);
5114 FminFmaxDoubleHelper(qnan, 0,
5115 qnan_processed, qnan_processed,
5116 0, 0);
5117 FminFmaxDoubleHelper(0, qnan,
5118 qnan_processed, qnan_processed,
5119 0, 0);
5120 FminFmaxDoubleHelper(qnan, snan,
5121 snan_processed, snan_processed,
5122 snan_processed, snan_processed);
5123 FminFmaxDoubleHelper(snan, qnan,
5124 snan_processed, snan_processed,
5125 snan_processed, snan_processed);
5126
5127 // Iterate over all combinations of inputs.
5128 double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0,
5129 -DBL_MAX, -DBL_MIN, -1.0, -0.0,
5130 kFP64PositiveInfinity, kFP64NegativeInfinity,
5131 kFP64QuietNaN, kFP64SignallingNaN };
5132
5133 const int count = sizeof(inputs) / sizeof(inputs[0]);
5134
5135 for (int in = 0; in < count; in++) {
5136 double n = inputs[in];
5137 for (int im = 0; im < count; im++) {
5138 double m = inputs[im];
5139 FminFmaxDoubleHelper(n, m,
5140 MinMaxHelper(n, m, true),
5141 MinMaxHelper(n, m, false),
5142 MinMaxHelper(n, m, true, kFP64PositiveInfinity),
5143 MinMaxHelper(n, m, false, kFP64NegativeInfinity));
5144 }
5145 }
5146 }
5147
5148
FminFmaxFloatHelper(float n,float m,float min,float max,float minnm,float maxnm)5149 static void FminFmaxFloatHelper(float n, float m, float min, float max,
5150 float minnm, float maxnm) {
5151 SETUP();
5152
5153 START();
5154 __ Fmov(s0, n);
5155 __ Fmov(s1, m);
5156 __ Fmin(s28, s0, s1);
5157 __ Fmax(s29, s0, s1);
5158 __ Fminnm(s30, s0, s1);
5159 __ Fmaxnm(s31, s0, s1);
5160 END();
5161
5162 RUN();
5163
5164 ASSERT_EQUAL_FP32(min, s28);
5165 ASSERT_EQUAL_FP32(max, s29);
5166 ASSERT_EQUAL_FP32(minnm, s30);
5167 ASSERT_EQUAL_FP32(maxnm, s31);
5168
5169 TEARDOWN();
5170 }
5171
5172
TEST(fmax_fmin_s)5173 TEST(fmax_fmin_s) {
5174 // Use non-standard NaNs to check that the payload bits are preserved.
5175 float snan = rawbits_to_float(0x7f951234);
5176 float qnan = rawbits_to_float(0x7fea8765);
5177
5178 float snan_processed = rawbits_to_float(0x7fd51234);
5179 float qnan_processed = qnan;
5180
5181 VIXL_ASSERT(IsSignallingNaN(snan));
5182 VIXL_ASSERT(IsQuietNaN(qnan));
5183 VIXL_ASSERT(IsQuietNaN(snan_processed));
5184 VIXL_ASSERT(IsQuietNaN(qnan_processed));
5185
5186 // Bootstrap tests.
5187 FminFmaxFloatHelper(0, 0, 0, 0, 0, 0);
5188 FminFmaxFloatHelper(0, 1, 0, 1, 0, 1);
5189 FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity,
5190 kFP32NegativeInfinity, kFP32PositiveInfinity,
5191 kFP32NegativeInfinity, kFP32PositiveInfinity);
5192 FminFmaxFloatHelper(snan, 0,
5193 snan_processed, snan_processed,
5194 snan_processed, snan_processed);
5195 FminFmaxFloatHelper(0, snan,
5196 snan_processed, snan_processed,
5197 snan_processed, snan_processed);
5198 FminFmaxFloatHelper(qnan, 0,
5199 qnan_processed, qnan_processed,
5200 0, 0);
5201 FminFmaxFloatHelper(0, qnan,
5202 qnan_processed, qnan_processed,
5203 0, 0);
5204 FminFmaxFloatHelper(qnan, snan,
5205 snan_processed, snan_processed,
5206 snan_processed, snan_processed);
5207 FminFmaxFloatHelper(snan, qnan,
5208 snan_processed, snan_processed,
5209 snan_processed, snan_processed);
5210
5211 // Iterate over all combinations of inputs.
5212 float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0,
5213 -FLT_MAX, -FLT_MIN, -1.0, -0.0,
5214 kFP32PositiveInfinity, kFP32NegativeInfinity,
5215 kFP32QuietNaN, kFP32SignallingNaN };
5216
5217 const int count = sizeof(inputs) / sizeof(inputs[0]);
5218
5219 for (int in = 0; in < count; in++) {
5220 float n = inputs[in];
5221 for (int im = 0; im < count; im++) {
5222 float m = inputs[im];
5223 FminFmaxFloatHelper(n, m,
5224 MinMaxHelper(n, m, true),
5225 MinMaxHelper(n, m, false),
5226 MinMaxHelper(n, m, true, kFP32PositiveInfinity),
5227 MinMaxHelper(n, m, false, kFP32NegativeInfinity));
5228 }
5229 }
5230 }
5231
5232
TEST(fccmp)5233 TEST(fccmp) {
5234 SETUP();
5235
5236 START();
5237 __ Fmov(s16, 0.0);
5238 __ Fmov(s17, 0.5);
5239 __ Fmov(d18, -0.5);
5240 __ Fmov(d19, -1.0);
5241 __ Mov(x20, 0);
5242
5243 __ Cmp(x20, 0);
5244 __ Fccmp(s16, s16, NoFlag, eq);
5245 __ Mrs(x0, NZCV);
5246
5247 __ Cmp(x20, 0);
5248 __ Fccmp(s16, s16, VFlag, ne);
5249 __ Mrs(x1, NZCV);
5250
5251 __ Cmp(x20, 0);
5252 __ Fccmp(s16, s17, CFlag, ge);
5253 __ Mrs(x2, NZCV);
5254
5255 __ Cmp(x20, 0);
5256 __ Fccmp(s16, s17, CVFlag, lt);
5257 __ Mrs(x3, NZCV);
5258
5259 __ Cmp(x20, 0);
5260 __ Fccmp(d18, d18, ZFlag, le);
5261 __ Mrs(x4, NZCV);
5262
5263 __ Cmp(x20, 0);
5264 __ Fccmp(d18, d18, ZVFlag, gt);
5265 __ Mrs(x5, NZCV);
5266
5267 __ Cmp(x20, 0);
5268 __ Fccmp(d18, d19, ZCVFlag, ls);
5269 __ Mrs(x6, NZCV);
5270
5271 __ Cmp(x20, 0);
5272 __ Fccmp(d18, d19, NFlag, hi);
5273 __ Mrs(x7, NZCV);
5274
5275 __ fccmp(s16, s16, NFlag, al);
5276 __ Mrs(x8, NZCV);
5277
5278 __ fccmp(d18, d18, NFlag, nv);
5279 __ Mrs(x9, NZCV);
5280 END();
5281
5282 RUN();
5283
5284 ASSERT_EQUAL_32(ZCFlag, w0);
5285 ASSERT_EQUAL_32(VFlag, w1);
5286 ASSERT_EQUAL_32(NFlag, w2);
5287 ASSERT_EQUAL_32(CVFlag, w3);
5288 ASSERT_EQUAL_32(ZCFlag, w4);
5289 ASSERT_EQUAL_32(ZVFlag, w5);
5290 ASSERT_EQUAL_32(CFlag, w6);
5291 ASSERT_EQUAL_32(NFlag, w7);
5292 ASSERT_EQUAL_32(ZCFlag, w8);
5293 ASSERT_EQUAL_32(ZCFlag, w9);
5294
5295 TEARDOWN();
5296 }
5297
5298
TEST(fcmp)5299 TEST(fcmp) {
5300 SETUP();
5301
5302 START();
5303
5304 // Some of these tests require a floating-point scratch register assigned to
5305 // the macro assembler, but most do not.
5306 {
5307 UseScratchRegisterScope temps(&masm);
5308 temps.ExcludeAll();
5309 temps.Include(ip0, ip1);
5310
5311 __ Fmov(s8, 0.0);
5312 __ Fmov(s9, 0.5);
5313 __ Mov(w18, 0x7f800001); // Single precision NaN.
5314 __ Fmov(s18, w18);
5315
5316 __ Fcmp(s8, s8);
5317 __ Mrs(x0, NZCV);
5318 __ Fcmp(s8, s9);
5319 __ Mrs(x1, NZCV);
5320 __ Fcmp(s9, s8);
5321 __ Mrs(x2, NZCV);
5322 __ Fcmp(s8, s18);
5323 __ Mrs(x3, NZCV);
5324 __ Fcmp(s18, s18);
5325 __ Mrs(x4, NZCV);
5326 __ Fcmp(s8, 0.0);
5327 __ Mrs(x5, NZCV);
5328 temps.Include(d0);
5329 __ Fcmp(s8, 255.0);
5330 temps.Exclude(d0);
5331 __ Mrs(x6, NZCV);
5332
5333 __ Fmov(d19, 0.0);
5334 __ Fmov(d20, 0.5);
5335 __ Mov(x21, 0x7ff0000000000001); // Double precision NaN.
5336 __ Fmov(d21, x21);
5337
5338 __ Fcmp(d19, d19);
5339 __ Mrs(x10, NZCV);
5340 __ Fcmp(d19, d20);
5341 __ Mrs(x11, NZCV);
5342 __ Fcmp(d20, d19);
5343 __ Mrs(x12, NZCV);
5344 __ Fcmp(d19, d21);
5345 __ Mrs(x13, NZCV);
5346 __ Fcmp(d21, d21);
5347 __ Mrs(x14, NZCV);
5348 __ Fcmp(d19, 0.0);
5349 __ Mrs(x15, NZCV);
5350 temps.Include(d0);
5351 __ Fcmp(d19, 12.3456);
5352 temps.Exclude(d0);
5353 __ Mrs(x16, NZCV);
5354 }
5355
5356 END();
5357
5358 RUN();
5359
5360 ASSERT_EQUAL_32(ZCFlag, w0);
5361 ASSERT_EQUAL_32(NFlag, w1);
5362 ASSERT_EQUAL_32(CFlag, w2);
5363 ASSERT_EQUAL_32(CVFlag, w3);
5364 ASSERT_EQUAL_32(CVFlag, w4);
5365 ASSERT_EQUAL_32(ZCFlag, w5);
5366 ASSERT_EQUAL_32(NFlag, w6);
5367 ASSERT_EQUAL_32(ZCFlag, w10);
5368 ASSERT_EQUAL_32(NFlag, w11);
5369 ASSERT_EQUAL_32(CFlag, w12);
5370 ASSERT_EQUAL_32(CVFlag, w13);
5371 ASSERT_EQUAL_32(CVFlag, w14);
5372 ASSERT_EQUAL_32(ZCFlag, w15);
5373 ASSERT_EQUAL_32(NFlag, w16);
5374
5375 TEARDOWN();
5376 }
5377
5378
TEST(fcsel)5379 TEST(fcsel) {
5380 SETUP();
5381
5382 START();
5383 __ Mov(x16, 0);
5384 __ Fmov(s16, 1.0);
5385 __ Fmov(s17, 2.0);
5386 __ Fmov(d18, 3.0);
5387 __ Fmov(d19, 4.0);
5388
5389 __ Cmp(x16, 0);
5390 __ Fcsel(s0, s16, s17, eq);
5391 __ Fcsel(s1, s16, s17, ne);
5392 __ Fcsel(d2, d18, d19, eq);
5393 __ Fcsel(d3, d18, d19, ne);
5394 __ fcsel(s4, s16, s17, al);
5395 __ fcsel(d5, d18, d19, nv);
5396 END();
5397
5398 RUN();
5399
5400 ASSERT_EQUAL_FP32(1.0, s0);
5401 ASSERT_EQUAL_FP32(2.0, s1);
5402 ASSERT_EQUAL_FP64(3.0, d2);
5403 ASSERT_EQUAL_FP64(4.0, d3);
5404 ASSERT_EQUAL_FP32(1.0, s4);
5405 ASSERT_EQUAL_FP64(3.0, d5);
5406
5407 TEARDOWN();
5408 }
5409
5410
TEST(fneg)5411 TEST(fneg) {
5412 SETUP();
5413
5414 START();
5415 __ Fmov(s16, 1.0);
5416 __ Fmov(s17, 0.0);
5417 __ Fmov(s18, kFP32PositiveInfinity);
5418 __ Fmov(d19, 1.0);
5419 __ Fmov(d20, 0.0);
5420 __ Fmov(d21, kFP64PositiveInfinity);
5421
5422 __ Fneg(s0, s16);
5423 __ Fneg(s1, s0);
5424 __ Fneg(s2, s17);
5425 __ Fneg(s3, s2);
5426 __ Fneg(s4, s18);
5427 __ Fneg(s5, s4);
5428 __ Fneg(d6, d19);
5429 __ Fneg(d7, d6);
5430 __ Fneg(d8, d20);
5431 __ Fneg(d9, d8);
5432 __ Fneg(d10, d21);
5433 __ Fneg(d11, d10);
5434 END();
5435
5436 RUN();
5437
5438 ASSERT_EQUAL_FP32(-1.0, s0);
5439 ASSERT_EQUAL_FP32(1.0, s1);
5440 ASSERT_EQUAL_FP32(-0.0, s2);
5441 ASSERT_EQUAL_FP32(0.0, s3);
5442 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
5443 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
5444 ASSERT_EQUAL_FP64(-1.0, d6);
5445 ASSERT_EQUAL_FP64(1.0, d7);
5446 ASSERT_EQUAL_FP64(-0.0, d8);
5447 ASSERT_EQUAL_FP64(0.0, d9);
5448 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
5449 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
5450
5451 TEARDOWN();
5452 }
5453
5454
TEST(fabs)5455 TEST(fabs) {
5456 SETUP();
5457
5458 START();
5459 __ Fmov(s16, -1.0);
5460 __ Fmov(s17, -0.0);
5461 __ Fmov(s18, kFP32NegativeInfinity);
5462 __ Fmov(d19, -1.0);
5463 __ Fmov(d20, -0.0);
5464 __ Fmov(d21, kFP64NegativeInfinity);
5465
5466 __ Fabs(s0, s16);
5467 __ Fabs(s1, s0);
5468 __ Fabs(s2, s17);
5469 __ Fabs(s3, s18);
5470 __ Fabs(d4, d19);
5471 __ Fabs(d5, d4);
5472 __ Fabs(d6, d20);
5473 __ Fabs(d7, d21);
5474 END();
5475
5476 RUN();
5477
5478 ASSERT_EQUAL_FP32(1.0, s0);
5479 ASSERT_EQUAL_FP32(1.0, s1);
5480 ASSERT_EQUAL_FP32(0.0, s2);
5481 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
5482 ASSERT_EQUAL_FP64(1.0, d4);
5483 ASSERT_EQUAL_FP64(1.0, d5);
5484 ASSERT_EQUAL_FP64(0.0, d6);
5485 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
5486
5487 TEARDOWN();
5488 }
5489
5490
TEST(fsqrt)5491 TEST(fsqrt) {
5492 SETUP();
5493
5494 START();
5495 __ Fmov(s16, 0.0);
5496 __ Fmov(s17, 1.0);
5497 __ Fmov(s18, 0.25);
5498 __ Fmov(s19, 65536.0);
5499 __ Fmov(s20, -0.0);
5500 __ Fmov(s21, kFP32PositiveInfinity);
5501 __ Fmov(s22, -1.0);
5502 __ Fmov(d23, 0.0);
5503 __ Fmov(d24, 1.0);
5504 __ Fmov(d25, 0.25);
5505 __ Fmov(d26, 4294967296.0);
5506 __ Fmov(d27, -0.0);
5507 __ Fmov(d28, kFP64PositiveInfinity);
5508 __ Fmov(d29, -1.0);
5509
5510 __ Fsqrt(s0, s16);
5511 __ Fsqrt(s1, s17);
5512 __ Fsqrt(s2, s18);
5513 __ Fsqrt(s3, s19);
5514 __ Fsqrt(s4, s20);
5515 __ Fsqrt(s5, s21);
5516 __ Fsqrt(s6, s22);
5517 __ Fsqrt(d7, d23);
5518 __ Fsqrt(d8, d24);
5519 __ Fsqrt(d9, d25);
5520 __ Fsqrt(d10, d26);
5521 __ Fsqrt(d11, d27);
5522 __ Fsqrt(d12, d28);
5523 __ Fsqrt(d13, d29);
5524 END();
5525
5526 RUN();
5527
5528 ASSERT_EQUAL_FP32(0.0, s0);
5529 ASSERT_EQUAL_FP32(1.0, s1);
5530 ASSERT_EQUAL_FP32(0.5, s2);
5531 ASSERT_EQUAL_FP32(256.0, s3);
5532 ASSERT_EQUAL_FP32(-0.0, s4);
5533 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
5534 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
5535 ASSERT_EQUAL_FP64(0.0, d7);
5536 ASSERT_EQUAL_FP64(1.0, d8);
5537 ASSERT_EQUAL_FP64(0.5, d9);
5538 ASSERT_EQUAL_FP64(65536.0, d10);
5539 ASSERT_EQUAL_FP64(-0.0, d11);
5540 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
5541 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
5542
5543 TEARDOWN();
5544 }
5545
5546
TEST(frinta)5547 TEST(frinta) {
5548 SETUP();
5549
5550 START();
5551 __ Fmov(s16, 1.0);
5552 __ Fmov(s17, 1.1);
5553 __ Fmov(s18, 1.5);
5554 __ Fmov(s19, 1.9);
5555 __ Fmov(s20, 2.5);
5556 __ Fmov(s21, -1.5);
5557 __ Fmov(s22, -2.5);
5558 __ Fmov(s23, kFP32PositiveInfinity);
5559 __ Fmov(s24, kFP32NegativeInfinity);
5560 __ Fmov(s25, 0.0);
5561 __ Fmov(s26, -0.0);
5562 __ Fmov(s27, -0.2);
5563
5564 __ Frinta(s0, s16);
5565 __ Frinta(s1, s17);
5566 __ Frinta(s2, s18);
5567 __ Frinta(s3, s19);
5568 __ Frinta(s4, s20);
5569 __ Frinta(s5, s21);
5570 __ Frinta(s6, s22);
5571 __ Frinta(s7, s23);
5572 __ Frinta(s8, s24);
5573 __ Frinta(s9, s25);
5574 __ Frinta(s10, s26);
5575 __ Frinta(s11, s27);
5576
5577 __ Fmov(d16, 1.0);
5578 __ Fmov(d17, 1.1);
5579 __ Fmov(d18, 1.5);
5580 __ Fmov(d19, 1.9);
5581 __ Fmov(d20, 2.5);
5582 __ Fmov(d21, -1.5);
5583 __ Fmov(d22, -2.5);
5584 __ Fmov(d23, kFP32PositiveInfinity);
5585 __ Fmov(d24, kFP32NegativeInfinity);
5586 __ Fmov(d25, 0.0);
5587 __ Fmov(d26, -0.0);
5588 __ Fmov(d27, -0.2);
5589
5590 __ Frinta(d12, d16);
5591 __ Frinta(d13, d17);
5592 __ Frinta(d14, d18);
5593 __ Frinta(d15, d19);
5594 __ Frinta(d16, d20);
5595 __ Frinta(d17, d21);
5596 __ Frinta(d18, d22);
5597 __ Frinta(d19, d23);
5598 __ Frinta(d20, d24);
5599 __ Frinta(d21, d25);
5600 __ Frinta(d22, d26);
5601 __ Frinta(d23, d27);
5602 END();
5603
5604 RUN();
5605
5606 ASSERT_EQUAL_FP32(1.0, s0);
5607 ASSERT_EQUAL_FP32(1.0, s1);
5608 ASSERT_EQUAL_FP32(2.0, s2);
5609 ASSERT_EQUAL_FP32(2.0, s3);
5610 ASSERT_EQUAL_FP32(3.0, s4);
5611 ASSERT_EQUAL_FP32(-2.0, s5);
5612 ASSERT_EQUAL_FP32(-3.0, s6);
5613 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5614 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5615 ASSERT_EQUAL_FP32(0.0, s9);
5616 ASSERT_EQUAL_FP32(-0.0, s10);
5617 ASSERT_EQUAL_FP32(-0.0, s11);
5618 ASSERT_EQUAL_FP64(1.0, d12);
5619 ASSERT_EQUAL_FP64(1.0, d13);
5620 ASSERT_EQUAL_FP64(2.0, d14);
5621 ASSERT_EQUAL_FP64(2.0, d15);
5622 ASSERT_EQUAL_FP64(3.0, d16);
5623 ASSERT_EQUAL_FP64(-2.0, d17);
5624 ASSERT_EQUAL_FP64(-3.0, d18);
5625 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
5626 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
5627 ASSERT_EQUAL_FP64(0.0, d21);
5628 ASSERT_EQUAL_FP64(-0.0, d22);
5629 ASSERT_EQUAL_FP64(-0.0, d23);
5630
5631 TEARDOWN();
5632 }
5633
5634
TEST(frintm)5635 TEST(frintm) {
5636 SETUP();
5637
5638 START();
5639 __ Fmov(s16, 1.0);
5640 __ Fmov(s17, 1.1);
5641 __ Fmov(s18, 1.5);
5642 __ Fmov(s19, 1.9);
5643 __ Fmov(s20, 2.5);
5644 __ Fmov(s21, -1.5);
5645 __ Fmov(s22, -2.5);
5646 __ Fmov(s23, kFP32PositiveInfinity);
5647 __ Fmov(s24, kFP32NegativeInfinity);
5648 __ Fmov(s25, 0.0);
5649 __ Fmov(s26, -0.0);
5650 __ Fmov(s27, -0.2);
5651
5652 __ Frintm(s0, s16);
5653 __ Frintm(s1, s17);
5654 __ Frintm(s2, s18);
5655 __ Frintm(s3, s19);
5656 __ Frintm(s4, s20);
5657 __ Frintm(s5, s21);
5658 __ Frintm(s6, s22);
5659 __ Frintm(s7, s23);
5660 __ Frintm(s8, s24);
5661 __ Frintm(s9, s25);
5662 __ Frintm(s10, s26);
5663 __ Frintm(s11, s27);
5664
5665 __ Fmov(d16, 1.0);
5666 __ Fmov(d17, 1.1);
5667 __ Fmov(d18, 1.5);
5668 __ Fmov(d19, 1.9);
5669 __ Fmov(d20, 2.5);
5670 __ Fmov(d21, -1.5);
5671 __ Fmov(d22, -2.5);
5672 __ Fmov(d23, kFP32PositiveInfinity);
5673 __ Fmov(d24, kFP32NegativeInfinity);
5674 __ Fmov(d25, 0.0);
5675 __ Fmov(d26, -0.0);
5676 __ Fmov(d27, -0.2);
5677
5678 __ Frintm(d12, d16);
5679 __ Frintm(d13, d17);
5680 __ Frintm(d14, d18);
5681 __ Frintm(d15, d19);
5682 __ Frintm(d16, d20);
5683 __ Frintm(d17, d21);
5684 __ Frintm(d18, d22);
5685 __ Frintm(d19, d23);
5686 __ Frintm(d20, d24);
5687 __ Frintm(d21, d25);
5688 __ Frintm(d22, d26);
5689 __ Frintm(d23, d27);
5690 END();
5691
5692 RUN();
5693
5694 ASSERT_EQUAL_FP32(1.0, s0);
5695 ASSERT_EQUAL_FP32(1.0, s1);
5696 ASSERT_EQUAL_FP32(1.0, s2);
5697 ASSERT_EQUAL_FP32(1.0, s3);
5698 ASSERT_EQUAL_FP32(2.0, s4);
5699 ASSERT_EQUAL_FP32(-2.0, s5);
5700 ASSERT_EQUAL_FP32(-3.0, s6);
5701 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5702 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5703 ASSERT_EQUAL_FP32(0.0, s9);
5704 ASSERT_EQUAL_FP32(-0.0, s10);
5705 ASSERT_EQUAL_FP32(-1.0, s11);
5706 ASSERT_EQUAL_FP64(1.0, d12);
5707 ASSERT_EQUAL_FP64(1.0, d13);
5708 ASSERT_EQUAL_FP64(1.0, d14);
5709 ASSERT_EQUAL_FP64(1.0, d15);
5710 ASSERT_EQUAL_FP64(2.0, d16);
5711 ASSERT_EQUAL_FP64(-2.0, d17);
5712 ASSERT_EQUAL_FP64(-3.0, d18);
5713 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
5714 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
5715 ASSERT_EQUAL_FP64(0.0, d21);
5716 ASSERT_EQUAL_FP64(-0.0, d22);
5717 ASSERT_EQUAL_FP64(-1.0, d23);
5718
5719 TEARDOWN();
5720 }
5721
5722
TEST(frintn)5723 TEST(frintn) {
5724 SETUP();
5725
5726 START();
5727 __ Fmov(s16, 1.0);
5728 __ Fmov(s17, 1.1);
5729 __ Fmov(s18, 1.5);
5730 __ Fmov(s19, 1.9);
5731 __ Fmov(s20, 2.5);
5732 __ Fmov(s21, -1.5);
5733 __ Fmov(s22, -2.5);
5734 __ Fmov(s23, kFP32PositiveInfinity);
5735 __ Fmov(s24, kFP32NegativeInfinity);
5736 __ Fmov(s25, 0.0);
5737 __ Fmov(s26, -0.0);
5738 __ Fmov(s27, -0.2);
5739
5740 __ Frintn(s0, s16);
5741 __ Frintn(s1, s17);
5742 __ Frintn(s2, s18);
5743 __ Frintn(s3, s19);
5744 __ Frintn(s4, s20);
5745 __ Frintn(s5, s21);
5746 __ Frintn(s6, s22);
5747 __ Frintn(s7, s23);
5748 __ Frintn(s8, s24);
5749 __ Frintn(s9, s25);
5750 __ Frintn(s10, s26);
5751 __ Frintn(s11, s27);
5752
5753 __ Fmov(d16, 1.0);
5754 __ Fmov(d17, 1.1);
5755 __ Fmov(d18, 1.5);
5756 __ Fmov(d19, 1.9);
5757 __ Fmov(d20, 2.5);
5758 __ Fmov(d21, -1.5);
5759 __ Fmov(d22, -2.5);
5760 __ Fmov(d23, kFP32PositiveInfinity);
5761 __ Fmov(d24, kFP32NegativeInfinity);
5762 __ Fmov(d25, 0.0);
5763 __ Fmov(d26, -0.0);
5764 __ Fmov(d27, -0.2);
5765
5766 __ Frintn(d12, d16);
5767 __ Frintn(d13, d17);
5768 __ Frintn(d14, d18);
5769 __ Frintn(d15, d19);
5770 __ Frintn(d16, d20);
5771 __ Frintn(d17, d21);
5772 __ Frintn(d18, d22);
5773 __ Frintn(d19, d23);
5774 __ Frintn(d20, d24);
5775 __ Frintn(d21, d25);
5776 __ Frintn(d22, d26);
5777 __ Frintn(d23, d27);
5778 END();
5779
5780 RUN();
5781
5782 ASSERT_EQUAL_FP32(1.0, s0);
5783 ASSERT_EQUAL_FP32(1.0, s1);
5784 ASSERT_EQUAL_FP32(2.0, s2);
5785 ASSERT_EQUAL_FP32(2.0, s3);
5786 ASSERT_EQUAL_FP32(2.0, s4);
5787 ASSERT_EQUAL_FP32(-2.0, s5);
5788 ASSERT_EQUAL_FP32(-2.0, s6);
5789 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5790 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5791 ASSERT_EQUAL_FP32(0.0, s9);
5792 ASSERT_EQUAL_FP32(-0.0, s10);
5793 ASSERT_EQUAL_FP32(-0.0, s11);
5794 ASSERT_EQUAL_FP64(1.0, d12);
5795 ASSERT_EQUAL_FP64(1.0, d13);
5796 ASSERT_EQUAL_FP64(2.0, d14);
5797 ASSERT_EQUAL_FP64(2.0, d15);
5798 ASSERT_EQUAL_FP64(2.0, d16);
5799 ASSERT_EQUAL_FP64(-2.0, d17);
5800 ASSERT_EQUAL_FP64(-2.0, d18);
5801 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
5802 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
5803 ASSERT_EQUAL_FP64(0.0, d21);
5804 ASSERT_EQUAL_FP64(-0.0, d22);
5805 ASSERT_EQUAL_FP64(-0.0, d23);
5806
5807 TEARDOWN();
5808 }
5809
5810
TEST(frintz)5811 TEST(frintz) {
5812 SETUP();
5813
5814 START();
5815 __ Fmov(s16, 1.0);
5816 __ Fmov(s17, 1.1);
5817 __ Fmov(s18, 1.5);
5818 __ Fmov(s19, 1.9);
5819 __ Fmov(s20, 2.5);
5820 __ Fmov(s21, -1.5);
5821 __ Fmov(s22, -2.5);
5822 __ Fmov(s23, kFP32PositiveInfinity);
5823 __ Fmov(s24, kFP32NegativeInfinity);
5824 __ Fmov(s25, 0.0);
5825 __ Fmov(s26, -0.0);
5826
5827 __ Frintz(s0, s16);
5828 __ Frintz(s1, s17);
5829 __ Frintz(s2, s18);
5830 __ Frintz(s3, s19);
5831 __ Frintz(s4, s20);
5832 __ Frintz(s5, s21);
5833 __ Frintz(s6, s22);
5834 __ Frintz(s7, s23);
5835 __ Frintz(s8, s24);
5836 __ Frintz(s9, s25);
5837 __ Frintz(s10, s26);
5838
5839 __ Fmov(d16, 1.0);
5840 __ Fmov(d17, 1.1);
5841 __ Fmov(d18, 1.5);
5842 __ Fmov(d19, 1.9);
5843 __ Fmov(d20, 2.5);
5844 __ Fmov(d21, -1.5);
5845 __ Fmov(d22, -2.5);
5846 __ Fmov(d23, kFP32PositiveInfinity);
5847 __ Fmov(d24, kFP32NegativeInfinity);
5848 __ Fmov(d25, 0.0);
5849 __ Fmov(d26, -0.0);
5850
5851 __ Frintz(d11, d16);
5852 __ Frintz(d12, d17);
5853 __ Frintz(d13, d18);
5854 __ Frintz(d14, d19);
5855 __ Frintz(d15, d20);
5856 __ Frintz(d16, d21);
5857 __ Frintz(d17, d22);
5858 __ Frintz(d18, d23);
5859 __ Frintz(d19, d24);
5860 __ Frintz(d20, d25);
5861 __ Frintz(d21, d26);
5862 END();
5863
5864 RUN();
5865
5866 ASSERT_EQUAL_FP32(1.0, s0);
5867 ASSERT_EQUAL_FP32(1.0, s1);
5868 ASSERT_EQUAL_FP32(1.0, s2);
5869 ASSERT_EQUAL_FP32(1.0, s3);
5870 ASSERT_EQUAL_FP32(2.0, s4);
5871 ASSERT_EQUAL_FP32(-1.0, s5);
5872 ASSERT_EQUAL_FP32(-2.0, s6);
5873 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5874 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5875 ASSERT_EQUAL_FP32(0.0, s9);
5876 ASSERT_EQUAL_FP32(-0.0, s10);
5877 ASSERT_EQUAL_FP64(1.0, d11);
5878 ASSERT_EQUAL_FP64(1.0, d12);
5879 ASSERT_EQUAL_FP64(1.0, d13);
5880 ASSERT_EQUAL_FP64(1.0, d14);
5881 ASSERT_EQUAL_FP64(2.0, d15);
5882 ASSERT_EQUAL_FP64(-1.0, d16);
5883 ASSERT_EQUAL_FP64(-2.0, d17);
5884 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
5885 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
5886 ASSERT_EQUAL_FP64(0.0, d20);
5887 ASSERT_EQUAL_FP64(-0.0, d21);
5888
5889 TEARDOWN();
5890 }
5891
5892
TEST(fcvt_ds)5893 TEST(fcvt_ds) {
5894 SETUP();
5895
5896 START();
5897 __ Fmov(s16, 1.0);
5898 __ Fmov(s17, 1.1);
5899 __ Fmov(s18, 1.5);
5900 __ Fmov(s19, 1.9);
5901 __ Fmov(s20, 2.5);
5902 __ Fmov(s21, -1.5);
5903 __ Fmov(s22, -2.5);
5904 __ Fmov(s23, kFP32PositiveInfinity);
5905 __ Fmov(s24, kFP32NegativeInfinity);
5906 __ Fmov(s25, 0.0);
5907 __ Fmov(s26, -0.0);
5908 __ Fmov(s27, FLT_MAX);
5909 __ Fmov(s28, FLT_MIN);
5910 __ Fmov(s29, rawbits_to_float(0x7fc12345)); // Quiet NaN.
5911 __ Fmov(s30, rawbits_to_float(0x7f812345)); // Signalling NaN.
5912
5913 __ Fcvt(d0, s16);
5914 __ Fcvt(d1, s17);
5915 __ Fcvt(d2, s18);
5916 __ Fcvt(d3, s19);
5917 __ Fcvt(d4, s20);
5918 __ Fcvt(d5, s21);
5919 __ Fcvt(d6, s22);
5920 __ Fcvt(d7, s23);
5921 __ Fcvt(d8, s24);
5922 __ Fcvt(d9, s25);
5923 __ Fcvt(d10, s26);
5924 __ Fcvt(d11, s27);
5925 __ Fcvt(d12, s28);
5926 __ Fcvt(d13, s29);
5927 __ Fcvt(d14, s30);
5928 END();
5929
5930 RUN();
5931
5932 ASSERT_EQUAL_FP64(1.0f, d0);
5933 ASSERT_EQUAL_FP64(1.1f, d1);
5934 ASSERT_EQUAL_FP64(1.5f, d2);
5935 ASSERT_EQUAL_FP64(1.9f, d3);
5936 ASSERT_EQUAL_FP64(2.5f, d4);
5937 ASSERT_EQUAL_FP64(-1.5f, d5);
5938 ASSERT_EQUAL_FP64(-2.5f, d6);
5939 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
5940 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
5941 ASSERT_EQUAL_FP64(0.0f, d9);
5942 ASSERT_EQUAL_FP64(-0.0f, d10);
5943 ASSERT_EQUAL_FP64(FLT_MAX, d11);
5944 ASSERT_EQUAL_FP64(FLT_MIN, d12);
5945
5946 // Check that the NaN payload is preserved according to A64 conversion rules:
5947 // - The sign bit is preserved.
5948 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
5949 // - The remaining mantissa bits are copied until they run out.
5950 // - The low-order bits that haven't already been assigned are set to 0.
5951 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
5952 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
5953
5954 TEARDOWN();
5955 }
5956
5957
TEST(fcvt_sd)5958 TEST(fcvt_sd) {
5959 // Test simple conversions here. Complex behaviour (such as rounding
5960 // specifics) are tested in the simulator tests.
5961
5962 SETUP();
5963
5964 START();
5965 __ Fmov(d16, 1.0);
5966 __ Fmov(d17, 1.1);
5967 __ Fmov(d18, 1.5);
5968 __ Fmov(d19, 1.9);
5969 __ Fmov(d20, 2.5);
5970 __ Fmov(d21, -1.5);
5971 __ Fmov(d22, -2.5);
5972 __ Fmov(d23, kFP32PositiveInfinity);
5973 __ Fmov(d24, kFP32NegativeInfinity);
5974 __ Fmov(d25, 0.0);
5975 __ Fmov(d26, -0.0);
5976 __ Fmov(d27, FLT_MAX);
5977 __ Fmov(d28, FLT_MIN);
5978 __ Fmov(d29, rawbits_to_double(0x7ff82468a0000000)); // Quiet NaN.
5979 __ Fmov(d30, rawbits_to_double(0x7ff02468a0000000)); // Signalling NaN.
5980
5981 __ Fcvt(s0, d16);
5982 __ Fcvt(s1, d17);
5983 __ Fcvt(s2, d18);
5984 __ Fcvt(s3, d19);
5985 __ Fcvt(s4, d20);
5986 __ Fcvt(s5, d21);
5987 __ Fcvt(s6, d22);
5988 __ Fcvt(s7, d23);
5989 __ Fcvt(s8, d24);
5990 __ Fcvt(s9, d25);
5991 __ Fcvt(s10, d26);
5992 __ Fcvt(s11, d27);
5993 __ Fcvt(s12, d28);
5994 __ Fcvt(s13, d29);
5995 __ Fcvt(s14, d30);
5996 END();
5997
5998 RUN();
5999
6000 ASSERT_EQUAL_FP32(1.0f, s0);
6001 ASSERT_EQUAL_FP32(1.1f, s1);
6002 ASSERT_EQUAL_FP32(1.5f, s2);
6003 ASSERT_EQUAL_FP32(1.9f, s3);
6004 ASSERT_EQUAL_FP32(2.5f, s4);
6005 ASSERT_EQUAL_FP32(-1.5f, s5);
6006 ASSERT_EQUAL_FP32(-2.5f, s6);
6007 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
6008 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
6009 ASSERT_EQUAL_FP32(0.0f, s9);
6010 ASSERT_EQUAL_FP32(-0.0f, s10);
6011 ASSERT_EQUAL_FP32(FLT_MAX, s11);
6012 ASSERT_EQUAL_FP32(FLT_MIN, s12);
6013
6014 // Check that the NaN payload is preserved according to A64 conversion rules:
6015 // - The sign bit is preserved.
6016 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
6017 // - The remaining mantissa bits are copied until they run out.
6018 // - The low-order bits that haven't already been assigned are set to 0.
6019 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s13);
6020 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s14);
6021
6022 TEARDOWN();
6023 }
6024
6025
TEST(fcvtas)6026 TEST(fcvtas) {
6027 SETUP();
6028
6029 START();
6030 __ Fmov(s0, 1.0);
6031 __ Fmov(s1, 1.1);
6032 __ Fmov(s2, 2.5);
6033 __ Fmov(s3, -2.5);
6034 __ Fmov(s4, kFP32PositiveInfinity);
6035 __ Fmov(s5, kFP32NegativeInfinity);
6036 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6037 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
6038 __ Fmov(d8, 1.0);
6039 __ Fmov(d9, 1.1);
6040 __ Fmov(d10, 2.5);
6041 __ Fmov(d11, -2.5);
6042 __ Fmov(d12, kFP64PositiveInfinity);
6043 __ Fmov(d13, kFP64NegativeInfinity);
6044 __ Fmov(d14, kWMaxInt - 1);
6045 __ Fmov(d15, kWMinInt + 1);
6046 __ Fmov(s17, 1.1);
6047 __ Fmov(s18, 2.5);
6048 __ Fmov(s19, -2.5);
6049 __ Fmov(s20, kFP32PositiveInfinity);
6050 __ Fmov(s21, kFP32NegativeInfinity);
6051 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6052 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
6053 __ Fmov(d24, 1.1);
6054 __ Fmov(d25, 2.5);
6055 __ Fmov(d26, -2.5);
6056 __ Fmov(d27, kFP64PositiveInfinity);
6057 __ Fmov(d28, kFP64NegativeInfinity);
6058 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6059 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
6060
6061 __ Fcvtas(w0, s0);
6062 __ Fcvtas(w1, s1);
6063 __ Fcvtas(w2, s2);
6064 __ Fcvtas(w3, s3);
6065 __ Fcvtas(w4, s4);
6066 __ Fcvtas(w5, s5);
6067 __ Fcvtas(w6, s6);
6068 __ Fcvtas(w7, s7);
6069 __ Fcvtas(w8, d8);
6070 __ Fcvtas(w9, d9);
6071 __ Fcvtas(w10, d10);
6072 __ Fcvtas(w11, d11);
6073 __ Fcvtas(w12, d12);
6074 __ Fcvtas(w13, d13);
6075 __ Fcvtas(w14, d14);
6076 __ Fcvtas(w15, d15);
6077 __ Fcvtas(x17, s17);
6078 __ Fcvtas(x18, s18);
6079 __ Fcvtas(x19, s19);
6080 __ Fcvtas(x20, s20);
6081 __ Fcvtas(x21, s21);
6082 __ Fcvtas(x22, s22);
6083 __ Fcvtas(x23, s23);
6084 __ Fcvtas(x24, d24);
6085 __ Fcvtas(x25, d25);
6086 __ Fcvtas(x26, d26);
6087 __ Fcvtas(x27, d27);
6088 __ Fcvtas(x28, d28);
6089 __ Fcvtas(x29, d29);
6090 __ Fcvtas(x30, d30);
6091 END();
6092
6093 RUN();
6094
6095 ASSERT_EQUAL_64(1, x0);
6096 ASSERT_EQUAL_64(1, x1);
6097 ASSERT_EQUAL_64(3, x2);
6098 ASSERT_EQUAL_64(0xfffffffd, x3);
6099 ASSERT_EQUAL_64(0x7fffffff, x4);
6100 ASSERT_EQUAL_64(0x80000000, x5);
6101 ASSERT_EQUAL_64(0x7fffff80, x6);
6102 ASSERT_EQUAL_64(0x80000080, x7);
6103 ASSERT_EQUAL_64(1, x8);
6104 ASSERT_EQUAL_64(1, x9);
6105 ASSERT_EQUAL_64(3, x10);
6106 ASSERT_EQUAL_64(0xfffffffd, x11);
6107 ASSERT_EQUAL_64(0x7fffffff, x12);
6108 ASSERT_EQUAL_64(0x80000000, x13);
6109 ASSERT_EQUAL_64(0x7ffffffe, x14);
6110 ASSERT_EQUAL_64(0x80000001, x15);
6111 ASSERT_EQUAL_64(1, x17);
6112 ASSERT_EQUAL_64(3, x18);
6113 ASSERT_EQUAL_64(0xfffffffffffffffd, x19);
6114 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6115 ASSERT_EQUAL_64(0x8000000000000000, x21);
6116 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6117 ASSERT_EQUAL_64(0x8000008000000000, x23);
6118 ASSERT_EQUAL_64(1, x24);
6119 ASSERT_EQUAL_64(3, x25);
6120 ASSERT_EQUAL_64(0xfffffffffffffffd, x26);
6121 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6122 ASSERT_EQUAL_64(0x8000000000000000, x28);
6123 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6124 ASSERT_EQUAL_64(0x8000000000000400, x30);
6125
6126 TEARDOWN();
6127 }
6128
6129
TEST(fcvtau)6130 TEST(fcvtau) {
6131 SETUP();
6132
6133 START();
6134 __ Fmov(s0, 1.0);
6135 __ Fmov(s1, 1.1);
6136 __ Fmov(s2, 2.5);
6137 __ Fmov(s3, -2.5);
6138 __ Fmov(s4, kFP32PositiveInfinity);
6139 __ Fmov(s5, kFP32NegativeInfinity);
6140 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
6141 __ Fmov(d8, 1.0);
6142 __ Fmov(d9, 1.1);
6143 __ Fmov(d10, 2.5);
6144 __ Fmov(d11, -2.5);
6145 __ Fmov(d12, kFP64PositiveInfinity);
6146 __ Fmov(d13, kFP64NegativeInfinity);
6147 __ Fmov(d14, 0xfffffffe);
6148 __ Fmov(s16, 1.0);
6149 __ Fmov(s17, 1.1);
6150 __ Fmov(s18, 2.5);
6151 __ Fmov(s19, -2.5);
6152 __ Fmov(s20, kFP32PositiveInfinity);
6153 __ Fmov(s21, kFP32NegativeInfinity);
6154 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
6155 __ Fmov(d24, 1.1);
6156 __ Fmov(d25, 2.5);
6157 __ Fmov(d26, -2.5);
6158 __ Fmov(d27, kFP64PositiveInfinity);
6159 __ Fmov(d28, kFP64NegativeInfinity);
6160 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
6161 __ Fmov(s30, 0x100000000);
6162
6163 __ Fcvtau(w0, s0);
6164 __ Fcvtau(w1, s1);
6165 __ Fcvtau(w2, s2);
6166 __ Fcvtau(w3, s3);
6167 __ Fcvtau(w4, s4);
6168 __ Fcvtau(w5, s5);
6169 __ Fcvtau(w6, s6);
6170 __ Fcvtau(w8, d8);
6171 __ Fcvtau(w9, d9);
6172 __ Fcvtau(w10, d10);
6173 __ Fcvtau(w11, d11);
6174 __ Fcvtau(w12, d12);
6175 __ Fcvtau(w13, d13);
6176 __ Fcvtau(w14, d14);
6177 __ Fcvtau(w15, d15);
6178 __ Fcvtau(x16, s16);
6179 __ Fcvtau(x17, s17);
6180 __ Fcvtau(x18, s18);
6181 __ Fcvtau(x19, s19);
6182 __ Fcvtau(x20, s20);
6183 __ Fcvtau(x21, s21);
6184 __ Fcvtau(x22, s22);
6185 __ Fcvtau(x24, d24);
6186 __ Fcvtau(x25, d25);
6187 __ Fcvtau(x26, d26);
6188 __ Fcvtau(x27, d27);
6189 __ Fcvtau(x28, d28);
6190 __ Fcvtau(x29, d29);
6191 __ Fcvtau(w30, s30);
6192 END();
6193
6194 RUN();
6195
6196 ASSERT_EQUAL_64(1, x0);
6197 ASSERT_EQUAL_64(1, x1);
6198 ASSERT_EQUAL_64(3, x2);
6199 ASSERT_EQUAL_64(0, x3);
6200 ASSERT_EQUAL_64(0xffffffff, x4);
6201 ASSERT_EQUAL_64(0, x5);
6202 ASSERT_EQUAL_64(0xffffff00, x6);
6203 ASSERT_EQUAL_64(1, x8);
6204 ASSERT_EQUAL_64(1, x9);
6205 ASSERT_EQUAL_64(3, x10);
6206 ASSERT_EQUAL_64(0, x11);
6207 ASSERT_EQUAL_64(0xffffffff, x12);
6208 ASSERT_EQUAL_64(0, x13);
6209 ASSERT_EQUAL_64(0xfffffffe, x14);
6210 ASSERT_EQUAL_64(1, x16);
6211 ASSERT_EQUAL_64(1, x17);
6212 ASSERT_EQUAL_64(3, x18);
6213 ASSERT_EQUAL_64(0, x19);
6214 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6215 ASSERT_EQUAL_64(0, x21);
6216 ASSERT_EQUAL_64(0xffffff0000000000, x22);
6217 ASSERT_EQUAL_64(1, x24);
6218 ASSERT_EQUAL_64(3, x25);
6219 ASSERT_EQUAL_64(0, x26);
6220 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6221 ASSERT_EQUAL_64(0, x28);
6222 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
6223 ASSERT_EQUAL_64(0xffffffff, x30);
6224
6225 TEARDOWN();
6226 }
6227
6228
TEST(fcvtms)6229 TEST(fcvtms) {
6230 SETUP();
6231
6232 START();
6233 __ Fmov(s0, 1.0);
6234 __ Fmov(s1, 1.1);
6235 __ Fmov(s2, 1.5);
6236 __ Fmov(s3, -1.5);
6237 __ Fmov(s4, kFP32PositiveInfinity);
6238 __ Fmov(s5, kFP32NegativeInfinity);
6239 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6240 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
6241 __ Fmov(d8, 1.0);
6242 __ Fmov(d9, 1.1);
6243 __ Fmov(d10, 1.5);
6244 __ Fmov(d11, -1.5);
6245 __ Fmov(d12, kFP64PositiveInfinity);
6246 __ Fmov(d13, kFP64NegativeInfinity);
6247 __ Fmov(d14, kWMaxInt - 1);
6248 __ Fmov(d15, kWMinInt + 1);
6249 __ Fmov(s17, 1.1);
6250 __ Fmov(s18, 1.5);
6251 __ Fmov(s19, -1.5);
6252 __ Fmov(s20, kFP32PositiveInfinity);
6253 __ Fmov(s21, kFP32NegativeInfinity);
6254 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6255 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
6256 __ Fmov(d24, 1.1);
6257 __ Fmov(d25, 1.5);
6258 __ Fmov(d26, -1.5);
6259 __ Fmov(d27, kFP64PositiveInfinity);
6260 __ Fmov(d28, kFP64NegativeInfinity);
6261 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6262 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
6263
6264 __ Fcvtms(w0, s0);
6265 __ Fcvtms(w1, s1);
6266 __ Fcvtms(w2, s2);
6267 __ Fcvtms(w3, s3);
6268 __ Fcvtms(w4, s4);
6269 __ Fcvtms(w5, s5);
6270 __ Fcvtms(w6, s6);
6271 __ Fcvtms(w7, s7);
6272 __ Fcvtms(w8, d8);
6273 __ Fcvtms(w9, d9);
6274 __ Fcvtms(w10, d10);
6275 __ Fcvtms(w11, d11);
6276 __ Fcvtms(w12, d12);
6277 __ Fcvtms(w13, d13);
6278 __ Fcvtms(w14, d14);
6279 __ Fcvtms(w15, d15);
6280 __ Fcvtms(x17, s17);
6281 __ Fcvtms(x18, s18);
6282 __ Fcvtms(x19, s19);
6283 __ Fcvtms(x20, s20);
6284 __ Fcvtms(x21, s21);
6285 __ Fcvtms(x22, s22);
6286 __ Fcvtms(x23, s23);
6287 __ Fcvtms(x24, d24);
6288 __ Fcvtms(x25, d25);
6289 __ Fcvtms(x26, d26);
6290 __ Fcvtms(x27, d27);
6291 __ Fcvtms(x28, d28);
6292 __ Fcvtms(x29, d29);
6293 __ Fcvtms(x30, d30);
6294 END();
6295
6296 RUN();
6297
6298 ASSERT_EQUAL_64(1, x0);
6299 ASSERT_EQUAL_64(1, x1);
6300 ASSERT_EQUAL_64(1, x2);
6301 ASSERT_EQUAL_64(0xfffffffe, x3);
6302 ASSERT_EQUAL_64(0x7fffffff, x4);
6303 ASSERT_EQUAL_64(0x80000000, x5);
6304 ASSERT_EQUAL_64(0x7fffff80, x6);
6305 ASSERT_EQUAL_64(0x80000080, x7);
6306 ASSERT_EQUAL_64(1, x8);
6307 ASSERT_EQUAL_64(1, x9);
6308 ASSERT_EQUAL_64(1, x10);
6309 ASSERT_EQUAL_64(0xfffffffe, x11);
6310 ASSERT_EQUAL_64(0x7fffffff, x12);
6311 ASSERT_EQUAL_64(0x80000000, x13);
6312 ASSERT_EQUAL_64(0x7ffffffe, x14);
6313 ASSERT_EQUAL_64(0x80000001, x15);
6314 ASSERT_EQUAL_64(1, x17);
6315 ASSERT_EQUAL_64(1, x18);
6316 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
6317 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6318 ASSERT_EQUAL_64(0x8000000000000000, x21);
6319 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6320 ASSERT_EQUAL_64(0x8000008000000000, x23);
6321 ASSERT_EQUAL_64(1, x24);
6322 ASSERT_EQUAL_64(1, x25);
6323 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
6324 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6325 ASSERT_EQUAL_64(0x8000000000000000, x28);
6326 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6327 ASSERT_EQUAL_64(0x8000000000000400, x30);
6328
6329 TEARDOWN();
6330 }
6331
6332
TEST(fcvtmu)6333 TEST(fcvtmu) {
6334 SETUP();
6335
6336 START();
6337 __ Fmov(s0, 1.0);
6338 __ Fmov(s1, 1.1);
6339 __ Fmov(s2, 1.5);
6340 __ Fmov(s3, -1.5);
6341 __ Fmov(s4, kFP32PositiveInfinity);
6342 __ Fmov(s5, kFP32NegativeInfinity);
6343 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6344 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
6345 __ Fmov(d8, 1.0);
6346 __ Fmov(d9, 1.1);
6347 __ Fmov(d10, 1.5);
6348 __ Fmov(d11, -1.5);
6349 __ Fmov(d12, kFP64PositiveInfinity);
6350 __ Fmov(d13, kFP64NegativeInfinity);
6351 __ Fmov(d14, kWMaxInt - 1);
6352 __ Fmov(d15, kWMinInt + 1);
6353 __ Fmov(s17, 1.1);
6354 __ Fmov(s18, 1.5);
6355 __ Fmov(s19, -1.5);
6356 __ Fmov(s20, kFP32PositiveInfinity);
6357 __ Fmov(s21, kFP32NegativeInfinity);
6358 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6359 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
6360 __ Fmov(d24, 1.1);
6361 __ Fmov(d25, 1.5);
6362 __ Fmov(d26, -1.5);
6363 __ Fmov(d27, kFP64PositiveInfinity);
6364 __ Fmov(d28, kFP64NegativeInfinity);
6365 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6366 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
6367
6368 __ Fcvtmu(w0, s0);
6369 __ Fcvtmu(w1, s1);
6370 __ Fcvtmu(w2, s2);
6371 __ Fcvtmu(w3, s3);
6372 __ Fcvtmu(w4, s4);
6373 __ Fcvtmu(w5, s5);
6374 __ Fcvtmu(w6, s6);
6375 __ Fcvtmu(w7, s7);
6376 __ Fcvtmu(w8, d8);
6377 __ Fcvtmu(w9, d9);
6378 __ Fcvtmu(w10, d10);
6379 __ Fcvtmu(w11, d11);
6380 __ Fcvtmu(w12, d12);
6381 __ Fcvtmu(w13, d13);
6382 __ Fcvtmu(w14, d14);
6383 __ Fcvtmu(x17, s17);
6384 __ Fcvtmu(x18, s18);
6385 __ Fcvtmu(x19, s19);
6386 __ Fcvtmu(x20, s20);
6387 __ Fcvtmu(x21, s21);
6388 __ Fcvtmu(x22, s22);
6389 __ Fcvtmu(x23, s23);
6390 __ Fcvtmu(x24, d24);
6391 __ Fcvtmu(x25, d25);
6392 __ Fcvtmu(x26, d26);
6393 __ Fcvtmu(x27, d27);
6394 __ Fcvtmu(x28, d28);
6395 __ Fcvtmu(x29, d29);
6396 __ Fcvtmu(x30, d30);
6397 END();
6398
6399 RUN();
6400
6401 ASSERT_EQUAL_64(1, x0);
6402 ASSERT_EQUAL_64(1, x1);
6403 ASSERT_EQUAL_64(1, x2);
6404 ASSERT_EQUAL_64(0, x3);
6405 ASSERT_EQUAL_64(0xffffffff, x4);
6406 ASSERT_EQUAL_64(0, x5);
6407 ASSERT_EQUAL_64(0x7fffff80, x6);
6408 ASSERT_EQUAL_64(0, x7);
6409 ASSERT_EQUAL_64(1, x8);
6410 ASSERT_EQUAL_64(1, x9);
6411 ASSERT_EQUAL_64(1, x10);
6412 ASSERT_EQUAL_64(0, x11);
6413 ASSERT_EQUAL_64(0xffffffff, x12);
6414 ASSERT_EQUAL_64(0, x13);
6415 ASSERT_EQUAL_64(0x7ffffffe, x14);
6416 ASSERT_EQUAL_64(1, x17);
6417 ASSERT_EQUAL_64(1, x18);
6418 ASSERT_EQUAL_64(0, x19);
6419 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6420 ASSERT_EQUAL_64(0, x21);
6421 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6422 ASSERT_EQUAL_64(0, x23);
6423 ASSERT_EQUAL_64(1, x24);
6424 ASSERT_EQUAL_64(1, x25);
6425 ASSERT_EQUAL_64(0, x26);
6426 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6427 ASSERT_EQUAL_64(0, x28);
6428 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6429 ASSERT_EQUAL_64(0, x30);
6430
6431 TEARDOWN();
6432 }
6433
6434
TEST(fcvtns)6435 TEST(fcvtns) {
6436 SETUP();
6437
6438 START();
6439 __ Fmov(s0, 1.0);
6440 __ Fmov(s1, 1.1);
6441 __ Fmov(s2, 1.5);
6442 __ Fmov(s3, -1.5);
6443 __ Fmov(s4, kFP32PositiveInfinity);
6444 __ Fmov(s5, kFP32NegativeInfinity);
6445 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6446 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
6447 __ Fmov(d8, 1.0);
6448 __ Fmov(d9, 1.1);
6449 __ Fmov(d10, 1.5);
6450 __ Fmov(d11, -1.5);
6451 __ Fmov(d12, kFP64PositiveInfinity);
6452 __ Fmov(d13, kFP64NegativeInfinity);
6453 __ Fmov(d14, kWMaxInt - 1);
6454 __ Fmov(d15, kWMinInt + 1);
6455 __ Fmov(s17, 1.1);
6456 __ Fmov(s18, 1.5);
6457 __ Fmov(s19, -1.5);
6458 __ Fmov(s20, kFP32PositiveInfinity);
6459 __ Fmov(s21, kFP32NegativeInfinity);
6460 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6461 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
6462 __ Fmov(d24, 1.1);
6463 __ Fmov(d25, 1.5);
6464 __ Fmov(d26, -1.5);
6465 __ Fmov(d27, kFP64PositiveInfinity);
6466 __ Fmov(d28, kFP64NegativeInfinity);
6467 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6468 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
6469
6470 __ Fcvtns(w0, s0);
6471 __ Fcvtns(w1, s1);
6472 __ Fcvtns(w2, s2);
6473 __ Fcvtns(w3, s3);
6474 __ Fcvtns(w4, s4);
6475 __ Fcvtns(w5, s5);
6476 __ Fcvtns(w6, s6);
6477 __ Fcvtns(w7, s7);
6478 __ Fcvtns(w8, d8);
6479 __ Fcvtns(w9, d9);
6480 __ Fcvtns(w10, d10);
6481 __ Fcvtns(w11, d11);
6482 __ Fcvtns(w12, d12);
6483 __ Fcvtns(w13, d13);
6484 __ Fcvtns(w14, d14);
6485 __ Fcvtns(w15, d15);
6486 __ Fcvtns(x17, s17);
6487 __ Fcvtns(x18, s18);
6488 __ Fcvtns(x19, s19);
6489 __ Fcvtns(x20, s20);
6490 __ Fcvtns(x21, s21);
6491 __ Fcvtns(x22, s22);
6492 __ Fcvtns(x23, s23);
6493 __ Fcvtns(x24, d24);
6494 __ Fcvtns(x25, d25);
6495 __ Fcvtns(x26, d26);
6496 __ Fcvtns(x27, d27);
6497 __ Fcvtns(x28, d28);
6498 __ Fcvtns(x29, d29);
6499 __ Fcvtns(x30, d30);
6500 END();
6501
6502 RUN();
6503
6504 ASSERT_EQUAL_64(1, x0);
6505 ASSERT_EQUAL_64(1, x1);
6506 ASSERT_EQUAL_64(2, x2);
6507 ASSERT_EQUAL_64(0xfffffffe, x3);
6508 ASSERT_EQUAL_64(0x7fffffff, x4);
6509 ASSERT_EQUAL_64(0x80000000, x5);
6510 ASSERT_EQUAL_64(0x7fffff80, x6);
6511 ASSERT_EQUAL_64(0x80000080, x7);
6512 ASSERT_EQUAL_64(1, x8);
6513 ASSERT_EQUAL_64(1, x9);
6514 ASSERT_EQUAL_64(2, x10);
6515 ASSERT_EQUAL_64(0xfffffffe, x11);
6516 ASSERT_EQUAL_64(0x7fffffff, x12);
6517 ASSERT_EQUAL_64(0x80000000, x13);
6518 ASSERT_EQUAL_64(0x7ffffffe, x14);
6519 ASSERT_EQUAL_64(0x80000001, x15);
6520 ASSERT_EQUAL_64(1, x17);
6521 ASSERT_EQUAL_64(2, x18);
6522 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
6523 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6524 ASSERT_EQUAL_64(0x8000000000000000, x21);
6525 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6526 ASSERT_EQUAL_64(0x8000008000000000, x23);
6527 ASSERT_EQUAL_64(1, x24);
6528 ASSERT_EQUAL_64(2, x25);
6529 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
6530 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6531 ASSERT_EQUAL_64(0x8000000000000000, x28);
6532 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6533 ASSERT_EQUAL_64(0x8000000000000400, x30);
6534
6535 TEARDOWN();
6536 }
6537
6538
TEST(fcvtnu)6539 TEST(fcvtnu) {
6540 SETUP();
6541
6542 START();
6543 __ Fmov(s0, 1.0);
6544 __ Fmov(s1, 1.1);
6545 __ Fmov(s2, 1.5);
6546 __ Fmov(s3, -1.5);
6547 __ Fmov(s4, kFP32PositiveInfinity);
6548 __ Fmov(s5, kFP32NegativeInfinity);
6549 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
6550 __ Fmov(d8, 1.0);
6551 __ Fmov(d9, 1.1);
6552 __ Fmov(d10, 1.5);
6553 __ Fmov(d11, -1.5);
6554 __ Fmov(d12, kFP64PositiveInfinity);
6555 __ Fmov(d13, kFP64NegativeInfinity);
6556 __ Fmov(d14, 0xfffffffe);
6557 __ Fmov(s16, 1.0);
6558 __ Fmov(s17, 1.1);
6559 __ Fmov(s18, 1.5);
6560 __ Fmov(s19, -1.5);
6561 __ Fmov(s20, kFP32PositiveInfinity);
6562 __ Fmov(s21, kFP32NegativeInfinity);
6563 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
6564 __ Fmov(d24, 1.1);
6565 __ Fmov(d25, 1.5);
6566 __ Fmov(d26, -1.5);
6567 __ Fmov(d27, kFP64PositiveInfinity);
6568 __ Fmov(d28, kFP64NegativeInfinity);
6569 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
6570 __ Fmov(s30, 0x100000000);
6571
6572 __ Fcvtnu(w0, s0);
6573 __ Fcvtnu(w1, s1);
6574 __ Fcvtnu(w2, s2);
6575 __ Fcvtnu(w3, s3);
6576 __ Fcvtnu(w4, s4);
6577 __ Fcvtnu(w5, s5);
6578 __ Fcvtnu(w6, s6);
6579 __ Fcvtnu(w8, d8);
6580 __ Fcvtnu(w9, d9);
6581 __ Fcvtnu(w10, d10);
6582 __ Fcvtnu(w11, d11);
6583 __ Fcvtnu(w12, d12);
6584 __ Fcvtnu(w13, d13);
6585 __ Fcvtnu(w14, d14);
6586 __ Fcvtnu(w15, d15);
6587 __ Fcvtnu(x16, s16);
6588 __ Fcvtnu(x17, s17);
6589 __ Fcvtnu(x18, s18);
6590 __ Fcvtnu(x19, s19);
6591 __ Fcvtnu(x20, s20);
6592 __ Fcvtnu(x21, s21);
6593 __ Fcvtnu(x22, s22);
6594 __ Fcvtnu(x24, d24);
6595 __ Fcvtnu(x25, d25);
6596 __ Fcvtnu(x26, d26);
6597 __ Fcvtnu(x27, d27);
6598 __ Fcvtnu(x28, d28);
6599 __ Fcvtnu(x29, d29);
6600 __ Fcvtnu(w30, s30);
6601 END();
6602
6603 RUN();
6604
6605 ASSERT_EQUAL_64(1, x0);
6606 ASSERT_EQUAL_64(1, x1);
6607 ASSERT_EQUAL_64(2, x2);
6608 ASSERT_EQUAL_64(0, x3);
6609 ASSERT_EQUAL_64(0xffffffff, x4);
6610 ASSERT_EQUAL_64(0, x5);
6611 ASSERT_EQUAL_64(0xffffff00, x6);
6612 ASSERT_EQUAL_64(1, x8);
6613 ASSERT_EQUAL_64(1, x9);
6614 ASSERT_EQUAL_64(2, x10);
6615 ASSERT_EQUAL_64(0, x11);
6616 ASSERT_EQUAL_64(0xffffffff, x12);
6617 ASSERT_EQUAL_64(0, x13);
6618 ASSERT_EQUAL_64(0xfffffffe, x14);
6619 ASSERT_EQUAL_64(1, x16);
6620 ASSERT_EQUAL_64(1, x17);
6621 ASSERT_EQUAL_64(2, x18);
6622 ASSERT_EQUAL_64(0, x19);
6623 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6624 ASSERT_EQUAL_64(0, x21);
6625 ASSERT_EQUAL_64(0xffffff0000000000, x22);
6626 ASSERT_EQUAL_64(1, x24);
6627 ASSERT_EQUAL_64(2, x25);
6628 ASSERT_EQUAL_64(0, x26);
6629 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6630 ASSERT_EQUAL_64(0, x28);
6631 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
6632 ASSERT_EQUAL_64(0xffffffff, x30);
6633
6634 TEARDOWN();
6635 }
6636
6637
TEST(fcvtzs)6638 TEST(fcvtzs) {
6639 SETUP();
6640
6641 START();
6642 __ Fmov(s0, 1.0);
6643 __ Fmov(s1, 1.1);
6644 __ Fmov(s2, 1.5);
6645 __ Fmov(s3, -1.5);
6646 __ Fmov(s4, kFP32PositiveInfinity);
6647 __ Fmov(s5, kFP32NegativeInfinity);
6648 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6649 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
6650 __ Fmov(d8, 1.0);
6651 __ Fmov(d9, 1.1);
6652 __ Fmov(d10, 1.5);
6653 __ Fmov(d11, -1.5);
6654 __ Fmov(d12, kFP64PositiveInfinity);
6655 __ Fmov(d13, kFP64NegativeInfinity);
6656 __ Fmov(d14, kWMaxInt - 1);
6657 __ Fmov(d15, kWMinInt + 1);
6658 __ Fmov(s17, 1.1);
6659 __ Fmov(s18, 1.5);
6660 __ Fmov(s19, -1.5);
6661 __ Fmov(s20, kFP32PositiveInfinity);
6662 __ Fmov(s21, kFP32NegativeInfinity);
6663 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6664 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
6665 __ Fmov(d24, 1.1);
6666 __ Fmov(d25, 1.5);
6667 __ Fmov(d26, -1.5);
6668 __ Fmov(d27, kFP64PositiveInfinity);
6669 __ Fmov(d28, kFP64NegativeInfinity);
6670 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6671 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
6672
6673 __ Fcvtzs(w0, s0);
6674 __ Fcvtzs(w1, s1);
6675 __ Fcvtzs(w2, s2);
6676 __ Fcvtzs(w3, s3);
6677 __ Fcvtzs(w4, s4);
6678 __ Fcvtzs(w5, s5);
6679 __ Fcvtzs(w6, s6);
6680 __ Fcvtzs(w7, s7);
6681 __ Fcvtzs(w8, d8);
6682 __ Fcvtzs(w9, d9);
6683 __ Fcvtzs(w10, d10);
6684 __ Fcvtzs(w11, d11);
6685 __ Fcvtzs(w12, d12);
6686 __ Fcvtzs(w13, d13);
6687 __ Fcvtzs(w14, d14);
6688 __ Fcvtzs(w15, d15);
6689 __ Fcvtzs(x17, s17);
6690 __ Fcvtzs(x18, s18);
6691 __ Fcvtzs(x19, s19);
6692 __ Fcvtzs(x20, s20);
6693 __ Fcvtzs(x21, s21);
6694 __ Fcvtzs(x22, s22);
6695 __ Fcvtzs(x23, s23);
6696 __ Fcvtzs(x24, d24);
6697 __ Fcvtzs(x25, d25);
6698 __ Fcvtzs(x26, d26);
6699 __ Fcvtzs(x27, d27);
6700 __ Fcvtzs(x28, d28);
6701 __ Fcvtzs(x29, d29);
6702 __ Fcvtzs(x30, d30);
6703 END();
6704
6705 RUN();
6706
6707 ASSERT_EQUAL_64(1, x0);
6708 ASSERT_EQUAL_64(1, x1);
6709 ASSERT_EQUAL_64(1, x2);
6710 ASSERT_EQUAL_64(0xffffffff, x3);
6711 ASSERT_EQUAL_64(0x7fffffff, x4);
6712 ASSERT_EQUAL_64(0x80000000, x5);
6713 ASSERT_EQUAL_64(0x7fffff80, x6);
6714 ASSERT_EQUAL_64(0x80000080, x7);
6715 ASSERT_EQUAL_64(1, x8);
6716 ASSERT_EQUAL_64(1, x9);
6717 ASSERT_EQUAL_64(1, x10);
6718 ASSERT_EQUAL_64(0xffffffff, x11);
6719 ASSERT_EQUAL_64(0x7fffffff, x12);
6720 ASSERT_EQUAL_64(0x80000000, x13);
6721 ASSERT_EQUAL_64(0x7ffffffe, x14);
6722 ASSERT_EQUAL_64(0x80000001, x15);
6723 ASSERT_EQUAL_64(1, x17);
6724 ASSERT_EQUAL_64(1, x18);
6725 ASSERT_EQUAL_64(0xffffffffffffffff, x19);
6726 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6727 ASSERT_EQUAL_64(0x8000000000000000, x21);
6728 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6729 ASSERT_EQUAL_64(0x8000008000000000, x23);
6730 ASSERT_EQUAL_64(1, x24);
6731 ASSERT_EQUAL_64(1, x25);
6732 ASSERT_EQUAL_64(0xffffffffffffffff, x26);
6733 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6734 ASSERT_EQUAL_64(0x8000000000000000, x28);
6735 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6736 ASSERT_EQUAL_64(0x8000000000000400, x30);
6737
6738 TEARDOWN();
6739 }
6740
TEST(fcvtzu)6741 TEST(fcvtzu) {
6742 SETUP();
6743
6744 START();
6745 __ Fmov(s0, 1.0);
6746 __ Fmov(s1, 1.1);
6747 __ Fmov(s2, 1.5);
6748 __ Fmov(s3, -1.5);
6749 __ Fmov(s4, kFP32PositiveInfinity);
6750 __ Fmov(s5, kFP32NegativeInfinity);
6751 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6752 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
6753 __ Fmov(d8, 1.0);
6754 __ Fmov(d9, 1.1);
6755 __ Fmov(d10, 1.5);
6756 __ Fmov(d11, -1.5);
6757 __ Fmov(d12, kFP64PositiveInfinity);
6758 __ Fmov(d13, kFP64NegativeInfinity);
6759 __ Fmov(d14, kWMaxInt - 1);
6760 __ Fmov(d15, kWMinInt + 1);
6761 __ Fmov(s17, 1.1);
6762 __ Fmov(s18, 1.5);
6763 __ Fmov(s19, -1.5);
6764 __ Fmov(s20, kFP32PositiveInfinity);
6765 __ Fmov(s21, kFP32NegativeInfinity);
6766 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6767 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
6768 __ Fmov(d24, 1.1);
6769 __ Fmov(d25, 1.5);
6770 __ Fmov(d26, -1.5);
6771 __ Fmov(d27, kFP64PositiveInfinity);
6772 __ Fmov(d28, kFP64NegativeInfinity);
6773 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6774 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
6775
6776 __ Fcvtzu(w0, s0);
6777 __ Fcvtzu(w1, s1);
6778 __ Fcvtzu(w2, s2);
6779 __ Fcvtzu(w3, s3);
6780 __ Fcvtzu(w4, s4);
6781 __ Fcvtzu(w5, s5);
6782 __ Fcvtzu(w6, s6);
6783 __ Fcvtzu(w7, s7);
6784 __ Fcvtzu(w8, d8);
6785 __ Fcvtzu(w9, d9);
6786 __ Fcvtzu(w10, d10);
6787 __ Fcvtzu(w11, d11);
6788 __ Fcvtzu(w12, d12);
6789 __ Fcvtzu(w13, d13);
6790 __ Fcvtzu(w14, d14);
6791 __ Fcvtzu(x17, s17);
6792 __ Fcvtzu(x18, s18);
6793 __ Fcvtzu(x19, s19);
6794 __ Fcvtzu(x20, s20);
6795 __ Fcvtzu(x21, s21);
6796 __ Fcvtzu(x22, s22);
6797 __ Fcvtzu(x23, s23);
6798 __ Fcvtzu(x24, d24);
6799 __ Fcvtzu(x25, d25);
6800 __ Fcvtzu(x26, d26);
6801 __ Fcvtzu(x27, d27);
6802 __ Fcvtzu(x28, d28);
6803 __ Fcvtzu(x29, d29);
6804 __ Fcvtzu(x30, d30);
6805 END();
6806
6807 RUN();
6808
6809 ASSERT_EQUAL_64(1, x0);
6810 ASSERT_EQUAL_64(1, x1);
6811 ASSERT_EQUAL_64(1, x2);
6812 ASSERT_EQUAL_64(0, x3);
6813 ASSERT_EQUAL_64(0xffffffff, x4);
6814 ASSERT_EQUAL_64(0, x5);
6815 ASSERT_EQUAL_64(0x7fffff80, x6);
6816 ASSERT_EQUAL_64(0, x7);
6817 ASSERT_EQUAL_64(1, x8);
6818 ASSERT_EQUAL_64(1, x9);
6819 ASSERT_EQUAL_64(1, x10);
6820 ASSERT_EQUAL_64(0, x11);
6821 ASSERT_EQUAL_64(0xffffffff, x12);
6822 ASSERT_EQUAL_64(0, x13);
6823 ASSERT_EQUAL_64(0x7ffffffe, x14);
6824 ASSERT_EQUAL_64(1, x17);
6825 ASSERT_EQUAL_64(1, x18);
6826 ASSERT_EQUAL_64(0, x19);
6827 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6828 ASSERT_EQUAL_64(0, x21);
6829 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6830 ASSERT_EQUAL_64(0, x23);
6831 ASSERT_EQUAL_64(1, x24);
6832 ASSERT_EQUAL_64(1, x25);
6833 ASSERT_EQUAL_64(0, x26);
6834 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6835 ASSERT_EQUAL_64(0, x28);
6836 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6837 ASSERT_EQUAL_64(0, x30);
6838
6839 TEARDOWN();
6840 }
6841
6842
6843 // Test that scvtf and ucvtf can convert the 64-bit input into the expected
6844 // value. All possible values of 'fbits' are tested. The expected value is
6845 // modified accordingly in each case.
6846 //
6847 // The expected value is specified as the bit encoding of the expected double
6848 // produced by scvtf (expected_scvtf_bits) as well as ucvtf
6849 // (expected_ucvtf_bits).
6850 //
6851 // Where the input value is representable by int32_t or uint32_t, conversions
6852 // from W registers will also be tested.
TestUScvtfHelper(uint64_t in,uint64_t expected_scvtf_bits,uint64_t expected_ucvtf_bits)6853 static void TestUScvtfHelper(uint64_t in,
6854 uint64_t expected_scvtf_bits,
6855 uint64_t expected_ucvtf_bits) {
6856 uint64_t u64 = in;
6857 uint32_t u32 = u64 & 0xffffffff;
6858 int64_t s64 = static_cast<int64_t>(in);
6859 int32_t s32 = s64 & 0x7fffffff;
6860
6861 bool cvtf_s32 = (s64 == s32);
6862 bool cvtf_u32 = (u64 == u32);
6863
6864 double results_scvtf_x[65];
6865 double results_ucvtf_x[65];
6866 double results_scvtf_w[33];
6867 double results_ucvtf_w[33];
6868
6869 SETUP();
6870 START();
6871
6872 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
6873 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
6874 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
6875 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
6876
6877 __ Mov(x10, s64);
6878
6879 // Corrupt the top word, in case it is accidentally used during W-register
6880 // conversions.
6881 __ Mov(x11, 0x5555555555555555);
6882 __ Bfi(x11, x10, 0, kWRegSize);
6883
6884 // Test integer conversions.
6885 __ Scvtf(d0, x10);
6886 __ Ucvtf(d1, x10);
6887 __ Scvtf(d2, w11);
6888 __ Ucvtf(d3, w11);
6889 __ Str(d0, MemOperand(x0));
6890 __ Str(d1, MemOperand(x1));
6891 __ Str(d2, MemOperand(x2));
6892 __ Str(d3, MemOperand(x3));
6893
6894 // Test all possible values of fbits.
6895 for (int fbits = 1; fbits <= 32; fbits++) {
6896 __ Scvtf(d0, x10, fbits);
6897 __ Ucvtf(d1, x10, fbits);
6898 __ Scvtf(d2, w11, fbits);
6899 __ Ucvtf(d3, w11, fbits);
6900 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
6901 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
6902 __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes));
6903 __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes));
6904 }
6905
6906 // Conversions from W registers can only handle fbits values <= 32, so just
6907 // test conversions from X registers for 32 < fbits <= 64.
6908 for (int fbits = 33; fbits <= 64; fbits++) {
6909 __ Scvtf(d0, x10, fbits);
6910 __ Ucvtf(d1, x10, fbits);
6911 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
6912 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
6913 }
6914
6915 END();
6916 RUN();
6917
6918 // Check the results.
6919 double expected_scvtf_base = rawbits_to_double(expected_scvtf_bits);
6920 double expected_ucvtf_base = rawbits_to_double(expected_ucvtf_bits);
6921
6922 for (int fbits = 0; fbits <= 32; fbits++) {
6923 double expected_scvtf = expected_scvtf_base / pow(2, fbits);
6924 double expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
6925 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
6926 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
6927 if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
6928 if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
6929 }
6930 for (int fbits = 33; fbits <= 64; fbits++) {
6931 double expected_scvtf = expected_scvtf_base / pow(2, fbits);
6932 double expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
6933 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
6934 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
6935 }
6936
6937 TEARDOWN();
6938 }
6939
6940
TEST(scvtf_ucvtf_double)6941 TEST(scvtf_ucvtf_double) {
6942 // Simple conversions of positive numbers which require no rounding; the
6943 // results should not depened on the rounding mode, and ucvtf and scvtf should
6944 // produce the same result.
6945 TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000);
6946 TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000);
6947 TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000);
6948 TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000);
6949 TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000);
6950 // Test mantissa extremities.
6951 TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001);
6952 // The largest int32_t that fits in a double.
6953 TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000);
6954 // Values that would be negative if treated as an int32_t.
6955 TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000);
6956 TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000);
6957 TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000);
6958 // The largest int64_t that fits in a double.
6959 TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff);
6960 // Check for bit pattern reproduction.
6961 TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde);
6962 TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000);
6963
6964 // Simple conversions of negative int64_t values. These require no rounding,
6965 // and the results should not depend on the rounding mode.
6966 TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000);
6967 TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000);
6968 TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000);
6969
6970 // Conversions which require rounding.
6971 TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000);
6972 TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000);
6973 TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000);
6974 TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001);
6975 TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001);
6976 TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001);
6977 TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002);
6978 TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002);
6979 TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002);
6980 TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002);
6981 TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002);
6982 TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003);
6983 TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003);
6984 // Check rounding of negative int64_t values (and large uint64_t values).
6985 TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000);
6986 TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000);
6987 TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000);
6988 TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000);
6989 TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000);
6990 TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001);
6991 TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001);
6992 TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001);
6993 TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001);
6994 TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001);
6995 TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001);
6996 TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001);
6997 TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002);
6998 // Round up to produce a result that's too big for the input to represent.
6999 TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000);
7000 TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000);
7001 TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000);
7002 TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000);
7003 }
7004
7005
7006 // The same as TestUScvtfHelper, but convert to floats.
TestUScvtf32Helper(uint64_t in,uint32_t expected_scvtf_bits,uint32_t expected_ucvtf_bits)7007 static void TestUScvtf32Helper(uint64_t in,
7008 uint32_t expected_scvtf_bits,
7009 uint32_t expected_ucvtf_bits) {
7010 uint64_t u64 = in;
7011 uint32_t u32 = u64 & 0xffffffff;
7012 int64_t s64 = static_cast<int64_t>(in);
7013 int32_t s32 = s64 & 0x7fffffff;
7014
7015 bool cvtf_s32 = (s64 == s32);
7016 bool cvtf_u32 = (u64 == u32);
7017
7018 float results_scvtf_x[65];
7019 float results_ucvtf_x[65];
7020 float results_scvtf_w[33];
7021 float results_ucvtf_w[33];
7022
7023 SETUP();
7024 START();
7025
7026 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
7027 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
7028 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
7029 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
7030
7031 __ Mov(x10, s64);
7032
7033 // Corrupt the top word, in case it is accidentally used during W-register
7034 // conversions.
7035 __ Mov(x11, 0x5555555555555555);
7036 __ Bfi(x11, x10, 0, kWRegSize);
7037
7038 // Test integer conversions.
7039 __ Scvtf(s0, x10);
7040 __ Ucvtf(s1, x10);
7041 __ Scvtf(s2, w11);
7042 __ Ucvtf(s3, w11);
7043 __ Str(s0, MemOperand(x0));
7044 __ Str(s1, MemOperand(x1));
7045 __ Str(s2, MemOperand(x2));
7046 __ Str(s3, MemOperand(x3));
7047
7048 // Test all possible values of fbits.
7049 for (int fbits = 1; fbits <= 32; fbits++) {
7050 __ Scvtf(s0, x10, fbits);
7051 __ Ucvtf(s1, x10, fbits);
7052 __ Scvtf(s2, w11, fbits);
7053 __ Ucvtf(s3, w11, fbits);
7054 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
7055 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
7056 __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes));
7057 __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes));
7058 }
7059
7060 // Conversions from W registers can only handle fbits values <= 32, so just
7061 // test conversions from X registers for 32 < fbits <= 64.
7062 for (int fbits = 33; fbits <= 64; fbits++) {
7063 __ Scvtf(s0, x10, fbits);
7064 __ Ucvtf(s1, x10, fbits);
7065 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
7066 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
7067 }
7068
7069 END();
7070 RUN();
7071
7072 // Check the results.
7073 float expected_scvtf_base = rawbits_to_float(expected_scvtf_bits);
7074 float expected_ucvtf_base = rawbits_to_float(expected_ucvtf_bits);
7075
7076 for (int fbits = 0; fbits <= 32; fbits++) {
7077 float expected_scvtf = expected_scvtf_base / powf(2, fbits);
7078 float expected_ucvtf = expected_ucvtf_base / powf(2, fbits);
7079 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
7080 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
7081 if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
7082 if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
7083 break;
7084 }
7085 for (int fbits = 33; fbits <= 64; fbits++) {
7086 break;
7087 float expected_scvtf = expected_scvtf_base / powf(2, fbits);
7088 float expected_ucvtf = expected_ucvtf_base / powf(2, fbits);
7089 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
7090 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
7091 }
7092
7093 TEARDOWN();
7094 }
7095
7096
TEST(scvtf_ucvtf_float)7097 TEST(scvtf_ucvtf_float) {
7098 // Simple conversions of positive numbers which require no rounding; the
7099 // results should not depened on the rounding mode, and ucvtf and scvtf should
7100 // produce the same result.
7101 TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000);
7102 TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000);
7103 TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000);
7104 TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000);
7105 TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000);
7106 // Test mantissa extremities.
7107 TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001);
7108 TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001);
7109 // The largest int32_t that fits in a float.
7110 TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff);
7111 // Values that would be negative if treated as an int32_t.
7112 TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff);
7113 TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000);
7114 TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001);
7115 // The largest int64_t that fits in a float.
7116 TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff);
7117 // Check for bit pattern reproduction.
7118 TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543);
7119
7120 // Simple conversions of negative int64_t values. These require no rounding,
7121 // and the results should not depend on the rounding mode.
7122 TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc);
7123 TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000);
7124
7125 // Conversions which require rounding.
7126 TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000);
7127 TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000);
7128 TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000);
7129 TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001);
7130 TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001);
7131 TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001);
7132 TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002);
7133 TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002);
7134 TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002);
7135 TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002);
7136 TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002);
7137 TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003);
7138 TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003);
7139 // Check rounding of negative int64_t values (and large uint64_t values).
7140 TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000);
7141 TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000);
7142 TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000);
7143 TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000);
7144 TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000);
7145 TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001);
7146 TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001);
7147 TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001);
7148 TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001);
7149 TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001);
7150 TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001);
7151 TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001);
7152 TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002);
7153 // Round up to produce a result that's too big for the input to represent.
7154 TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000);
7155 TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000);
7156 TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000);
7157 TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000);
7158 TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000);
7159 TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000);
7160 TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000);
7161 TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000);
7162 }
7163
7164
TEST(system_mrs)7165 TEST(system_mrs) {
7166 SETUP();
7167
7168 START();
7169 __ Mov(w0, 0);
7170 __ Mov(w1, 1);
7171 __ Mov(w2, 0x80000000);
7172
7173 // Set the Z and C flags.
7174 __ Cmp(w0, w0);
7175 __ Mrs(x3, NZCV);
7176
7177 // Set the N flag.
7178 __ Cmp(w0, w1);
7179 __ Mrs(x4, NZCV);
7180
7181 // Set the Z, C and V flags.
7182 __ Adds(w0, w2, w2);
7183 __ Mrs(x5, NZCV);
7184
7185 // Read the default FPCR.
7186 __ Mrs(x6, FPCR);
7187 END();
7188
7189 RUN();
7190
7191 // NZCV
7192 ASSERT_EQUAL_32(ZCFlag, w3);
7193 ASSERT_EQUAL_32(NFlag, w4);
7194 ASSERT_EQUAL_32(ZCVFlag, w5);
7195
7196 // FPCR
7197 // The default FPCR on Linux-based platforms is 0.
7198 ASSERT_EQUAL_32(0, w6);
7199
7200 TEARDOWN();
7201 }
7202
7203
TEST(system_msr)7204 TEST(system_msr) {
7205 // All FPCR fields that must be implemented: AHP, DN, FZ, RMode
7206 const uint64_t fpcr_core = 0x07c00000;
7207
7208 // All FPCR fields (including fields which may be read-as-zero):
7209 // Stride, Len
7210 // IDE, IXE, UFE, OFE, DZE, IOE
7211 const uint64_t fpcr_all = fpcr_core | 0x00379f00;
7212
7213 SETUP();
7214
7215 START();
7216 __ Mov(w0, 0);
7217 __ Mov(w1, 0x7fffffff);
7218
7219 __ Mov(x7, 0);
7220
7221 __ Mov(x10, NVFlag);
7222 __ Cmp(w0, w0); // Set Z and C.
7223 __ Msr(NZCV, x10); // Set N and V.
7224 // The Msr should have overwritten every flag set by the Cmp.
7225 __ Cinc(x7, x7, mi); // N
7226 __ Cinc(x7, x7, ne); // !Z
7227 __ Cinc(x7, x7, lo); // !C
7228 __ Cinc(x7, x7, vs); // V
7229
7230 __ Mov(x10, ZCFlag);
7231 __ Cmn(w1, w1); // Set N and V.
7232 __ Msr(NZCV, x10); // Set Z and C.
7233 // The Msr should have overwritten every flag set by the Cmn.
7234 __ Cinc(x7, x7, pl); // !N
7235 __ Cinc(x7, x7, eq); // Z
7236 __ Cinc(x7, x7, hs); // C
7237 __ Cinc(x7, x7, vc); // !V
7238
7239 // All core FPCR fields must be writable.
7240 __ Mov(x8, fpcr_core);
7241 __ Msr(FPCR, x8);
7242 __ Mrs(x8, FPCR);
7243
7244 // All FPCR fields, including optional ones. This part of the test doesn't
7245 // achieve much other than ensuring that supported fields can be cleared by
7246 // the next test.
7247 __ Mov(x9, fpcr_all);
7248 __ Msr(FPCR, x9);
7249 __ Mrs(x9, FPCR);
7250 __ And(x9, x9, fpcr_core);
7251
7252 // The undefined bits must ignore writes.
7253 // It's conceivable that a future version of the architecture could use these
7254 // fields (making this test fail), but in the meantime this is a useful test
7255 // for the simulator.
7256 __ Mov(x10, ~fpcr_all);
7257 __ Msr(FPCR, x10);
7258 __ Mrs(x10, FPCR);
7259
7260 END();
7261
7262 RUN();
7263
7264 // We should have incremented x7 (from 0) exactly 8 times.
7265 ASSERT_EQUAL_64(8, x7);
7266
7267 ASSERT_EQUAL_64(fpcr_core, x8);
7268 ASSERT_EQUAL_64(fpcr_core, x9);
7269 ASSERT_EQUAL_64(0, x10);
7270
7271 TEARDOWN();
7272 }
7273
7274
TEST(system_nop)7275 TEST(system_nop) {
7276 SETUP();
7277 RegisterDump before;
7278
7279 START();
7280 before.Dump(&masm);
7281 __ Nop();
7282 END();
7283
7284 RUN();
7285
7286 ASSERT_EQUAL_REGISTERS(before);
7287 ASSERT_EQUAL_NZCV(before.flags_nzcv());
7288
7289 TEARDOWN();
7290 }
7291
7292
TEST(zero_dest)7293 TEST(zero_dest) {
7294 SETUP();
7295 RegisterDump before;
7296
7297 START();
7298 // Preserve the stack pointer, in case we clobber it.
7299 __ Mov(x30, sp);
7300 // Initialize the other registers used in this test.
7301 uint64_t literal_base = 0x0100001000100101;
7302 __ Mov(x0, 0);
7303 __ Mov(x1, literal_base);
7304 for (unsigned i = 2; i < x30.code(); i++) {
7305 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
7306 }
7307 before.Dump(&masm);
7308
7309 // All of these instructions should be NOPs in these forms, but have
7310 // alternate forms which can write into the stack pointer.
7311 __ add(xzr, x0, x1);
7312 __ add(xzr, x1, xzr);
7313 __ add(xzr, xzr, x1);
7314
7315 __ and_(xzr, x0, x2);
7316 __ and_(xzr, x2, xzr);
7317 __ and_(xzr, xzr, x2);
7318
7319 __ bic(xzr, x0, x3);
7320 __ bic(xzr, x3, xzr);
7321 __ bic(xzr, xzr, x3);
7322
7323 __ eon(xzr, x0, x4);
7324 __ eon(xzr, x4, xzr);
7325 __ eon(xzr, xzr, x4);
7326
7327 __ eor(xzr, x0, x5);
7328 __ eor(xzr, x5, xzr);
7329 __ eor(xzr, xzr, x5);
7330
7331 __ orr(xzr, x0, x6);
7332 __ orr(xzr, x6, xzr);
7333 __ orr(xzr, xzr, x6);
7334
7335 __ sub(xzr, x0, x7);
7336 __ sub(xzr, x7, xzr);
7337 __ sub(xzr, xzr, x7);
7338
7339 // Swap the saved stack pointer with the real one. If sp was written
7340 // during the test, it will show up in x30. This is done because the test
7341 // framework assumes that sp will be valid at the end of the test.
7342 __ Mov(x29, x30);
7343 __ Mov(x30, sp);
7344 __ Mov(sp, x29);
7345 // We used x29 as a scratch register, so reset it to make sure it doesn't
7346 // trigger a test failure.
7347 __ Add(x29, x28, x1);
7348 END();
7349
7350 RUN();
7351
7352 ASSERT_EQUAL_REGISTERS(before);
7353 ASSERT_EQUAL_NZCV(before.flags_nzcv());
7354
7355 TEARDOWN();
7356 }
7357
7358
TEST(zero_dest_setflags)7359 TEST(zero_dest_setflags) {
7360 SETUP();
7361 RegisterDump before;
7362
7363 START();
7364 // Preserve the stack pointer, in case we clobber it.
7365 __ Mov(x30, sp);
7366 // Initialize the other registers used in this test.
7367 uint64_t literal_base = 0x0100001000100101;
7368 __ Mov(x0, 0);
7369 __ Mov(x1, literal_base);
7370 for (int i = 2; i < 30; i++) {
7371 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
7372 }
7373 before.Dump(&masm);
7374
7375 // All of these instructions should only write to the flags in these forms,
7376 // but have alternate forms which can write into the stack pointer.
7377 __ adds(xzr, x0, Operand(x1, UXTX));
7378 __ adds(xzr, x1, Operand(xzr, UXTX));
7379 __ adds(xzr, x1, 1234);
7380 __ adds(xzr, x0, x1);
7381 __ adds(xzr, x1, xzr);
7382 __ adds(xzr, xzr, x1);
7383
7384 __ ands(xzr, x2, ~0xf);
7385 __ ands(xzr, xzr, ~0xf);
7386 __ ands(xzr, x0, x2);
7387 __ ands(xzr, x2, xzr);
7388 __ ands(xzr, xzr, x2);
7389
7390 __ bics(xzr, x3, ~0xf);
7391 __ bics(xzr, xzr, ~0xf);
7392 __ bics(xzr, x0, x3);
7393 __ bics(xzr, x3, xzr);
7394 __ bics(xzr, xzr, x3);
7395
7396 __ subs(xzr, x0, Operand(x3, UXTX));
7397 __ subs(xzr, x3, Operand(xzr, UXTX));
7398 __ subs(xzr, x3, 1234);
7399 __ subs(xzr, x0, x3);
7400 __ subs(xzr, x3, xzr);
7401 __ subs(xzr, xzr, x3);
7402
7403 // Swap the saved stack pointer with the real one. If sp was written
7404 // during the test, it will show up in x30. This is done because the test
7405 // framework assumes that sp will be valid at the end of the test.
7406 __ Mov(x29, x30);
7407 __ Mov(x30, sp);
7408 __ Mov(sp, x29);
7409 // We used x29 as a scratch register, so reset it to make sure it doesn't
7410 // trigger a test failure.
7411 __ Add(x29, x28, x1);
7412 END();
7413
7414 RUN();
7415
7416 ASSERT_EQUAL_REGISTERS(before);
7417
7418 TEARDOWN();
7419 }
7420
7421
TEST(register_bit)7422 TEST(register_bit) {
7423 // No code generation takes place in this test, so no need to setup and
7424 // teardown.
7425
7426 // Simple tests.
7427 assert(x0.Bit() == (UINT64_C(1) << 0));
7428 assert(x1.Bit() == (UINT64_C(1) << 1));
7429 assert(x10.Bit() == (UINT64_C(1) << 10));
7430
7431 // AAPCS64 definitions.
7432 assert(lr.Bit() == (UINT64_C(1) << kLinkRegCode));
7433
7434 // Fixed (hardware) definitions.
7435 assert(xzr.Bit() == (UINT64_C(1) << kZeroRegCode));
7436
7437 // Internal ABI definitions.
7438 assert(sp.Bit() == (UINT64_C(1) << kSPRegInternalCode));
7439 assert(sp.Bit() != xzr.Bit());
7440
7441 // xn.Bit() == wn.Bit() at all times, for the same n.
7442 assert(x0.Bit() == w0.Bit());
7443 assert(x1.Bit() == w1.Bit());
7444 assert(x10.Bit() == w10.Bit());
7445 assert(xzr.Bit() == wzr.Bit());
7446 assert(sp.Bit() == wsp.Bit());
7447 }
7448
7449
TEST(stack_pointer_override)7450 TEST(stack_pointer_override) {
7451 // This test generates some stack maintenance code, but the test only checks
7452 // the reported state.
7453 SETUP();
7454 START();
7455
7456 // The default stack pointer in VIXL is sp.
7457 assert(sp.Is(__ StackPointer()));
7458 __ SetStackPointer(x0);
7459 assert(x0.Is(__ StackPointer()));
7460 __ SetStackPointer(x28);
7461 assert(x28.Is(__ StackPointer()));
7462 __ SetStackPointer(sp);
7463 assert(sp.Is(__ StackPointer()));
7464
7465 END();
7466 RUN();
7467 TEARDOWN();
7468 }
7469
7470
TEST(peek_poke_simple)7471 TEST(peek_poke_simple) {
7472 SETUP();
7473 START();
7474
7475 static const RegList x0_to_x3 = x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit();
7476 static const RegList x10_to_x13 = x10.Bit() | x11.Bit() |
7477 x12.Bit() | x13.Bit();
7478
7479 // The literal base is chosen to have two useful properties:
7480 // * When multiplied by small values (such as a register index), this value
7481 // is clearly readable in the result.
7482 // * The value is not formed from repeating fixed-size smaller values, so it
7483 // can be used to detect endianness-related errors.
7484 uint64_t literal_base = 0x0100001000100101;
7485
7486 // Initialize the registers.
7487 __ Mov(x0, literal_base);
7488 __ Add(x1, x0, x0);
7489 __ Add(x2, x1, x0);
7490 __ Add(x3, x2, x0);
7491
7492 __ Claim(32);
7493
7494 // Simple exchange.
7495 // After this test:
7496 // x0-x3 should be unchanged.
7497 // w10-w13 should contain the lower words of x0-x3.
7498 __ Poke(x0, 0);
7499 __ Poke(x1, 8);
7500 __ Poke(x2, 16);
7501 __ Poke(x3, 24);
7502 Clobber(&masm, x0_to_x3);
7503 __ Peek(x0, 0);
7504 __ Peek(x1, 8);
7505 __ Peek(x2, 16);
7506 __ Peek(x3, 24);
7507
7508 __ Poke(w0, 0);
7509 __ Poke(w1, 4);
7510 __ Poke(w2, 8);
7511 __ Poke(w3, 12);
7512 Clobber(&masm, x10_to_x13);
7513 __ Peek(w10, 0);
7514 __ Peek(w11, 4);
7515 __ Peek(w12, 8);
7516 __ Peek(w13, 12);
7517
7518 __ Drop(32);
7519
7520 END();
7521 RUN();
7522
7523 ASSERT_EQUAL_64(literal_base * 1, x0);
7524 ASSERT_EQUAL_64(literal_base * 2, x1);
7525 ASSERT_EQUAL_64(literal_base * 3, x2);
7526 ASSERT_EQUAL_64(literal_base * 4, x3);
7527
7528 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
7529 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
7530 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
7531 ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
7532
7533 TEARDOWN();
7534 }
7535
7536
TEST(peek_poke_unaligned)7537 TEST(peek_poke_unaligned) {
7538 SETUP();
7539 START();
7540
7541 // The literal base is chosen to have two useful properties:
7542 // * When multiplied by small values (such as a register index), this value
7543 // is clearly readable in the result.
7544 // * The value is not formed from repeating fixed-size smaller values, so it
7545 // can be used to detect endianness-related errors.
7546 uint64_t literal_base = 0x0100001000100101;
7547
7548 // Initialize the registers.
7549 __ Mov(x0, literal_base);
7550 __ Add(x1, x0, x0);
7551 __ Add(x2, x1, x0);
7552 __ Add(x3, x2, x0);
7553 __ Add(x4, x3, x0);
7554 __ Add(x5, x4, x0);
7555 __ Add(x6, x5, x0);
7556
7557 __ Claim(32);
7558
7559 // Unaligned exchanges.
7560 // After this test:
7561 // x0-x6 should be unchanged.
7562 // w10-w12 should contain the lower words of x0-x2.
7563 __ Poke(x0, 1);
7564 Clobber(&masm, x0.Bit());
7565 __ Peek(x0, 1);
7566 __ Poke(x1, 2);
7567 Clobber(&masm, x1.Bit());
7568 __ Peek(x1, 2);
7569 __ Poke(x2, 3);
7570 Clobber(&masm, x2.Bit());
7571 __ Peek(x2, 3);
7572 __ Poke(x3, 4);
7573 Clobber(&masm, x3.Bit());
7574 __ Peek(x3, 4);
7575 __ Poke(x4, 5);
7576 Clobber(&masm, x4.Bit());
7577 __ Peek(x4, 5);
7578 __ Poke(x5, 6);
7579 Clobber(&masm, x5.Bit());
7580 __ Peek(x5, 6);
7581 __ Poke(x6, 7);
7582 Clobber(&masm, x6.Bit());
7583 __ Peek(x6, 7);
7584
7585 __ Poke(w0, 1);
7586 Clobber(&masm, w10.Bit());
7587 __ Peek(w10, 1);
7588 __ Poke(w1, 2);
7589 Clobber(&masm, w11.Bit());
7590 __ Peek(w11, 2);
7591 __ Poke(w2, 3);
7592 Clobber(&masm, w12.Bit());
7593 __ Peek(w12, 3);
7594
7595 __ Drop(32);
7596
7597 END();
7598 RUN();
7599
7600 ASSERT_EQUAL_64(literal_base * 1, x0);
7601 ASSERT_EQUAL_64(literal_base * 2, x1);
7602 ASSERT_EQUAL_64(literal_base * 3, x2);
7603 ASSERT_EQUAL_64(literal_base * 4, x3);
7604 ASSERT_EQUAL_64(literal_base * 5, x4);
7605 ASSERT_EQUAL_64(literal_base * 6, x5);
7606 ASSERT_EQUAL_64(literal_base * 7, x6);
7607
7608 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
7609 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
7610 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
7611
7612 TEARDOWN();
7613 }
7614
7615
TEST(peek_poke_endianness)7616 TEST(peek_poke_endianness) {
7617 SETUP();
7618 START();
7619
7620 // The literal base is chosen to have two useful properties:
7621 // * When multiplied by small values (such as a register index), this value
7622 // is clearly readable in the result.
7623 // * The value is not formed from repeating fixed-size smaller values, so it
7624 // can be used to detect endianness-related errors.
7625 uint64_t literal_base = 0x0100001000100101;
7626
7627 // Initialize the registers.
7628 __ Mov(x0, literal_base);
7629 __ Add(x1, x0, x0);
7630
7631 __ Claim(32);
7632
7633 // Endianness tests.
7634 // After this section:
7635 // x4 should match x0[31:0]:x0[63:32]
7636 // w5 should match w1[15:0]:w1[31:16]
7637 __ Poke(x0, 0);
7638 __ Poke(x0, 8);
7639 __ Peek(x4, 4);
7640
7641 __ Poke(w1, 0);
7642 __ Poke(w1, 4);
7643 __ Peek(w5, 2);
7644
7645 __ Drop(32);
7646
7647 END();
7648 RUN();
7649
7650 uint64_t x0_expected = literal_base * 1;
7651 uint64_t x1_expected = literal_base * 2;
7652 uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32);
7653 uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) |
7654 ((x1_expected >> 16) & 0x0000ffff);
7655
7656 ASSERT_EQUAL_64(x0_expected, x0);
7657 ASSERT_EQUAL_64(x1_expected, x1);
7658 ASSERT_EQUAL_64(x4_expected, x4);
7659 ASSERT_EQUAL_64(x5_expected, x5);
7660
7661 TEARDOWN();
7662 }
7663
7664
TEST(peek_poke_mixed)7665 TEST(peek_poke_mixed) {
7666 SETUP();
7667 START();
7668
7669 // The literal base is chosen to have two useful properties:
7670 // * When multiplied by small values (such as a register index), this value
7671 // is clearly readable in the result.
7672 // * The value is not formed from repeating fixed-size smaller values, so it
7673 // can be used to detect endianness-related errors.
7674 uint64_t literal_base = 0x0100001000100101;
7675
7676 // Initialize the registers.
7677 __ Mov(x0, literal_base);
7678 __ Add(x1, x0, x0);
7679 __ Add(x2, x1, x0);
7680 __ Add(x3, x2, x0);
7681
7682 __ Claim(32);
7683
7684 // Mix with other stack operations.
7685 // After this section:
7686 // x0-x3 should be unchanged.
7687 // x6 should match x1[31:0]:x0[63:32]
7688 // w7 should match x1[15:0]:x0[63:48]
7689 __ Poke(x1, 8);
7690 __ Poke(x0, 0);
7691 {
7692 VIXL_ASSERT(__ StackPointer().Is(sp));
7693 __ Mov(x4, __ StackPointer());
7694 __ SetStackPointer(x4);
7695
7696 __ Poke(wzr, 0); // Clobber the space we're about to drop.
7697 __ Drop(4);
7698 __ Peek(x6, 0);
7699 __ Claim(8);
7700 __ Peek(w7, 10);
7701 __ Poke(x3, 28);
7702 __ Poke(xzr, 0); // Clobber the space we're about to drop.
7703 __ Drop(8);
7704 __ Poke(x2, 12);
7705 __ Push(w0);
7706
7707 __ Mov(sp, __ StackPointer());
7708 __ SetStackPointer(sp);
7709 }
7710
7711 __ Pop(x0, x1, x2, x3);
7712
7713 END();
7714 RUN();
7715
7716 uint64_t x0_expected = literal_base * 1;
7717 uint64_t x1_expected = literal_base * 2;
7718 uint64_t x2_expected = literal_base * 3;
7719 uint64_t x3_expected = literal_base * 4;
7720 uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32);
7721 uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) |
7722 ((x0_expected >> 48) & 0x0000ffff);
7723
7724 ASSERT_EQUAL_64(x0_expected, x0);
7725 ASSERT_EQUAL_64(x1_expected, x1);
7726 ASSERT_EQUAL_64(x2_expected, x2);
7727 ASSERT_EQUAL_64(x3_expected, x3);
7728 ASSERT_EQUAL_64(x6_expected, x6);
7729 ASSERT_EQUAL_64(x7_expected, x7);
7730
7731 TEARDOWN();
7732 }
7733
7734
7735 // This enum is used only as an argument to the push-pop test helpers.
7736 enum PushPopMethod {
7737 // Push or Pop using the Push and Pop methods, with blocks of up to four
7738 // registers. (Smaller blocks will be used if necessary.)
7739 PushPopByFour,
7740
7741 // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers.
7742 PushPopRegList
7743 };
7744
7745
7746 // The maximum number of registers that can be used by the PushPopXReg* tests,
7747 // where a reg_count field is provided.
7748 static int const kPushPopXRegMaxRegCount = -1;
7749
7750 // Test a simple push-pop pattern:
7751 // * Claim <claim> bytes to set the stack alignment.
7752 // * Push <reg_count> registers with size <reg_size>.
7753 // * Clobber the register contents.
7754 // * Pop <reg_count> registers to restore the original contents.
7755 // * Drop <claim> bytes to restore the original stack pointer.
7756 //
7757 // Different push and pop methods can be specified independently to test for
7758 // proper word-endian behaviour.
PushPopXRegSimpleHelper(int reg_count,int claim,int reg_size,PushPopMethod push_method,PushPopMethod pop_method)7759 static void PushPopXRegSimpleHelper(int reg_count,
7760 int claim,
7761 int reg_size,
7762 PushPopMethod push_method,
7763 PushPopMethod pop_method) {
7764 SETUP();
7765
7766 START();
7767
7768 // Arbitrarily pick a register to use as a stack pointer.
7769 const Register& stack_pointer = x20;
7770 const RegList allowed = ~stack_pointer.Bit();
7771 if (reg_count == kPushPopXRegMaxRegCount) {
7772 reg_count = CountSetBits(allowed, kNumberOfRegisters);
7773 }
7774 // Work out which registers to use, based on reg_size.
7775 Register r[kNumberOfRegisters];
7776 Register x[kNumberOfRegisters];
7777 RegList list = PopulateRegisterArray(NULL, x, r, reg_size, reg_count,
7778 allowed);
7779
7780 // The literal base is chosen to have two useful properties:
7781 // * When multiplied by small values (such as a register index), this value
7782 // is clearly readable in the result.
7783 // * The value is not formed from repeating fixed-size smaller values, so it
7784 // can be used to detect endianness-related errors.
7785 uint64_t literal_base = 0x0100001000100101;
7786
7787 {
7788 VIXL_ASSERT(__ StackPointer().Is(sp));
7789 __ Mov(stack_pointer, __ StackPointer());
7790 __ SetStackPointer(stack_pointer);
7791
7792 int i;
7793
7794 // Initialize the registers.
7795 for (i = 0; i < reg_count; i++) {
7796 // Always write into the X register, to ensure that the upper word is
7797 // properly ignored by Push when testing W registers.
7798 __ Mov(x[i], literal_base * i);
7799 }
7800
7801 // Claim memory first, as requested.
7802 __ Claim(claim);
7803
7804 switch (push_method) {
7805 case PushPopByFour:
7806 // Push high-numbered registers first (to the highest addresses).
7807 for (i = reg_count; i >= 4; i -= 4) {
7808 __ Push(r[i-1], r[i-2], r[i-3], r[i-4]);
7809 }
7810 // Finish off the leftovers.
7811 switch (i) {
7812 case 3: __ Push(r[2], r[1], r[0]); break;
7813 case 2: __ Push(r[1], r[0]); break;
7814 case 1: __ Push(r[0]); break;
7815 default: VIXL_ASSERT(i == 0); break;
7816 }
7817 break;
7818 case PushPopRegList:
7819 __ PushSizeRegList(list, reg_size);
7820 break;
7821 }
7822
7823 // Clobber all the registers, to ensure that they get repopulated by Pop.
7824 Clobber(&masm, list);
7825
7826 switch (pop_method) {
7827 case PushPopByFour:
7828 // Pop low-numbered registers first (from the lowest addresses).
7829 for (i = 0; i <= (reg_count-4); i += 4) {
7830 __ Pop(r[i], r[i+1], r[i+2], r[i+3]);
7831 }
7832 // Finish off the leftovers.
7833 switch (reg_count - i) {
7834 case 3: __ Pop(r[i], r[i+1], r[i+2]); break;
7835 case 2: __ Pop(r[i], r[i+1]); break;
7836 case 1: __ Pop(r[i]); break;
7837 default: VIXL_ASSERT(i == reg_count); break;
7838 }
7839 break;
7840 case PushPopRegList:
7841 __ PopSizeRegList(list, reg_size);
7842 break;
7843 }
7844
7845 // Drop memory to restore stack_pointer.
7846 __ Drop(claim);
7847
7848 __ Mov(sp, __ StackPointer());
7849 __ SetStackPointer(sp);
7850 }
7851
7852 END();
7853
7854 RUN();
7855
7856 // Check that the register contents were preserved.
7857 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
7858 // that the upper word was properly cleared by Pop.
7859 literal_base &= (0xffffffffffffffff >> (64-reg_size));
7860 for (int i = 0; i < reg_count; i++) {
7861 if (x[i].Is(xzr)) {
7862 ASSERT_EQUAL_64(0, x[i]);
7863 } else {
7864 ASSERT_EQUAL_64(literal_base * i, x[i]);
7865 }
7866 }
7867
7868 TEARDOWN();
7869 }
7870
7871
TEST(push_pop_xreg_simple_32)7872 TEST(push_pop_xreg_simple_32) {
7873 for (int claim = 0; claim <= 8; claim++) {
7874 for (int count = 0; count <= 8; count++) {
7875 PushPopXRegSimpleHelper(count, claim, kWRegSize,
7876 PushPopByFour, PushPopByFour);
7877 PushPopXRegSimpleHelper(count, claim, kWRegSize,
7878 PushPopByFour, PushPopRegList);
7879 PushPopXRegSimpleHelper(count, claim, kWRegSize,
7880 PushPopRegList, PushPopByFour);
7881 PushPopXRegSimpleHelper(count, claim, kWRegSize,
7882 PushPopRegList, PushPopRegList);
7883 }
7884 // Test with the maximum number of registers.
7885 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7886 claim, kWRegSize, PushPopByFour, PushPopByFour);
7887 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7888 claim, kWRegSize, PushPopByFour, PushPopRegList);
7889 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7890 claim, kWRegSize, PushPopRegList, PushPopByFour);
7891 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7892 claim, kWRegSize, PushPopRegList, PushPopRegList);
7893 }
7894 }
7895
7896
TEST(push_pop_xreg_simple_64)7897 TEST(push_pop_xreg_simple_64) {
7898 for (int claim = 0; claim <= 8; claim++) {
7899 for (int count = 0; count <= 8; count++) {
7900 PushPopXRegSimpleHelper(count, claim, kXRegSize,
7901 PushPopByFour, PushPopByFour);
7902 PushPopXRegSimpleHelper(count, claim, kXRegSize,
7903 PushPopByFour, PushPopRegList);
7904 PushPopXRegSimpleHelper(count, claim, kXRegSize,
7905 PushPopRegList, PushPopByFour);
7906 PushPopXRegSimpleHelper(count, claim, kXRegSize,
7907 PushPopRegList, PushPopRegList);
7908 }
7909 // Test with the maximum number of registers.
7910 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7911 claim, kXRegSize, PushPopByFour, PushPopByFour);
7912 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7913 claim, kXRegSize, PushPopByFour, PushPopRegList);
7914 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7915 claim, kXRegSize, PushPopRegList, PushPopByFour);
7916 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7917 claim, kXRegSize, PushPopRegList, PushPopRegList);
7918 }
7919 }
7920
7921
7922 // The maximum number of registers that can be used by the PushPopFPXReg* tests,
7923 // where a reg_count field is provided.
7924 static int const kPushPopFPXRegMaxRegCount = -1;
7925
7926 // Test a simple push-pop pattern:
7927 // * Claim <claim> bytes to set the stack alignment.
7928 // * Push <reg_count> FP registers with size <reg_size>.
7929 // * Clobber the register contents.
7930 // * Pop <reg_count> FP registers to restore the original contents.
7931 // * Drop <claim> bytes to restore the original stack pointer.
7932 //
7933 // Different push and pop methods can be specified independently to test for
7934 // proper word-endian behaviour.
PushPopFPXRegSimpleHelper(int reg_count,int claim,int reg_size,PushPopMethod push_method,PushPopMethod pop_method)7935 static void PushPopFPXRegSimpleHelper(int reg_count,
7936 int claim,
7937 int reg_size,
7938 PushPopMethod push_method,
7939 PushPopMethod pop_method) {
7940 SETUP();
7941
7942 START();
7943
7944 // We can use any floating-point register. None of them are reserved for
7945 // debug code, for example.
7946 static RegList const allowed = ~0;
7947 if (reg_count == kPushPopFPXRegMaxRegCount) {
7948 reg_count = CountSetBits(allowed, kNumberOfFPRegisters);
7949 }
7950 // Work out which registers to use, based on reg_size.
7951 FPRegister v[kNumberOfRegisters];
7952 FPRegister d[kNumberOfRegisters];
7953 RegList list = PopulateFPRegisterArray(NULL, d, v, reg_size, reg_count,
7954 allowed);
7955
7956 // Arbitrarily pick a register to use as a stack pointer.
7957 const Register& stack_pointer = x10;
7958
7959 // The literal base is chosen to have two useful properties:
7960 // * When multiplied (using an integer) by small values (such as a register
7961 // index), this value is clearly readable in the result.
7962 // * The value is not formed from repeating fixed-size smaller values, so it
7963 // can be used to detect endianness-related errors.
7964 // * It is never a floating-point NaN, and will therefore always compare
7965 // equal to itself.
7966 uint64_t literal_base = 0x0100001000100101;
7967
7968 {
7969 VIXL_ASSERT(__ StackPointer().Is(sp));
7970 __ Mov(stack_pointer, __ StackPointer());
7971 __ SetStackPointer(stack_pointer);
7972
7973 int i;
7974
7975 // Initialize the registers, using X registers to load the literal.
7976 __ Mov(x0, 0);
7977 __ Mov(x1, literal_base);
7978 for (i = 0; i < reg_count; i++) {
7979 // Always write into the D register, to ensure that the upper word is
7980 // properly ignored by Push when testing S registers.
7981 __ Fmov(d[i], x0);
7982 // Calculate the next literal.
7983 __ Add(x0, x0, x1);
7984 }
7985
7986 // Claim memory first, as requested.
7987 __ Claim(claim);
7988
7989 switch (push_method) {
7990 case PushPopByFour:
7991 // Push high-numbered registers first (to the highest addresses).
7992 for (i = reg_count; i >= 4; i -= 4) {
7993 __ Push(v[i-1], v[i-2], v[i-3], v[i-4]);
7994 }
7995 // Finish off the leftovers.
7996 switch (i) {
7997 case 3: __ Push(v[2], v[1], v[0]); break;
7998 case 2: __ Push(v[1], v[0]); break;
7999 case 1: __ Push(v[0]); break;
8000 default: VIXL_ASSERT(i == 0); break;
8001 }
8002 break;
8003 case PushPopRegList:
8004 __ PushSizeRegList(list, reg_size, CPURegister::kFPRegister);
8005 break;
8006 }
8007
8008 // Clobber all the registers, to ensure that they get repopulated by Pop.
8009 ClobberFP(&masm, list);
8010
8011 switch (pop_method) {
8012 case PushPopByFour:
8013 // Pop low-numbered registers first (from the lowest addresses).
8014 for (i = 0; i <= (reg_count-4); i += 4) {
8015 __ Pop(v[i], v[i+1], v[i+2], v[i+3]);
8016 }
8017 // Finish off the leftovers.
8018 switch (reg_count - i) {
8019 case 3: __ Pop(v[i], v[i+1], v[i+2]); break;
8020 case 2: __ Pop(v[i], v[i+1]); break;
8021 case 1: __ Pop(v[i]); break;
8022 default: VIXL_ASSERT(i == reg_count); break;
8023 }
8024 break;
8025 case PushPopRegList:
8026 __ PopSizeRegList(list, reg_size, CPURegister::kFPRegister);
8027 break;
8028 }
8029
8030 // Drop memory to restore the stack pointer.
8031 __ Drop(claim);
8032
8033 __ Mov(sp, __ StackPointer());
8034 __ SetStackPointer(sp);
8035 }
8036
8037 END();
8038
8039 RUN();
8040
8041 // Check that the register contents were preserved.
8042 // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
8043 // test that the upper word was properly cleared by Pop.
8044 literal_base &= (0xffffffffffffffff >> (64-reg_size));
8045 for (int i = 0; i < reg_count; i++) {
8046 uint64_t literal = literal_base * i;
8047 double expected;
8048 memcpy(&expected, &literal, sizeof(expected));
8049 ASSERT_EQUAL_FP64(expected, d[i]);
8050 }
8051
8052 TEARDOWN();
8053 }
8054
8055
TEST(push_pop_fp_xreg_simple_32)8056 TEST(push_pop_fp_xreg_simple_32) {
8057 for (int claim = 0; claim <= 8; claim++) {
8058 for (int count = 0; count <= 8; count++) {
8059 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8060 PushPopByFour, PushPopByFour);
8061 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8062 PushPopByFour, PushPopRegList);
8063 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8064 PushPopRegList, PushPopByFour);
8065 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8066 PushPopRegList, PushPopRegList);
8067 }
8068 // Test with the maximum number of registers.
8069 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8070 PushPopByFour, PushPopByFour);
8071 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8072 PushPopByFour, PushPopRegList);
8073 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8074 PushPopRegList, PushPopByFour);
8075 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8076 PushPopRegList, PushPopRegList);
8077 }
8078 }
8079
8080
TEST(push_pop_fp_xreg_simple_64)8081 TEST(push_pop_fp_xreg_simple_64) {
8082 for (int claim = 0; claim <= 8; claim++) {
8083 for (int count = 0; count <= 8; count++) {
8084 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8085 PushPopByFour, PushPopByFour);
8086 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8087 PushPopByFour, PushPopRegList);
8088 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8089 PushPopRegList, PushPopByFour);
8090 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8091 PushPopRegList, PushPopRegList);
8092 }
8093 // Test with the maximum number of registers.
8094 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8095 PushPopByFour, PushPopByFour);
8096 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8097 PushPopByFour, PushPopRegList);
8098 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8099 PushPopRegList, PushPopByFour);
8100 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8101 PushPopRegList, PushPopRegList);
8102 }
8103 }
8104
8105
8106 // Push and pop data using an overlapping combination of Push/Pop and
8107 // RegList-based methods.
PushPopXRegMixedMethodsHelper(int claim,int reg_size)8108 static void PushPopXRegMixedMethodsHelper(int claim, int reg_size) {
8109 SETUP();
8110
8111 // Arbitrarily pick a register to use as a stack pointer.
8112 const Register& stack_pointer = x5;
8113 const RegList allowed = ~stack_pointer.Bit();
8114 // Work out which registers to use, based on reg_size.
8115 Register r[10];
8116 Register x[10];
8117 PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed);
8118
8119 // Calculate some handy register lists.
8120 RegList r0_to_r3 = 0;
8121 for (int i = 0; i <= 3; i++) {
8122 r0_to_r3 |= x[i].Bit();
8123 }
8124 RegList r4_to_r5 = 0;
8125 for (int i = 4; i <= 5; i++) {
8126 r4_to_r5 |= x[i].Bit();
8127 }
8128 RegList r6_to_r9 = 0;
8129 for (int i = 6; i <= 9; i++) {
8130 r6_to_r9 |= x[i].Bit();
8131 }
8132
8133 // The literal base is chosen to have two useful properties:
8134 // * When multiplied by small values (such as a register index), this value
8135 // is clearly readable in the result.
8136 // * The value is not formed from repeating fixed-size smaller values, so it
8137 // can be used to detect endianness-related errors.
8138 uint64_t literal_base = 0x0100001000100101;
8139
8140 START();
8141 {
8142 VIXL_ASSERT(__ StackPointer().Is(sp));
8143 __ Mov(stack_pointer, __ StackPointer());
8144 __ SetStackPointer(stack_pointer);
8145
8146 // Claim memory first, as requested.
8147 __ Claim(claim);
8148
8149 __ Mov(x[3], literal_base * 3);
8150 __ Mov(x[2], literal_base * 2);
8151 __ Mov(x[1], literal_base * 1);
8152 __ Mov(x[0], literal_base * 0);
8153
8154 __ PushSizeRegList(r0_to_r3, reg_size);
8155 __ Push(r[3], r[2]);
8156
8157 Clobber(&masm, r0_to_r3);
8158 __ PopSizeRegList(r0_to_r3, reg_size);
8159
8160 __ Push(r[2], r[1], r[3], r[0]);
8161
8162 Clobber(&masm, r4_to_r5);
8163 __ Pop(r[4], r[5]);
8164 Clobber(&masm, r6_to_r9);
8165 __ Pop(r[6], r[7], r[8], r[9]);
8166
8167 // Drop memory to restore stack_pointer.
8168 __ Drop(claim);
8169
8170 __ Mov(sp, __ StackPointer());
8171 __ SetStackPointer(sp);
8172 }
8173
8174 END();
8175
8176 RUN();
8177
8178 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
8179 // that the upper word was properly cleared by Pop.
8180 literal_base &= (0xffffffffffffffff >> (64-reg_size));
8181
8182 ASSERT_EQUAL_64(literal_base * 3, x[9]);
8183 ASSERT_EQUAL_64(literal_base * 2, x[8]);
8184 ASSERT_EQUAL_64(literal_base * 0, x[7]);
8185 ASSERT_EQUAL_64(literal_base * 3, x[6]);
8186 ASSERT_EQUAL_64(literal_base * 1, x[5]);
8187 ASSERT_EQUAL_64(literal_base * 2, x[4]);
8188
8189 TEARDOWN();
8190 }
8191
8192
TEST(push_pop_xreg_mixed_methods_64)8193 TEST(push_pop_xreg_mixed_methods_64) {
8194 for (int claim = 0; claim <= 8; claim++) {
8195 PushPopXRegMixedMethodsHelper(claim, kXRegSize);
8196 }
8197 }
8198
8199
TEST(push_pop_xreg_mixed_methods_32)8200 TEST(push_pop_xreg_mixed_methods_32) {
8201 for (int claim = 0; claim <= 8; claim++) {
8202 PushPopXRegMixedMethodsHelper(claim, kWRegSize);
8203 }
8204 }
8205
8206
8207 // Push and pop data using overlapping X- and W-sized quantities.
PushPopXRegWXOverlapHelper(int reg_count,int claim)8208 static void PushPopXRegWXOverlapHelper(int reg_count, int claim) {
8209 SETUP();
8210
8211 // Arbitrarily pick a register to use as a stack pointer.
8212 const Register& stack_pointer = x10;
8213 const RegList allowed = ~stack_pointer.Bit();
8214 if (reg_count == kPushPopXRegMaxRegCount) {
8215 reg_count = CountSetBits(allowed, kNumberOfRegisters);
8216 }
8217 // Work out which registers to use, based on reg_size.
8218 Register w[kNumberOfRegisters];
8219 Register x[kNumberOfRegisters];
8220 RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed);
8221
8222 // The number of W-sized slots we expect to pop. When we pop, we alternate
8223 // between W and X registers, so we need reg_count*1.5 W-sized slots.
8224 int const requested_w_slots = reg_count + reg_count / 2;
8225
8226 // Track what _should_ be on the stack, using W-sized slots.
8227 static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2;
8228 uint32_t stack[kMaxWSlots];
8229 for (int i = 0; i < kMaxWSlots; i++) {
8230 stack[i] = 0xdeadbeef;
8231 }
8232
8233 // The literal base is chosen to have two useful properties:
8234 // * When multiplied by small values (such as a register index), this value
8235 // is clearly readable in the result.
8236 // * The value is not formed from repeating fixed-size smaller values, so it
8237 // can be used to detect endianness-related errors.
8238 static uint64_t const literal_base = 0x0100001000100101;
8239 static uint64_t const literal_base_hi = literal_base >> 32;
8240 static uint64_t const literal_base_lo = literal_base & 0xffffffff;
8241 static uint64_t const literal_base_w = literal_base & 0xffffffff;
8242
8243 START();
8244 {
8245 VIXL_ASSERT(__ StackPointer().Is(sp));
8246 __ Mov(stack_pointer, __ StackPointer());
8247 __ SetStackPointer(stack_pointer);
8248
8249 // Initialize the registers.
8250 for (int i = 0; i < reg_count; i++) {
8251 // Always write into the X register, to ensure that the upper word is
8252 // properly ignored by Push when testing W registers.
8253 __ Mov(x[i], literal_base * i);
8254 }
8255
8256 // Claim memory first, as requested.
8257 __ Claim(claim);
8258
8259 // The push-pop pattern is as follows:
8260 // Push: Pop:
8261 // x[0](hi) -> w[0]
8262 // x[0](lo) -> x[1](hi)
8263 // w[1] -> x[1](lo)
8264 // w[1] -> w[2]
8265 // x[2](hi) -> x[2](hi)
8266 // x[2](lo) -> x[2](lo)
8267 // x[2](hi) -> w[3]
8268 // x[2](lo) -> x[4](hi)
8269 // x[2](hi) -> x[4](lo)
8270 // x[2](lo) -> w[5]
8271 // w[3] -> x[5](hi)
8272 // w[3] -> x[6](lo)
8273 // w[3] -> w[7]
8274 // w[3] -> x[8](hi)
8275 // x[4](hi) -> x[8](lo)
8276 // x[4](lo) -> w[9]
8277 // ... pattern continues ...
8278 //
8279 // That is, registers are pushed starting with the lower numbers,
8280 // alternating between x and w registers, and pushing i%4+1 copies of each,
8281 // where i is the register number.
8282 // Registers are popped starting with the higher numbers one-by-one,
8283 // alternating between x and w registers, but only popping one at a time.
8284 //
8285 // This pattern provides a wide variety of alignment effects and overlaps.
8286
8287 // ---- Push ----
8288
8289 int active_w_slots = 0;
8290 for (int i = 0; active_w_slots < requested_w_slots; i++) {
8291 VIXL_ASSERT(i < reg_count);
8292 // In order to test various arguments to PushMultipleTimes, and to try to
8293 // exercise different alignment and overlap effects, we push each
8294 // register a different number of times.
8295 int times = i % 4 + 1;
8296 if (i & 1) {
8297 // Push odd-numbered registers as W registers.
8298 __ PushMultipleTimes(times, w[i]);
8299 // Fill in the expected stack slots.
8300 for (int j = 0; j < times; j++) {
8301 if (w[i].Is(wzr)) {
8302 // The zero register always writes zeroes.
8303 stack[active_w_slots++] = 0;
8304 } else {
8305 stack[active_w_slots++] = literal_base_w * i;
8306 }
8307 }
8308 } else {
8309 // Push even-numbered registers as X registers.
8310 __ PushMultipleTimes(times, x[i]);
8311 // Fill in the expected stack slots.
8312 for (int j = 0; j < times; j++) {
8313 if (x[i].Is(xzr)) {
8314 // The zero register always writes zeroes.
8315 stack[active_w_slots++] = 0;
8316 stack[active_w_slots++] = 0;
8317 } else {
8318 stack[active_w_slots++] = literal_base_hi * i;
8319 stack[active_w_slots++] = literal_base_lo * i;
8320 }
8321 }
8322 }
8323 }
8324 // Because we were pushing several registers at a time, we probably pushed
8325 // more than we needed to.
8326 if (active_w_slots > requested_w_slots) {
8327 __ Drop((active_w_slots - requested_w_slots) * kWRegSizeInBytes);
8328 // Bump the number of active W-sized slots back to where it should be,
8329 // and fill the empty space with a dummy value.
8330 do {
8331 stack[active_w_slots--] = 0xdeadbeef;
8332 } while (active_w_slots > requested_w_slots);
8333 }
8334
8335 // ---- Pop ----
8336
8337 Clobber(&masm, list);
8338
8339 // If popping an even number of registers, the first one will be X-sized.
8340 // Otherwise, the first one will be W-sized.
8341 bool next_is_64 = !(reg_count & 1);
8342 for (int i = reg_count-1; i >= 0; i--) {
8343 if (next_is_64) {
8344 __ Pop(x[i]);
8345 active_w_slots -= 2;
8346 } else {
8347 __ Pop(w[i]);
8348 active_w_slots -= 1;
8349 }
8350 next_is_64 = !next_is_64;
8351 }
8352 VIXL_ASSERT(active_w_slots == 0);
8353
8354 // Drop memory to restore stack_pointer.
8355 __ Drop(claim);
8356
8357 __ Mov(sp, __ StackPointer());
8358 __ SetStackPointer(sp);
8359 }
8360
8361 END();
8362
8363 RUN();
8364
8365 int slot = 0;
8366 for (int i = 0; i < reg_count; i++) {
8367 // Even-numbered registers were written as W registers.
8368 // Odd-numbered registers were written as X registers.
8369 bool expect_64 = (i & 1);
8370 uint64_t expected;
8371
8372 if (expect_64) {
8373 uint64_t hi = stack[slot++];
8374 uint64_t lo = stack[slot++];
8375 expected = (hi << 32) | lo;
8376 } else {
8377 expected = stack[slot++];
8378 }
8379
8380 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
8381 // test that the upper word was properly cleared by Pop.
8382 if (x[i].Is(xzr)) {
8383 ASSERT_EQUAL_64(0, x[i]);
8384 } else {
8385 ASSERT_EQUAL_64(expected, x[i]);
8386 }
8387 }
8388 VIXL_ASSERT(slot == requested_w_slots);
8389
8390 TEARDOWN();
8391 }
8392
8393
TEST(push_pop_xreg_wx_overlap)8394 TEST(push_pop_xreg_wx_overlap) {
8395 for (int claim = 0; claim <= 8; claim++) {
8396 for (int count = 1; count <= 8; count++) {
8397 PushPopXRegWXOverlapHelper(count, claim);
8398 }
8399 // Test with the maximum number of registers.
8400 PushPopXRegWXOverlapHelper(kPushPopXRegMaxRegCount, claim);
8401 }
8402 }
8403
8404
TEST(push_pop_sp)8405 TEST(push_pop_sp) {
8406 SETUP();
8407
8408 START();
8409
8410 VIXL_ASSERT(sp.Is(__ StackPointer()));
8411
8412 __ Mov(x3, 0x3333333333333333);
8413 __ Mov(x2, 0x2222222222222222);
8414 __ Mov(x1, 0x1111111111111111);
8415 __ Mov(x0, 0x0000000000000000);
8416 __ Claim(2 * kXRegSizeInBytes);
8417 __ PushXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
8418 __ Push(x3, x2);
8419 __ PopXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
8420 __ Push(x2, x1, x3, x0);
8421 __ Pop(x4, x5);
8422 __ Pop(x6, x7, x8, x9);
8423
8424 __ Claim(2 * kXRegSizeInBytes);
8425 __ PushWRegList(w0.Bit() | w1.Bit() | w2.Bit() | w3.Bit());
8426 __ Push(w3, w1, w2, w0);
8427 __ PopWRegList(w10.Bit() | w11.Bit() | w12.Bit() | w13.Bit());
8428 __ Pop(w14, w15, w16, w17);
8429
8430 __ Claim(2 * kXRegSizeInBytes);
8431 __ Push(w2, w2, w1, w1);
8432 __ Push(x3, x3);
8433 __ Pop(w18, w19, w20, w21);
8434 __ Pop(x22, x23);
8435
8436 __ Claim(2 * kXRegSizeInBytes);
8437 __ PushXRegList(x1.Bit() | x22.Bit());
8438 __ PopXRegList(x24.Bit() | x26.Bit());
8439
8440 __ Claim(2 * kXRegSizeInBytes);
8441 __ PushWRegList(w1.Bit() | w2.Bit() | w4.Bit() | w22.Bit());
8442 __ PopWRegList(w25.Bit() | w27.Bit() | w28.Bit() | w29.Bit());
8443
8444 __ Claim(2 * kXRegSizeInBytes);
8445 __ PushXRegList(0);
8446 __ PopXRegList(0);
8447 __ PushXRegList(0xffffffff);
8448 __ PopXRegList(0xffffffff);
8449 __ Drop(12 * kXRegSizeInBytes);
8450 END();
8451
8452 RUN();
8453
8454 ASSERT_EQUAL_64(0x1111111111111111, x3);
8455 ASSERT_EQUAL_64(0x0000000000000000, x2);
8456 ASSERT_EQUAL_64(0x3333333333333333, x1);
8457 ASSERT_EQUAL_64(0x2222222222222222, x0);
8458 ASSERT_EQUAL_64(0x3333333333333333, x9);
8459 ASSERT_EQUAL_64(0x2222222222222222, x8);
8460 ASSERT_EQUAL_64(0x0000000000000000, x7);
8461 ASSERT_EQUAL_64(0x3333333333333333, x6);
8462 ASSERT_EQUAL_64(0x1111111111111111, x5);
8463 ASSERT_EQUAL_64(0x2222222222222222, x4);
8464
8465 ASSERT_EQUAL_32(0x11111111U, w13);
8466 ASSERT_EQUAL_32(0x33333333U, w12);
8467 ASSERT_EQUAL_32(0x00000000U, w11);
8468 ASSERT_EQUAL_32(0x22222222U, w10);
8469 ASSERT_EQUAL_32(0x11111111U, w17);
8470 ASSERT_EQUAL_32(0x00000000U, w16);
8471 ASSERT_EQUAL_32(0x33333333U, w15);
8472 ASSERT_EQUAL_32(0x22222222U, w14);
8473
8474 ASSERT_EQUAL_32(0x11111111U, w18);
8475 ASSERT_EQUAL_32(0x11111111U, w19);
8476 ASSERT_EQUAL_32(0x11111111U, w20);
8477 ASSERT_EQUAL_32(0x11111111U, w21);
8478 ASSERT_EQUAL_64(0x3333333333333333, x22);
8479 ASSERT_EQUAL_64(0x0000000000000000, x23);
8480
8481 ASSERT_EQUAL_64(0x3333333333333333, x24);
8482 ASSERT_EQUAL_64(0x3333333333333333, x26);
8483
8484 ASSERT_EQUAL_32(0x33333333U, w25);
8485 ASSERT_EQUAL_32(0x00000000U, w27);
8486 ASSERT_EQUAL_32(0x22222222U, w28);
8487 ASSERT_EQUAL_32(0x33333333U, w29);
8488 TEARDOWN();
8489 }
8490
8491
TEST(noreg)8492 TEST(noreg) {
8493 // This test doesn't generate any code, but it verifies some invariants
8494 // related to NoReg.
8495 VIXL_CHECK(NoReg.Is(NoFPReg));
8496 VIXL_CHECK(NoFPReg.Is(NoReg));
8497 VIXL_CHECK(NoReg.Is(NoCPUReg));
8498 VIXL_CHECK(NoCPUReg.Is(NoReg));
8499 VIXL_CHECK(NoFPReg.Is(NoCPUReg));
8500 VIXL_CHECK(NoCPUReg.Is(NoFPReg));
8501
8502 VIXL_CHECK(NoReg.IsNone());
8503 VIXL_CHECK(NoFPReg.IsNone());
8504 VIXL_CHECK(NoCPUReg.IsNone());
8505 }
8506
8507
TEST(isvalid)8508 TEST(isvalid) {
8509 // This test doesn't generate any code, but it verifies some invariants
8510 // related to IsValid().
8511 VIXL_CHECK(!NoReg.IsValid());
8512 VIXL_CHECK(!NoFPReg.IsValid());
8513 VIXL_CHECK(!NoCPUReg.IsValid());
8514
8515 VIXL_CHECK(x0.IsValid());
8516 VIXL_CHECK(w0.IsValid());
8517 VIXL_CHECK(x30.IsValid());
8518 VIXL_CHECK(w30.IsValid());
8519 VIXL_CHECK(xzr.IsValid());
8520 VIXL_CHECK(wzr.IsValid());
8521
8522 VIXL_CHECK(sp.IsValid());
8523 VIXL_CHECK(wsp.IsValid());
8524
8525 VIXL_CHECK(d0.IsValid());
8526 VIXL_CHECK(s0.IsValid());
8527 VIXL_CHECK(d31.IsValid());
8528 VIXL_CHECK(s31.IsValid());
8529
8530 VIXL_CHECK(x0.IsValidRegister());
8531 VIXL_CHECK(w0.IsValidRegister());
8532 VIXL_CHECK(xzr.IsValidRegister());
8533 VIXL_CHECK(wzr.IsValidRegister());
8534 VIXL_CHECK(sp.IsValidRegister());
8535 VIXL_CHECK(wsp.IsValidRegister());
8536 VIXL_CHECK(!x0.IsValidFPRegister());
8537 VIXL_CHECK(!w0.IsValidFPRegister());
8538 VIXL_CHECK(!xzr.IsValidFPRegister());
8539 VIXL_CHECK(!wzr.IsValidFPRegister());
8540 VIXL_CHECK(!sp.IsValidFPRegister());
8541 VIXL_CHECK(!wsp.IsValidFPRegister());
8542
8543 VIXL_CHECK(d0.IsValidFPRegister());
8544 VIXL_CHECK(s0.IsValidFPRegister());
8545 VIXL_CHECK(!d0.IsValidRegister());
8546 VIXL_CHECK(!s0.IsValidRegister());
8547
8548 // Test the same as before, but using CPURegister types. This shouldn't make
8549 // any difference.
8550 VIXL_CHECK(static_cast<CPURegister>(x0).IsValid());
8551 VIXL_CHECK(static_cast<CPURegister>(w0).IsValid());
8552 VIXL_CHECK(static_cast<CPURegister>(x30).IsValid());
8553 VIXL_CHECK(static_cast<CPURegister>(w30).IsValid());
8554 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValid());
8555 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValid());
8556
8557 VIXL_CHECK(static_cast<CPURegister>(sp).IsValid());
8558 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValid());
8559
8560 VIXL_CHECK(static_cast<CPURegister>(d0).IsValid());
8561 VIXL_CHECK(static_cast<CPURegister>(s0).IsValid());
8562 VIXL_CHECK(static_cast<CPURegister>(d31).IsValid());
8563 VIXL_CHECK(static_cast<CPURegister>(s31).IsValid());
8564
8565 VIXL_CHECK(static_cast<CPURegister>(x0).IsValidRegister());
8566 VIXL_CHECK(static_cast<CPURegister>(w0).IsValidRegister());
8567 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValidRegister());
8568 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValidRegister());
8569 VIXL_CHECK(static_cast<CPURegister>(sp).IsValidRegister());
8570 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValidRegister());
8571 VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister());
8572 VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister());
8573 VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister());
8574 VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister());
8575 VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister());
8576 VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister());
8577
8578 VIXL_CHECK(static_cast<CPURegister>(d0).IsValidFPRegister());
8579 VIXL_CHECK(static_cast<CPURegister>(s0).IsValidFPRegister());
8580 VIXL_CHECK(!static_cast<CPURegister>(d0).IsValidRegister());
8581 VIXL_CHECK(!static_cast<CPURegister>(s0).IsValidRegister());
8582 }
8583
8584
TEST(printf)8585 TEST(printf) {
8586 SETUP_SIZE(BUF_SIZE * 2);
8587 START();
8588
8589 char const * test_plain_string = "Printf with no arguments.\n";
8590 char const * test_substring = "'This is a substring.'";
8591 RegisterDump before;
8592
8593 // Initialize x29 to the value of the stack pointer. We will use x29 as a
8594 // temporary stack pointer later, and initializing it in this way allows the
8595 // RegisterDump check to pass.
8596 __ Mov(x29, __ StackPointer());
8597
8598 // Test simple integer arguments.
8599 __ Mov(x0, 1234);
8600 __ Mov(x1, 0x1234);
8601
8602 // Test simple floating-point arguments.
8603 __ Fmov(d0, 1.234);
8604
8605 // Test pointer (string) arguments.
8606 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
8607
8608 // Test the maximum number of arguments, and sign extension.
8609 __ Mov(w3, 0xffffffff);
8610 __ Mov(w4, 0xffffffff);
8611 __ Mov(x5, 0xffffffffffffffff);
8612 __ Mov(x6, 0xffffffffffffffff);
8613 __ Fmov(s1, 1.234);
8614 __ Fmov(s2, 2.345);
8615 __ Fmov(d3, 3.456);
8616 __ Fmov(d4, 4.567);
8617
8618 // Test printing callee-saved registers.
8619 __ Mov(x28, 0x123456789abcdef);
8620 __ Fmov(d10, 42.0);
8621
8622 // Test with three arguments.
8623 __ Mov(x10, 3);
8624 __ Mov(x11, 40);
8625 __ Mov(x12, 500);
8626
8627 // A single character.
8628 __ Mov(w13, 'x');
8629
8630 // Check that we don't clobber any registers.
8631 before.Dump(&masm);
8632
8633 __ Printf(test_plain_string); // NOLINT(runtime/printf)
8634 __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
8635 __ Printf("w5: %" PRId32 ", x5: %" PRId64"\n", w5, x5);
8636 __ Printf("d0: %f\n", d0);
8637 __ Printf("Test %%s: %s\n", x2);
8638 __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
8639 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
8640 w3, w4, x5, x6);
8641 __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
8642 __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
8643 __ Printf("%g\n", d10);
8644 __ Printf("%%%%%s%%%c%%\n", x2, w13);
8645
8646 // Print the stack pointer (sp).
8647 __ Printf("StackPointer(sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8648 __ StackPointer(), __ StackPointer().W());
8649
8650 // Test with a different stack pointer.
8651 const Register old_stack_pointer = __ StackPointer();
8652 __ Mov(x29, old_stack_pointer);
8653 __ SetStackPointer(x29);
8654 // Print the stack pointer (not sp).
8655 __ Printf("StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8656 __ StackPointer(), __ StackPointer().W());
8657 __ Mov(old_stack_pointer, __ StackPointer());
8658 __ SetStackPointer(old_stack_pointer);
8659
8660 // Test with three arguments.
8661 __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
8662
8663 // Mixed argument types.
8664 __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
8665 w3, s1, x5, d3);
8666 __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n",
8667 s1, d3, w3, x5);
8668
8669 END();
8670 RUN();
8671
8672 // We cannot easily test the output of the Printf sequences, and because
8673 // Printf preserves all registers by default, we can't look at the number of
8674 // bytes that were printed. However, the printf_no_preserve test should check
8675 // that, and here we just test that we didn't clobber any registers.
8676 ASSERT_EQUAL_REGISTERS(before);
8677
8678 TEARDOWN();
8679 }
8680
8681
TEST(printf_no_preserve)8682 TEST(printf_no_preserve) {
8683 SETUP();
8684 START();
8685
8686 char const * test_plain_string = "Printf with no arguments.\n";
8687 char const * test_substring = "'This is a substring.'";
8688
8689 __ PrintfNoPreserve(test_plain_string);
8690 __ Mov(x19, x0);
8691
8692 // Test simple integer arguments.
8693 __ Mov(x0, 1234);
8694 __ Mov(x1, 0x1234);
8695 __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
8696 __ Mov(x20, x0);
8697
8698 // Test simple floating-point arguments.
8699 __ Fmov(d0, 1.234);
8700 __ PrintfNoPreserve("d0: %f\n", d0);
8701 __ Mov(x21, x0);
8702
8703 // Test pointer (string) arguments.
8704 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
8705 __ PrintfNoPreserve("Test %%s: %s\n", x2);
8706 __ Mov(x22, x0);
8707
8708 // Test the maximum number of arguments, and sign extension.
8709 __ Mov(w3, 0xffffffff);
8710 __ Mov(w4, 0xffffffff);
8711 __ Mov(x5, 0xffffffffffffffff);
8712 __ Mov(x6, 0xffffffffffffffff);
8713 __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
8714 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
8715 w3, w4, x5, x6);
8716 __ Mov(x23, x0);
8717
8718 __ Fmov(s1, 1.234);
8719 __ Fmov(s2, 2.345);
8720 __ Fmov(d3, 3.456);
8721 __ Fmov(d4, 4.567);
8722 __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
8723 __ Mov(x24, x0);
8724
8725 // Test printing callee-saved registers.
8726 __ Mov(x28, 0x123456789abcdef);
8727 __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
8728 __ Mov(x25, x0);
8729
8730 __ Fmov(d10, 42.0);
8731 __ PrintfNoPreserve("%g\n", d10);
8732 __ Mov(x26, x0);
8733
8734 // Test with a different stack pointer.
8735 const Register old_stack_pointer = __ StackPointer();
8736 __ Mov(x29, old_stack_pointer);
8737 __ SetStackPointer(x29);
8738 // Print the stack pointer (not sp).
8739 __ PrintfNoPreserve(
8740 "StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8741 __ StackPointer(), __ StackPointer().W());
8742 __ Mov(x27, x0);
8743 __ Mov(old_stack_pointer, __ StackPointer());
8744 __ SetStackPointer(old_stack_pointer);
8745
8746 // Test with three arguments.
8747 __ Mov(x3, 3);
8748 __ Mov(x4, 40);
8749 __ Mov(x5, 500);
8750 __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
8751 __ Mov(x28, x0);
8752
8753 // Mixed argument types.
8754 __ Mov(w3, 0xffffffff);
8755 __ Fmov(s1, 1.234);
8756 __ Mov(x5, 0xffffffffffffffff);
8757 __ Fmov(d3, 3.456);
8758 __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
8759 w3, s1, x5, d3);
8760 __ Mov(x29, x0);
8761
8762 END();
8763 RUN();
8764
8765 // We cannot easily test the exact output of the Printf sequences, but we can
8766 // use the return code to check that the string length was correct.
8767
8768 // Printf with no arguments.
8769 ASSERT_EQUAL_64(strlen(test_plain_string), x19);
8770 // x0: 1234, x1: 0x00001234
8771 ASSERT_EQUAL_64(25, x20);
8772 // d0: 1.234000
8773 ASSERT_EQUAL_64(13, x21);
8774 // Test %s: 'This is a substring.'
8775 ASSERT_EQUAL_64(32, x22);
8776 // w3(uint32): 4294967295
8777 // w4(int32): -1
8778 // x5(uint64): 18446744073709551615
8779 // x6(int64): -1
8780 ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
8781 // %f: 1.234000
8782 // %g: 2.345
8783 // %e: 3.456000e+00
8784 // %E: 4.567000E+00
8785 ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
8786 // 0x89abcdef, 0x123456789abcdef
8787 ASSERT_EQUAL_64(30, x25);
8788 // 42
8789 ASSERT_EQUAL_64(3, x26);
8790 // StackPointer(not sp): 0x00007fb037ae2370, 0x37ae2370
8791 // Note: This is an example value, but the field width is fixed here so the
8792 // string length is still predictable.
8793 ASSERT_EQUAL_64(53, x27);
8794 // 3=3, 4=40, 5=500
8795 ASSERT_EQUAL_64(17, x28);
8796 // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
8797 ASSERT_EQUAL_64(69, x29);
8798
8799 TEARDOWN();
8800 }
8801
8802
8803 #ifndef USE_SIMULATOR
TEST(trace)8804 TEST(trace) {
8805 // The Trace helper should not generate any code unless the simulator (or
8806 // debugger) is being used.
8807 SETUP();
8808 START();
8809
8810 Label start;
8811 __ Bind(&start);
8812 __ Trace(LOG_ALL, TRACE_ENABLE);
8813 __ Trace(LOG_ALL, TRACE_DISABLE);
8814 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
8815
8816 END();
8817 TEARDOWN();
8818 }
8819 #endif
8820
8821
8822 #ifndef USE_SIMULATOR
TEST(log)8823 TEST(log) {
8824 // The Log helper should not generate any code unless the simulator (or
8825 // debugger) is being used.
8826 SETUP();
8827 START();
8828
8829 Label start;
8830 __ Bind(&start);
8831 __ Log(LOG_ALL);
8832 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
8833
8834 END();
8835 TEARDOWN();
8836 }
8837 #endif
8838
8839
TEST(instruction_accurate_scope)8840 TEST(instruction_accurate_scope) {
8841 SETUP();
8842 START();
8843
8844 // By default macro instructions are allowed.
8845 VIXL_ASSERT(masm.AllowMacroInstructions());
8846 {
8847 InstructionAccurateScope scope1(&masm);
8848 VIXL_ASSERT(!masm.AllowMacroInstructions());
8849 {
8850 InstructionAccurateScope scope2(&masm);
8851 VIXL_ASSERT(!masm.AllowMacroInstructions());
8852 }
8853 VIXL_ASSERT(!masm.AllowMacroInstructions());
8854 }
8855 VIXL_ASSERT(masm.AllowMacroInstructions());
8856
8857 {
8858 InstructionAccurateScope scope(&masm, 2);
8859 __ add(x0, x0, x0);
8860 __ sub(x0, x0, x0);
8861 }
8862
8863 END();
8864 RUN();
8865 TEARDOWN();
8866 }
8867
8868
TEST(blr_lr)8869 TEST(blr_lr) {
8870 // A simple test to check that the simulator correcty handle "blr lr".
8871 SETUP();
8872
8873 START();
8874 Label target;
8875 Label end;
8876
8877 __ Mov(x0, 0x0);
8878 __ Adr(lr, &target);
8879
8880 __ Blr(lr);
8881 __ Mov(x0, 0xdeadbeef);
8882 __ B(&end);
8883
8884 __ Bind(&target);
8885 __ Mov(x0, 0xc001c0de);
8886
8887 __ Bind(&end);
8888 END();
8889
8890 RUN();
8891
8892 ASSERT_EQUAL_64(0xc001c0de, x0);
8893
8894 TEARDOWN();
8895 }
8896
8897
TEST(barriers)8898 TEST(barriers) {
8899 // Generate all supported barriers, this is just a smoke test
8900 SETUP();
8901
8902 START();
8903
8904 // DMB
8905 __ Dmb(FullSystem, BarrierAll);
8906 __ Dmb(FullSystem, BarrierReads);
8907 __ Dmb(FullSystem, BarrierWrites);
8908 __ Dmb(FullSystem, BarrierOther);
8909
8910 __ Dmb(InnerShareable, BarrierAll);
8911 __ Dmb(InnerShareable, BarrierReads);
8912 __ Dmb(InnerShareable, BarrierWrites);
8913 __ Dmb(InnerShareable, BarrierOther);
8914
8915 __ Dmb(NonShareable, BarrierAll);
8916 __ Dmb(NonShareable, BarrierReads);
8917 __ Dmb(NonShareable, BarrierWrites);
8918 __ Dmb(NonShareable, BarrierOther);
8919
8920 __ Dmb(OuterShareable, BarrierAll);
8921 __ Dmb(OuterShareable, BarrierReads);
8922 __ Dmb(OuterShareable, BarrierWrites);
8923 __ Dmb(OuterShareable, BarrierOther);
8924
8925 // DSB
8926 __ Dsb(FullSystem, BarrierAll);
8927 __ Dsb(FullSystem, BarrierReads);
8928 __ Dsb(FullSystem, BarrierWrites);
8929 __ Dsb(FullSystem, BarrierOther);
8930
8931 __ Dsb(InnerShareable, BarrierAll);
8932 __ Dsb(InnerShareable, BarrierReads);
8933 __ Dsb(InnerShareable, BarrierWrites);
8934 __ Dsb(InnerShareable, BarrierOther);
8935
8936 __ Dsb(NonShareable, BarrierAll);
8937 __ Dsb(NonShareable, BarrierReads);
8938 __ Dsb(NonShareable, BarrierWrites);
8939 __ Dsb(NonShareable, BarrierOther);
8940
8941 __ Dsb(OuterShareable, BarrierAll);
8942 __ Dsb(OuterShareable, BarrierReads);
8943 __ Dsb(OuterShareable, BarrierWrites);
8944 __ Dsb(OuterShareable, BarrierOther);
8945
8946 // ISB
8947 __ Isb();
8948
8949 END();
8950
8951 RUN();
8952
8953 TEARDOWN();
8954 }
8955
8956
TEST(process_nan_double)8957 TEST(process_nan_double) {
8958 // Make sure that NaN propagation works correctly.
8959 double sn = rawbits_to_double(0x7ff5555511111111);
8960 double qn = rawbits_to_double(0x7ffaaaaa11111111);
8961 VIXL_ASSERT(IsSignallingNaN(sn));
8962 VIXL_ASSERT(IsQuietNaN(qn));
8963
8964 // The input NaNs after passing through ProcessNaN.
8965 double sn_proc = rawbits_to_double(0x7ffd555511111111);
8966 double qn_proc = qn;
8967 VIXL_ASSERT(IsQuietNaN(sn_proc));
8968 VIXL_ASSERT(IsQuietNaN(qn_proc));
8969
8970 SETUP();
8971 START();
8972
8973 // Execute a number of instructions which all use ProcessNaN, and check that
8974 // they all handle the NaN correctly.
8975 __ Fmov(d0, sn);
8976 __ Fmov(d10, qn);
8977
8978 // Operations that always propagate NaNs unchanged, even signalling NaNs.
8979 // - Signalling NaN
8980 __ Fmov(d1, d0);
8981 __ Fabs(d2, d0);
8982 __ Fneg(d3, d0);
8983 // - Quiet NaN
8984 __ Fmov(d11, d10);
8985 __ Fabs(d12, d10);
8986 __ Fneg(d13, d10);
8987
8988 // Operations that use ProcessNaN.
8989 // - Signalling NaN
8990 __ Fsqrt(d4, d0);
8991 __ Frinta(d5, d0);
8992 __ Frintn(d6, d0);
8993 __ Frintz(d7, d0);
8994 // - Quiet NaN
8995 __ Fsqrt(d14, d10);
8996 __ Frinta(d15, d10);
8997 __ Frintn(d16, d10);
8998 __ Frintz(d17, d10);
8999
9000 // The behaviour of fcvt is checked in TEST(fcvt_sd).
9001
9002 END();
9003 RUN();
9004
9005 uint64_t qn_raw = double_to_rawbits(qn);
9006 uint64_t sn_raw = double_to_rawbits(sn);
9007
9008 // - Signalling NaN
9009 ASSERT_EQUAL_FP64(sn, d1);
9010 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2);
9011 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3);
9012 // - Quiet NaN
9013 ASSERT_EQUAL_FP64(qn, d11);
9014 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12);
9015 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13);
9016
9017 // - Signalling NaN
9018 ASSERT_EQUAL_FP64(sn_proc, d4);
9019 ASSERT_EQUAL_FP64(sn_proc, d5);
9020 ASSERT_EQUAL_FP64(sn_proc, d6);
9021 ASSERT_EQUAL_FP64(sn_proc, d7);
9022 // - Quiet NaN
9023 ASSERT_EQUAL_FP64(qn_proc, d14);
9024 ASSERT_EQUAL_FP64(qn_proc, d15);
9025 ASSERT_EQUAL_FP64(qn_proc, d16);
9026 ASSERT_EQUAL_FP64(qn_proc, d17);
9027
9028 TEARDOWN();
9029 }
9030
9031
TEST(process_nan_float)9032 TEST(process_nan_float) {
9033 // Make sure that NaN propagation works correctly.
9034 float sn = rawbits_to_float(0x7f951111);
9035 float qn = rawbits_to_float(0x7fea1111);
9036 VIXL_ASSERT(IsSignallingNaN(sn));
9037 VIXL_ASSERT(IsQuietNaN(qn));
9038
9039 // The input NaNs after passing through ProcessNaN.
9040 float sn_proc = rawbits_to_float(0x7fd51111);
9041 float qn_proc = qn;
9042 VIXL_ASSERT(IsQuietNaN(sn_proc));
9043 VIXL_ASSERT(IsQuietNaN(qn_proc));
9044
9045 SETUP();
9046 START();
9047
9048 // Execute a number of instructions which all use ProcessNaN, and check that
9049 // they all handle the NaN correctly.
9050 __ Fmov(s0, sn);
9051 __ Fmov(s10, qn);
9052
9053 // Operations that always propagate NaNs unchanged, even signalling NaNs.
9054 // - Signalling NaN
9055 __ Fmov(s1, s0);
9056 __ Fabs(s2, s0);
9057 __ Fneg(s3, s0);
9058 // - Quiet NaN
9059 __ Fmov(s11, s10);
9060 __ Fabs(s12, s10);
9061 __ Fneg(s13, s10);
9062
9063 // Operations that use ProcessNaN.
9064 // - Signalling NaN
9065 __ Fsqrt(s4, s0);
9066 __ Frinta(s5, s0);
9067 __ Frintn(s6, s0);
9068 __ Frintz(s7, s0);
9069 // - Quiet NaN
9070 __ Fsqrt(s14, s10);
9071 __ Frinta(s15, s10);
9072 __ Frintn(s16, s10);
9073 __ Frintz(s17, s10);
9074
9075 // The behaviour of fcvt is checked in TEST(fcvt_sd).
9076
9077 END();
9078 RUN();
9079
9080 uint32_t qn_raw = float_to_rawbits(qn);
9081 uint32_t sn_raw = float_to_rawbits(sn);
9082
9083 // - Signalling NaN
9084 ASSERT_EQUAL_FP32(sn, s1);
9085 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2);
9086 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3);
9087 // - Quiet NaN
9088 ASSERT_EQUAL_FP32(qn, s11);
9089 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12);
9090 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13);
9091
9092 // - Signalling NaN
9093 ASSERT_EQUAL_FP32(sn_proc, s4);
9094 ASSERT_EQUAL_FP32(sn_proc, s5);
9095 ASSERT_EQUAL_FP32(sn_proc, s6);
9096 ASSERT_EQUAL_FP32(sn_proc, s7);
9097 // - Quiet NaN
9098 ASSERT_EQUAL_FP32(qn_proc, s14);
9099 ASSERT_EQUAL_FP32(qn_proc, s15);
9100 ASSERT_EQUAL_FP32(qn_proc, s16);
9101 ASSERT_EQUAL_FP32(qn_proc, s17);
9102
9103 TEARDOWN();
9104 }
9105
9106
ProcessNaNsHelper(double n,double m,double expected)9107 static void ProcessNaNsHelper(double n, double m, double expected) {
9108 VIXL_ASSERT(isnan(n) || isnan(m));
9109 VIXL_ASSERT(isnan(expected));
9110
9111 SETUP();
9112 START();
9113
9114 // Execute a number of instructions which all use ProcessNaNs, and check that
9115 // they all propagate NaNs correctly.
9116 __ Fmov(d0, n);
9117 __ Fmov(d1, m);
9118
9119 __ Fadd(d2, d0, d1);
9120 __ Fsub(d3, d0, d1);
9121 __ Fmul(d4, d0, d1);
9122 __ Fdiv(d5, d0, d1);
9123 __ Fmax(d6, d0, d1);
9124 __ Fmin(d7, d0, d1);
9125
9126 END();
9127 RUN();
9128
9129 ASSERT_EQUAL_FP64(expected, d2);
9130 ASSERT_EQUAL_FP64(expected, d3);
9131 ASSERT_EQUAL_FP64(expected, d4);
9132 ASSERT_EQUAL_FP64(expected, d5);
9133 ASSERT_EQUAL_FP64(expected, d6);
9134 ASSERT_EQUAL_FP64(expected, d7);
9135
9136 TEARDOWN();
9137 }
9138
9139
TEST(process_nans_double)9140 TEST(process_nans_double) {
9141 // Make sure that NaN propagation works correctly.
9142 double sn = rawbits_to_double(0x7ff5555511111111);
9143 double sm = rawbits_to_double(0x7ff5555522222222);
9144 double qn = rawbits_to_double(0x7ffaaaaa11111111);
9145 double qm = rawbits_to_double(0x7ffaaaaa22222222);
9146 VIXL_ASSERT(IsSignallingNaN(sn));
9147 VIXL_ASSERT(IsSignallingNaN(sm));
9148 VIXL_ASSERT(IsQuietNaN(qn));
9149 VIXL_ASSERT(IsQuietNaN(qm));
9150
9151 // The input NaNs after passing through ProcessNaN.
9152 double sn_proc = rawbits_to_double(0x7ffd555511111111);
9153 double sm_proc = rawbits_to_double(0x7ffd555522222222);
9154 double qn_proc = qn;
9155 double qm_proc = qm;
9156 VIXL_ASSERT(IsQuietNaN(sn_proc));
9157 VIXL_ASSERT(IsQuietNaN(sm_proc));
9158 VIXL_ASSERT(IsQuietNaN(qn_proc));
9159 VIXL_ASSERT(IsQuietNaN(qm_proc));
9160
9161 // Quiet NaNs are propagated.
9162 ProcessNaNsHelper(qn, 0, qn_proc);
9163 ProcessNaNsHelper(0, qm, qm_proc);
9164 ProcessNaNsHelper(qn, qm, qn_proc);
9165
9166 // Signalling NaNs are propagated, and made quiet.
9167 ProcessNaNsHelper(sn, 0, sn_proc);
9168 ProcessNaNsHelper(0, sm, sm_proc);
9169 ProcessNaNsHelper(sn, sm, sn_proc);
9170
9171 // Signalling NaNs take precedence over quiet NaNs.
9172 ProcessNaNsHelper(sn, qm, sn_proc);
9173 ProcessNaNsHelper(qn, sm, sm_proc);
9174 ProcessNaNsHelper(sn, sm, sn_proc);
9175 }
9176
9177
ProcessNaNsHelper(float n,float m,float expected)9178 static void ProcessNaNsHelper(float n, float m, float expected) {
9179 VIXL_ASSERT(isnan(n) || isnan(m));
9180 VIXL_ASSERT(isnan(expected));
9181
9182 SETUP();
9183 START();
9184
9185 // Execute a number of instructions which all use ProcessNaNs, and check that
9186 // they all propagate NaNs correctly.
9187 __ Fmov(s0, n);
9188 __ Fmov(s1, m);
9189
9190 __ Fadd(s2, s0, s1);
9191 __ Fsub(s3, s0, s1);
9192 __ Fmul(s4, s0, s1);
9193 __ Fdiv(s5, s0, s1);
9194 __ Fmax(s6, s0, s1);
9195 __ Fmin(s7, s0, s1);
9196
9197 END();
9198 RUN();
9199
9200 ASSERT_EQUAL_FP32(expected, s2);
9201 ASSERT_EQUAL_FP32(expected, s3);
9202 ASSERT_EQUAL_FP32(expected, s4);
9203 ASSERT_EQUAL_FP32(expected, s5);
9204 ASSERT_EQUAL_FP32(expected, s6);
9205 ASSERT_EQUAL_FP32(expected, s7);
9206
9207 TEARDOWN();
9208 }
9209
9210
TEST(process_nans_float)9211 TEST(process_nans_float) {
9212 // Make sure that NaN propagation works correctly.
9213 float sn = rawbits_to_float(0x7f951111);
9214 float sm = rawbits_to_float(0x7f952222);
9215 float qn = rawbits_to_float(0x7fea1111);
9216 float qm = rawbits_to_float(0x7fea2222);
9217 VIXL_ASSERT(IsSignallingNaN(sn));
9218 VIXL_ASSERT(IsSignallingNaN(sm));
9219 VIXL_ASSERT(IsQuietNaN(qn));
9220 VIXL_ASSERT(IsQuietNaN(qm));
9221
9222 // The input NaNs after passing through ProcessNaN.
9223 float sn_proc = rawbits_to_float(0x7fd51111);
9224 float sm_proc = rawbits_to_float(0x7fd52222);
9225 float qn_proc = qn;
9226 float qm_proc = qm;
9227 VIXL_ASSERT(IsQuietNaN(sn_proc));
9228 VIXL_ASSERT(IsQuietNaN(sm_proc));
9229 VIXL_ASSERT(IsQuietNaN(qn_proc));
9230 VIXL_ASSERT(IsQuietNaN(qm_proc));
9231
9232 // Quiet NaNs are propagated.
9233 ProcessNaNsHelper(qn, 0, qn_proc);
9234 ProcessNaNsHelper(0, qm, qm_proc);
9235 ProcessNaNsHelper(qn, qm, qn_proc);
9236
9237 // Signalling NaNs are propagated, and made quiet.
9238 ProcessNaNsHelper(sn, 0, sn_proc);
9239 ProcessNaNsHelper(0, sm, sm_proc);
9240 ProcessNaNsHelper(sn, sm, sn_proc);
9241
9242 // Signalling NaNs take precedence over quiet NaNs.
9243 ProcessNaNsHelper(sn, qm, sn_proc);
9244 ProcessNaNsHelper(qn, sm, sm_proc);
9245 ProcessNaNsHelper(sn, sm, sn_proc);
9246 }
9247
9248
DefaultNaNHelper(float n,float m,float a)9249 static void DefaultNaNHelper(float n, float m, float a) {
9250 VIXL_ASSERT(isnan(n) || isnan(m) || isnan(a));
9251
9252 bool test_1op = isnan(n);
9253 bool test_2op = isnan(n) || isnan(m);
9254
9255 SETUP();
9256 START();
9257
9258 // Enable Default-NaN mode in the FPCR.
9259 __ Mrs(x0, FPCR);
9260 __ Orr(x1, x0, DN_mask);
9261 __ Msr(FPCR, x1);
9262
9263 // Execute a number of instructions which all use ProcessNaNs, and check that
9264 // they all produce the default NaN.
9265 __ Fmov(s0, n);
9266 __ Fmov(s1, m);
9267 __ Fmov(s2, a);
9268
9269 if (test_1op) {
9270 // Operations that always propagate NaNs unchanged, even signalling NaNs.
9271 __ Fmov(s10, s0);
9272 __ Fabs(s11, s0);
9273 __ Fneg(s12, s0);
9274
9275 // Operations that use ProcessNaN.
9276 __ Fsqrt(s13, s0);
9277 __ Frinta(s14, s0);
9278 __ Frintn(s15, s0);
9279 __ Frintz(s16, s0);
9280
9281 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
9282 __ Fcvt(d17, s0);
9283 }
9284
9285 if (test_2op) {
9286 __ Fadd(s18, s0, s1);
9287 __ Fsub(s19, s0, s1);
9288 __ Fmul(s20, s0, s1);
9289 __ Fdiv(s21, s0, s1);
9290 __ Fmax(s22, s0, s1);
9291 __ Fmin(s23, s0, s1);
9292 }
9293
9294 __ Fmadd(s24, s0, s1, s2);
9295 __ Fmsub(s25, s0, s1, s2);
9296 __ Fnmadd(s26, s0, s1, s2);
9297 __ Fnmsub(s27, s0, s1, s2);
9298
9299 // Restore FPCR.
9300 __ Msr(FPCR, x0);
9301
9302 END();
9303 RUN();
9304
9305 if (test_1op) {
9306 uint32_t n_raw = float_to_rawbits(n);
9307 ASSERT_EQUAL_FP32(n, s10);
9308 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11);
9309 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12);
9310 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13);
9311 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14);
9312 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15);
9313 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16);
9314 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17);
9315 }
9316
9317 if (test_2op) {
9318 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18);
9319 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19);
9320 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20);
9321 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21);
9322 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22);
9323 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23);
9324 }
9325
9326 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24);
9327 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25);
9328 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26);
9329 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27);
9330
9331 TEARDOWN();
9332 }
9333
9334
TEST(default_nan_float)9335 TEST(default_nan_float) {
9336 float sn = rawbits_to_float(0x7f951111);
9337 float sm = rawbits_to_float(0x7f952222);
9338 float sa = rawbits_to_float(0x7f95aaaa);
9339 float qn = rawbits_to_float(0x7fea1111);
9340 float qm = rawbits_to_float(0x7fea2222);
9341 float qa = rawbits_to_float(0x7feaaaaa);
9342 VIXL_ASSERT(IsSignallingNaN(sn));
9343 VIXL_ASSERT(IsSignallingNaN(sm));
9344 VIXL_ASSERT(IsSignallingNaN(sa));
9345 VIXL_ASSERT(IsQuietNaN(qn));
9346 VIXL_ASSERT(IsQuietNaN(qm));
9347 VIXL_ASSERT(IsQuietNaN(qa));
9348
9349 // - Signalling NaNs
9350 DefaultNaNHelper(sn, 0.0f, 0.0f);
9351 DefaultNaNHelper(0.0f, sm, 0.0f);
9352 DefaultNaNHelper(0.0f, 0.0f, sa);
9353 DefaultNaNHelper(sn, sm, 0.0f);
9354 DefaultNaNHelper(0.0f, sm, sa);
9355 DefaultNaNHelper(sn, 0.0f, sa);
9356 DefaultNaNHelper(sn, sm, sa);
9357 // - Quiet NaNs
9358 DefaultNaNHelper(qn, 0.0f, 0.0f);
9359 DefaultNaNHelper(0.0f, qm, 0.0f);
9360 DefaultNaNHelper(0.0f, 0.0f, qa);
9361 DefaultNaNHelper(qn, qm, 0.0f);
9362 DefaultNaNHelper(0.0f, qm, qa);
9363 DefaultNaNHelper(qn, 0.0f, qa);
9364 DefaultNaNHelper(qn, qm, qa);
9365 // - Mixed NaNs
9366 DefaultNaNHelper(qn, sm, sa);
9367 DefaultNaNHelper(sn, qm, sa);
9368 DefaultNaNHelper(sn, sm, qa);
9369 DefaultNaNHelper(qn, qm, sa);
9370 DefaultNaNHelper(sn, qm, qa);
9371 DefaultNaNHelper(qn, sm, qa);
9372 DefaultNaNHelper(qn, qm, qa);
9373 }
9374
9375
DefaultNaNHelper(double n,double m,double a)9376 static void DefaultNaNHelper(double n, double m, double a) {
9377 VIXL_ASSERT(isnan(n) || isnan(m) || isnan(a));
9378
9379 bool test_1op = isnan(n);
9380 bool test_2op = isnan(n) || isnan(m);
9381
9382 SETUP();
9383 START();
9384
9385 // Enable Default-NaN mode in the FPCR.
9386 __ Mrs(x0, FPCR);
9387 __ Orr(x1, x0, DN_mask);
9388 __ Msr(FPCR, x1);
9389
9390 // Execute a number of instructions which all use ProcessNaNs, and check that
9391 // they all produce the default NaN.
9392 __ Fmov(d0, n);
9393 __ Fmov(d1, m);
9394 __ Fmov(d2, a);
9395
9396 if (test_1op) {
9397 // Operations that always propagate NaNs unchanged, even signalling NaNs.
9398 __ Fmov(d10, d0);
9399 __ Fabs(d11, d0);
9400 __ Fneg(d12, d0);
9401
9402 // Operations that use ProcessNaN.
9403 __ Fsqrt(d13, d0);
9404 __ Frinta(d14, d0);
9405 __ Frintn(d15, d0);
9406 __ Frintz(d16, d0);
9407
9408 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
9409 __ Fcvt(s17, d0);
9410 }
9411
9412 if (test_2op) {
9413 __ Fadd(d18, d0, d1);
9414 __ Fsub(d19, d0, d1);
9415 __ Fmul(d20, d0, d1);
9416 __ Fdiv(d21, d0, d1);
9417 __ Fmax(d22, d0, d1);
9418 __ Fmin(d23, d0, d1);
9419 }
9420
9421 __ Fmadd(d24, d0, d1, d2);
9422 __ Fmsub(d25, d0, d1, d2);
9423 __ Fnmadd(d26, d0, d1, d2);
9424 __ Fnmsub(d27, d0, d1, d2);
9425
9426 // Restore FPCR.
9427 __ Msr(FPCR, x0);
9428
9429 END();
9430 RUN();
9431
9432 if (test_1op) {
9433 uint64_t n_raw = double_to_rawbits(n);
9434 ASSERT_EQUAL_FP64(n, d10);
9435 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11);
9436 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12);
9437 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
9438 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14);
9439 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15);
9440 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16);
9441 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17);
9442 }
9443
9444 if (test_2op) {
9445 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18);
9446 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19);
9447 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20);
9448 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21);
9449 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22);
9450 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23);
9451 }
9452
9453 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24);
9454 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25);
9455 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26);
9456 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27);
9457
9458 TEARDOWN();
9459 }
9460
9461
TEST(default_nan_double)9462 TEST(default_nan_double) {
9463 double sn = rawbits_to_double(0x7ff5555511111111);
9464 double sm = rawbits_to_double(0x7ff5555522222222);
9465 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
9466 double qn = rawbits_to_double(0x7ffaaaaa11111111);
9467 double qm = rawbits_to_double(0x7ffaaaaa22222222);
9468 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
9469 VIXL_ASSERT(IsSignallingNaN(sn));
9470 VIXL_ASSERT(IsSignallingNaN(sm));
9471 VIXL_ASSERT(IsSignallingNaN(sa));
9472 VIXL_ASSERT(IsQuietNaN(qn));
9473 VIXL_ASSERT(IsQuietNaN(qm));
9474 VIXL_ASSERT(IsQuietNaN(qa));
9475
9476 // - Signalling NaNs
9477 DefaultNaNHelper(sn, 0.0, 0.0);
9478 DefaultNaNHelper(0.0, sm, 0.0);
9479 DefaultNaNHelper(0.0, 0.0, sa);
9480 DefaultNaNHelper(sn, sm, 0.0);
9481 DefaultNaNHelper(0.0, sm, sa);
9482 DefaultNaNHelper(sn, 0.0, sa);
9483 DefaultNaNHelper(sn, sm, sa);
9484 // - Quiet NaNs
9485 DefaultNaNHelper(qn, 0.0, 0.0);
9486 DefaultNaNHelper(0.0, qm, 0.0);
9487 DefaultNaNHelper(0.0, 0.0, qa);
9488 DefaultNaNHelper(qn, qm, 0.0);
9489 DefaultNaNHelper(0.0, qm, qa);
9490 DefaultNaNHelper(qn, 0.0, qa);
9491 DefaultNaNHelper(qn, qm, qa);
9492 // - Mixed NaNs
9493 DefaultNaNHelper(qn, sm, sa);
9494 DefaultNaNHelper(sn, qm, sa);
9495 DefaultNaNHelper(sn, sm, qa);
9496 DefaultNaNHelper(qn, qm, sa);
9497 DefaultNaNHelper(sn, qm, qa);
9498 DefaultNaNHelper(qn, sm, qa);
9499 DefaultNaNHelper(qn, qm, qa);
9500 }
9501
9502
9503 } // namespace vixl
9504