blob: c2a021a9e876321518ce03d043038d47f617f9b4 [file] [log] [blame]
armvixlad96eda2013-06-14 11:42:37 +01001// 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 <string.h>
armvixl578645f2013-08-15 17:21:42 +010029#include <math.h>
30#include <float.h>
armvixlad96eda2013-06-14 11:42:37 +010031
32#include "cctest.h"
33#include "test-utils-a64.h"
34#include "a64/macro-assembler-a64.h"
35#include "a64/simulator-a64.h"
36#include "a64/debugger-a64.h"
37#include "a64/disasm-a64.h"
38#include "a64/cpu-a64.h"
39
40namespace vixl {
41
42// Test infrastructure.
43//
44// Tests are functions which accept no parameters and have no return values.
45// The testing code should not perform an explicit return once completed. For
46// example to test the mov immediate instruction a very simple test would be:
47//
48// TEST(mov_x0_one) {
49// SETUP();
50//
51// START();
52// __ mov(x0, Operand(1));
53// END();
54//
55// RUN();
56//
57// ASSERT_EQUAL_64(1, x0);
58//
59// TEARDOWN();
60// }
61//
62// Within a START ... END block all registers but sp can be modified. sp has to
63// be explicitly saved/restored. The END() macro replaces the function return
64// so it may appear multiple times in a test if the test has multiple exit
65// points.
66//
67// Once the test has been run all integer and floating point registers as well
68// as flags are accessible through a RegisterDump instance, see
69// utils-a64.cc for more info on RegisterDump.
70//
71// We provide some helper assert to handle common cases:
72//
73// ASSERT_EQUAL_32(int32_t, int_32t)
74// ASSERT_EQUAL_FP32(float, float)
75// ASSERT_EQUAL_32(int32_t, W register)
76// ASSERT_EQUAL_FP32(float, S register)
77// ASSERT_EQUAL_64(int64_t, int_64t)
78// ASSERT_EQUAL_FP64(double, double)
79// ASSERT_EQUAL_64(int64_t, X register)
80// ASSERT_EQUAL_64(X register, X register)
81// ASSERT_EQUAL_FP64(double, D register)
82//
83// e.g. ASSERT_EQUAL_64(0.5, d30);
84//
armvixl578645f2013-08-15 17:21:42 +010085// If more advanced computation is required before the assert then access the
armvixlad96eda2013-06-14 11:42:37 +010086// RegisterDump named core directly:
87//
88// ASSERT_EQUAL_64(0x1234, core->reg_x0() & 0xffff);
89
90
91#define __ masm.
92#define TEST(name) TEST_(ASM_##name)
93
94#define BUF_SIZE (4096)
95
96#define SETUP() SETUP_SIZE(BUF_SIZE)
97
98#ifdef USE_SIMULATOR
99
100// Run tests with the simulator.
101#define SETUP_SIZE(buf_size) \
102 byte* buf = new byte[buf_size]; \
103 MacroAssembler masm(buf, buf_size); \
104 Decoder decoder; \
105 Simulator* simulator = NULL; \
106 if (Cctest::run_debugger()) { \
107 simulator = new Debugger(&decoder); \
108 } else { \
109 simulator = new Simulator(&decoder); \
110 simulator->set_disasm_trace(Cctest::trace_sim()); \
111 } \
112 simulator->set_coloured_trace(Cctest::coloured_trace()); \
armvixl578645f2013-08-15 17:21:42 +0100113 simulator->set_instruction_stats(Cctest::instruction_stats()); \
armvixlad96eda2013-06-14 11:42:37 +0100114 RegisterDump core
115
116#define START() \
117 masm.Reset(); \
118 simulator->ResetState(); \
119 __ PushCalleeSavedRegisters(); \
120 if (Cctest::run_debugger()) { \
121 if (Cctest::trace_reg()) { \
122 __ Trace(LOG_STATE, TRACE_ENABLE); \
123 } \
124 if (Cctest::trace_sim()) { \
125 __ Trace(LOG_DISASM, TRACE_ENABLE); \
126 } \
armvixl578645f2013-08-15 17:21:42 +0100127 } \
128 if (Cctest::instruction_stats()) { \
129 __ EnableInstrumentation(); \
armvixlad96eda2013-06-14 11:42:37 +0100130 }
131
132#define END() \
armvixl578645f2013-08-15 17:21:42 +0100133 if (Cctest::instruction_stats()) { \
134 __ DisableInstrumentation(); \
135 } \
armvixlad96eda2013-06-14 11:42:37 +0100136 if (Cctest::run_debugger()) { \
137 __ Trace(LOG_ALL, TRACE_DISABLE); \
138 } \
139 core.Dump(&masm); \
140 __ PopCalleeSavedRegisters(); \
141 __ Ret(); \
142 masm.FinalizeCode()
143
144#define RUN() \
145 simulator->RunFrom(reinterpret_cast<Instruction*>(buf))
146
147#define TEARDOWN() \
148 delete simulator; \
149 delete[] buf;
150
151#else // ifdef USE_SIMULATOR.
152// Run the test on real hardware or models.
153#define SETUP_SIZE(buf_size) \
154 byte* buf = new byte[buf_size]; \
155 MacroAssembler masm(buf, buf_size); \
156 RegisterDump core; \
157 CPU::SetUp()
158
159#define START() \
160 masm.Reset(); \
161 __ PushCalleeSavedRegisters()
162
163#define END() \
164 core.Dump(&masm); \
165 __ PopCalleeSavedRegisters(); \
166 __ Ret(); \
167 masm.FinalizeCode()
168
169#define RUN() \
170 CPU::EnsureIAndDCacheCoherency(&buf, sizeof(buf)); \
171 { \
172 void (*test_function)(void); \
173 memcpy(&test_function, &buf, sizeof(buf)); \
174 test_function(); \
175 }
176
177#define TEARDOWN() \
178 delete[] buf;
179
180#endif // ifdef USE_SIMULATOR.
181
182#define ASSERT_EQUAL_NZCV(expected) \
183 assert(EqualNzcv(expected, core.flags_nzcv()))
184
185#define ASSERT_EQUAL_REGISTERS(expected) \
186 assert(EqualRegisters(&expected, &core))
187
188#define ASSERT_EQUAL_32(expected, result) \
189 assert(Equal32(static_cast<uint32_t>(expected), &core, result))
190
191#define ASSERT_EQUAL_FP32(expected, result) \
192 assert(EqualFP32(expected, &core, result))
193
194#define ASSERT_EQUAL_64(expected, result) \
195 assert(Equal64(expected, &core, result))
196
197#define ASSERT_EQUAL_FP64(expected, result) \
198 assert(EqualFP64(expected, &core, result))
199
200#define ASSERT_LITERAL_POOL_SIZE(expected) \
201 assert((expected) == (__ LiteralPoolSize()))
202
203
204TEST(stack_ops) {
205 SETUP();
206
207 START();
208 // save sp.
209 __ Mov(x29, sp);
210
211 // Set the sp to a known value.
212 __ Mov(sp, 0x1004);
213 __ Mov(x0, sp);
214
215 // Add immediate to the sp, and move the result to a normal register.
216 __ Add(sp, sp, Operand(0x50));
217 __ Mov(x1, sp);
218
219 // Add extended to the sp, and move the result to a normal register.
220 __ Mov(x17, 0xfff);
221 __ Add(sp, sp, Operand(x17, SXTB));
222 __ Mov(x2, sp);
223
224 // Create an sp using a logical instruction, and move to normal register.
225 __ Orr(sp, xzr, Operand(0x1fff));
226 __ Mov(x3, sp);
227
228 // Write wsp using a logical instruction.
229 __ Orr(wsp, wzr, Operand(0xfffffff8L));
230 __ Mov(x4, sp);
231
232 // Write sp, and read back wsp.
233 __ Orr(sp, xzr, Operand(0xfffffff8L));
234 __ Mov(w5, wsp);
235
236 // restore sp.
237 __ Mov(sp, x29);
238 END();
239
240 RUN();
241
242 ASSERT_EQUAL_64(0x1004, x0);
243 ASSERT_EQUAL_64(0x1054, x1);
244 ASSERT_EQUAL_64(0x1053, x2);
245 ASSERT_EQUAL_64(0x1fff, x3);
246 ASSERT_EQUAL_64(0xfffffff8, x4);
247 ASSERT_EQUAL_64(0xfffffff8, x5);
248
249 TEARDOWN();
250}
251
252
253TEST(mvn) {
254 SETUP();
255
256 START();
257 __ Mvn(w0, 0xfff);
258 __ Mvn(x1, 0xfff);
259 __ Mvn(w2, Operand(w0, LSL, 1));
260 __ Mvn(x3, Operand(x1, LSL, 2));
261 __ Mvn(w4, Operand(w0, LSR, 3));
262 __ Mvn(x5, Operand(x1, LSR, 4));
263 __ Mvn(w6, Operand(w0, ASR, 11));
264 __ Mvn(x7, Operand(x1, ASR, 12));
265 __ Mvn(w8, Operand(w0, ROR, 13));
266 __ Mvn(x9, Operand(x1, ROR, 14));
267 __ Mvn(w10, Operand(w2, UXTB));
268 __ Mvn(x11, Operand(x2, SXTB, 1));
269 __ Mvn(w12, Operand(w2, UXTH, 2));
270 __ Mvn(x13, Operand(x2, SXTH, 3));
271 __ Mvn(x14, Operand(w2, UXTW, 4));
272 __ Mvn(x15, Operand(w2, SXTW, 4));
273 END();
274
275 RUN();
276
277 ASSERT_EQUAL_64(0xfffff000, x0);
278 ASSERT_EQUAL_64(0xfffffffffffff000UL, x1);
279 ASSERT_EQUAL_64(0x00001fff, x2);
280 ASSERT_EQUAL_64(0x0000000000003fffUL, x3);
281 ASSERT_EQUAL_64(0xe00001ff, x4);
282 ASSERT_EQUAL_64(0xf0000000000000ffUL, x5);
283 ASSERT_EQUAL_64(0x00000001, x6);
284 ASSERT_EQUAL_64(0x0, x7);
285 ASSERT_EQUAL_64(0x7ff80000, x8);
286 ASSERT_EQUAL_64(0x3ffc000000000000UL, x9);
287 ASSERT_EQUAL_64(0xffffff00, x10);
288 ASSERT_EQUAL_64(0x0000000000000001UL, x11);
289 ASSERT_EQUAL_64(0xffff8003, x12);
290 ASSERT_EQUAL_64(0xffffffffffff0007UL, x13);
291 ASSERT_EQUAL_64(0xfffffffffffe000fUL, x14);
292 ASSERT_EQUAL_64(0xfffffffffffe000fUL, x15);
293
294 TEARDOWN();
295}
296
297
298TEST(mov) {
299 SETUP();
300
301 START();
302 __ Mov(x0, 0xffffffffffffffffL);
303 __ Mov(x1, 0xffffffffffffffffL);
304 __ Mov(x2, 0xffffffffffffffffL);
305 __ Mov(x3, 0xffffffffffffffffL);
306
307 __ Mov(x0, 0x0123456789abcdefL);
308
309 __ movz(x1, 0xabcdL << 16);
310 __ movk(x2, 0xabcdL << 32);
311 __ movn(x3, 0xabcdL << 48);
312
313 __ Mov(x4, 0x0123456789abcdefL);
314 __ Mov(x5, x4);
315
316 __ Mov(w6, -1);
317
318 // Test that moves back to the same register have the desired effect. This
319 // is a no-op for X registers, and a truncation for W registers.
320 __ Mov(x7, 0x0123456789abcdefL);
321 __ Mov(x7, x7);
322 __ Mov(x8, 0x0123456789abcdefL);
323 __ Mov(w8, w8);
324 __ Mov(x9, 0x0123456789abcdefL);
325 __ Mov(x9, Operand(x9));
326 __ Mov(x10, 0x0123456789abcdefL);
327 __ Mov(w10, Operand(w10));
328
329 __ Mov(w11, 0xfff);
330 __ Mov(x12, 0xfff);
331 __ Mov(w13, Operand(w11, LSL, 1));
332 __ Mov(x14, Operand(x12, LSL, 2));
333 __ Mov(w15, Operand(w11, LSR, 3));
334 __ Mov(x18, Operand(x12, LSR, 4));
335 __ Mov(w19, Operand(w11, ASR, 11));
336 __ Mov(x20, Operand(x12, ASR, 12));
337 __ Mov(w21, Operand(w11, ROR, 13));
338 __ Mov(x22, Operand(x12, ROR, 14));
339 __ Mov(w23, Operand(w13, UXTB));
340 __ Mov(x24, Operand(x13, SXTB, 1));
341 __ Mov(w25, Operand(w13, UXTH, 2));
342 __ Mov(x26, Operand(x13, SXTH, 3));
343 __ Mov(x27, Operand(w13, UXTW, 4));
344 END();
345
346 RUN();
347
348 ASSERT_EQUAL_64(0x0123456789abcdefL, x0);
349 ASSERT_EQUAL_64(0x00000000abcd0000L, x1);
350 ASSERT_EQUAL_64(0xffffabcdffffffffL, x2);
351 ASSERT_EQUAL_64(0x5432ffffffffffffL, x3);
352 ASSERT_EQUAL_64(x4, x5);
353 ASSERT_EQUAL_32(-1, w6);
354 ASSERT_EQUAL_64(0x0123456789abcdefL, x7);
355 ASSERT_EQUAL_32(0x89abcdefL, w8);
356 ASSERT_EQUAL_64(0x0123456789abcdefL, x9);
357 ASSERT_EQUAL_32(0x89abcdefL, w10);
358 ASSERT_EQUAL_64(0x00000fff, x11);
359 ASSERT_EQUAL_64(0x0000000000000fffUL, x12);
360 ASSERT_EQUAL_64(0x00001ffe, x13);
361 ASSERT_EQUAL_64(0x0000000000003ffcUL, x14);
362 ASSERT_EQUAL_64(0x000001ff, x15);
363 ASSERT_EQUAL_64(0x00000000000000ffUL, x18);
364 ASSERT_EQUAL_64(0x00000001, x19);
365 ASSERT_EQUAL_64(0x0, x20);
366 ASSERT_EQUAL_64(0x7ff80000, x21);
367 ASSERT_EQUAL_64(0x3ffc000000000000UL, x22);
368 ASSERT_EQUAL_64(0x000000fe, x23);
369 ASSERT_EQUAL_64(0xfffffffffffffffcUL, x24);
370 ASSERT_EQUAL_64(0x00007ff8, x25);
371 ASSERT_EQUAL_64(0x000000000000fff0UL, x26);
372 ASSERT_EQUAL_64(0x000000000001ffe0UL, x27);
373
374 TEARDOWN();
375}
376
377
378TEST(orr) {
379 SETUP();
380
381 START();
382 __ Mov(x0, 0xf0f0);
383 __ Mov(x1, 0xf00000ff);
384
385 __ Orr(x2, x0, Operand(x1));
386 __ Orr(w3, w0, Operand(w1, LSL, 28));
387 __ Orr(x4, x0, Operand(x1, LSL, 32));
388 __ Orr(x5, x0, Operand(x1, LSR, 4));
389 __ Orr(w6, w0, Operand(w1, ASR, 4));
390 __ Orr(x7, x0, Operand(x1, ASR, 4));
391 __ Orr(w8, w0, Operand(w1, ROR, 12));
392 __ Orr(x9, x0, Operand(x1, ROR, 12));
393 __ Orr(w10, w0, Operand(0xf));
394 __ Orr(x11, x0, Operand(0xf0000000f0000000L));
395 END();
396
397 RUN();
398
399 ASSERT_EQUAL_64(0xf000f0ff, x2);
400 ASSERT_EQUAL_64(0xf000f0f0, x3);
401 ASSERT_EQUAL_64(0xf00000ff0000f0f0L, x4);
402 ASSERT_EQUAL_64(0x0f00f0ff, x5);
403 ASSERT_EQUAL_64(0xff00f0ff, x6);
404 ASSERT_EQUAL_64(0x0f00f0ff, x7);
405 ASSERT_EQUAL_64(0x0ffff0f0, x8);
406 ASSERT_EQUAL_64(0x0ff00000000ff0f0L, x9);
407 ASSERT_EQUAL_64(0xf0ff, x10);
408 ASSERT_EQUAL_64(0xf0000000f000f0f0L, x11);
409
410 TEARDOWN();
411}
412
413
414TEST(orr_extend) {
415 SETUP();
416
417 START();
418 __ Mov(x0, 1);
419 __ Mov(x1, 0x8000000080008080UL);
420 __ Orr(w6, w0, Operand(w1, UXTB));
421 __ Orr(x7, x0, Operand(x1, UXTH, 1));
422 __ Orr(w8, w0, Operand(w1, UXTW, 2));
423 __ Orr(x9, x0, Operand(x1, UXTX, 3));
424 __ Orr(w10, w0, Operand(w1, SXTB));
425 __ Orr(x11, x0, Operand(x1, SXTH, 1));
426 __ Orr(x12, x0, Operand(x1, SXTW, 2));
427 __ Orr(x13, x0, Operand(x1, SXTX, 3));
428 END();
429
430 RUN();
431
432 ASSERT_EQUAL_64(0x00000081, x6);
433 ASSERT_EQUAL_64(0x00010101, x7);
434 ASSERT_EQUAL_64(0x00020201, x8);
435 ASSERT_EQUAL_64(0x0000000400040401UL, x9);
436 ASSERT_EQUAL_64(0x00000000ffffff81UL, x10);
437 ASSERT_EQUAL_64(0xffffffffffff0101UL, x11);
438 ASSERT_EQUAL_64(0xfffffffe00020201UL, x12);
439 ASSERT_EQUAL_64(0x0000000400040401UL, x13);
440
441 TEARDOWN();
442}
443
444
445TEST(bitwise_wide_imm) {
446 SETUP();
447
448 START();
449 __ Mov(x0, 0);
450 __ Mov(x1, 0xf0f0f0f0f0f0f0f0UL);
451
452 __ Orr(x10, x0, Operand(0x1234567890abcdefUL));
453 __ Orr(w11, w1, Operand(0x90abcdef));
454 END();
455
456 RUN();
457
458 ASSERT_EQUAL_64(0, x0);
459 ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0UL, x1);
460 ASSERT_EQUAL_64(0x1234567890abcdefUL, x10);
461 ASSERT_EQUAL_64(0xf0fbfdffUL, x11);
462
463 TEARDOWN();
464}
465
466
467TEST(orn) {
468 SETUP();
469
470 START();
471 __ Mov(x0, 0xf0f0);
472 __ Mov(x1, 0xf00000ff);
473
474 __ Orn(x2, x0, Operand(x1));
475 __ Orn(w3, w0, Operand(w1, LSL, 4));
476 __ Orn(x4, x0, Operand(x1, LSL, 4));
477 __ Orn(x5, x0, Operand(x1, LSR, 1));
478 __ Orn(w6, w0, Operand(w1, ASR, 1));
479 __ Orn(x7, x0, Operand(x1, ASR, 1));
480 __ Orn(w8, w0, Operand(w1, ROR, 16));
481 __ Orn(x9, x0, Operand(x1, ROR, 16));
482 __ Orn(w10, w0, Operand(0xffff));
483 __ Orn(x11, x0, Operand(0xffff0000ffffL));
484 END();
485
486 RUN();
487
488 ASSERT_EQUAL_64(0xffffffff0ffffff0L, x2);
489 ASSERT_EQUAL_64(0xfffff0ff, x3);
490 ASSERT_EQUAL_64(0xfffffff0fffff0ffL, x4);
491 ASSERT_EQUAL_64(0xffffffff87fffff0L, x5);
492 ASSERT_EQUAL_64(0x07fffff0, x6);
493 ASSERT_EQUAL_64(0xffffffff87fffff0L, x7);
494 ASSERT_EQUAL_64(0xff00ffff, x8);
495 ASSERT_EQUAL_64(0xff00ffffffffffffL, x9);
496 ASSERT_EQUAL_64(0xfffff0f0, x10);
497 ASSERT_EQUAL_64(0xffff0000fffff0f0L, x11);
498
499 TEARDOWN();
500}
501
502
503TEST(orn_extend) {
504 SETUP();
505
506 START();
507 __ Mov(x0, 1);
508 __ Mov(x1, 0x8000000080008081UL);
509 __ Orn(w6, w0, Operand(w1, UXTB));
510 __ Orn(x7, x0, Operand(x1, UXTH, 1));
511 __ Orn(w8, w0, Operand(w1, UXTW, 2));
512 __ Orn(x9, x0, Operand(x1, UXTX, 3));
513 __ Orn(w10, w0, Operand(w1, SXTB));
514 __ Orn(x11, x0, Operand(x1, SXTH, 1));
515 __ Orn(x12, x0, Operand(x1, SXTW, 2));
516 __ Orn(x13, x0, Operand(x1, SXTX, 3));
517 END();
518
519 RUN();
520
521 ASSERT_EQUAL_64(0xffffff7f, x6);
522 ASSERT_EQUAL_64(0xfffffffffffefefdUL, x7);
523 ASSERT_EQUAL_64(0xfffdfdfb, x8);
524 ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x9);
525 ASSERT_EQUAL_64(0x0000007f, x10);
526 ASSERT_EQUAL_64(0x0000fefd, x11);
527 ASSERT_EQUAL_64(0x00000001fffdfdfbUL, x12);
528 ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x13);
529
530 TEARDOWN();
531}
532
533
534TEST(and_) {
535 SETUP();
536
537 START();
538 __ Mov(x0, 0xfff0);
539 __ Mov(x1, 0xf00000ff);
540
541 __ And(x2, x0, Operand(x1));
542 __ And(w3, w0, Operand(w1, LSL, 4));
543 __ And(x4, x0, Operand(x1, LSL, 4));
544 __ And(x5, x0, Operand(x1, LSR, 1));
545 __ And(w6, w0, Operand(w1, ASR, 20));
546 __ And(x7, x0, Operand(x1, ASR, 20));
547 __ And(w8, w0, Operand(w1, ROR, 28));
548 __ And(x9, x0, Operand(x1, ROR, 28));
549 __ And(w10, w0, Operand(0xff00));
550 __ And(x11, x0, Operand(0xff));
551 END();
552
553 RUN();
554
555 ASSERT_EQUAL_64(0x000000f0, x2);
556 ASSERT_EQUAL_64(0x00000ff0, x3);
557 ASSERT_EQUAL_64(0x00000ff0, x4);
558 ASSERT_EQUAL_64(0x00000070, x5);
559 ASSERT_EQUAL_64(0x0000ff00, x6);
560 ASSERT_EQUAL_64(0x00000f00, x7);
561 ASSERT_EQUAL_64(0x00000ff0, x8);
562 ASSERT_EQUAL_64(0x00000000, x9);
563 ASSERT_EQUAL_64(0x0000ff00, x10);
564 ASSERT_EQUAL_64(0x000000f0, x11);
565
566 TEARDOWN();
567}
568
569
570TEST(and_extend) {
571 SETUP();
572
573 START();
574 __ Mov(x0, 0xffffffffffffffffUL);
575 __ Mov(x1, 0x8000000080008081UL);
576 __ And(w6, w0, Operand(w1, UXTB));
577 __ And(x7, x0, Operand(x1, UXTH, 1));
578 __ And(w8, w0, Operand(w1, UXTW, 2));
579 __ And(x9, x0, Operand(x1, UXTX, 3));
580 __ And(w10, w0, Operand(w1, SXTB));
581 __ And(x11, x0, Operand(x1, SXTH, 1));
582 __ And(x12, x0, Operand(x1, SXTW, 2));
583 __ And(x13, x0, Operand(x1, SXTX, 3));
584 END();
585
586 RUN();
587
588 ASSERT_EQUAL_64(0x00000081, x6);
589 ASSERT_EQUAL_64(0x00010102, x7);
590 ASSERT_EQUAL_64(0x00020204, x8);
591 ASSERT_EQUAL_64(0x0000000400040408UL, x9);
592 ASSERT_EQUAL_64(0xffffff81, x10);
593 ASSERT_EQUAL_64(0xffffffffffff0102UL, x11);
594 ASSERT_EQUAL_64(0xfffffffe00020204UL, x12);
595 ASSERT_EQUAL_64(0x0000000400040408UL, x13);
596
597 TEARDOWN();
598}
599
600
601TEST(ands) {
602 SETUP();
603
604 START();
605 __ Mov(x1, 0xf00000ff);
606 __ And(w0, w1, Operand(w1), SetFlags);
607 END();
608
609 RUN();
610
611 ASSERT_EQUAL_NZCV(NFlag);
612 ASSERT_EQUAL_64(0xf00000ff, x0);
613
614 START();
615 __ Mov(x0, 0xfff0);
616 __ Mov(x1, 0xf00000ff);
617 __ And(w0, w0, Operand(w1, LSR, 4), SetFlags);
618 END();
619
620 RUN();
621
622 ASSERT_EQUAL_NZCV(ZFlag);
623 ASSERT_EQUAL_64(0x00000000, x0);
624
625 START();
626 __ Mov(x0, 0x8000000000000000L);
627 __ Mov(x1, 0x00000001);
628 __ And(x0, x0, Operand(x1, ROR, 1), SetFlags);
629 END();
630
631 RUN();
632
633 ASSERT_EQUAL_NZCV(NFlag);
634 ASSERT_EQUAL_64(0x8000000000000000L, x0);
635
636 START();
637 __ Mov(x0, 0xfff0);
638 __ And(w0, w0, Operand(0xf), SetFlags);
639 END();
640
641 RUN();
642
643 ASSERT_EQUAL_NZCV(ZFlag);
644 ASSERT_EQUAL_64(0x00000000, x0);
645
646 START();
647 __ Mov(x0, 0xff000000);
648 __ And(w0, w0, Operand(0x80000000), SetFlags);
649 END();
650
651 RUN();
652
653 ASSERT_EQUAL_NZCV(NFlag);
654 ASSERT_EQUAL_64(0x80000000, x0);
655
656 TEARDOWN();
657}
658
659
660TEST(bic) {
661 SETUP();
662
663 START();
664 __ Mov(x0, 0xfff0);
665 __ Mov(x1, 0xf00000ff);
666
667 __ Bic(x2, x0, Operand(x1));
668 __ Bic(w3, w0, Operand(w1, LSL, 4));
669 __ Bic(x4, x0, Operand(x1, LSL, 4));
670 __ Bic(x5, x0, Operand(x1, LSR, 1));
671 __ Bic(w6, w0, Operand(w1, ASR, 20));
672 __ Bic(x7, x0, Operand(x1, ASR, 20));
673 __ Bic(w8, w0, Operand(w1, ROR, 28));
674 __ Bic(x9, x0, Operand(x1, ROR, 24));
675 __ Bic(x10, x0, Operand(0x1f));
676 __ Bic(x11, x0, Operand(0x100));
677
678 // Test bic into sp when the constant cannot be encoded in the immediate
679 // field.
680 // Use x20 to preserve sp. We check for the result via x21 because the
681 // test infrastructure requires that sp be restored to its original value.
682 __ Mov(x20, sp);
683 __ Mov(x0, 0xffffff);
684 __ Bic(sp, x0, Operand(0xabcdef));
685 __ Mov(x21, sp);
686 __ Mov(sp, x20);
687 END();
688
689 RUN();
690
691 ASSERT_EQUAL_64(0x0000ff00, x2);
692 ASSERT_EQUAL_64(0x0000f000, x3);
693 ASSERT_EQUAL_64(0x0000f000, x4);
694 ASSERT_EQUAL_64(0x0000ff80, x5);
695 ASSERT_EQUAL_64(0x000000f0, x6);
696 ASSERT_EQUAL_64(0x0000f0f0, x7);
697 ASSERT_EQUAL_64(0x0000f000, x8);
698 ASSERT_EQUAL_64(0x0000ff00, x9);
699 ASSERT_EQUAL_64(0x0000ffe0, x10);
700 ASSERT_EQUAL_64(0x0000fef0, x11);
701
702 ASSERT_EQUAL_64(0x543210, x21);
703
704 TEARDOWN();
705}
706
707
708TEST(bic_extend) {
709 SETUP();
710
711 START();
712 __ Mov(x0, 0xffffffffffffffffUL);
713 __ Mov(x1, 0x8000000080008081UL);
714 __ Bic(w6, w0, Operand(w1, UXTB));
715 __ Bic(x7, x0, Operand(x1, UXTH, 1));
716 __ Bic(w8, w0, Operand(w1, UXTW, 2));
717 __ Bic(x9, x0, Operand(x1, UXTX, 3));
718 __ Bic(w10, w0, Operand(w1, SXTB));
719 __ Bic(x11, x0, Operand(x1, SXTH, 1));
720 __ Bic(x12, x0, Operand(x1, SXTW, 2));
721 __ Bic(x13, x0, Operand(x1, SXTX, 3));
722 END();
723
724 RUN();
725
726 ASSERT_EQUAL_64(0xffffff7e, x6);
727 ASSERT_EQUAL_64(0xfffffffffffefefdUL, x7);
728 ASSERT_EQUAL_64(0xfffdfdfb, x8);
729 ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x9);
730 ASSERT_EQUAL_64(0x0000007e, x10);
731 ASSERT_EQUAL_64(0x0000fefd, x11);
732 ASSERT_EQUAL_64(0x00000001fffdfdfbUL, x12);
733 ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x13);
734
735 TEARDOWN();
736}
737
738
739TEST(bics) {
740 SETUP();
741
742 START();
743 __ Mov(x1, 0xffff);
744 __ Bic(w0, w1, Operand(w1), SetFlags);
745 END();
746
747 RUN();
748
749 ASSERT_EQUAL_NZCV(ZFlag);
750 ASSERT_EQUAL_64(0x00000000, x0);
751
752 START();
753 __ Mov(x0, 0xffffffff);
754 __ Bic(w0, w0, Operand(w0, LSR, 1), SetFlags);
755 END();
756
757 RUN();
758
759 ASSERT_EQUAL_NZCV(NFlag);
760 ASSERT_EQUAL_64(0x80000000, x0);
761
762 START();
763 __ Mov(x0, 0x8000000000000000L);
764 __ Mov(x1, 0x00000001);
765 __ Bic(x0, x0, Operand(x1, ROR, 1), SetFlags);
766 END();
767
768 RUN();
769
770 ASSERT_EQUAL_NZCV(ZFlag);
771 ASSERT_EQUAL_64(0x00000000, x0);
772
773 START();
774 __ Mov(x0, 0xffffffffffffffffL);
775 __ Bic(x0, x0, Operand(0x7fffffffffffffffL), SetFlags);
776 END();
777
778 RUN();
779
780 ASSERT_EQUAL_NZCV(NFlag);
781 ASSERT_EQUAL_64(0x8000000000000000L, x0);
782
783 START();
784 __ Mov(w0, 0xffff0000);
785 __ Bic(w0, w0, Operand(0xfffffff0), SetFlags);
786 END();
787
788 RUN();
789
790 ASSERT_EQUAL_NZCV(ZFlag);
791 ASSERT_EQUAL_64(0x00000000, x0);
792
793 TEARDOWN();
794}
795
796
797TEST(eor) {
798 SETUP();
799
800 START();
801 __ Mov(x0, 0xfff0);
802 __ Mov(x1, 0xf00000ff);
803
804 __ Eor(x2, x0, Operand(x1));
805 __ Eor(w3, w0, Operand(w1, LSL, 4));
806 __ Eor(x4, x0, Operand(x1, LSL, 4));
807 __ Eor(x5, x0, Operand(x1, LSR, 1));
808 __ Eor(w6, w0, Operand(w1, ASR, 20));
809 __ Eor(x7, x0, Operand(x1, ASR, 20));
810 __ Eor(w8, w0, Operand(w1, ROR, 28));
811 __ Eor(x9, x0, Operand(x1, ROR, 28));
812 __ Eor(w10, w0, Operand(0xff00ff00));
813 __ Eor(x11, x0, Operand(0xff00ff00ff00ff00L));
814 END();
815
816 RUN();
817
818 ASSERT_EQUAL_64(0xf000ff0f, x2);
819 ASSERT_EQUAL_64(0x0000f000, x3);
820 ASSERT_EQUAL_64(0x0000000f0000f000L, x4);
821 ASSERT_EQUAL_64(0x7800ff8f, x5);
822 ASSERT_EQUAL_64(0xffff00f0, x6);
823 ASSERT_EQUAL_64(0x0000f0f0, x7);
824 ASSERT_EQUAL_64(0x0000f00f, x8);
825 ASSERT_EQUAL_64(0x00000ff00000ffffL, x9);
826 ASSERT_EQUAL_64(0xff0000f0, x10);
827 ASSERT_EQUAL_64(0xff00ff00ff0000f0L, x11);
828
829 TEARDOWN();
830}
831
832TEST(eor_extend) {
833 SETUP();
834
835 START();
836 __ Mov(x0, 0x1111111111111111UL);
837 __ Mov(x1, 0x8000000080008081UL);
838 __ Eor(w6, w0, Operand(w1, UXTB));
839 __ Eor(x7, x0, Operand(x1, UXTH, 1));
840 __ Eor(w8, w0, Operand(w1, UXTW, 2));
841 __ Eor(x9, x0, Operand(x1, UXTX, 3));
842 __ Eor(w10, w0, Operand(w1, SXTB));
843 __ Eor(x11, x0, Operand(x1, SXTH, 1));
844 __ Eor(x12, x0, Operand(x1, SXTW, 2));
845 __ Eor(x13, x0, Operand(x1, SXTX, 3));
846 END();
847
848 RUN();
849
850 ASSERT_EQUAL_64(0x11111190, x6);
851 ASSERT_EQUAL_64(0x1111111111101013UL, x7);
852 ASSERT_EQUAL_64(0x11131315, x8);
853 ASSERT_EQUAL_64(0x1111111511151519UL, x9);
854 ASSERT_EQUAL_64(0xeeeeee90, x10);
855 ASSERT_EQUAL_64(0xeeeeeeeeeeee1013UL, x11);
856 ASSERT_EQUAL_64(0xeeeeeeef11131315UL, x12);
857 ASSERT_EQUAL_64(0x1111111511151519UL, x13);
858
859 TEARDOWN();
860}
861
862
863TEST(eon) {
864 SETUP();
865
866 START();
867 __ Mov(x0, 0xfff0);
868 __ Mov(x1, 0xf00000ff);
869
870 __ Eon(x2, x0, Operand(x1));
871 __ Eon(w3, w0, Operand(w1, LSL, 4));
872 __ Eon(x4, x0, Operand(x1, LSL, 4));
873 __ Eon(x5, x0, Operand(x1, LSR, 1));
874 __ Eon(w6, w0, Operand(w1, ASR, 20));
875 __ Eon(x7, x0, Operand(x1, ASR, 20));
876 __ Eon(w8, w0, Operand(w1, ROR, 28));
877 __ Eon(x9, x0, Operand(x1, ROR, 28));
878 __ Eon(w10, w0, Operand(0x03c003c0));
879 __ Eon(x11, x0, Operand(0x0000100000001000L));
880 END();
881
882 RUN();
883
884 ASSERT_EQUAL_64(0xffffffff0fff00f0L, x2);
885 ASSERT_EQUAL_64(0xffff0fff, x3);
886 ASSERT_EQUAL_64(0xfffffff0ffff0fffL, x4);
887 ASSERT_EQUAL_64(0xffffffff87ff0070L, x5);
888 ASSERT_EQUAL_64(0x0000ff0f, x6);
889 ASSERT_EQUAL_64(0xffffffffffff0f0fL, x7);
890 ASSERT_EQUAL_64(0xffff0ff0, x8);
891 ASSERT_EQUAL_64(0xfffff00fffff0000L, x9);
892 ASSERT_EQUAL_64(0xfc3f03cf, x10);
893 ASSERT_EQUAL_64(0xffffefffffff100fL, x11);
894
895 TEARDOWN();
896}
897
898
899TEST(eon_extend) {
900 SETUP();
901
902 START();
903 __ Mov(x0, 0x1111111111111111UL);
904 __ Mov(x1, 0x8000000080008081UL);
905 __ Eon(w6, w0, Operand(w1, UXTB));
906 __ Eon(x7, x0, Operand(x1, UXTH, 1));
907 __ Eon(w8, w0, Operand(w1, UXTW, 2));
908 __ Eon(x9, x0, Operand(x1, UXTX, 3));
909 __ Eon(w10, w0, Operand(w1, SXTB));
910 __ Eon(x11, x0, Operand(x1, SXTH, 1));
911 __ Eon(x12, x0, Operand(x1, SXTW, 2));
912 __ Eon(x13, x0, Operand(x1, SXTX, 3));
913 END();
914
915 RUN();
916
917 ASSERT_EQUAL_64(0xeeeeee6f, x6);
918 ASSERT_EQUAL_64(0xeeeeeeeeeeefefecUL, x7);
919 ASSERT_EQUAL_64(0xeeececea, x8);
920 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x9);
921 ASSERT_EQUAL_64(0x1111116f, x10);
922 ASSERT_EQUAL_64(0x111111111111efecUL, x11);
923 ASSERT_EQUAL_64(0x11111110eeececeaUL, x12);
924 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x13);
925
926 TEARDOWN();
927}
928
929
930TEST(mul) {
931 SETUP();
932
933 START();
934 __ Mov(x16, 0);
935 __ Mov(x17, 1);
936 __ Mov(x18, 0xffffffff);
937 __ Mov(x19, 0xffffffffffffffffUL);
938
939 __ Mul(w0, w16, w16);
940 __ Mul(w1, w16, w17);
941 __ Mul(w2, w17, w18);
942 __ Mul(w3, w18, w19);
943 __ Mul(x4, x16, x16);
944 __ Mul(x5, x17, x18);
945 __ Mul(x6, x18, x19);
946 __ Mul(x7, x19, x19);
947 __ Smull(x8, w17, w18);
948 __ Smull(x9, w18, w18);
949 __ Smull(x10, w19, w19);
950 __ Mneg(w11, w16, w16);
951 __ Mneg(w12, w16, w17);
952 __ Mneg(w13, w17, w18);
953 __ Mneg(w14, w18, w19);
954 __ Mneg(x20, x16, x16);
955 __ Mneg(x21, x17, x18);
956 __ Mneg(x22, x18, x19);
957 __ Mneg(x23, x19, x19);
958 END();
959
960 RUN();
961
962 ASSERT_EQUAL_64(0, x0);
963 ASSERT_EQUAL_64(0, x1);
964 ASSERT_EQUAL_64(0xffffffff, x2);
965 ASSERT_EQUAL_64(1, x3);
966 ASSERT_EQUAL_64(0, x4);
967 ASSERT_EQUAL_64(0xffffffff, x5);
968 ASSERT_EQUAL_64(0xffffffff00000001UL, x6);
969 ASSERT_EQUAL_64(1, x7);
970 ASSERT_EQUAL_64(0xffffffffffffffffUL, x8);
971 ASSERT_EQUAL_64(1, x9);
972 ASSERT_EQUAL_64(1, x10);
973 ASSERT_EQUAL_64(0, x11);
974 ASSERT_EQUAL_64(0, x12);
975 ASSERT_EQUAL_64(1, x13);
976 ASSERT_EQUAL_64(0xffffffff, x14);
977 ASSERT_EQUAL_64(0, x20);
978 ASSERT_EQUAL_64(0xffffffff00000001UL, x21);
979 ASSERT_EQUAL_64(0xffffffff, x22);
980 ASSERT_EQUAL_64(0xffffffffffffffffUL, x23);
981
982 TEARDOWN();
983}
984
985
986TEST(madd) {
987 SETUP();
988
989 START();
990 __ Mov(x16, 0);
991 __ Mov(x17, 1);
992 __ Mov(x18, 0xffffffff);
993 __ Mov(x19, 0xffffffffffffffffUL);
994
995 __ Madd(w0, w16, w16, w16);
996 __ Madd(w1, w16, w16, w17);
997 __ Madd(w2, w16, w16, w18);
998 __ Madd(w3, w16, w16, w19);
999 __ Madd(w4, w16, w17, w17);
1000 __ Madd(w5, w17, w17, w18);
1001 __ Madd(w6, w17, w17, w19);
1002 __ Madd(w7, w17, w18, w16);
1003 __ Madd(w8, w17, w18, w18);
1004 __ Madd(w9, w18, w18, w17);
1005 __ Madd(w10, w18, w19, w18);
1006 __ Madd(w11, w19, w19, w19);
1007
1008 __ Madd(x12, x16, x16, x16);
1009 __ Madd(x13, x16, x16, x17);
1010 __ Madd(x14, x16, x16, x18);
1011 __ Madd(x15, x16, x16, x19);
1012 __ Madd(x20, x16, x17, x17);
1013 __ Madd(x21, x17, x17, x18);
1014 __ Madd(x22, x17, x17, x19);
1015 __ Madd(x23, x17, x18, x16);
1016 __ Madd(x24, x17, x18, x18);
1017 __ Madd(x25, x18, x18, x17);
1018 __ Madd(x26, x18, x19, x18);
1019 __ Madd(x27, x19, x19, x19);
1020
1021 END();
1022
1023 RUN();
1024
1025 ASSERT_EQUAL_64(0, x0);
1026 ASSERT_EQUAL_64(1, x1);
1027 ASSERT_EQUAL_64(0xffffffff, x2);
1028 ASSERT_EQUAL_64(0xffffffff, x3);
1029 ASSERT_EQUAL_64(1, x4);
1030 ASSERT_EQUAL_64(0, x5);
1031 ASSERT_EQUAL_64(0, x6);
1032 ASSERT_EQUAL_64(0xffffffff, x7);
1033 ASSERT_EQUAL_64(0xfffffffe, x8);
1034 ASSERT_EQUAL_64(2, x9);
1035 ASSERT_EQUAL_64(0, x10);
1036 ASSERT_EQUAL_64(0, x11);
1037
1038 ASSERT_EQUAL_64(0, x12);
1039 ASSERT_EQUAL_64(1, x13);
1040 ASSERT_EQUAL_64(0xffffffff, x14);
1041 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1042 ASSERT_EQUAL_64(1, x20);
1043 ASSERT_EQUAL_64(0x100000000UL, x21);
1044 ASSERT_EQUAL_64(0, x22);
1045 ASSERT_EQUAL_64(0xffffffff, x23);
1046 ASSERT_EQUAL_64(0x1fffffffe, x24);
1047 ASSERT_EQUAL_64(0xfffffffe00000002UL, x25);
1048 ASSERT_EQUAL_64(0, x26);
1049 ASSERT_EQUAL_64(0, x27);
1050
1051 TEARDOWN();
1052}
1053
1054
1055TEST(msub) {
1056 SETUP();
1057
1058 START();
1059 __ Mov(x16, 0);
1060 __ Mov(x17, 1);
1061 __ Mov(x18, 0xffffffff);
1062 __ Mov(x19, 0xffffffffffffffffUL);
1063
1064 __ Msub(w0, w16, w16, w16);
1065 __ Msub(w1, w16, w16, w17);
1066 __ Msub(w2, w16, w16, w18);
1067 __ Msub(w3, w16, w16, w19);
1068 __ Msub(w4, w16, w17, w17);
1069 __ Msub(w5, w17, w17, w18);
1070 __ Msub(w6, w17, w17, w19);
1071 __ Msub(w7, w17, w18, w16);
1072 __ Msub(w8, w17, w18, w18);
1073 __ Msub(w9, w18, w18, w17);
1074 __ Msub(w10, w18, w19, w18);
1075 __ Msub(w11, w19, w19, w19);
1076
1077 __ Msub(x12, x16, x16, x16);
1078 __ Msub(x13, x16, x16, x17);
1079 __ Msub(x14, x16, x16, x18);
1080 __ Msub(x15, x16, x16, x19);
1081 __ Msub(x20, x16, x17, x17);
1082 __ Msub(x21, x17, x17, x18);
1083 __ Msub(x22, x17, x17, x19);
1084 __ Msub(x23, x17, x18, x16);
1085 __ Msub(x24, x17, x18, x18);
1086 __ Msub(x25, x18, x18, x17);
1087 __ Msub(x26, x18, x19, x18);
1088 __ Msub(x27, x19, x19, x19);
1089
1090 END();
1091
1092 RUN();
1093
1094 ASSERT_EQUAL_64(0, x0);
1095 ASSERT_EQUAL_64(1, x1);
1096 ASSERT_EQUAL_64(0xffffffff, x2);
1097 ASSERT_EQUAL_64(0xffffffff, x3);
1098 ASSERT_EQUAL_64(1, x4);
1099 ASSERT_EQUAL_64(0xfffffffe, x5);
1100 ASSERT_EQUAL_64(0xfffffffe, x6);
1101 ASSERT_EQUAL_64(1, x7);
1102 ASSERT_EQUAL_64(0, x8);
1103 ASSERT_EQUAL_64(0, x9);
1104 ASSERT_EQUAL_64(0xfffffffe, x10);
1105 ASSERT_EQUAL_64(0xfffffffe, x11);
1106
1107 ASSERT_EQUAL_64(0, x12);
1108 ASSERT_EQUAL_64(1, x13);
1109 ASSERT_EQUAL_64(0xffffffff, x14);
1110 ASSERT_EQUAL_64(0xffffffffffffffffUL, x15);
1111 ASSERT_EQUAL_64(1, x20);
1112 ASSERT_EQUAL_64(0xfffffffeUL, x21);
1113 ASSERT_EQUAL_64(0xfffffffffffffffeUL, x22);
1114 ASSERT_EQUAL_64(0xffffffff00000001UL, x23);
1115 ASSERT_EQUAL_64(0, x24);
1116 ASSERT_EQUAL_64(0x200000000UL, x25);
1117 ASSERT_EQUAL_64(0x1fffffffeUL, x26);
1118 ASSERT_EQUAL_64(0xfffffffffffffffeUL, x27);
1119
1120 TEARDOWN();
1121}
1122
1123
1124TEST(smulh) {
1125 SETUP();
1126
1127 START();
1128 __ Mov(x20, 0);
1129 __ Mov(x21, 1);
1130 __ Mov(x22, 0x0000000100000000L);
1131 __ Mov(x23, 0x12345678);
1132 __ Mov(x24, 0x0123456789abcdefL);
1133 __ Mov(x25, 0x0000000200000000L);
1134 __ Mov(x26, 0x8000000000000000UL);
1135 __ Mov(x27, 0xffffffffffffffffUL);
1136 __ Mov(x28, 0x5555555555555555UL);
1137 __ Mov(x29, 0xaaaaaaaaaaaaaaaaUL);
1138
1139 __ Smulh(x0, x20, x24);
1140 __ Smulh(x1, x21, x24);
1141 __ Smulh(x2, x22, x23);
1142 __ Smulh(x3, x22, x24);
1143 __ Smulh(x4, x24, x25);
1144 __ Smulh(x5, x23, x27);
1145 __ Smulh(x6, x26, x26);
1146 __ Smulh(x7, x26, x27);
1147 __ Smulh(x8, x27, x27);
1148 __ Smulh(x9, x28, x28);
1149 __ Smulh(x10, x28, x29);
1150 __ Smulh(x11, x29, x29);
1151 END();
1152
1153 RUN();
1154
1155 ASSERT_EQUAL_64(0, x0);
1156 ASSERT_EQUAL_64(0, x1);
1157 ASSERT_EQUAL_64(0, x2);
1158 ASSERT_EQUAL_64(0x01234567, x3);
1159 ASSERT_EQUAL_64(0x02468acf, x4);
1160 ASSERT_EQUAL_64(0xffffffffffffffffUL, x5);
1161 ASSERT_EQUAL_64(0x4000000000000000UL, x6);
1162 ASSERT_EQUAL_64(0, x7);
1163 ASSERT_EQUAL_64(0, x8);
1164 ASSERT_EQUAL_64(0x1c71c71c71c71c71UL, x9);
1165 ASSERT_EQUAL_64(0xe38e38e38e38e38eUL, x10);
1166 ASSERT_EQUAL_64(0x1c71c71c71c71c72UL, x11);
1167
1168 TEARDOWN();
1169}
1170
1171
1172TEST(smaddl_umaddl) {
1173 SETUP();
1174
1175 START();
1176 __ Mov(x17, 1);
1177 __ Mov(x18, 0xffffffff);
1178 __ Mov(x19, 0xffffffffffffffffUL);
1179 __ Mov(x20, 4);
1180 __ Mov(x21, 0x200000000UL);
1181
1182 __ Smaddl(x9, w17, w18, x20);
1183 __ Smaddl(x10, w18, w18, x20);
1184 __ Smaddl(x11, w19, w19, x20);
1185 __ Smaddl(x12, w19, w19, x21);
1186 __ Umaddl(x13, w17, w18, x20);
1187 __ Umaddl(x14, w18, w18, x20);
1188 __ Umaddl(x15, w19, w19, x20);
1189 __ Umaddl(x22, w19, w19, x21);
1190 END();
1191
1192 RUN();
1193
1194 ASSERT_EQUAL_64(3, x9);
1195 ASSERT_EQUAL_64(5, x10);
1196 ASSERT_EQUAL_64(5, x11);
1197 ASSERT_EQUAL_64(0x200000001UL, x12);
1198 ASSERT_EQUAL_64(0x100000003UL, x13);
1199 ASSERT_EQUAL_64(0xfffffffe00000005UL, x14);
1200 ASSERT_EQUAL_64(0xfffffffe00000005UL, x15);
1201 ASSERT_EQUAL_64(0x1, x22);
1202
1203 TEARDOWN();
1204}
1205
1206
1207TEST(smsubl_umsubl) {
1208 SETUP();
1209
1210 START();
1211 __ Mov(x17, 1);
1212 __ Mov(x18, 0xffffffff);
1213 __ Mov(x19, 0xffffffffffffffffUL);
1214 __ Mov(x20, 4);
1215 __ Mov(x21, 0x200000000UL);
1216
1217 __ Smsubl(x9, w17, w18, x20);
1218 __ Smsubl(x10, w18, w18, x20);
1219 __ Smsubl(x11, w19, w19, x20);
1220 __ Smsubl(x12, w19, w19, x21);
1221 __ Umsubl(x13, w17, w18, x20);
1222 __ Umsubl(x14, w18, w18, x20);
1223 __ Umsubl(x15, w19, w19, x20);
1224 __ Umsubl(x22, w19, w19, x21);
1225 END();
1226
1227 RUN();
1228
1229 ASSERT_EQUAL_64(5, x9);
1230 ASSERT_EQUAL_64(3, x10);
1231 ASSERT_EQUAL_64(3, x11);
1232 ASSERT_EQUAL_64(0x1ffffffffUL, x12);
1233 ASSERT_EQUAL_64(0xffffffff00000005UL, x13);
1234 ASSERT_EQUAL_64(0x200000003UL, x14);
1235 ASSERT_EQUAL_64(0x200000003UL, x15);
1236 ASSERT_EQUAL_64(0x3ffffffffUL, x22);
1237
1238 TEARDOWN();
1239}
1240
1241
1242TEST(div) {
1243 SETUP();
1244
1245 START();
1246 __ Mov(x16, 1);
1247 __ Mov(x17, 0xffffffff);
1248 __ Mov(x18, 0xffffffffffffffffUL);
1249 __ Mov(x19, 0x80000000);
1250 __ Mov(x20, 0x8000000000000000UL);
1251 __ Mov(x21, 2);
1252
1253 __ Udiv(w0, w16, w16);
1254 __ Udiv(w1, w17, w16);
1255 __ Sdiv(w2, w16, w16);
1256 __ Sdiv(w3, w16, w17);
1257 __ Sdiv(w4, w17, w18);
1258
1259 __ Udiv(x5, x16, x16);
1260 __ Udiv(x6, x17, x18);
1261 __ Sdiv(x7, x16, x16);
1262 __ Sdiv(x8, x16, x17);
1263 __ Sdiv(x9, x17, x18);
1264
1265 __ Udiv(w10, w19, w21);
1266 __ Sdiv(w11, w19, w21);
1267 __ Udiv(x12, x19, x21);
1268 __ Sdiv(x13, x19, x21);
1269 __ Udiv(x14, x20, x21);
1270 __ Sdiv(x15, x20, x21);
1271 END();
1272
1273 RUN();
1274
1275 ASSERT_EQUAL_64(1, x0);
1276 ASSERT_EQUAL_64(0xffffffff, x1);
1277 ASSERT_EQUAL_64(1, x2);
1278 ASSERT_EQUAL_64(0xffffffff, x3);
1279 ASSERT_EQUAL_64(1, x4);
1280 ASSERT_EQUAL_64(1, x5);
1281 ASSERT_EQUAL_64(0, x6);
1282 ASSERT_EQUAL_64(1, x7);
1283 ASSERT_EQUAL_64(0, x8);
1284 ASSERT_EQUAL_64(0xffffffff00000001UL, x9);
1285 ASSERT_EQUAL_64(0x40000000, x10);
1286 ASSERT_EQUAL_64(0xC0000000, x11);
1287 ASSERT_EQUAL_64(0x40000000, x12);
1288 ASSERT_EQUAL_64(0x40000000, x13);
1289 ASSERT_EQUAL_64(0x4000000000000000UL, x14);
1290 ASSERT_EQUAL_64(0xC000000000000000UL, x15);
1291
1292 TEARDOWN();
1293}
1294
1295
1296TEST(rbit_rev) {
1297 SETUP();
1298
1299 START();
1300 __ Mov(x24, 0xfedcba9876543210UL);
1301 __ Rbit(w0, w24);
1302 __ Rbit(x1, x24);
1303 __ Rev16(w2, w24);
1304 __ Rev16(x3, x24);
1305 __ Rev(w4, w24);
1306 __ Rev32(x5, x24);
1307 __ Rev(x6, x24);
1308 END();
1309
1310 RUN();
1311
1312 ASSERT_EQUAL_64(0x084c2a6e, x0);
1313 ASSERT_EQUAL_64(0x084c2a6e195d3b7fUL, x1);
1314 ASSERT_EQUAL_64(0x54761032, x2);
1315 ASSERT_EQUAL_64(0xdcfe98ba54761032UL, x3);
1316 ASSERT_EQUAL_64(0x10325476, x4);
1317 ASSERT_EQUAL_64(0x98badcfe10325476UL, x5);
1318 ASSERT_EQUAL_64(0x1032547698badcfeUL, x6);
1319
1320 TEARDOWN();
1321}
1322
1323
1324TEST(clz_cls) {
1325 SETUP();
1326
1327 START();
1328 __ Mov(x24, 0x0008000000800000UL);
1329 __ Mov(x25, 0xff800000fff80000UL);
1330 __ Mov(x26, 0);
1331 __ Clz(w0, w24);
1332 __ Clz(x1, x24);
1333 __ Clz(w2, w25);
1334 __ Clz(x3, x25);
1335 __ Clz(w4, w26);
1336 __ Clz(x5, x26);
1337 __ Cls(w6, w24);
1338 __ Cls(x7, x24);
1339 __ Cls(w8, w25);
1340 __ Cls(x9, x25);
1341 __ Cls(w10, w26);
1342 __ Cls(x11, x26);
1343 END();
1344
1345 RUN();
1346
1347 ASSERT_EQUAL_64(8, x0);
1348 ASSERT_EQUAL_64(12, x1);
1349 ASSERT_EQUAL_64(0, x2);
1350 ASSERT_EQUAL_64(0, x3);
1351 ASSERT_EQUAL_64(32, x4);
1352 ASSERT_EQUAL_64(64, x5);
1353 ASSERT_EQUAL_64(7, x6);
1354 ASSERT_EQUAL_64(11, x7);
1355 ASSERT_EQUAL_64(12, x8);
1356 ASSERT_EQUAL_64(8, x9);
1357 ASSERT_EQUAL_64(31, x10);
1358 ASSERT_EQUAL_64(63, x11);
1359
1360 TEARDOWN();
1361}
1362
1363
1364TEST(label) {
1365 SETUP();
1366
1367 Label label_1, label_2, label_3, label_4;
1368
1369 START();
1370 __ Mov(x0, 0x1);
1371 __ Mov(x1, 0x0);
1372 __ Mov(x22, lr); // Save lr.
1373
1374 __ B(&label_1);
1375 __ B(&label_1);
1376 __ B(&label_1); // Multiple branches to the same label.
1377 __ Mov(x0, 0x0);
1378 __ Bind(&label_2);
1379 __ B(&label_3); // Forward branch.
1380 __ Mov(x0, 0x0);
1381 __ Bind(&label_1);
1382 __ B(&label_2); // Backward branch.
1383 __ Mov(x0, 0x0);
1384 __ Bind(&label_3);
1385 __ Bl(&label_4);
1386 END();
1387
1388 __ Bind(&label_4);
1389 __ Mov(x1, 0x1);
1390 __ Mov(lr, x22);
1391 END();
1392
1393 RUN();
1394
1395 ASSERT_EQUAL_64(0x1, x0);
1396 ASSERT_EQUAL_64(0x1, x1);
1397
1398 TEARDOWN();
1399}
1400
1401
1402TEST(adr) {
1403 SETUP();
1404
1405 Label label_1, label_2, label_3, label_4;
1406
1407 START();
1408 __ Mov(x0, 0x0); // Set to non-zero to indicate failure.
1409 __ Adr(x1, &label_3); // Set to zero to indicate success.
1410
1411 __ Adr(x2, &label_1); // Multiple forward references to the same label.
1412 __ Adr(x3, &label_1);
1413 __ Adr(x4, &label_1);
1414
1415 __ Bind(&label_2);
1416 __ Eor(x5, x2, Operand(x3)); // Ensure that x2,x3 and x4 are identical.
1417 __ Eor(x6, x2, Operand(x4));
1418 __ Orr(x0, x0, Operand(x5));
1419 __ Orr(x0, x0, Operand(x6));
1420 __ Br(x2); // label_1, label_3
1421
1422 __ Bind(&label_3);
1423 __ Adr(x2, &label_3); // Self-reference (offset 0).
1424 __ Eor(x1, x1, Operand(x2));
1425 __ Adr(x2, &label_4); // Simple forward reference.
1426 __ Br(x2); // label_4
1427
1428 __ Bind(&label_1);
1429 __ Adr(x2, &label_3); // Multiple reverse references to the same label.
1430 __ Adr(x3, &label_3);
1431 __ Adr(x4, &label_3);
1432 __ Adr(x5, &label_2); // Simple reverse reference.
1433 __ Br(x5); // label_2
1434
1435 __ Bind(&label_4);
1436 END();
1437
1438 RUN();
1439
1440 ASSERT_EQUAL_64(0x0, x0);
1441 ASSERT_EQUAL_64(0x0, x1);
1442
1443 TEARDOWN();
1444}
1445
1446
1447TEST(branch_cond) {
1448 SETUP();
1449
1450 Label wrong;
1451
1452 START();
1453 __ Mov(x0, 0x1);
1454 __ Mov(x1, 0x1);
1455 __ Mov(x2, 0x8000000000000000L);
1456
1457 // For each 'cmp' instruction below, condition codes other than the ones
1458 // following it would branch.
1459
armvixl578645f2013-08-15 17:21:42 +01001460 __ Cmp(x1, 0);
armvixlad96eda2013-06-14 11:42:37 +01001461 __ B(&wrong, eq);
1462 __ B(&wrong, lo);
1463 __ B(&wrong, mi);
1464 __ B(&wrong, vs);
1465 __ B(&wrong, ls);
1466 __ B(&wrong, lt);
1467 __ B(&wrong, le);
1468 Label ok_1;
1469 __ B(&ok_1, ne);
1470 __ Mov(x0, 0x0);
1471 __ Bind(&ok_1);
1472
armvixl578645f2013-08-15 17:21:42 +01001473 __ Cmp(x1, 1);
armvixlad96eda2013-06-14 11:42:37 +01001474 __ B(&wrong, ne);
1475 __ B(&wrong, lo);
1476 __ B(&wrong, mi);
1477 __ B(&wrong, vs);
1478 __ B(&wrong, hi);
1479 __ B(&wrong, lt);
1480 __ B(&wrong, gt);
1481 Label ok_2;
1482 __ B(&ok_2, pl);
1483 __ Mov(x0, 0x0);
1484 __ Bind(&ok_2);
1485
armvixl578645f2013-08-15 17:21:42 +01001486 __ Cmp(x1, 2);
armvixlad96eda2013-06-14 11:42:37 +01001487 __ B(&wrong, eq);
1488 __ B(&wrong, hs);
1489 __ B(&wrong, pl);
1490 __ B(&wrong, vs);
1491 __ B(&wrong, hi);
1492 __ B(&wrong, ge);
1493 __ B(&wrong, gt);
1494 Label ok_3;
1495 __ B(&ok_3, vc);
1496 __ Mov(x0, 0x0);
1497 __ Bind(&ok_3);
1498
armvixl578645f2013-08-15 17:21:42 +01001499 __ Cmp(x2, 1);
armvixlad96eda2013-06-14 11:42:37 +01001500 __ B(&wrong, eq);
1501 __ B(&wrong, lo);
1502 __ B(&wrong, mi);
1503 __ B(&wrong, vc);
1504 __ B(&wrong, ls);
1505 __ B(&wrong, ge);
1506 __ B(&wrong, gt);
1507 Label ok_4;
1508 __ B(&ok_4, le);
1509 __ Mov(x0, 0x0);
1510 __ Bind(&ok_4);
armvixl578645f2013-08-15 17:21:42 +01001511
1512 Label ok_5;
1513 __ b(&ok_5, al);
1514 __ Mov(x0, 0x0);
1515 __ Bind(&ok_5);
1516
1517 Label ok_6;
1518 __ b(&ok_6, nv);
1519 __ Mov(x0, 0x0);
1520 __ Bind(&ok_6);
1521
armvixlad96eda2013-06-14 11:42:37 +01001522 END();
1523
1524 __ Bind(&wrong);
1525 __ Mov(x0, 0x0);
1526 END();
1527
1528 RUN();
1529
1530 ASSERT_EQUAL_64(0x1, x0);
1531
1532 TEARDOWN();
1533}
1534
1535
1536TEST(branch_to_reg) {
1537 SETUP();
1538
1539 // Test br.
1540 Label fn1, after_fn1;
1541
1542 START();
1543 __ Mov(x29, lr);
1544
1545 __ Mov(x1, 0);
1546 __ B(&after_fn1);
1547
1548 __ Bind(&fn1);
1549 __ Mov(x0, lr);
1550 __ Mov(x1, 42);
1551 __ Br(x0);
1552
1553 __ Bind(&after_fn1);
1554 __ Bl(&fn1);
1555
1556 // Test blr.
1557 Label fn2, after_fn2;
1558
1559 __ Mov(x2, 0);
1560 __ B(&after_fn2);
1561
1562 __ Bind(&fn2);
1563 __ Mov(x0, lr);
1564 __ Mov(x2, 84);
1565 __ Blr(x0);
1566
1567 __ Bind(&after_fn2);
1568 __ Bl(&fn2);
1569 __ Mov(x3, lr);
1570
1571 __ Mov(lr, x29);
1572 END();
1573
1574 RUN();
1575
1576 ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
1577 ASSERT_EQUAL_64(42, x1);
1578 ASSERT_EQUAL_64(84, x2);
1579
1580 TEARDOWN();
1581}
1582
1583
1584TEST(compare_branch) {
1585 SETUP();
1586
1587 START();
1588 __ Mov(x0, 0);
1589 __ Mov(x1, 0);
1590 __ Mov(x2, 0);
1591 __ Mov(x3, 0);
1592 __ Mov(x4, 0);
1593 __ Mov(x5, 0);
1594 __ Mov(x16, 0);
1595 __ Mov(x17, 42);
1596
1597 Label zt, zt_end;
1598 __ Cbz(w16, &zt);
1599 __ B(&zt_end);
1600 __ Bind(&zt);
1601 __ Mov(x0, 1);
1602 __ Bind(&zt_end);
1603
1604 Label zf, zf_end;
1605 __ Cbz(x17, &zf);
1606 __ B(&zf_end);
1607 __ Bind(&zf);
1608 __ Mov(x1, 1);
1609 __ Bind(&zf_end);
1610
1611 Label nzt, nzt_end;
1612 __ Cbnz(w17, &nzt);
1613 __ B(&nzt_end);
1614 __ Bind(&nzt);
1615 __ Mov(x2, 1);
1616 __ Bind(&nzt_end);
1617
1618 Label nzf, nzf_end;
1619 __ Cbnz(x16, &nzf);
1620 __ B(&nzf_end);
1621 __ Bind(&nzf);
1622 __ Mov(x3, 1);
1623 __ Bind(&nzf_end);
1624
1625 __ Mov(x18, 0xffffffff00000000UL);
1626
1627 Label a, a_end;
1628 __ Cbz(w18, &a);
1629 __ B(&a_end);
1630 __ Bind(&a);
1631 __ Mov(x4, 1);
1632 __ Bind(&a_end);
1633
1634 Label b, b_end;
1635 __ Cbnz(w18, &b);
1636 __ B(&b_end);
1637 __ Bind(&b);
1638 __ Mov(x5, 1);
1639 __ Bind(&b_end);
1640
1641 END();
1642
1643 RUN();
1644
1645 ASSERT_EQUAL_64(1, x0);
1646 ASSERT_EQUAL_64(0, x1);
1647 ASSERT_EQUAL_64(1, x2);
1648 ASSERT_EQUAL_64(0, x3);
1649 ASSERT_EQUAL_64(1, x4);
1650 ASSERT_EQUAL_64(0, x5);
1651
1652 TEARDOWN();
1653}
1654
1655
1656TEST(test_branch) {
1657 SETUP();
1658
1659 START();
1660 __ Mov(x0, 0);
1661 __ Mov(x1, 0);
1662 __ Mov(x2, 0);
1663 __ Mov(x3, 0);
1664 __ Mov(x16, 0xaaaaaaaaaaaaaaaaUL);
1665
1666 Label bz, bz_end;
1667 __ Tbz(x16, 0, &bz);
1668 __ B(&bz_end);
1669 __ Bind(&bz);
1670 __ Mov(x0, 1);
1671 __ Bind(&bz_end);
1672
1673 Label bo, bo_end;
1674 __ Tbz(x16, 63, &bo);
1675 __ B(&bo_end);
1676 __ Bind(&bo);
1677 __ Mov(x1, 1);
1678 __ Bind(&bo_end);
1679
1680 Label nbz, nbz_end;
1681 __ Tbnz(x16, 61, &nbz);
1682 __ B(&nbz_end);
1683 __ Bind(&nbz);
1684 __ Mov(x2, 1);
1685 __ Bind(&nbz_end);
1686
1687 Label nbo, nbo_end;
1688 __ Tbnz(x16, 2, &nbo);
1689 __ B(&nbo_end);
1690 __ Bind(&nbo);
1691 __ Mov(x3, 1);
1692 __ Bind(&nbo_end);
1693 END();
1694
1695 RUN();
1696
1697 ASSERT_EQUAL_64(1, x0);
1698 ASSERT_EQUAL_64(0, x1);
1699 ASSERT_EQUAL_64(1, x2);
1700 ASSERT_EQUAL_64(0, x3);
1701
1702 TEARDOWN();
1703}
1704
1705
1706TEST(ldr_str_offset) {
1707 SETUP();
1708
1709 uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL};
1710 uint64_t dst[5] = {0, 0, 0, 0, 0};
1711 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1712 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
1713
1714 START();
1715 __ Mov(x17, src_base);
1716 __ Mov(x18, dst_base);
1717 __ Ldr(w0, MemOperand(x17));
1718 __ Str(w0, MemOperand(x18));
1719 __ Ldr(w1, MemOperand(x17, 4));
1720 __ Str(w1, MemOperand(x18, 12));
1721 __ Ldr(x2, MemOperand(x17, 8));
1722 __ Str(x2, MemOperand(x18, 16));
1723 __ Ldrb(w3, MemOperand(x17, 1));
1724 __ Strb(w3, MemOperand(x18, 25));
1725 __ Ldrh(w4, MemOperand(x17, 2));
1726 __ Strh(w4, MemOperand(x18, 33));
1727 END();
1728
1729 RUN();
1730
1731 ASSERT_EQUAL_64(0x76543210, x0);
1732 ASSERT_EQUAL_64(0x76543210, dst[0]);
1733 ASSERT_EQUAL_64(0xfedcba98, x1);
1734 ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]);
1735 ASSERT_EQUAL_64(0x0123456789abcdefUL, x2);
1736 ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]);
1737 ASSERT_EQUAL_64(0x32, x3);
1738 ASSERT_EQUAL_64(0x3200, dst[3]);
1739 ASSERT_EQUAL_64(0x7654, x4);
1740 ASSERT_EQUAL_64(0x765400, dst[4]);
1741 ASSERT_EQUAL_64(src_base, x17);
1742 ASSERT_EQUAL_64(dst_base, x18);
1743
1744 TEARDOWN();
1745}
1746
1747
1748TEST(ldr_str_wide) {
1749 SETUP();
1750
1751 uint32_t src[8192];
1752 uint32_t dst[8192];
1753 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1754 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
1755 memset(src, 0xaa, 8192 * sizeof(src[0]));
1756 memset(dst, 0xaa, 8192 * sizeof(dst[0]));
1757 src[0] = 0;
1758 src[6144] = 6144;
1759 src[8191] = 8191;
1760
1761 START();
1762 __ Mov(x22, src_base);
1763 __ Mov(x23, dst_base);
1764 __ Mov(x24, src_base);
1765 __ Mov(x25, dst_base);
1766 __ Mov(x26, src_base);
1767 __ Mov(x27, dst_base);
1768
1769 __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
1770 __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
1771 __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
1772 __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
1773 __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
1774 __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
1775 END();
1776
1777 RUN();
1778
1779 ASSERT_EQUAL_32(8191, w0);
1780 ASSERT_EQUAL_32(8191, dst[8191]);
1781 ASSERT_EQUAL_64(src_base, x22);
1782 ASSERT_EQUAL_64(dst_base, x23);
1783 ASSERT_EQUAL_32(0, w1);
1784 ASSERT_EQUAL_32(0, dst[0]);
1785 ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
1786 ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
1787 ASSERT_EQUAL_32(6144, w2);
1788 ASSERT_EQUAL_32(6144, dst[6144]);
1789 ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
1790 ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
1791
1792 TEARDOWN();
1793}
1794
1795
1796TEST(ldr_str_preindex) {
1797 SETUP();
1798
1799 uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL};
1800 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
1801 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1802 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
1803
1804 START();
1805 __ Mov(x17, src_base);
1806 __ Mov(x18, dst_base);
1807 __ Mov(x19, src_base);
1808 __ Mov(x20, dst_base);
1809 __ Mov(x21, src_base + 16);
1810 __ Mov(x22, dst_base + 40);
1811 __ Mov(x23, src_base);
1812 __ Mov(x24, dst_base);
1813 __ Mov(x25, src_base);
1814 __ Mov(x26, dst_base);
1815 __ Ldr(w0, MemOperand(x17, 4, PreIndex));
1816 __ Str(w0, MemOperand(x18, 12, PreIndex));
1817 __ Ldr(x1, MemOperand(x19, 8, PreIndex));
1818 __ Str(x1, MemOperand(x20, 16, PreIndex));
1819 __ Ldr(w2, MemOperand(x21, -4, PreIndex));
1820 __ Str(w2, MemOperand(x22, -4, PreIndex));
1821 __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
1822 __ Strb(w3, MemOperand(x24, 25, PreIndex));
1823 __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
1824 __ Strh(w4, MemOperand(x26, 41, PreIndex));
1825 END();
1826
1827 RUN();
1828
1829 ASSERT_EQUAL_64(0xfedcba98, x0);
1830 ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]);
1831 ASSERT_EQUAL_64(0x0123456789abcdefUL, x1);
1832 ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]);
1833 ASSERT_EQUAL_64(0x01234567, x2);
1834 ASSERT_EQUAL_64(0x0123456700000000UL, dst[4]);
1835 ASSERT_EQUAL_64(0x32, x3);
1836 ASSERT_EQUAL_64(0x3200, dst[3]);
1837 ASSERT_EQUAL_64(0x9876, x4);
1838 ASSERT_EQUAL_64(0x987600, dst[5]);
1839 ASSERT_EQUAL_64(src_base + 4, x17);
1840 ASSERT_EQUAL_64(dst_base + 12, x18);
1841 ASSERT_EQUAL_64(src_base + 8, x19);
1842 ASSERT_EQUAL_64(dst_base + 16, x20);
1843 ASSERT_EQUAL_64(src_base + 12, x21);
1844 ASSERT_EQUAL_64(dst_base + 36, x22);
1845 ASSERT_EQUAL_64(src_base + 1, x23);
1846 ASSERT_EQUAL_64(dst_base + 25, x24);
1847 ASSERT_EQUAL_64(src_base + 3, x25);
1848 ASSERT_EQUAL_64(dst_base + 41, x26);
1849
1850 TEARDOWN();
1851}
1852
1853
1854TEST(ldr_str_postindex) {
1855 SETUP();
1856
1857 uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL};
1858 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
1859 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1860 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
1861
1862 START();
1863 __ Mov(x17, src_base + 4);
1864 __ Mov(x18, dst_base + 12);
1865 __ Mov(x19, src_base + 8);
1866 __ Mov(x20, dst_base + 16);
1867 __ Mov(x21, src_base + 8);
1868 __ Mov(x22, dst_base + 32);
1869 __ Mov(x23, src_base + 1);
1870 __ Mov(x24, dst_base + 25);
1871 __ Mov(x25, src_base + 3);
1872 __ Mov(x26, dst_base + 41);
1873 __ Ldr(w0, MemOperand(x17, 4, PostIndex));
1874 __ Str(w0, MemOperand(x18, 12, PostIndex));
1875 __ Ldr(x1, MemOperand(x19, 8, PostIndex));
1876 __ Str(x1, MemOperand(x20, 16, PostIndex));
1877 __ Ldr(x2, MemOperand(x21, -8, PostIndex));
1878 __ Str(x2, MemOperand(x22, -32, PostIndex));
1879 __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
1880 __ Strb(w3, MemOperand(x24, 5, PostIndex));
1881 __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
1882 __ Strh(w4, MemOperand(x26, -41, PostIndex));
1883 END();
1884
1885 RUN();
1886
1887 ASSERT_EQUAL_64(0xfedcba98, x0);
1888 ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]);
1889 ASSERT_EQUAL_64(0x0123456789abcdefUL, x1);
1890 ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]);
1891 ASSERT_EQUAL_64(0x0123456789abcdefUL, x2);
1892 ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[4]);
1893 ASSERT_EQUAL_64(0x32, x3);
1894 ASSERT_EQUAL_64(0x3200, dst[3]);
1895 ASSERT_EQUAL_64(0x9876, x4);
1896 ASSERT_EQUAL_64(0x987600, dst[5]);
1897 ASSERT_EQUAL_64(src_base + 8, x17);
1898 ASSERT_EQUAL_64(dst_base + 24, x18);
1899 ASSERT_EQUAL_64(src_base + 16, x19);
1900 ASSERT_EQUAL_64(dst_base + 32, x20);
1901 ASSERT_EQUAL_64(src_base, x21);
1902 ASSERT_EQUAL_64(dst_base, x22);
1903 ASSERT_EQUAL_64(src_base + 2, x23);
1904 ASSERT_EQUAL_64(dst_base + 30, x24);
1905 ASSERT_EQUAL_64(src_base, x25);
1906 ASSERT_EQUAL_64(dst_base, x26);
1907
1908 TEARDOWN();
1909}
1910
1911
1912TEST(ldr_str_largeindex) {
1913 SETUP();
1914
1915 // This value won't fit in the immediate offset field of ldr/str instructions.
1916 int largeoffset = 0xabcdef;
1917
1918 int64_t data[3] = { 0x1122334455667788, 0, 0 };
1919 uintptr_t base_addr = reinterpret_cast<uintptr_t>(data);
1920 uintptr_t drifted_addr = base_addr - largeoffset;
1921
1922 // This test checks that we we can use large immediate offsets when
1923 // using PreIndex or PostIndex addressing mode of the MacroAssembler
1924 // Ldr/Str instructions.
1925
1926 START();
1927 __ Mov(x17, drifted_addr);
1928 __ Ldr(x0, MemOperand(x17, largeoffset, PreIndex));
1929
1930 __ Mov(x18, base_addr);
1931 __ Ldr(x1, MemOperand(x18, largeoffset, PostIndex));
1932
1933 __ Mov(x19, drifted_addr);
1934 __ Str(x0, MemOperand(x19, largeoffset + 8, PreIndex));
1935
1936 __ Mov(x20, base_addr + 16);
1937 __ Str(x0, MemOperand(x20, largeoffset, PostIndex));
1938 END();
1939
1940 RUN();
1941
1942 ASSERT_EQUAL_64(0x1122334455667788, data[0]);
1943 ASSERT_EQUAL_64(0x1122334455667788, data[1]);
1944 ASSERT_EQUAL_64(0x1122334455667788, data[2]);
1945 ASSERT_EQUAL_64(0x1122334455667788, x0);
1946 ASSERT_EQUAL_64(0x1122334455667788, x1);
1947
1948 ASSERT_EQUAL_64(base_addr, x17);
1949 ASSERT_EQUAL_64(base_addr + largeoffset, x18);
1950 ASSERT_EQUAL_64(base_addr + 8, x19);
1951 ASSERT_EQUAL_64(base_addr + 16 + largeoffset, x20);
1952
1953 TEARDOWN();
1954}
1955
1956
1957TEST(load_signed) {
1958 SETUP();
1959
1960 uint32_t src[2] = {0x80008080, 0x7fff7f7f};
1961 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1962
1963 START();
1964 __ Mov(x24, src_base);
1965 __ Ldrsb(w0, MemOperand(x24));
1966 __ Ldrsb(w1, MemOperand(x24, 4));
1967 __ Ldrsh(w2, MemOperand(x24));
1968 __ Ldrsh(w3, MemOperand(x24, 4));
1969 __ Ldrsb(x4, MemOperand(x24));
1970 __ Ldrsb(x5, MemOperand(x24, 4));
1971 __ Ldrsh(x6, MemOperand(x24));
1972 __ Ldrsh(x7, MemOperand(x24, 4));
1973 __ Ldrsw(x8, MemOperand(x24));
1974 __ Ldrsw(x9, MemOperand(x24, 4));
1975 END();
1976
1977 RUN();
1978
1979 ASSERT_EQUAL_64(0xffffff80, x0);
1980 ASSERT_EQUAL_64(0x0000007f, x1);
1981 ASSERT_EQUAL_64(0xffff8080, x2);
1982 ASSERT_EQUAL_64(0x00007f7f, x3);
1983 ASSERT_EQUAL_64(0xffffffffffffff80UL, x4);
1984 ASSERT_EQUAL_64(0x000000000000007fUL, x5);
1985 ASSERT_EQUAL_64(0xffffffffffff8080UL, x6);
1986 ASSERT_EQUAL_64(0x0000000000007f7fUL, x7);
1987 ASSERT_EQUAL_64(0xffffffff80008080UL, x8);
1988 ASSERT_EQUAL_64(0x000000007fff7f7fUL, x9);
1989
1990 TEARDOWN();
1991}
1992
1993
1994TEST(load_store_regoffset) {
1995 SETUP();
1996
1997 uint32_t src[3] = {1, 2, 3};
1998 uint32_t dst[4] = {0, 0, 0, 0};
1999 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2000 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2001
2002 START();
2003 __ Mov(x16, src_base);
2004 __ Mov(x17, dst_base);
2005 __ Mov(x18, src_base + 3 * sizeof(src[0]));
2006 __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
2007 __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
2008 __ Mov(x24, 0);
2009 __ Mov(x25, 4);
2010 __ Mov(x26, -4);
2011 __ Mov(x27, 0xfffffffc); // 32-bit -4.
2012 __ Mov(x28, 0xfffffffe); // 32-bit -2.
2013 __ Mov(x29, 0xffffffff); // 32-bit -1.
2014
2015 __ Ldr(w0, MemOperand(x16, x24));
2016 __ Ldr(x1, MemOperand(x16, x25));
2017 __ Ldr(w2, MemOperand(x18, x26));
2018 __ Ldr(w3, MemOperand(x18, x27, SXTW));
2019 __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
2020 __ Str(w0, MemOperand(x17, x24));
2021 __ Str(x1, MemOperand(x17, x25));
2022 __ Str(w2, MemOperand(x20, x29, SXTW, 2));
2023 END();
2024
2025 RUN();
2026
2027 ASSERT_EQUAL_64(1, x0);
2028 ASSERT_EQUAL_64(0x0000000300000002UL, x1);
2029 ASSERT_EQUAL_64(3, x2);
2030 ASSERT_EQUAL_64(3, x3);
2031 ASSERT_EQUAL_64(2, x4);
2032 ASSERT_EQUAL_32(1, dst[0]);
2033 ASSERT_EQUAL_32(2, dst[1]);
2034 ASSERT_EQUAL_32(3, dst[2]);
2035 ASSERT_EQUAL_32(3, dst[3]);
2036
2037 TEARDOWN();
2038}
2039
2040
2041TEST(load_store_float) {
2042 SETUP();
2043
2044 float src[3] = {1.0, 2.0, 3.0};
2045 float dst[3] = {0.0, 0.0, 0.0};
2046 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2047 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2048
2049 START();
2050 __ Mov(x17, src_base);
2051 __ Mov(x18, dst_base);
2052 __ Mov(x19, src_base);
2053 __ Mov(x20, dst_base);
2054 __ Mov(x21, src_base);
2055 __ Mov(x22, dst_base);
2056 __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
2057 __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2058 __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
2059 __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2060 __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2061 __ Str(s2, MemOperand(x22, sizeof(dst[0])));
2062 END();
2063
2064 RUN();
2065
2066 ASSERT_EQUAL_FP32(2.0, s0);
2067 ASSERT_EQUAL_FP32(2.0, dst[0]);
2068 ASSERT_EQUAL_FP32(1.0, s1);
2069 ASSERT_EQUAL_FP32(1.0, dst[2]);
2070 ASSERT_EQUAL_FP32(3.0, s2);
2071 ASSERT_EQUAL_FP32(3.0, dst[1]);
2072 ASSERT_EQUAL_64(src_base, x17);
2073 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2074 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2075 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2076 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2077 ASSERT_EQUAL_64(dst_base, x22);
2078
2079 TEARDOWN();
2080}
2081
2082
2083TEST(load_store_double) {
2084 SETUP();
2085
2086 double src[3] = {1.0, 2.0, 3.0};
2087 double dst[3] = {0.0, 0.0, 0.0};
2088 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2089 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2090
2091 START();
2092 __ Mov(x17, src_base);
2093 __ Mov(x18, dst_base);
2094 __ Mov(x19, src_base);
2095 __ Mov(x20, dst_base);
2096 __ Mov(x21, src_base);
2097 __ Mov(x22, dst_base);
2098 __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
2099 __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2100 __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
2101 __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2102 __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2103 __ Str(d2, MemOperand(x22, sizeof(dst[0])));
2104 END();
2105
2106 RUN();
2107
2108 ASSERT_EQUAL_FP64(2.0, d0);
2109 ASSERT_EQUAL_FP64(2.0, dst[0]);
2110 ASSERT_EQUAL_FP64(1.0, d1);
2111 ASSERT_EQUAL_FP64(1.0, dst[2]);
2112 ASSERT_EQUAL_FP64(3.0, d2);
2113 ASSERT_EQUAL_FP64(3.0, dst[1]);
2114 ASSERT_EQUAL_64(src_base, x17);
2115 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2116 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2117 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2118 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2119 ASSERT_EQUAL_64(dst_base, x22);
2120
2121 TEARDOWN();
2122}
2123
2124
2125TEST(ldp_stp_float) {
2126 SETUP();
2127
2128 float src[2] = {1.0, 2.0};
2129 float dst[3] = {0.0, 0.0, 0.0};
2130 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2131 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2132
2133 START();
2134 __ Mov(x16, src_base);
2135 __ Mov(x17, dst_base);
2136 __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2137 __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2138 END();
2139
2140 RUN();
2141
2142 ASSERT_EQUAL_FP32(1.0, s31);
2143 ASSERT_EQUAL_FP32(2.0, s0);
2144 ASSERT_EQUAL_FP32(0.0, dst[0]);
2145 ASSERT_EQUAL_FP32(2.0, dst[1]);
2146 ASSERT_EQUAL_FP32(1.0, dst[2]);
2147 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2148 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2149
2150 TEARDOWN();
2151}
2152
2153
2154TEST(ldp_stp_double) {
2155 SETUP();
2156
2157 double src[2] = {1.0, 2.0};
2158 double dst[3] = {0.0, 0.0, 0.0};
2159 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2160 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2161
2162 START();
2163 __ Mov(x16, src_base);
2164 __ Mov(x17, dst_base);
2165 __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2166 __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2167 END();
2168
2169 RUN();
2170
2171 ASSERT_EQUAL_FP64(1.0, d31);
2172 ASSERT_EQUAL_FP64(2.0, d0);
2173 ASSERT_EQUAL_FP64(0.0, dst[0]);
2174 ASSERT_EQUAL_FP64(2.0, dst[1]);
2175 ASSERT_EQUAL_FP64(1.0, dst[2]);
2176 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2177 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2178
2179 TEARDOWN();
2180}
2181
2182
2183TEST(ldp_stp_offset) {
2184 SETUP();
2185
2186 uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL,
2187 0xffeeddccbbaa9988UL};
2188 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2189 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2190 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2191
2192 START();
2193 __ Mov(x16, src_base);
2194 __ Mov(x17, dst_base);
2195 __ Mov(x18, src_base + 24);
2196 __ Mov(x19, dst_base + 56);
2197 __ Ldp(w0, w1, MemOperand(x16));
2198 __ Ldp(w2, w3, MemOperand(x16, 4));
2199 __ Ldp(x4, x5, MemOperand(x16, 8));
2200 __ Ldp(w6, w7, MemOperand(x18, -12));
2201 __ Ldp(x8, x9, MemOperand(x18, -16));
2202 __ Stp(w0, w1, MemOperand(x17));
2203 __ Stp(w2, w3, MemOperand(x17, 8));
2204 __ Stp(x4, x5, MemOperand(x17, 16));
2205 __ Stp(w6, w7, MemOperand(x19, -24));
2206 __ Stp(x8, x9, MemOperand(x19, -16));
2207 END();
2208
2209 RUN();
2210
2211 ASSERT_EQUAL_64(0x44556677, x0);
2212 ASSERT_EQUAL_64(0x00112233, x1);
2213 ASSERT_EQUAL_64(0x0011223344556677UL, dst[0]);
2214 ASSERT_EQUAL_64(0x00112233, x2);
2215 ASSERT_EQUAL_64(0xccddeeff, x3);
2216 ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[1]);
2217 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4);
2218 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
2219 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5);
2220 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
2221 ASSERT_EQUAL_64(0x8899aabb, x6);
2222 ASSERT_EQUAL_64(0xbbaa9988, x7);
2223 ASSERT_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
2224 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x8);
2225 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
2226 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x9);
2227 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
2228 ASSERT_EQUAL_64(src_base, x16);
2229 ASSERT_EQUAL_64(dst_base, x17);
2230 ASSERT_EQUAL_64(src_base + 24, x18);
2231 ASSERT_EQUAL_64(dst_base + 56, x19);
2232
2233 TEARDOWN();
2234}
2235
2236
2237TEST(ldnp_stnp_offset) {
2238 SETUP();
2239
2240 uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL,
2241 0xffeeddccbbaa9988UL};
2242 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2243 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2244 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2245
2246 START();
2247 __ Mov(x16, src_base);
2248 __ Mov(x17, dst_base);
2249 __ Mov(x18, src_base + 24);
2250 __ Mov(x19, dst_base + 56);
2251 __ Ldnp(w0, w1, MemOperand(x16));
2252 __ Ldnp(w2, w3, MemOperand(x16, 4));
2253 __ Ldnp(x4, x5, MemOperand(x16, 8));
2254 __ Ldnp(w6, w7, MemOperand(x18, -12));
2255 __ Ldnp(x8, x9, MemOperand(x18, -16));
2256 __ Stnp(w0, w1, MemOperand(x17));
2257 __ Stnp(w2, w3, MemOperand(x17, 8));
2258 __ Stnp(x4, x5, MemOperand(x17, 16));
2259 __ Stnp(w6, w7, MemOperand(x19, -24));
2260 __ Stnp(x8, x9, MemOperand(x19, -16));
2261 END();
2262
2263 RUN();
2264
2265 ASSERT_EQUAL_64(0x44556677, x0);
2266 ASSERT_EQUAL_64(0x00112233, x1);
2267 ASSERT_EQUAL_64(0x0011223344556677UL, dst[0]);
2268 ASSERT_EQUAL_64(0x00112233, x2);
2269 ASSERT_EQUAL_64(0xccddeeff, x3);
2270 ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[1]);
2271 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4);
2272 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
2273 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5);
2274 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
2275 ASSERT_EQUAL_64(0x8899aabb, x6);
2276 ASSERT_EQUAL_64(0xbbaa9988, x7);
2277 ASSERT_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
2278 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x8);
2279 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
2280 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x9);
2281 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
2282 ASSERT_EQUAL_64(src_base, x16);
2283 ASSERT_EQUAL_64(dst_base, x17);
2284 ASSERT_EQUAL_64(src_base + 24, x18);
2285 ASSERT_EQUAL_64(dst_base + 56, x19);
2286
2287 TEARDOWN();
2288}
2289
2290
2291TEST(ldp_stp_preindex) {
2292 SETUP();
2293
2294 uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL,
2295 0xffeeddccbbaa9988UL};
2296 uint64_t dst[5] = {0, 0, 0, 0, 0};
2297 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2298 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2299
2300 START();
2301 __ Mov(x16, src_base);
2302 __ Mov(x17, dst_base);
2303 __ Mov(x18, dst_base + 16);
2304 __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
2305 __ Mov(x19, x16);
2306 __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
2307 __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
2308 __ Mov(x20, x17);
2309 __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
2310 __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
2311 __ Mov(x21, x16);
2312 __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
2313 __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
2314 __ Mov(x22, x18);
2315 __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
2316 END();
2317
2318 RUN();
2319
2320 ASSERT_EQUAL_64(0x00112233, x0);
2321 ASSERT_EQUAL_64(0xccddeeff, x1);
2322 ASSERT_EQUAL_64(0x44556677, x2);
2323 ASSERT_EQUAL_64(0x00112233, x3);
2324 ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[0]);
2325 ASSERT_EQUAL_64(0x0000000000112233UL, dst[1]);
2326 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4);
2327 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5);
2328 ASSERT_EQUAL_64(0x0011223344556677UL, x6);
2329 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x7);
2330 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
2331 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
2332 ASSERT_EQUAL_64(0x0011223344556677UL, dst[4]);
2333 ASSERT_EQUAL_64(src_base, x16);
2334 ASSERT_EQUAL_64(dst_base, x17);
2335 ASSERT_EQUAL_64(dst_base + 16, x18);
2336 ASSERT_EQUAL_64(src_base + 4, x19);
2337 ASSERT_EQUAL_64(dst_base + 4, x20);
2338 ASSERT_EQUAL_64(src_base + 8, x21);
2339 ASSERT_EQUAL_64(dst_base + 24, x22);
2340
2341 TEARDOWN();
2342}
2343
2344
2345TEST(ldp_stp_postindex) {
2346 SETUP();
2347
2348 uint64_t src[4] = {0x0011223344556677UL, 0x8899aabbccddeeffUL,
2349 0xffeeddccbbaa9988UL, 0x7766554433221100UL};
2350 uint64_t dst[5] = {0, 0, 0, 0, 0};
2351 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2352 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2353
2354 START();
2355 __ Mov(x16, src_base);
2356 __ Mov(x17, dst_base);
2357 __ Mov(x18, dst_base + 16);
2358 __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
2359 __ Mov(x19, x16);
2360 __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
2361 __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
2362 __ Mov(x20, x17);
2363 __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
2364 __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
2365 __ Mov(x21, x16);
2366 __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
2367 __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
2368 __ Mov(x22, x18);
2369 __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
2370 END();
2371
2372 RUN();
2373
2374 ASSERT_EQUAL_64(0x44556677, x0);
2375 ASSERT_EQUAL_64(0x00112233, x1);
2376 ASSERT_EQUAL_64(0x00112233, x2);
2377 ASSERT_EQUAL_64(0xccddeeff, x3);
2378 ASSERT_EQUAL_64(0x4455667700112233UL, dst[0]);
2379 ASSERT_EQUAL_64(0x0000000000112233UL, dst[1]);
2380 ASSERT_EQUAL_64(0x0011223344556677UL, x4);
2381 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x5);
2382 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x6);
2383 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x7);
2384 ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
2385 ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
2386 ASSERT_EQUAL_64(0x0011223344556677UL, dst[4]);
2387 ASSERT_EQUAL_64(src_base, x16);
2388 ASSERT_EQUAL_64(dst_base, x17);
2389 ASSERT_EQUAL_64(dst_base + 16, x18);
2390 ASSERT_EQUAL_64(src_base + 4, x19);
2391 ASSERT_EQUAL_64(dst_base + 4, x20);
2392 ASSERT_EQUAL_64(src_base + 8, x21);
2393 ASSERT_EQUAL_64(dst_base + 24, x22);
2394
2395 TEARDOWN();
2396}
2397
2398
2399TEST(ldp_sign_extend) {
2400 SETUP();
2401
2402 uint32_t src[2] = {0x80000000, 0x7fffffff};
2403 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2404
2405 START();
2406 __ Mov(x24, src_base);
2407 __ Ldpsw(x0, x1, MemOperand(x24));
2408 END();
2409
2410 RUN();
2411
2412 ASSERT_EQUAL_64(0xffffffff80000000UL, x0);
2413 ASSERT_EQUAL_64(0x000000007fffffffUL, x1);
2414
2415 TEARDOWN();
2416}
2417
2418
2419TEST(ldur_stur) {
2420 SETUP();
2421
2422 int64_t src[2] = {0x0123456789abcdefUL, 0x0123456789abcdefUL};
2423 int64_t dst[5] = {0, 0, 0, 0, 0};
2424 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2425 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2426
2427 START();
2428 __ Mov(x17, src_base);
2429 __ Mov(x18, dst_base);
2430 __ Mov(x19, src_base + 16);
2431 __ Mov(x20, dst_base + 32);
2432 __ Mov(x21, dst_base + 40);
2433 __ Ldr(w0, MemOperand(x17, 1));
2434 __ Str(w0, MemOperand(x18, 2));
2435 __ Ldr(x1, MemOperand(x17, 3));
2436 __ Str(x1, MemOperand(x18, 9));
2437 __ Ldr(w2, MemOperand(x19, -9));
2438 __ Str(w2, MemOperand(x20, -5));
2439 __ Ldrb(w3, MemOperand(x19, -1));
2440 __ Strb(w3, MemOperand(x21, -1));
2441 END();
2442
2443 RUN();
2444
2445 ASSERT_EQUAL_64(0x6789abcd, x0);
2446 ASSERT_EQUAL_64(0x6789abcd0000L, dst[0]);
2447 ASSERT_EQUAL_64(0xabcdef0123456789L, x1);
2448 ASSERT_EQUAL_64(0xcdef012345678900L, dst[1]);
2449 ASSERT_EQUAL_64(0x000000ab, dst[2]);
2450 ASSERT_EQUAL_64(0xabcdef01, x2);
2451 ASSERT_EQUAL_64(0x00abcdef01000000L, dst[3]);
2452 ASSERT_EQUAL_64(0x00000001, x3);
2453 ASSERT_EQUAL_64(0x0100000000000000L, dst[4]);
2454 ASSERT_EQUAL_64(src_base, x17);
2455 ASSERT_EQUAL_64(dst_base, x18);
2456 ASSERT_EQUAL_64(src_base + 16, x19);
2457 ASSERT_EQUAL_64(dst_base + 32, x20);
2458
2459 TEARDOWN();
2460}
2461
2462
2463TEST(ldr_literal) {
2464 SETUP();
2465
2466 START();
2467 __ Ldr(x2, 0x1234567890abcdefUL);
2468 __ Ldr(w3, 0xfedcba09);
2469 __ Ldr(d13, 1.234);
2470 __ Ldr(s25, 2.5);
2471 END();
2472
2473 RUN();
2474
2475 ASSERT_EQUAL_64(0x1234567890abcdefUL, x2);
2476 ASSERT_EQUAL_64(0xfedcba09, x3);
2477 ASSERT_EQUAL_FP64(1.234, d13);
2478 ASSERT_EQUAL_FP32(2.5, s25);
2479
2480 TEARDOWN();
2481}
2482
2483
2484static void LdrLiteralRangeHelper(ptrdiff_t range_,
2485 LiteralPoolEmitOption option,
2486 bool expect_dump) {
2487 ASSERT(range_ > 0);
2488 SETUP_SIZE(range_ + 1024);
2489
2490 Label label_1, label_2;
2491
2492 size_t range = static_cast<size_t>(range_);
2493 size_t code_size = 0;
2494 size_t pool_guard_size;
2495
2496 if (option == NoJumpRequired) {
2497 // Space for an explicit branch.
2498 pool_guard_size = sizeof(Instr);
2499 } else {
2500 pool_guard_size = 0;
2501 }
2502
2503 START();
2504 // Force a pool dump so the pool starts off empty.
2505 __ EmitLiteralPool(JumpRequired);
2506 ASSERT_LITERAL_POOL_SIZE(0);
2507
2508 __ Ldr(x0, 0x1234567890abcdefUL);
2509 __ Ldr(w1, 0xfedcba09);
2510 __ Ldr(d0, 1.234);
2511 __ Ldr(s1, 2.5);
2512 ASSERT_LITERAL_POOL_SIZE(24);
2513
2514 code_size += 4 * sizeof(Instr);
2515
2516 // Check that the requested range (allowing space for a branch over the pool)
2517 // can be handled by this test.
2518 ASSERT((code_size + pool_guard_size) <= range);
2519
2520 // Emit NOPs up to 'range', leaving space for the pool guard.
2521 while ((code_size + pool_guard_size) < range) {
2522 __ Nop();
2523 code_size += sizeof(Instr);
2524 }
2525
2526 // Emit the guard sequence before the literal pool.
2527 if (option == NoJumpRequired) {
2528 __ B(&label_1);
2529 code_size += sizeof(Instr);
2530 }
2531
2532 ASSERT(code_size == range);
2533 ASSERT_LITERAL_POOL_SIZE(24);
2534
2535 // Possibly generate a literal pool.
2536 __ CheckLiteralPool(option);
2537 __ Bind(&label_1);
2538 if (expect_dump) {
2539 ASSERT_LITERAL_POOL_SIZE(0);
2540 } else {
2541 ASSERT_LITERAL_POOL_SIZE(24);
2542 }
2543
2544 // Force a pool flush to check that a second pool functions correctly.
2545 __ EmitLiteralPool(JumpRequired);
2546 ASSERT_LITERAL_POOL_SIZE(0);
2547
2548 // These loads should be after the pool (and will require a new one).
2549 __ Ldr(x4, 0x34567890abcdef12UL);
2550 __ Ldr(w5, 0xdcba09fe);
2551 __ Ldr(d4, 123.4);
2552 __ Ldr(s5, 250.0);
2553 ASSERT_LITERAL_POOL_SIZE(24);
2554 END();
2555
2556 RUN();
2557
2558 // Check that the literals loaded correctly.
2559 ASSERT_EQUAL_64(0x1234567890abcdefUL, x0);
2560 ASSERT_EQUAL_64(0xfedcba09, x1);
2561 ASSERT_EQUAL_FP64(1.234, d0);
2562 ASSERT_EQUAL_FP32(2.5, s1);
2563 ASSERT_EQUAL_64(0x34567890abcdef12UL, x4);
2564 ASSERT_EQUAL_64(0xdcba09fe, x5);
2565 ASSERT_EQUAL_FP64(123.4, d4);
2566 ASSERT_EQUAL_FP32(250.0, s5);
2567
2568 TEARDOWN();
2569}
2570
2571
2572TEST(ldr_literal_range_1) {
2573 LdrLiteralRangeHelper(kRecommendedLiteralPoolRange,
2574 NoJumpRequired,
2575 true);
2576}
2577
2578
2579TEST(ldr_literal_range_2) {
2580 LdrLiteralRangeHelper(kRecommendedLiteralPoolRange-sizeof(Instr),
2581 NoJumpRequired,
2582 false);
2583}
2584
2585
2586TEST(ldr_literal_range_3) {
2587 LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange,
2588 JumpRequired,
2589 true);
2590}
2591
2592
2593TEST(ldr_literal_range_4) {
2594 LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange-sizeof(Instr),
2595 JumpRequired,
2596 false);
2597}
2598
2599
2600TEST(ldr_literal_range_5) {
2601 LdrLiteralRangeHelper(kLiteralPoolCheckInterval,
2602 JumpRequired,
2603 false);
2604}
2605
2606
2607TEST(ldr_literal_range_6) {
2608 LdrLiteralRangeHelper(kLiteralPoolCheckInterval-sizeof(Instr),
2609 JumpRequired,
2610 false);
2611}
2612
2613
2614TEST(add_sub_imm) {
2615 SETUP();
2616
2617 START();
2618 __ Mov(x0, 0x0);
2619 __ Mov(x1, 0x1111);
2620 __ Mov(x2, 0xffffffffffffffffL);
2621 __ Mov(x3, 0x8000000000000000L);
2622
2623 __ Add(x10, x0, Operand(0x123));
2624 __ Add(x11, x1, Operand(0x122000));
2625 __ Add(x12, x0, Operand(0xabc << 12));
2626 __ Add(x13, x2, Operand(1));
2627
2628 __ Add(w14, w0, Operand(0x123));
2629 __ Add(w15, w1, Operand(0x122000));
2630 __ Add(w16, w0, Operand(0xabc << 12));
2631 __ Add(w17, w2, Operand(1));
2632
2633 __ Sub(x20, x0, Operand(0x1));
2634 __ Sub(x21, x1, Operand(0x111));
2635 __ Sub(x22, x1, Operand(0x1 << 12));
2636 __ Sub(x23, x3, Operand(1));
2637
2638 __ Sub(w24, w0, Operand(0x1));
2639 __ Sub(w25, w1, Operand(0x111));
2640 __ Sub(w26, w1, Operand(0x1 << 12));
2641 __ Sub(w27, w3, Operand(1));
2642 END();
2643
2644 RUN();
2645
2646 ASSERT_EQUAL_64(0x123, x10);
2647 ASSERT_EQUAL_64(0x123111, x11);
2648 ASSERT_EQUAL_64(0xabc000, x12);
2649 ASSERT_EQUAL_64(0x0, x13);
2650
2651 ASSERT_EQUAL_32(0x123, w14);
2652 ASSERT_EQUAL_32(0x123111, w15);
2653 ASSERT_EQUAL_32(0xabc000, w16);
2654 ASSERT_EQUAL_32(0x0, w17);
2655
2656 ASSERT_EQUAL_64(0xffffffffffffffffL, x20);
2657 ASSERT_EQUAL_64(0x1000, x21);
2658 ASSERT_EQUAL_64(0x111, x22);
2659 ASSERT_EQUAL_64(0x7fffffffffffffffL, x23);
2660
2661 ASSERT_EQUAL_32(0xffffffff, w24);
2662 ASSERT_EQUAL_32(0x1000, w25);
2663 ASSERT_EQUAL_32(0x111, w26);
2664 ASSERT_EQUAL_32(0xffffffff, w27);
2665
2666 TEARDOWN();
2667}
2668
2669
2670TEST(add_sub_wide_imm) {
2671 SETUP();
2672
2673 START();
2674 __ Mov(x0, 0x0);
2675 __ Mov(x1, 0x1);
2676
2677 __ Add(x10, x0, Operand(0x1234567890abcdefUL));
2678 __ Add(x11, x1, Operand(0xffffffff));
2679
2680 __ Add(w12, w0, Operand(0x12345678));
2681 __ Add(w13, w1, Operand(0xffffffff));
2682
2683 __ Sub(x20, x0, Operand(0x1234567890abcdefUL));
2684
2685 __ Sub(w21, w0, Operand(0x12345678));
2686 END();
2687
2688 RUN();
2689
2690 ASSERT_EQUAL_64(0x1234567890abcdefUL, x10);
2691 ASSERT_EQUAL_64(0x100000000UL, x11);
2692
2693 ASSERT_EQUAL_32(0x12345678, w12);
2694 ASSERT_EQUAL_64(0x0, x13);
2695
2696 ASSERT_EQUAL_64(-0x1234567890abcdefUL, x20);
2697
2698 ASSERT_EQUAL_32(-0x12345678, w21);
2699
2700 TEARDOWN();
2701}
2702
2703
2704TEST(add_sub_shifted) {
2705 SETUP();
2706
2707 START();
2708 __ Mov(x0, 0);
2709 __ Mov(x1, 0x0123456789abcdefL);
2710 __ Mov(x2, 0xfedcba9876543210L);
2711 __ Mov(x3, 0xffffffffffffffffL);
2712
2713 __ Add(x10, x1, Operand(x2));
2714 __ Add(x11, x0, Operand(x1, LSL, 8));
2715 __ Add(x12, x0, Operand(x1, LSR, 8));
2716 __ Add(x13, x0, Operand(x1, ASR, 8));
2717 __ Add(x14, x0, Operand(x2, ASR, 8));
2718 __ Add(w15, w0, Operand(w1, ASR, 8));
2719 __ Add(w18, w3, Operand(w1, ROR, 8));
2720 __ Add(x19, x3, Operand(x1, ROR, 8));
2721
2722 __ Sub(x20, x3, Operand(x2));
2723 __ Sub(x21, x3, Operand(x1, LSL, 8));
2724 __ Sub(x22, x3, Operand(x1, LSR, 8));
2725 __ Sub(x23, x3, Operand(x1, ASR, 8));
2726 __ Sub(x24, x3, Operand(x2, ASR, 8));
2727 __ Sub(w25, w3, Operand(w1, ASR, 8));
2728 __ Sub(w26, w3, Operand(w1, ROR, 8));
2729 __ Sub(x27, x3, Operand(x1, ROR, 8));
2730 END();
2731
2732 RUN();
2733
2734 ASSERT_EQUAL_64(0xffffffffffffffffL, x10);
2735 ASSERT_EQUAL_64(0x23456789abcdef00L, x11);
2736 ASSERT_EQUAL_64(0x000123456789abcdL, x12);
2737 ASSERT_EQUAL_64(0x000123456789abcdL, x13);
2738 ASSERT_EQUAL_64(0xfffedcba98765432L, x14);
2739 ASSERT_EQUAL_64(0xff89abcd, x15);
2740 ASSERT_EQUAL_64(0xef89abcc, x18);
2741 ASSERT_EQUAL_64(0xef0123456789abccL, x19);
2742
2743 ASSERT_EQUAL_64(0x0123456789abcdefL, x20);
2744 ASSERT_EQUAL_64(0xdcba9876543210ffL, x21);
2745 ASSERT_EQUAL_64(0xfffedcba98765432L, x22);
2746 ASSERT_EQUAL_64(0xfffedcba98765432L, x23);
2747 ASSERT_EQUAL_64(0x000123456789abcdL, x24);
2748 ASSERT_EQUAL_64(0x00765432, x25);
2749 ASSERT_EQUAL_64(0x10765432, x26);
2750 ASSERT_EQUAL_64(0x10fedcba98765432L, x27);
2751
2752 TEARDOWN();
2753}
2754
2755
2756TEST(add_sub_extended) {
2757 SETUP();
2758
2759 START();
2760 __ Mov(x0, 0);
2761 __ Mov(x1, 0x0123456789abcdefL);
2762 __ Mov(x2, 0xfedcba9876543210L);
2763 __ Mov(w3, 0x80);
2764
2765 __ Add(x10, x0, Operand(x1, UXTB, 0));
2766 __ Add(x11, x0, Operand(x1, UXTB, 1));
2767 __ Add(x12, x0, Operand(x1, UXTH, 2));
2768 __ Add(x13, x0, Operand(x1, UXTW, 4));
2769
2770 __ Add(x14, x0, Operand(x1, SXTB, 0));
2771 __ Add(x15, x0, Operand(x1, SXTB, 1));
2772 __ Add(x16, x0, Operand(x1, SXTH, 2));
2773 __ Add(x17, x0, Operand(x1, SXTW, 3));
2774 __ Add(x18, x0, Operand(x2, SXTB, 0));
2775 __ Add(x19, x0, Operand(x2, SXTB, 1));
2776 __ Add(x20, x0, Operand(x2, SXTH, 2));
2777 __ Add(x21, x0, Operand(x2, SXTW, 3));
2778
2779 __ Add(x22, x1, Operand(x2, SXTB, 1));
2780 __ Sub(x23, x1, Operand(x2, SXTB, 1));
2781
2782 __ Add(w24, w1, Operand(w2, UXTB, 2));
2783 __ Add(w25, w0, Operand(w1, SXTB, 0));
2784 __ Add(w26, w0, Operand(w1, SXTB, 1));
2785 __ Add(w27, w2, Operand(w1, SXTW, 3));
2786
2787 __ Add(w28, w0, Operand(w1, SXTW, 3));
2788 __ Add(x29, x0, Operand(w1, SXTW, 3));
2789
2790 __ Sub(x30, x0, Operand(w3, SXTB, 1));
2791 END();
2792
2793 RUN();
2794
2795 ASSERT_EQUAL_64(0xefL, x10);
2796 ASSERT_EQUAL_64(0x1deL, x11);
2797 ASSERT_EQUAL_64(0x337bcL, x12);
2798 ASSERT_EQUAL_64(0x89abcdef0L, x13);
2799
2800 ASSERT_EQUAL_64(0xffffffffffffffefL, x14);
2801 ASSERT_EQUAL_64(0xffffffffffffffdeL, x15);
2802 ASSERT_EQUAL_64(0xffffffffffff37bcL, x16);
2803 ASSERT_EQUAL_64(0xfffffffc4d5e6f78L, x17);
2804 ASSERT_EQUAL_64(0x10L, x18);
2805 ASSERT_EQUAL_64(0x20L, x19);
2806 ASSERT_EQUAL_64(0xc840L, x20);
2807 ASSERT_EQUAL_64(0x3b2a19080L, x21);
2808
2809 ASSERT_EQUAL_64(0x0123456789abce0fL, x22);
2810 ASSERT_EQUAL_64(0x0123456789abcdcfL, x23);
2811
2812 ASSERT_EQUAL_32(0x89abce2f, w24);
2813 ASSERT_EQUAL_32(0xffffffef, w25);
2814 ASSERT_EQUAL_32(0xffffffde, w26);
2815 ASSERT_EQUAL_32(0xc3b2a188, w27);
2816
2817 ASSERT_EQUAL_32(0x4d5e6f78, w28);
2818 ASSERT_EQUAL_64(0xfffffffc4d5e6f78L, x29);
2819
2820 ASSERT_EQUAL_64(256, x30);
2821
2822 TEARDOWN();
2823}
2824
2825
2826TEST(add_sub_negative) {
2827 SETUP();
2828
2829 START();
2830 __ Mov(x0, 0);
2831 __ Mov(x1, 4687);
2832 __ Mov(x2, 0x1122334455667788);
2833 __ Mov(w3, 0x11223344);
2834 __ Mov(w4, 400000);
2835
2836 __ Add(x10, x0, -42);
2837 __ Add(x11, x1, -687);
2838 __ Add(x12, x2, -0x88);
2839
2840 __ Sub(x13, x0, -600);
2841 __ Sub(x14, x1, -313);
2842 __ Sub(x15, x2, -0x555);
2843
2844 __ Add(w19, w3, -0x344);
2845 __ Add(w20, w4, -2000);
2846
2847 __ Sub(w21, w3, -0xbc);
2848 __ Sub(w22, w4, -2000);
2849 END();
2850
2851 RUN();
2852
2853 ASSERT_EQUAL_64(-42, x10);
2854 ASSERT_EQUAL_64(4000, x11);
2855 ASSERT_EQUAL_64(0x1122334455667700, x12);
2856
2857 ASSERT_EQUAL_64(600, x13);
2858 ASSERT_EQUAL_64(5000, x14);
2859 ASSERT_EQUAL_64(0x1122334455667cdd, x15);
2860
2861 ASSERT_EQUAL_32(0x11223000, w19);
2862 ASSERT_EQUAL_32(398000, w20);
2863
2864 ASSERT_EQUAL_32(0x11223400, w21);
2865 ASSERT_EQUAL_32(402000, w22);
2866
2867 TEARDOWN();
2868}
2869
2870
2871TEST(neg) {
2872 SETUP();
2873
2874 START();
2875 __ Mov(x0, 0xf123456789abcdefL);
2876
2877 // Immediate.
2878 __ Neg(x1, 0x123);
2879 __ Neg(w2, 0x123);
2880
2881 // Shifted.
2882 __ Neg(x3, Operand(x0, LSL, 1));
2883 __ Neg(w4, Operand(w0, LSL, 2));
2884 __ Neg(x5, Operand(x0, LSR, 3));
2885 __ Neg(w6, Operand(w0, LSR, 4));
2886 __ Neg(x7, Operand(x0, ASR, 5));
2887 __ Neg(w8, Operand(w0, ASR, 6));
2888
2889 // Extended.
2890 __ Neg(w9, Operand(w0, UXTB));
2891 __ Neg(x10, Operand(x0, SXTB, 1));
2892 __ Neg(w11, Operand(w0, UXTH, 2));
2893 __ Neg(x12, Operand(x0, SXTH, 3));
2894 __ Neg(w13, Operand(w0, UXTW, 4));
2895 __ Neg(x14, Operand(x0, SXTW, 4));
2896 END();
2897
2898 RUN();
2899
2900 ASSERT_EQUAL_64(0xfffffffffffffeddUL, x1);
2901 ASSERT_EQUAL_64(0xfffffedd, x2);
2902 ASSERT_EQUAL_64(0x1db97530eca86422UL, x3);
2903 ASSERT_EQUAL_64(0xd950c844, x4);
2904 ASSERT_EQUAL_64(0xe1db97530eca8643UL, x5);
2905 ASSERT_EQUAL_64(0xf7654322, x6);
2906 ASSERT_EQUAL_64(0x0076e5d4c3b2a191UL, x7);
2907 ASSERT_EQUAL_64(0x01d950c9, x8);
2908 ASSERT_EQUAL_64(0xffffff11, x9);
2909 ASSERT_EQUAL_64(0x0000000000000022UL, x10);
2910 ASSERT_EQUAL_64(0xfffcc844, x11);
2911 ASSERT_EQUAL_64(0x0000000000019088UL, x12);
2912 ASSERT_EQUAL_64(0x65432110, x13);
2913 ASSERT_EQUAL_64(0x0000000765432110UL, x14);
2914
2915 TEARDOWN();
2916}
2917
2918
2919TEST(adc_sbc_shift) {
2920 SETUP();
2921
2922 START();
2923 __ Mov(x0, 0);
2924 __ Mov(x1, 1);
2925 __ Mov(x2, 0x0123456789abcdefL);
2926 __ Mov(x3, 0xfedcba9876543210L);
2927 __ Mov(x4, 0xffffffffffffffffL);
2928
2929 // Clear the C flag.
2930 __ Add(x0, x0, Operand(0), SetFlags);
2931
2932 __ Adc(x5, x2, Operand(x3));
2933 __ Adc(x6, x0, Operand(x1, LSL, 60));
2934 __ Sbc(x7, x4, Operand(x3, LSR, 4));
2935 __ Adc(x8, x2, Operand(x3, ASR, 4));
2936 __ Adc(x9, x2, Operand(x3, ROR, 8));
2937
2938 __ Adc(w10, w2, Operand(w3));
2939 __ Adc(w11, w0, Operand(w1, LSL, 30));
2940 __ Sbc(w12, w4, Operand(w3, LSR, 4));
2941 __ Adc(w13, w2, Operand(w3, ASR, 4));
2942 __ Adc(w14, w2, Operand(w3, ROR, 8));
2943
2944 // Set the C flag.
2945 __ Cmp(w0, Operand(w0));
2946
2947 __ Adc(x18, x2, Operand(x3));
2948 __ Adc(x19, x0, Operand(x1, LSL, 60));
2949 __ Sbc(x20, x4, Operand(x3, LSR, 4));
2950 __ Adc(x21, x2, Operand(x3, ASR, 4));
2951 __ Adc(x22, x2, Operand(x3, ROR, 8));
2952
2953 __ Adc(w23, w2, Operand(w3));
2954 __ Adc(w24, w0, Operand(w1, LSL, 30));
2955 __ Sbc(w25, w4, Operand(w3, LSR, 4));
2956 __ Adc(w26, w2, Operand(w3, ASR, 4));
2957 __ Adc(w27, w2, Operand(w3, ROR, 8));
2958 END();
2959
2960 RUN();
2961
2962 ASSERT_EQUAL_64(0xffffffffffffffffL, x5);
2963 ASSERT_EQUAL_64(1L << 60, x6);
2964 ASSERT_EQUAL_64(0xf0123456789abcddL, x7);
2965 ASSERT_EQUAL_64(0x0111111111111110L, x8);
2966 ASSERT_EQUAL_64(0x1222222222222221L, x9);
2967
2968 ASSERT_EQUAL_32(0xffffffff, w10);
2969 ASSERT_EQUAL_32(1 << 30, w11);
2970 ASSERT_EQUAL_32(0xf89abcdd, w12);
2971 ASSERT_EQUAL_32(0x91111110, w13);
2972 ASSERT_EQUAL_32(0x9a222221, w14);
2973
2974 ASSERT_EQUAL_64(0xffffffffffffffffL + 1, x18);
2975 ASSERT_EQUAL_64((1L << 60) + 1, x19);
2976 ASSERT_EQUAL_64(0xf0123456789abcddL + 1, x20);
2977 ASSERT_EQUAL_64(0x0111111111111110L + 1, x21);
2978 ASSERT_EQUAL_64(0x1222222222222221L + 1, x22);
2979
2980 ASSERT_EQUAL_32(0xffffffff + 1, w23);
2981 ASSERT_EQUAL_32((1 << 30) + 1, w24);
2982 ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
2983 ASSERT_EQUAL_32(0x91111110 + 1, w26);
2984 ASSERT_EQUAL_32(0x9a222221 + 1, w27);
2985
2986 // Check that adc correctly sets the condition flags.
2987 START();
2988 __ Mov(x0, 1);
2989 __ Mov(x1, 0xffffffffffffffffL);
2990 // Clear the C flag.
2991 __ Add(x0, x0, Operand(0), SetFlags);
2992 __ Adc(x10, x0, Operand(x1), SetFlags);
2993 END();
2994
2995 RUN();
2996
2997 ASSERT_EQUAL_NZCV(ZCFlag);
2998
2999 START();
3000 __ Mov(x0, 1);
3001 __ Mov(x1, 0x8000000000000000L);
3002 // Clear the C flag.
3003 __ Add(x0, x0, Operand(0), SetFlags);
3004 __ Adc(x10, x0, Operand(x1, ASR, 63), SetFlags);
3005 END();
3006
3007 RUN();
3008
3009 ASSERT_EQUAL_NZCV(ZCFlag);
3010
3011 START();
3012 __ Mov(x0, 0x10);
3013 __ Mov(x1, 0x07ffffffffffffffL);
3014 // Clear the C flag.
3015 __ Add(x0, x0, Operand(0), SetFlags);
3016 __ Adc(x10, x0, Operand(x1, LSL, 4), SetFlags);
3017 END();
3018
3019 RUN();
3020
3021 ASSERT_EQUAL_NZCV(NVFlag);
3022
3023 TEARDOWN();
3024}
3025
3026
3027TEST(adc_sbc_extend) {
3028 SETUP();
3029
3030 START();
3031 // Clear the C flag.
3032 __ Add(x0, x0, Operand(0), SetFlags);
3033
3034 __ Mov(x0, 0);
3035 __ Mov(x1, 1);
3036 __ Mov(x2, 0x0123456789abcdefL);
3037
3038 __ Adc(x10, x1, Operand(w2, UXTB, 1));
3039 __ Adc(x11, x1, Operand(x2, SXTH, 2));
3040 __ Sbc(x12, x1, Operand(w2, UXTW, 4));
3041 __ Adc(x13, x1, Operand(x2, UXTX, 4));
3042
3043 __ Adc(w14, w1, Operand(w2, UXTB, 1));
3044 __ Adc(w15, w1, Operand(w2, SXTH, 2));
3045 __ Adc(w9, w1, Operand(w2, UXTW, 4));
3046
3047 // Set the C flag.
3048 __ Cmp(w0, Operand(w0));
3049
3050 __ Adc(x20, x1, Operand(w2, UXTB, 1));
3051 __ Adc(x21, x1, Operand(x2, SXTH, 2));
3052 __ Sbc(x22, x1, Operand(w2, UXTW, 4));
3053 __ Adc(x23, x1, Operand(x2, UXTX, 4));
3054
3055 __ Adc(w24, w1, Operand(w2, UXTB, 1));
3056 __ Adc(w25, w1, Operand(w2, SXTH, 2));
3057 __ Adc(w26, w1, Operand(w2, UXTW, 4));
3058 END();
3059
3060 RUN();
3061
3062 ASSERT_EQUAL_64(0x1df, x10);
3063 ASSERT_EQUAL_64(0xffffffffffff37bdL, x11);
3064 ASSERT_EQUAL_64(0xfffffff765432110L, x12);
3065 ASSERT_EQUAL_64(0x123456789abcdef1L, x13);
3066
3067 ASSERT_EQUAL_32(0x1df, w14);
3068 ASSERT_EQUAL_32(0xffff37bd, w15);
3069 ASSERT_EQUAL_32(0x9abcdef1, w9);
3070
3071 ASSERT_EQUAL_64(0x1df + 1, x20);
3072 ASSERT_EQUAL_64(0xffffffffffff37bdL + 1, x21);
3073 ASSERT_EQUAL_64(0xfffffff765432110L + 1, x22);
3074 ASSERT_EQUAL_64(0x123456789abcdef1L + 1, x23);
3075
3076 ASSERT_EQUAL_32(0x1df + 1, w24);
3077 ASSERT_EQUAL_32(0xffff37bd + 1, w25);
3078 ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
3079
3080 // Check that adc correctly sets the condition flags.
3081 START();
3082 __ Mov(x0, 0xff);
3083 __ Mov(x1, 0xffffffffffffffffL);
3084 // Clear the C flag.
3085 __ Add(x0, x0, Operand(0), SetFlags);
3086 __ Adc(x10, x0, Operand(x1, SXTX, 1), SetFlags);
3087 END();
3088
3089 RUN();
3090
3091 ASSERT_EQUAL_NZCV(CFlag);
3092
3093 START();
3094 __ Mov(x0, 0x7fffffffffffffffL);
3095 __ Mov(x1, 1);
3096 // Clear the C flag.
3097 __ Add(x0, x0, Operand(0), SetFlags);
3098 __ Adc(x10, x0, Operand(x1, UXTB, 2), SetFlags);
3099 END();
3100
3101 RUN();
3102
3103 ASSERT_EQUAL_NZCV(NVFlag);
3104
3105 START();
3106 __ Mov(x0, 0x7fffffffffffffffL);
3107 // Clear the C flag.
3108 __ Add(x0, x0, Operand(0), SetFlags);
3109 __ Adc(x10, x0, Operand(1), SetFlags);
3110 END();
3111
3112 RUN();
3113
3114 ASSERT_EQUAL_NZCV(NVFlag);
3115
3116 TEARDOWN();
3117}
3118
3119
3120TEST(adc_sbc_wide_imm) {
3121 SETUP();
3122
3123 START();
3124 __ Mov(x0, 0);
3125
3126 // Clear the C flag.
3127 __ Add(x0, x0, Operand(0), SetFlags);
3128
3129 __ Adc(x7, x0, Operand(0x1234567890abcdefUL));
3130 __ Adc(w8, w0, Operand(0xffffffff));
3131
3132 // Set the C flag.
3133 __ Cmp(w0, Operand(w0));
3134
3135 __ Adc(x27, x0, Operand(0x1234567890abcdefUL));
3136 __ Adc(w28, w0, Operand(0xffffffff));
3137 END();
3138
3139 RUN();
3140
3141 ASSERT_EQUAL_64(0x1234567890abcdefUL, x7);
3142 ASSERT_EQUAL_64(0xffffffff, x8);
3143 ASSERT_EQUAL_64(0x1234567890abcdefUL + 1, x27);
3144 ASSERT_EQUAL_64(0, x28);
3145
3146 TEARDOWN();
3147}
3148
3149TEST(flags) {
3150 SETUP();
3151
3152 START();
3153 __ Mov(x0, 0);
3154 __ Mov(x1, 0x1111111111111111L);
3155 __ Neg(x10, Operand(x0));
3156 __ Neg(x11, Operand(x1));
3157 __ Neg(w12, Operand(w1));
3158 // Clear the C flag.
3159 __ Add(x0, x0, Operand(0), SetFlags);
3160 __ Ngc(x13, Operand(x0));
3161 // Set the C flag.
3162 __ Cmp(x0, Operand(x0));
3163 __ Ngc(w14, Operand(w0));
3164 END();
3165
3166 RUN();
3167
3168 ASSERT_EQUAL_64(0, x10);
3169 ASSERT_EQUAL_64(-0x1111111111111111L, x11);
3170 ASSERT_EQUAL_32(-0x11111111, w12);
3171 ASSERT_EQUAL_64(-1L, x13);
3172 ASSERT_EQUAL_32(0, w14);
3173
3174 START();
3175 __ Mov(x0, 0);
3176 __ Cmp(x0, Operand(x0));
3177 END();
3178
3179 RUN();
3180
3181 ASSERT_EQUAL_NZCV(ZCFlag);
3182
3183 START();
3184 __ Mov(w0, 0);
3185 __ Cmp(w0, Operand(w0));
3186 END();
3187
3188 RUN();
3189
3190 ASSERT_EQUAL_NZCV(ZCFlag);
3191
3192 START();
3193 __ Mov(x0, 0);
3194 __ Mov(x1, 0x1111111111111111L);
3195 __ Cmp(x0, Operand(x1));
3196 END();
3197
3198 RUN();
3199
3200 ASSERT_EQUAL_NZCV(NFlag);
3201
3202 START();
3203 __ Mov(w0, 0);
3204 __ Mov(w1, 0x11111111);
3205 __ Cmp(w0, Operand(w1));
3206 END();
3207
3208 RUN();
3209
3210 ASSERT_EQUAL_NZCV(NFlag);
3211
3212 START();
3213 __ Mov(x1, 0x1111111111111111L);
3214 __ Cmp(x1, Operand(0));
3215 END();
3216
3217 RUN();
3218
3219 ASSERT_EQUAL_NZCV(CFlag);
3220
3221 START();
3222 __ Mov(w1, 0x11111111);
3223 __ Cmp(w1, Operand(0));
3224 END();
3225
3226 RUN();
3227
3228 ASSERT_EQUAL_NZCV(CFlag);
3229
3230 START();
3231 __ Mov(x0, 1);
3232 __ Mov(x1, 0x7fffffffffffffffL);
3233 __ Cmn(x1, Operand(x0));
3234 END();
3235
3236 RUN();
3237
3238 ASSERT_EQUAL_NZCV(NVFlag);
3239
3240 START();
3241 __ Mov(w0, 1);
3242 __ Mov(w1, 0x7fffffff);
3243 __ Cmn(w1, Operand(w0));
3244 END();
3245
3246 RUN();
3247
3248 ASSERT_EQUAL_NZCV(NVFlag);
3249
3250 START();
3251 __ Mov(x0, 1);
3252 __ Mov(x1, 0xffffffffffffffffL);
3253 __ Cmn(x1, Operand(x0));
3254 END();
3255
3256 RUN();
3257
3258 ASSERT_EQUAL_NZCV(ZCFlag);
3259
3260 START();
3261 __ Mov(w0, 1);
3262 __ Mov(w1, 0xffffffff);
3263 __ Cmn(w1, Operand(w0));
3264 END();
3265
3266 RUN();
3267
3268 ASSERT_EQUAL_NZCV(ZCFlag);
3269
3270 START();
3271 __ Mov(w0, 0);
3272 __ Mov(w1, 1);
3273 // Clear the C flag.
3274 __ Add(w0, w0, Operand(0), SetFlags);
3275 __ Ngc(w0, Operand(w1), SetFlags);
3276 END();
3277
3278 RUN();
3279
3280 ASSERT_EQUAL_NZCV(NFlag);
3281
3282 START();
3283 __ Mov(w0, 0);
3284 __ Mov(w1, 0);
3285 // Set the C flag.
3286 __ Cmp(w0, Operand(w0));
3287 __ Ngc(w0, Operand(w1), SetFlags);
3288 END();
3289
3290 RUN();
3291
3292 ASSERT_EQUAL_NZCV(ZCFlag);
3293
3294 TEARDOWN();
3295}
3296
3297
3298TEST(cmp_shift) {
3299 SETUP();
3300
3301 START();
3302 __ Mov(x18, 0xf0000000);
3303 __ Mov(x19, 0xf000000010000000UL);
3304 __ Mov(x20, 0xf0000000f0000000UL);
3305 __ Mov(x21, 0x7800000078000000UL);
3306 __ Mov(x22, 0x3c0000003c000000UL);
3307 __ Mov(x23, 0x8000000780000000UL);
3308 __ Mov(x24, 0x0000000f00000000UL);
3309 __ Mov(x25, 0x00000003c0000000UL);
3310 __ Mov(x26, 0x8000000780000000UL);
3311 __ Mov(x27, 0xc0000003);
3312
3313 __ Cmp(w20, Operand(w21, LSL, 1));
3314 __ Mrs(x0, NZCV);
3315
3316 __ Cmp(x20, Operand(x22, LSL, 2));
3317 __ Mrs(x1, NZCV);
3318
3319 __ Cmp(w19, Operand(w23, LSR, 3));
3320 __ Mrs(x2, NZCV);
3321
3322 __ Cmp(x18, Operand(x24, LSR, 4));
3323 __ Mrs(x3, NZCV);
3324
3325 __ Cmp(w20, Operand(w25, ASR, 2));
3326 __ Mrs(x4, NZCV);
3327
3328 __ Cmp(x20, Operand(x26, ASR, 3));
3329 __ Mrs(x5, NZCV);
3330
3331 __ Cmp(w27, Operand(w22, ROR, 28));
3332 __ Mrs(x6, NZCV);
3333
3334 __ Cmp(x20, Operand(x21, ROR, 31));
3335 __ Mrs(x7, NZCV);
3336 END();
3337
3338 RUN();
3339
3340 ASSERT_EQUAL_32(ZCFlag, w0);
3341 ASSERT_EQUAL_32(ZCFlag, w1);
3342 ASSERT_EQUAL_32(ZCFlag, w2);
3343 ASSERT_EQUAL_32(ZCFlag, w3);
3344 ASSERT_EQUAL_32(ZCFlag, w4);
3345 ASSERT_EQUAL_32(ZCFlag, w5);
3346 ASSERT_EQUAL_32(ZCFlag, w6);
3347 ASSERT_EQUAL_32(ZCFlag, w7);
3348
3349 TEARDOWN();
3350}
3351
3352
3353TEST(cmp_extend) {
3354 SETUP();
3355
3356 START();
3357 __ Mov(w20, 0x2);
3358 __ Mov(w21, 0x1);
3359 __ Mov(x22, 0xffffffffffffffffUL);
3360 __ Mov(x23, 0xff);
3361 __ Mov(x24, 0xfffffffffffffffeUL);
3362 __ Mov(x25, 0xffff);
3363 __ Mov(x26, 0xffffffff);
3364
3365 __ Cmp(w20, Operand(w21, LSL, 1));
3366 __ Mrs(x0, NZCV);
3367
3368 __ Cmp(x22, Operand(x23, SXTB, 0));
3369 __ Mrs(x1, NZCV);
3370
3371 __ Cmp(x24, Operand(x23, SXTB, 1));
3372 __ Mrs(x2, NZCV);
3373
3374 __ Cmp(x24, Operand(x23, UXTB, 1));
3375 __ Mrs(x3, NZCV);
3376
3377 __ Cmp(w22, Operand(w25, UXTH));
3378 __ Mrs(x4, NZCV);
3379
3380 __ Cmp(x22, Operand(x25, SXTH));
3381 __ Mrs(x5, NZCV);
3382
3383 __ Cmp(x22, Operand(x26, UXTW));
3384 __ Mrs(x6, NZCV);
3385
3386 __ Cmp(x24, Operand(x26, SXTW, 1));
3387 __ Mrs(x7, NZCV);
3388 END();
3389
3390 RUN();
3391
3392 ASSERT_EQUAL_32(ZCFlag, w0);
3393 ASSERT_EQUAL_32(ZCFlag, w1);
3394 ASSERT_EQUAL_32(ZCFlag, w2);
3395 ASSERT_EQUAL_32(NCFlag, w3);
3396 ASSERT_EQUAL_32(NCFlag, w4);
3397 ASSERT_EQUAL_32(ZCFlag, w5);
3398 ASSERT_EQUAL_32(NCFlag, w6);
3399 ASSERT_EQUAL_32(ZCFlag, w7);
3400
3401 TEARDOWN();
3402}
3403
3404
3405TEST(ccmp) {
3406 SETUP();
3407
3408 START();
3409 __ Mov(w16, 0);
3410 __ Mov(w17, 1);
armvixl578645f2013-08-15 17:21:42 +01003411 __ Cmp(w16, w16);
3412 __ Ccmp(w16, w17, NCFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01003413 __ Mrs(x0, NZCV);
3414
armvixl578645f2013-08-15 17:21:42 +01003415 __ Cmp(w16, w16);
3416 __ Ccmp(w16, w17, NCFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01003417 __ Mrs(x1, NZCV);
3418
armvixl578645f2013-08-15 17:21:42 +01003419 __ Cmp(x16, x16);
3420 __ Ccmn(x16, 2, NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01003421 __ Mrs(x2, NZCV);
3422
armvixl578645f2013-08-15 17:21:42 +01003423 __ Cmp(x16, x16);
3424 __ Ccmn(x16, 2, NZCVFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01003425 __ Mrs(x3, NZCV);
armvixl578645f2013-08-15 17:21:42 +01003426
3427 __ ccmp(x16, x16, NZCVFlag, al);
3428 __ Mrs(x4, NZCV);
3429
3430 __ ccmp(x16, x16, NZCVFlag, nv);
3431 __ Mrs(x5, NZCV);
3432
armvixlad96eda2013-06-14 11:42:37 +01003433 END();
3434
3435 RUN();
3436
3437 ASSERT_EQUAL_32(NFlag, w0);
3438 ASSERT_EQUAL_32(NCFlag, w1);
3439 ASSERT_EQUAL_32(NoFlag, w2);
3440 ASSERT_EQUAL_32(NZCVFlag, w3);
armvixl578645f2013-08-15 17:21:42 +01003441 ASSERT_EQUAL_32(ZCFlag, w4);
3442 ASSERT_EQUAL_32(ZCFlag, w5);
armvixlad96eda2013-06-14 11:42:37 +01003443
3444 TEARDOWN();
3445}
3446
3447
3448TEST(ccmp_wide_imm) {
3449 SETUP();
3450
3451 START();
3452 __ Mov(w20, 0);
3453
3454 __ Cmp(w20, Operand(w20));
3455 __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
3456 __ Mrs(x0, NZCV);
3457
3458 __ Cmp(w20, Operand(w20));
3459 __ Ccmp(x20, Operand(0xffffffffffffffffUL), NZCVFlag, eq);
3460 __ Mrs(x1, NZCV);
3461 END();
3462
3463 RUN();
3464
3465 ASSERT_EQUAL_32(NFlag, w0);
3466 ASSERT_EQUAL_32(NoFlag, w1);
3467
3468 TEARDOWN();
3469}
3470
3471
3472TEST(ccmp_shift_extend) {
3473 SETUP();
3474
3475 START();
3476 __ Mov(w20, 0x2);
3477 __ Mov(w21, 0x1);
3478 __ Mov(x22, 0xffffffffffffffffUL);
3479 __ Mov(x23, 0xff);
3480 __ Mov(x24, 0xfffffffffffffffeUL);
3481
3482 __ Cmp(w20, Operand(w20));
3483 __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
3484 __ Mrs(x0, NZCV);
3485
3486 __ Cmp(w20, Operand(w20));
3487 __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
3488 __ Mrs(x1, NZCV);
3489
3490 __ Cmp(w20, Operand(w20));
3491 __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
3492 __ Mrs(x2, NZCV);
3493
3494 __ Cmp(w20, Operand(w20));
3495 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
3496 __ Mrs(x3, NZCV);
3497
3498 __ Cmp(w20, Operand(w20));
3499 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
3500 __ Mrs(x4, NZCV);
3501 END();
3502
3503 RUN();
3504
3505 ASSERT_EQUAL_32(ZCFlag, w0);
3506 ASSERT_EQUAL_32(ZCFlag, w1);
3507 ASSERT_EQUAL_32(ZCFlag, w2);
3508 ASSERT_EQUAL_32(NCFlag, w3);
3509 ASSERT_EQUAL_32(NZCVFlag, w4);
3510
3511 TEARDOWN();
3512}
3513
3514
3515TEST(csel) {
3516 SETUP();
3517
3518 START();
3519 __ Mov(x16, 0);
3520 __ Mov(x24, 0x0000000f0000000fUL);
3521 __ Mov(x25, 0x0000001f0000001fUL);
3522
3523 __ Cmp(w16, Operand(0));
3524 __ Csel(w0, w24, w25, eq);
3525 __ Csel(w1, w24, w25, ne);
3526 __ Csinc(w2, w24, w25, mi);
3527 __ Csinc(w3, w24, w25, pl);
3528
armvixl578645f2013-08-15 17:21:42 +01003529 __ csel(w13, w24, w25, al);
3530 __ csel(x14, x24, x25, nv);
3531
armvixlad96eda2013-06-14 11:42:37 +01003532 __ Cmp(x16, Operand(1));
3533 __ Csinv(x4, x24, x25, gt);
3534 __ Csinv(x5, x24, x25, le);
3535 __ Csneg(x6, x24, x25, hs);
3536 __ Csneg(x7, x24, x25, lo);
3537
3538 __ Cset(w8, ne);
3539 __ Csetm(w9, ne);
3540 __ Cinc(x10, x25, ne);
3541 __ Cinv(x11, x24, ne);
3542 __ Cneg(x12, x24, ne);
armvixl578645f2013-08-15 17:21:42 +01003543
3544 __ csel(w15, w24, w25, al);
3545 __ csel(x17, x24, x25, nv);
3546
armvixlad96eda2013-06-14 11:42:37 +01003547 END();
3548
3549 RUN();
3550
3551 ASSERT_EQUAL_64(0x0000000f, x0);
3552 ASSERT_EQUAL_64(0x0000001f, x1);
3553 ASSERT_EQUAL_64(0x00000020, x2);
3554 ASSERT_EQUAL_64(0x0000000f, x3);
3555 ASSERT_EQUAL_64(0xffffffe0ffffffe0UL, x4);
3556 ASSERT_EQUAL_64(0x0000000f0000000fUL, x5);
3557 ASSERT_EQUAL_64(0xffffffe0ffffffe1UL, x6);
3558 ASSERT_EQUAL_64(0x0000000f0000000fUL, x7);
3559 ASSERT_EQUAL_64(0x00000001, x8);
3560 ASSERT_EQUAL_64(0xffffffff, x9);
3561 ASSERT_EQUAL_64(0x0000001f00000020UL, x10);
3562 ASSERT_EQUAL_64(0xfffffff0fffffff0UL, x11);
3563 ASSERT_EQUAL_64(0xfffffff0fffffff1UL, x12);
armvixl578645f2013-08-15 17:21:42 +01003564 ASSERT_EQUAL_64(0x0000000f, x13);
3565 ASSERT_EQUAL_64(0x0000000f0000000fUL, x14);
3566 ASSERT_EQUAL_64(0x0000000f, x15);
3567 ASSERT_EQUAL_64(0x0000000f0000000fUL, x17);
armvixlad96eda2013-06-14 11:42:37 +01003568
3569 TEARDOWN();
3570}
3571
3572
3573TEST(lslv) {
3574 SETUP();
3575
3576 uint64_t value = 0x0123456789abcdefUL;
3577 int shift[] = {1, 3, 5, 9, 17, 33};
3578
3579 START();
3580 __ Mov(x0, value);
3581 __ Mov(w1, shift[0]);
3582 __ Mov(w2, shift[1]);
3583 __ Mov(w3, shift[2]);
3584 __ Mov(w4, shift[3]);
3585 __ Mov(w5, shift[4]);
3586 __ Mov(w6, shift[5]);
3587
3588 __ lslv(x0, x0, xzr);
3589
3590 __ Lsl(x16, x0, x1);
3591 __ Lsl(x17, x0, x2);
3592 __ Lsl(x18, x0, x3);
3593 __ Lsl(x19, x0, x4);
3594 __ Lsl(x20, x0, x5);
3595 __ Lsl(x21, x0, x6);
3596
3597 __ Lsl(w22, w0, w1);
3598 __ Lsl(w23, w0, w2);
3599 __ Lsl(w24, w0, w3);
3600 __ Lsl(w25, w0, w4);
3601 __ Lsl(w26, w0, w5);
3602 __ Lsl(w27, w0, w6);
3603 END();
3604
3605 RUN();
3606
3607 ASSERT_EQUAL_64(value, x0);
3608 ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
3609 ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
3610 ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
3611 ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
3612 ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
3613 ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
3614 ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
3615 ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
3616 ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
3617 ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
3618 ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
3619 ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
3620
3621 TEARDOWN();
3622}
3623
3624
3625TEST(lsrv) {
3626 SETUP();
3627
3628 uint64_t value = 0x0123456789abcdefUL;
3629 int shift[] = {1, 3, 5, 9, 17, 33};
3630
3631 START();
3632 __ Mov(x0, value);
3633 __ Mov(w1, shift[0]);
3634 __ Mov(w2, shift[1]);
3635 __ Mov(w3, shift[2]);
3636 __ Mov(w4, shift[3]);
3637 __ Mov(w5, shift[4]);
3638 __ Mov(w6, shift[5]);
3639
3640 __ lsrv(x0, x0, xzr);
3641
3642 __ Lsr(x16, x0, x1);
3643 __ Lsr(x17, x0, x2);
3644 __ Lsr(x18, x0, x3);
3645 __ Lsr(x19, x0, x4);
3646 __ Lsr(x20, x0, x5);
3647 __ Lsr(x21, x0, x6);
3648
3649 __ Lsr(w22, w0, w1);
3650 __ Lsr(w23, w0, w2);
3651 __ Lsr(w24, w0, w3);
3652 __ Lsr(w25, w0, w4);
3653 __ Lsr(w26, w0, w5);
3654 __ Lsr(w27, w0, w6);
3655 END();
3656
3657 RUN();
3658
3659 ASSERT_EQUAL_64(value, x0);
3660 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
3661 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
3662 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
3663 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
3664 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
3665 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
3666
3667 value &= 0xffffffffUL;
3668 ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
3669 ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
3670 ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
3671 ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
3672 ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
3673 ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
3674
3675 TEARDOWN();
3676}
3677
3678
3679TEST(asrv) {
3680 SETUP();
3681
3682 int64_t value = 0xfedcba98fedcba98UL;
3683 int shift[] = {1, 3, 5, 9, 17, 33};
3684
3685 START();
3686 __ Mov(x0, value);
3687 __ Mov(w1, shift[0]);
3688 __ Mov(w2, shift[1]);
3689 __ Mov(w3, shift[2]);
3690 __ Mov(w4, shift[3]);
3691 __ Mov(w5, shift[4]);
3692 __ Mov(w6, shift[5]);
3693
3694 __ asrv(x0, x0, xzr);
3695
3696 __ Asr(x16, x0, x1);
3697 __ Asr(x17, x0, x2);
3698 __ Asr(x18, x0, x3);
3699 __ Asr(x19, x0, x4);
3700 __ Asr(x20, x0, x5);
3701 __ Asr(x21, x0, x6);
3702
3703 __ Asr(w22, w0, w1);
3704 __ Asr(w23, w0, w2);
3705 __ Asr(w24, w0, w3);
3706 __ Asr(w25, w0, w4);
3707 __ Asr(w26, w0, w5);
3708 __ Asr(w27, w0, w6);
3709 END();
3710
3711 RUN();
3712
3713 ASSERT_EQUAL_64(value, x0);
3714 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
3715 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
3716 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
3717 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
3718 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
3719 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
3720
3721 int32_t value32 = static_cast<int32_t>(value & 0xffffffffUL);
3722 ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
3723 ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
3724 ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
3725 ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
3726 ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
3727 ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
3728
3729 TEARDOWN();
3730}
3731
3732
3733TEST(rorv) {
3734 SETUP();
3735
3736 uint64_t value = 0x0123456789abcdefUL;
3737 int shift[] = {4, 8, 12, 16, 24, 36};
3738
3739 START();
3740 __ Mov(x0, value);
3741 __ Mov(w1, shift[0]);
3742 __ Mov(w2, shift[1]);
3743 __ Mov(w3, shift[2]);
3744 __ Mov(w4, shift[3]);
3745 __ Mov(w5, shift[4]);
3746 __ Mov(w6, shift[5]);
3747
3748 __ rorv(x0, x0, xzr);
3749
3750 __ Ror(x16, x0, x1);
3751 __ Ror(x17, x0, x2);
3752 __ Ror(x18, x0, x3);
3753 __ Ror(x19, x0, x4);
3754 __ Ror(x20, x0, x5);
3755 __ Ror(x21, x0, x6);
3756
3757 __ Ror(w22, w0, w1);
3758 __ Ror(w23, w0, w2);
3759 __ Ror(w24, w0, w3);
3760 __ Ror(w25, w0, w4);
3761 __ Ror(w26, w0, w5);
3762 __ Ror(w27, w0, w6);
3763 END();
3764
3765 RUN();
3766
3767 ASSERT_EQUAL_64(value, x0);
3768 ASSERT_EQUAL_64(0xf0123456789abcdeUL, x16);
3769 ASSERT_EQUAL_64(0xef0123456789abcdUL, x17);
3770 ASSERT_EQUAL_64(0xdef0123456789abcUL, x18);
3771 ASSERT_EQUAL_64(0xcdef0123456789abUL, x19);
3772 ASSERT_EQUAL_64(0xabcdef0123456789UL, x20);
3773 ASSERT_EQUAL_64(0x789abcdef0123456UL, x21);
3774 ASSERT_EQUAL_32(0xf89abcde, w22);
3775 ASSERT_EQUAL_32(0xef89abcd, w23);
3776 ASSERT_EQUAL_32(0xdef89abc, w24);
3777 ASSERT_EQUAL_32(0xcdef89ab, w25);
3778 ASSERT_EQUAL_32(0xabcdef89, w26);
3779 ASSERT_EQUAL_32(0xf89abcde, w27);
3780
3781 TEARDOWN();
3782}
3783
3784
3785TEST(bfm) {
3786 SETUP();
3787
3788 START();
3789 __ Mov(x1, 0x0123456789abcdefL);
3790
3791 __ Mov(x10, 0x8888888888888888L);
3792 __ Mov(x11, 0x8888888888888888L);
3793 __ Mov(x12, 0x8888888888888888L);
3794 __ Mov(x13, 0x8888888888888888L);
3795 __ Mov(w20, 0x88888888);
3796 __ Mov(w21, 0x88888888);
3797
3798 __ bfm(x10, x1, 16, 31);
3799 __ bfm(x11, x1, 32, 15);
3800
3801 __ bfm(w20, w1, 16, 23);
3802 __ bfm(w21, w1, 24, 15);
3803
3804 // Aliases.
3805 __ Bfi(x12, x1, 16, 8);
3806 __ Bfxil(x13, x1, 16, 8);
3807 END();
3808
3809 RUN();
3810
3811
3812 ASSERT_EQUAL_64(0x88888888888889abL, x10);
3813 ASSERT_EQUAL_64(0x8888cdef88888888L, x11);
3814
3815 ASSERT_EQUAL_32(0x888888ab, w20);
3816 ASSERT_EQUAL_32(0x88cdef88, w21);
3817
3818 ASSERT_EQUAL_64(0x8888888888ef8888L, x12);
3819 ASSERT_EQUAL_64(0x88888888888888abL, x13);
3820
3821 TEARDOWN();
3822}
3823
3824
3825TEST(sbfm) {
3826 SETUP();
3827
3828 START();
3829 __ Mov(x1, 0x0123456789abcdefL);
3830 __ Mov(x2, 0xfedcba9876543210L);
3831
3832 __ sbfm(x10, x1, 16, 31);
3833 __ sbfm(x11, x1, 32, 15);
3834 __ sbfm(x12, x1, 32, 47);
3835 __ sbfm(x13, x1, 48, 35);
3836
3837 __ sbfm(w14, w1, 16, 23);
3838 __ sbfm(w15, w1, 24, 15);
3839 __ sbfm(w16, w2, 16, 23);
3840 __ sbfm(w17, w2, 24, 15);
3841
3842 // Aliases.
3843 __ Asr(x18, x1, 32);
3844 __ Asr(x19, x2, 32);
3845 __ Sbfiz(x20, x1, 8, 16);
3846 __ Sbfiz(x21, x2, 8, 16);
3847 __ Sbfx(x22, x1, 8, 16);
3848 __ Sbfx(x23, x2, 8, 16);
3849 __ Sxtb(x24, x1);
3850 __ Sxtb(x25, x2);
3851 __ Sxth(x26, x1);
3852 __ Sxth(x27, x2);
3853 __ Sxtw(x28, x1);
3854 __ Sxtw(x29, x2);
3855 END();
3856
3857 RUN();
3858
3859
3860 ASSERT_EQUAL_64(0xffffffffffff89abL, x10);
3861 ASSERT_EQUAL_64(0xffffcdef00000000L, x11);
3862 ASSERT_EQUAL_64(0x4567L, x12);
3863 ASSERT_EQUAL_64(0x789abcdef0000L, x13);
3864
3865 ASSERT_EQUAL_32(0xffffffab, w14);
3866 ASSERT_EQUAL_32(0xffcdef00, w15);
3867 ASSERT_EQUAL_32(0x54, w16);
3868 ASSERT_EQUAL_32(0x00321000, w17);
3869
3870 ASSERT_EQUAL_64(0x01234567L, x18);
3871 ASSERT_EQUAL_64(0xfffffffffedcba98L, x19);
3872 ASSERT_EQUAL_64(0xffffffffffcdef00L, x20);
3873 ASSERT_EQUAL_64(0x321000L, x21);
3874 ASSERT_EQUAL_64(0xffffffffffffabcdL, x22);
3875 ASSERT_EQUAL_64(0x5432L, x23);
3876 ASSERT_EQUAL_64(0xffffffffffffffefL, x24);
3877 ASSERT_EQUAL_64(0x10, x25);
3878 ASSERT_EQUAL_64(0xffffffffffffcdefL, x26);
3879 ASSERT_EQUAL_64(0x3210, x27);
3880 ASSERT_EQUAL_64(0xffffffff89abcdefL, x28);
3881 ASSERT_EQUAL_64(0x76543210, x29);
3882
3883 TEARDOWN();
3884}
3885
3886
3887TEST(ubfm) {
3888 SETUP();
3889
3890 START();
3891 __ Mov(x1, 0x0123456789abcdefL);
3892 __ Mov(x2, 0xfedcba9876543210L);
3893
3894 __ Mov(x10, 0x8888888888888888L);
3895 __ Mov(x11, 0x8888888888888888L);
3896
3897 __ ubfm(x10, x1, 16, 31);
3898 __ ubfm(x11, x1, 32, 15);
3899 __ ubfm(x12, x1, 32, 47);
3900 __ ubfm(x13, x1, 48, 35);
3901
3902 __ ubfm(w25, w1, 16, 23);
3903 __ ubfm(w26, w1, 24, 15);
3904 __ ubfm(w27, w2, 16, 23);
3905 __ ubfm(w28, w2, 24, 15);
3906
3907 // Aliases
3908 __ Lsl(x15, x1, 63);
3909 __ Lsl(x16, x1, 0);
3910 __ Lsr(x17, x1, 32);
3911 __ Ubfiz(x18, x1, 8, 16);
3912 __ Ubfx(x19, x1, 8, 16);
3913 __ Uxtb(x20, x1);
3914 __ Uxth(x21, x1);
3915 __ Uxtw(x22, x1);
3916 END();
3917
3918 RUN();
3919
3920 ASSERT_EQUAL_64(0x00000000000089abL, x10);
3921 ASSERT_EQUAL_64(0x0000cdef00000000L, x11);
3922 ASSERT_EQUAL_64(0x4567L, x12);
3923 ASSERT_EQUAL_64(0x789abcdef0000L, x13);
3924
3925 ASSERT_EQUAL_32(0x000000ab, w25);
3926 ASSERT_EQUAL_32(0x00cdef00, w26);
3927 ASSERT_EQUAL_32(0x54, w27);
3928 ASSERT_EQUAL_32(0x00321000, w28);
3929
3930 ASSERT_EQUAL_64(0x8000000000000000L, x15);
3931 ASSERT_EQUAL_64(0x0123456789abcdefL, x16);
3932 ASSERT_EQUAL_64(0x01234567L, x17);
3933 ASSERT_EQUAL_64(0xcdef00L, x18);
3934 ASSERT_EQUAL_64(0xabcdL, x19);
3935 ASSERT_EQUAL_64(0xefL, x20);
3936 ASSERT_EQUAL_64(0xcdefL, x21);
3937 ASSERT_EQUAL_64(0x89abcdefL, x22);
3938
3939 TEARDOWN();
3940}
3941
3942
3943TEST(extr) {
3944 SETUP();
3945
3946 START();
3947 __ Mov(x1, 0x0123456789abcdefL);
3948 __ Mov(x2, 0xfedcba9876543210L);
3949
3950 __ Extr(w10, w1, w2, 0);
3951 __ Extr(w11, w1, w2, 1);
3952 __ Extr(x12, x2, x1, 2);
3953
3954 __ Ror(w13, w1, 0);
3955 __ Ror(w14, w2, 17);
3956 __ Ror(w15, w1, 31);
3957 __ Ror(x18, x2, 1);
3958 __ Ror(x19, x1, 63);
3959 END();
3960
3961 RUN();
3962
3963 ASSERT_EQUAL_64(0x76543210, x10);
3964 ASSERT_EQUAL_64(0xbb2a1908, x11);
3965 ASSERT_EQUAL_64(0x0048d159e26af37bUL, x12);
3966 ASSERT_EQUAL_64(0x89abcdef, x13);
3967 ASSERT_EQUAL_64(0x19083b2a, x14);
3968 ASSERT_EQUAL_64(0x13579bdf, x15);
3969 ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908UL, x18);
3970 ASSERT_EQUAL_64(0x02468acf13579bdeUL, x19);
3971
3972 TEARDOWN();
3973}
3974
3975
3976TEST(fmov_imm) {
3977 SETUP();
3978
3979 START();
3980 __ Fmov(s11, 1.0);
3981 __ Fmov(d22, -13.0);
3982 __ Fmov(s1, 255.0);
3983 __ Fmov(d2, 12.34567);
3984 __ Fmov(s3, 0.0);
3985 __ Fmov(d4, 0.0);
3986 __ Fmov(s5, kFP32PositiveInfinity);
3987 __ Fmov(d6, kFP64NegativeInfinity);
3988 END();
3989
3990 RUN();
3991
3992 ASSERT_EQUAL_FP32(1.0, s11);
3993 ASSERT_EQUAL_FP64(-13.0, d22);
3994 ASSERT_EQUAL_FP32(255.0, s1);
3995 ASSERT_EQUAL_FP64(12.34567, d2);
3996 ASSERT_EQUAL_FP32(0.0, s3);
3997 ASSERT_EQUAL_FP64(0.0, d4);
3998 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
3999 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
4000
4001 TEARDOWN();
4002}
4003
4004
4005TEST(fmov_reg) {
4006 SETUP();
4007
4008 START();
4009 __ Fmov(s20, 1.0);
4010 __ Fmov(w10, s20);
4011 __ Fmov(s30, w10);
4012 __ Fmov(s5, s20);
4013 __ Fmov(d1, -13.0);
4014 __ Fmov(x1, d1);
4015 __ Fmov(d2, x1);
4016 __ Fmov(d4, d1);
4017 __ Fmov(d6, rawbits_to_double(0x0123456789abcdefL));
4018 __ Fmov(s6, s6);
4019 END();
4020
4021 RUN();
4022
4023 ASSERT_EQUAL_32(float_to_rawbits(1.0), w10);
4024 ASSERT_EQUAL_FP32(1.0, s30);
4025 ASSERT_EQUAL_FP32(1.0, s5);
4026 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1);
4027 ASSERT_EQUAL_FP64(-13.0, d2);
4028 ASSERT_EQUAL_FP64(-13.0, d4);
4029 ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
4030
4031 TEARDOWN();
4032}
4033
4034
4035TEST(fadd) {
4036 SETUP();
4037
4038 START();
4039 __ Fmov(s13, -0.0);
4040 __ Fmov(s14, kFP32PositiveInfinity);
4041 __ Fmov(s15, kFP32NegativeInfinity);
4042 __ Fmov(s16, 3.25);
4043 __ Fmov(s17, 1.0);
4044 __ Fmov(s18, 0);
4045
4046 __ Fmov(d26, -0.0);
4047 __ Fmov(d27, kFP64PositiveInfinity);
4048 __ Fmov(d28, kFP64NegativeInfinity);
4049 __ Fmov(d29, 0);
4050 __ Fmov(d30, -2.0);
4051 __ Fmov(d31, 2.25);
4052
4053 __ Fadd(s0, s16, s17);
4054 __ Fadd(s1, s17, s18);
4055 __ Fadd(s2, s13, s17);
4056 __ Fadd(s3, s14, s17);
4057 __ Fadd(s4, s15, s17);
4058
4059 __ Fadd(d5, d30, d31);
4060 __ Fadd(d6, d29, d31);
4061 __ Fadd(d7, d26, d31);
4062 __ Fadd(d8, d27, d31);
4063 __ Fadd(d9, d28, d31);
4064 END();
4065
4066 RUN();
4067
4068 ASSERT_EQUAL_FP32(4.25, s0);
4069 ASSERT_EQUAL_FP32(1.0, s1);
4070 ASSERT_EQUAL_FP32(1.0, s2);
4071 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
4072 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
4073 ASSERT_EQUAL_FP64(0.25, d5);
4074 ASSERT_EQUAL_FP64(2.25, d6);
4075 ASSERT_EQUAL_FP64(2.25, d7);
4076 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d8);
4077 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d9);
4078
4079 TEARDOWN();
4080}
4081
4082
4083TEST(fsub) {
4084 SETUP();
4085
4086 START();
4087 __ Fmov(s13, -0.0);
4088 __ Fmov(s14, kFP32PositiveInfinity);
4089 __ Fmov(s15, kFP32NegativeInfinity);
4090 __ Fmov(s16, 3.25);
4091 __ Fmov(s17, 1.0);
4092 __ Fmov(s18, 0);
4093
4094 __ Fmov(d26, -0.0);
4095 __ Fmov(d27, kFP64PositiveInfinity);
4096 __ Fmov(d28, kFP64NegativeInfinity);
4097 __ Fmov(d29, 0);
4098 __ Fmov(d30, -2.0);
4099 __ Fmov(d31, 2.25);
4100
4101 __ Fsub(s0, s16, s17);
4102 __ Fsub(s1, s17, s18);
4103 __ Fsub(s2, s13, s17);
4104 __ Fsub(s3, s17, s14);
4105 __ Fsub(s4, s17, s15);
4106
4107 __ Fsub(d5, d30, d31);
4108 __ Fsub(d6, d29, d31);
4109 __ Fsub(d7, d26, d31);
4110 __ Fsub(d8, d31, d27);
4111 __ Fsub(d9, d31, d28);
4112 END();
4113
4114 RUN();
4115
4116 ASSERT_EQUAL_FP32(2.25, s0);
4117 ASSERT_EQUAL_FP32(1.0, s1);
4118 ASSERT_EQUAL_FP32(-1.0, s2);
4119 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
4120 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
4121 ASSERT_EQUAL_FP64(-4.25, d5);
4122 ASSERT_EQUAL_FP64(-2.25, d6);
4123 ASSERT_EQUAL_FP64(-2.25, d7);
4124 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
4125 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d9);
4126
4127 TEARDOWN();
4128}
4129
4130
4131TEST(fmul) {
4132 SETUP();
4133
4134 START();
4135 __ Fmov(s13, -0.0);
4136 __ Fmov(s14, kFP32PositiveInfinity);
4137 __ Fmov(s15, kFP32NegativeInfinity);
4138 __ Fmov(s16, 3.25);
4139 __ Fmov(s17, 2.0);
4140 __ Fmov(s18, 0);
4141 __ Fmov(s19, -2.0);
4142
4143 __ Fmov(d26, -0.0);
4144 __ Fmov(d27, kFP64PositiveInfinity);
4145 __ Fmov(d28, kFP64NegativeInfinity);
4146 __ Fmov(d29, 0);
4147 __ Fmov(d30, -2.0);
4148 __ Fmov(d31, 2.25);
4149
4150 __ Fmul(s0, s16, s17);
4151 __ Fmul(s1, s17, s18);
4152 __ Fmul(s2, s13, s13);
4153 __ Fmul(s3, s14, s19);
4154 __ Fmul(s4, s15, s19);
4155
4156 __ Fmul(d5, d30, d31);
4157 __ Fmul(d6, d29, d31);
4158 __ Fmul(d7, d26, d26);
4159 __ Fmul(d8, d27, d30);
4160 __ Fmul(d9, d28, d30);
4161 END();
4162
4163 RUN();
4164
4165 ASSERT_EQUAL_FP32(6.5, s0);
4166 ASSERT_EQUAL_FP32(0.0, s1);
4167 ASSERT_EQUAL_FP32(0.0, s2);
4168 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
4169 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
4170 ASSERT_EQUAL_FP64(-4.5, d5);
4171 ASSERT_EQUAL_FP64(0.0, d6);
4172 ASSERT_EQUAL_FP64(0.0, d7);
4173 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
4174 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d9);
4175
4176 TEARDOWN();
4177}
4178
4179
4180TEST(fmsub) {
4181 SETUP();
4182
4183 START();
4184 __ Fmov(s16, 3.25);
4185 __ Fmov(s17, 2.0);
4186 __ Fmov(s18, 0);
4187 __ Fmov(s19, -0.5);
4188 __ Fmov(s20, kFP32PositiveInfinity);
4189 __ Fmov(s21, kFP32NegativeInfinity);
4190 __ Fmov(s22, -0);
4191
4192 __ Fmov(d29, 0);
4193 __ Fmov(d30, -2.0);
4194 __ Fmov(d31, 2.25);
4195 __ Fmov(d28, 4);
4196 __ Fmov(d24, kFP64PositiveInfinity);
4197 __ Fmov(d25, kFP64NegativeInfinity);
4198 __ Fmov(d26, -0);
4199
4200 // Normal combinations
4201 __ Fmsub(s0, s16, s17, s18);
4202 __ Fmsub(s1, s17, s18, s16);
4203 __ Fmsub(s2, s17, s16, s19);
4204 // Pos/Neg Infinity
4205 __ Fmsub(s3, s16, s21, s19);
4206 __ Fmsub(s4, s17, s16, s20);
4207 __ Fmsub(s5, s20, s16, s19);
4208 __ Fmsub(s6, s21, s16, s19);
4209 // -0
4210 __ Fmsub(s7, s22, s16, s19);
4211 __ Fmsub(s8, s19, s16, s22);
4212
4213 // Normal combinations
4214 __ Fmsub(d9, d30, d31, d29);
4215 __ Fmsub(d10, d29, d31, d30);
4216 __ Fmsub(d11, d30, d31, d28);
4217 // Pos/Neg Infinity
4218 __ Fmsub(d12, d30, d24, d28);
4219 __ Fmsub(d13, d24, d31, d25);
4220 __ Fmsub(d14, d24, d31, d28);
4221 __ Fmsub(d15, d25, d31, d28);
4222 // -0
4223 __ Fmsub(d16, d26, d31, d28);
4224 __ Fmsub(d17, d30, d26, d28);
4225 END();
4226
4227 RUN();
4228
4229 // Normal combinations
4230 ASSERT_EQUAL_FP32(-6.5, s0);
4231 ASSERT_EQUAL_FP32(3.25, s1);
4232 ASSERT_EQUAL_FP32(-7, s2);
4233 // Pos/Neg Infinity
4234 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
4235 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
4236 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s5);
4237 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s6);
4238 // -0
4239 ASSERT_EQUAL_FP32(-0.5, s7);
4240 ASSERT_EQUAL_FP32(1.625, s8);
4241
4242 // Normal combinations
4243 ASSERT_EQUAL_FP64(4.5, d9);
4244 ASSERT_EQUAL_FP64(-2.0, d10);
4245 ASSERT_EQUAL_FP64(8.5, d11);
4246 // Pos/Neg Infinity
4247 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d12);
4248 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d13);
4249 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d14);
4250 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d15);
4251 // -0
4252 ASSERT_EQUAL_FP64(4.0, d16);
4253 ASSERT_EQUAL_FP64(4.0, d17);
4254
4255 TEARDOWN();
4256}
4257
4258
4259TEST(fdiv) {
4260 SETUP();
4261
4262 START();
4263 __ Fmov(s13, -0.0);
4264 __ Fmov(s14, kFP32PositiveInfinity);
4265 __ Fmov(s15, kFP32NegativeInfinity);
4266 __ Fmov(s16, 3.25);
4267 __ Fmov(s17, 2.0);
4268 __ Fmov(s18, 2.0);
4269 __ Fmov(s19, -2.0);
4270
4271 __ Fmov(d26, -0.0);
4272 __ Fmov(d27, kFP64PositiveInfinity);
4273 __ Fmov(d28, kFP64NegativeInfinity);
4274 __ Fmov(d29, 0);
4275 __ Fmov(d30, -2.0);
4276 __ Fmov(d31, 2.25);
4277
4278 __ Fdiv(s0, s16, s17);
4279 __ Fdiv(s1, s17, s18);
4280 __ Fdiv(s2, s13, s17);
4281 __ Fdiv(s3, s17, s14);
4282 __ Fdiv(s4, s17, s15);
4283 __ Fdiv(d5, d31, d30);
4284 __ Fdiv(d6, d29, d31);
4285 __ Fdiv(d7, d26, d31);
4286 __ Fdiv(d8, d31, d27);
4287 __ Fdiv(d9, d31, d28);
4288 END();
4289
4290 RUN();
4291
4292 ASSERT_EQUAL_FP32(1.625, s0);
4293 ASSERT_EQUAL_FP32(1.0, s1);
4294 ASSERT_EQUAL_FP32(-0.0, s2);
4295 ASSERT_EQUAL_FP32(0.0, s3);
4296 ASSERT_EQUAL_FP32(-0.0, s4);
4297 ASSERT_EQUAL_FP64(-1.125, d5);
4298 ASSERT_EQUAL_FP64(0.0, d6);
4299 ASSERT_EQUAL_FP64(-0.0, d7);
4300 ASSERT_EQUAL_FP64(0.0, d8);
4301 ASSERT_EQUAL_FP64(-0.0, d9);
4302
4303 TEARDOWN();
4304}
4305
4306
4307TEST(fmin_s) {
4308 SETUP();
4309
4310 START();
4311 __ Fmov(s25, 0.0);
4312 __ Fneg(s26, s25);
4313 __ Fmov(s27, kFP32PositiveInfinity);
4314 __ Fmov(s28, 1.0);
4315 __ Fmin(s0, s25, s26);
4316 __ Fmin(s1, s27, s28);
4317 __ Fmin(s2, s28, s26);
4318 END();
4319
4320 RUN();
4321
4322 ASSERT_EQUAL_FP32(-0.0, s0);
4323 ASSERT_EQUAL_FP32(1.0, s1);
4324 ASSERT_EQUAL_FP32(-0.0, s2);
4325
4326 TEARDOWN();
4327}
4328
4329
4330TEST(fmin_d) {
4331 SETUP();
4332
4333 START();
4334 __ Fmov(d25, 0.0);
4335 __ Fneg(d26, d25);
4336 __ Fmov(d27, kFP32PositiveInfinity);
4337 __ Fneg(d28, d27);
4338 __ Fmov(d29, 1.0);
4339
4340 for (unsigned j = 0; j < 5; j++) {
4341 for (unsigned i = 0; i < 5; i++) {
4342 // Test all combinations, writing results into d0 - d24.
4343 __ Fmin(FPRegister::DRegFromCode(i + 5*j),
4344 FPRegister::DRegFromCode(i + 25),
4345 FPRegister::DRegFromCode(j + 25));
4346 }
4347 }
4348 END();
4349
4350 RUN();
4351
4352 // Second register is 0.0.
4353 ASSERT_EQUAL_FP64(0.0, d0);
4354 ASSERT_EQUAL_FP64(-0.0, d1);
4355 ASSERT_EQUAL_FP64(0.0, d2);
4356 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d3);
4357 ASSERT_EQUAL_FP64(0.0, d4);
4358
4359 // Second register is -0.0.
4360 ASSERT_EQUAL_FP64(-0.0, d5);
4361 ASSERT_EQUAL_FP64(-0.0, d6);
4362 ASSERT_EQUAL_FP64(-0.0, d7);
4363 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d8);
4364 ASSERT_EQUAL_FP64(-0.0, d9);
4365
4366 // Second register is +Inf.
4367 ASSERT_EQUAL_FP64(0.0, d10);
4368 ASSERT_EQUAL_FP64(-0.0, d11);
4369 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
4370 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d13);
4371 ASSERT_EQUAL_FP64(1.0, d14);
4372
4373 // Second register is -Inf.
4374 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d15);
4375 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d16);
4376 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d17);
4377 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d18);
4378 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d19);
4379
4380 // Second register is 1.0.
4381 ASSERT_EQUAL_FP64(0.0, d20);
4382 ASSERT_EQUAL_FP64(-0.0, d21);
4383 ASSERT_EQUAL_FP64(1.0, d22);
4384 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d23);
4385 ASSERT_EQUAL_FP64(1.0, d24);
4386
4387 TEARDOWN();
4388}
4389
4390
4391TEST(fmax_s) {
4392 SETUP();
4393
4394 START();
4395 __ Fmov(s25, 0.0);
4396 __ Fneg(s26, s25);
4397 __ Fmov(s27, kFP32PositiveInfinity);
4398 __ Fmov(s28, 1.0);
4399 __ Fmax(s0, s25, s26);
4400 __ Fmax(s1, s27, s28);
4401 __ Fmax(s2, s28, s26);
4402 END();
4403
4404 RUN();
4405
4406 ASSERT_EQUAL_FP32(0.0, s0);
4407 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s1);
4408 ASSERT_EQUAL_FP32(1.0, s2);
4409
4410 TEARDOWN();
4411}
4412
4413
4414TEST(fmax_d) {
4415 SETUP();
4416
4417 START();
4418 __ Fmov(d25, 0.0);
4419 __ Fneg(d26, d25);
4420 __ Fmov(d27, kFP32PositiveInfinity);
4421 __ Fneg(d28, d27);
4422 __ Fmov(d29, 1.0);
4423
4424 for (unsigned j = 0; j < 5; j++) {
4425 for (unsigned i = 0; i < 5; i++) {
4426 // Test all combinations, writing results into d0 - d24.
4427 __ Fmax(FPRegister::DRegFromCode(i + 5*j),
4428 FPRegister::DRegFromCode(i + 25),
4429 FPRegister::DRegFromCode(j + 25));
4430 }
4431 }
4432 END();
4433
4434 RUN();
4435
4436 // Second register is 0.0.
4437 ASSERT_EQUAL_FP64(0.0, d0);
4438 ASSERT_EQUAL_FP64(0.0, d1);
4439 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d2);
4440 ASSERT_EQUAL_FP64(0.0, d3);
4441 ASSERT_EQUAL_FP64(1.0, d4);
4442
4443 // Second register is -0.0.
4444 ASSERT_EQUAL_FP64(0.0, d5);
4445 ASSERT_EQUAL_FP64(-0.0, d6);
4446 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d7);
4447 ASSERT_EQUAL_FP64(-0.0, d8);
4448 ASSERT_EQUAL_FP64(1.0, d9);
4449
4450 // Second register is +Inf.
4451 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d10);
4452 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d11);
4453 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
4454 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d13);
4455 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d14);
4456
4457 // Second register is -Inf.
4458 ASSERT_EQUAL_FP64(0.0, d15);
4459 ASSERT_EQUAL_FP64(-0.0, d16);
4460 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d17);
4461 ASSERT_EQUAL_FP64(kFP32NegativeInfinity, d18);
4462 ASSERT_EQUAL_FP64(1.0, d19);
4463
4464 // Second register is 1.0.
4465 ASSERT_EQUAL_FP64(1.0, d20);
4466 ASSERT_EQUAL_FP64(1.0, d21);
4467 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d22);
4468 ASSERT_EQUAL_FP64(1.0, d23);
4469 ASSERT_EQUAL_FP64(1.0, d24);
4470
4471 TEARDOWN();
4472}
4473
4474
4475TEST(fccmp) {
4476 SETUP();
4477
4478 START();
4479 __ Fmov(s16, 0.0);
4480 __ Fmov(s17, 0.5);
4481 __ Fmov(d18, -0.5);
4482 __ Fmov(d19, -1.0);
4483 __ Mov(x20, 0);
4484
armvixl578645f2013-08-15 17:21:42 +01004485 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01004486 __ Fccmp(s16, s16, NoFlag, eq);
4487 __ Mrs(x0, NZCV);
4488
armvixl578645f2013-08-15 17:21:42 +01004489 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01004490 __ Fccmp(s16, s16, VFlag, ne);
4491 __ Mrs(x1, NZCV);
4492
armvixl578645f2013-08-15 17:21:42 +01004493 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01004494 __ Fccmp(s16, s17, CFlag, ge);
4495 __ Mrs(x2, NZCV);
4496
armvixl578645f2013-08-15 17:21:42 +01004497 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01004498 __ Fccmp(s16, s17, CVFlag, lt);
4499 __ Mrs(x3, NZCV);
4500
armvixl578645f2013-08-15 17:21:42 +01004501 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01004502 __ Fccmp(d18, d18, ZFlag, le);
4503 __ Mrs(x4, NZCV);
4504
armvixl578645f2013-08-15 17:21:42 +01004505 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01004506 __ Fccmp(d18, d18, ZVFlag, gt);
4507 __ Mrs(x5, NZCV);
4508
armvixl578645f2013-08-15 17:21:42 +01004509 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01004510 __ Fccmp(d18, d19, ZCVFlag, ls);
4511 __ Mrs(x6, NZCV);
4512
armvixl578645f2013-08-15 17:21:42 +01004513 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01004514 __ Fccmp(d18, d19, NFlag, hi);
4515 __ Mrs(x7, NZCV);
armvixl578645f2013-08-15 17:21:42 +01004516
4517 __ fccmp(s16, s16, NFlag, al);
4518 __ Mrs(x8, NZCV);
4519
4520 __ fccmp(d18, d18, NFlag, nv);
4521 __ Mrs(x9, NZCV);
armvixlad96eda2013-06-14 11:42:37 +01004522 END();
4523
4524 RUN();
4525
4526 ASSERT_EQUAL_32(ZCFlag, w0);
4527 ASSERT_EQUAL_32(VFlag, w1);
4528 ASSERT_EQUAL_32(NFlag, w2);
4529 ASSERT_EQUAL_32(CVFlag, w3);
4530 ASSERT_EQUAL_32(ZCFlag, w4);
4531 ASSERT_EQUAL_32(ZVFlag, w5);
4532 ASSERT_EQUAL_32(CFlag, w6);
4533 ASSERT_EQUAL_32(NFlag, w7);
armvixl578645f2013-08-15 17:21:42 +01004534 ASSERT_EQUAL_32(ZCFlag, w8);
4535 ASSERT_EQUAL_32(ZCFlag, w9);
armvixlad96eda2013-06-14 11:42:37 +01004536
4537 TEARDOWN();
4538}
4539
4540
4541TEST(fcmp) {
4542 SETUP();
4543
4544 START();
4545 __ Fmov(s8, 0.0);
4546 __ Fmov(s9, 0.5);
4547 __ Mov(w18, 0x7f800001); // Single precision NaN.
4548 __ Fmov(s18, w18);
4549
4550 __ Fcmp(s8, s8);
4551 __ Mrs(x0, NZCV);
4552 __ Fcmp(s8, s9);
4553 __ Mrs(x1, NZCV);
4554 __ Fcmp(s9, s8);
4555 __ Mrs(x2, NZCV);
4556 __ Fcmp(s8, s18);
4557 __ Mrs(x3, NZCV);
4558 __ Fcmp(s18, s18);
4559 __ Mrs(x4, NZCV);
4560 __ Fcmp(s8, 0.0);
4561 __ Mrs(x5, NZCV);
4562 __ Fcmp(s8, 255.0);
4563 __ Mrs(x6, NZCV);
4564
4565 __ Fmov(d19, 0.0);
4566 __ Fmov(d20, 0.5);
4567 __ Mov(x21, 0x7ff0000000000001UL); // Double precision NaN.
4568 __ Fmov(d21, x21);
4569
4570 __ Fcmp(d19, d19);
4571 __ Mrs(x10, NZCV);
4572 __ Fcmp(d19, d20);
4573 __ Mrs(x11, NZCV);
4574 __ Fcmp(d20, d19);
4575 __ Mrs(x12, NZCV);
4576 __ Fcmp(d19, d21);
4577 __ Mrs(x13, NZCV);
4578 __ Fcmp(d21, d21);
4579 __ Mrs(x14, NZCV);
4580 __ Fcmp(d19, 0.0);
4581 __ Mrs(x15, NZCV);
4582 __ Fcmp(d19, 12.3456);
4583 __ Mrs(x16, NZCV);
4584 END();
4585
4586 RUN();
4587
4588 ASSERT_EQUAL_32(ZCFlag, w0);
4589 ASSERT_EQUAL_32(NFlag, w1);
4590 ASSERT_EQUAL_32(CFlag, w2);
4591 ASSERT_EQUAL_32(CVFlag, w3);
4592 ASSERT_EQUAL_32(CVFlag, w4);
4593 ASSERT_EQUAL_32(ZCFlag, w5);
4594 ASSERT_EQUAL_32(NFlag, w6);
4595 ASSERT_EQUAL_32(ZCFlag, w10);
4596 ASSERT_EQUAL_32(NFlag, w11);
4597 ASSERT_EQUAL_32(CFlag, w12);
4598 ASSERT_EQUAL_32(CVFlag, w13);
4599 ASSERT_EQUAL_32(CVFlag, w14);
4600 ASSERT_EQUAL_32(ZCFlag, w15);
4601 ASSERT_EQUAL_32(NFlag, w16);
4602
4603 TEARDOWN();
4604}
4605
4606
4607TEST(fcsel) {
4608 SETUP();
4609
4610 START();
4611 __ Mov(x16, 0);
4612 __ Fmov(s16, 1.0);
4613 __ Fmov(s17, 2.0);
4614 __ Fmov(d18, 3.0);
4615 __ Fmov(d19, 4.0);
4616
armvixl578645f2013-08-15 17:21:42 +01004617 __ Cmp(x16, 0);
armvixlad96eda2013-06-14 11:42:37 +01004618 __ Fcsel(s0, s16, s17, eq);
4619 __ Fcsel(s1, s16, s17, ne);
4620 __ Fcsel(d2, d18, d19, eq);
4621 __ Fcsel(d3, d18, d19, ne);
armvixl578645f2013-08-15 17:21:42 +01004622 __ fcsel(s4, s16, s17, al);
4623 __ fcsel(d5, d18, d19, nv);
armvixlad96eda2013-06-14 11:42:37 +01004624 END();
4625
4626 RUN();
4627
4628 ASSERT_EQUAL_FP32(1.0, s0);
4629 ASSERT_EQUAL_FP32(2.0, s1);
4630 ASSERT_EQUAL_FP64(3.0, d2);
4631 ASSERT_EQUAL_FP64(4.0, d3);
armvixl578645f2013-08-15 17:21:42 +01004632 ASSERT_EQUAL_FP32(1.0, s4);
4633 ASSERT_EQUAL_FP64(3.0, d5);
armvixlad96eda2013-06-14 11:42:37 +01004634
4635 TEARDOWN();
4636}
4637
4638
4639TEST(fneg) {
4640 SETUP();
4641
4642 START();
4643 __ Fmov(s16, 1.0);
4644 __ Fmov(s17, 0.0);
4645 __ Fmov(s18, kFP32PositiveInfinity);
4646 __ Fmov(d19, 1.0);
4647 __ Fmov(d20, 0.0);
4648 __ Fmov(d21, kFP64PositiveInfinity);
4649
4650 __ Fneg(s0, s16);
4651 __ Fneg(s1, s0);
4652 __ Fneg(s2, s17);
4653 __ Fneg(s3, s2);
4654 __ Fneg(s4, s18);
4655 __ Fneg(s5, s4);
4656 __ Fneg(d6, d19);
4657 __ Fneg(d7, d6);
4658 __ Fneg(d8, d20);
4659 __ Fneg(d9, d8);
4660 __ Fneg(d10, d21);
4661 __ Fneg(d11, d10);
4662 END();
4663
4664 RUN();
4665
4666 ASSERT_EQUAL_FP32(-1.0, s0);
4667 ASSERT_EQUAL_FP32(1.0, s1);
4668 ASSERT_EQUAL_FP32(-0.0, s2);
4669 ASSERT_EQUAL_FP32(0.0, s3);
4670 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
4671 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
4672 ASSERT_EQUAL_FP64(-1.0, d6);
4673 ASSERT_EQUAL_FP64(1.0, d7);
4674 ASSERT_EQUAL_FP64(-0.0, d8);
4675 ASSERT_EQUAL_FP64(0.0, d9);
4676 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
4677 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
4678
4679 TEARDOWN();
4680}
4681
4682
4683TEST(fabs) {
4684 SETUP();
4685
4686 START();
4687 __ Fmov(s16, -1.0);
4688 __ Fmov(s17, -0.0);
4689 __ Fmov(s18, kFP32NegativeInfinity);
4690 __ Fmov(d19, -1.0);
4691 __ Fmov(d20, -0.0);
4692 __ Fmov(d21, kFP64NegativeInfinity);
4693
4694 __ Fabs(s0, s16);
4695 __ Fabs(s1, s0);
4696 __ Fabs(s2, s17);
4697 __ Fabs(s3, s18);
4698 __ Fabs(d4, d19);
4699 __ Fabs(d5, d4);
4700 __ Fabs(d6, d20);
4701 __ Fabs(d7, d21);
4702 END();
4703
4704 RUN();
4705
4706 ASSERT_EQUAL_FP32(1.0, s0);
4707 ASSERT_EQUAL_FP32(1.0, s1);
4708 ASSERT_EQUAL_FP32(0.0, s2);
4709 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
4710 ASSERT_EQUAL_FP64(1.0, d4);
4711 ASSERT_EQUAL_FP64(1.0, d5);
4712 ASSERT_EQUAL_FP64(0.0, d6);
4713 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
4714
4715 TEARDOWN();
4716}
4717
4718
4719TEST(fsqrt) {
4720 SETUP();
4721
4722 START();
4723 __ Fmov(s16, 0.0);
4724 __ Fmov(s17, 1.0);
4725 __ Fmov(s18, 0.25);
4726 __ Fmov(s19, 65536.0);
4727 __ Fmov(s20, -0.0);
4728 __ Fmov(s21, kFP32PositiveInfinity);
4729 __ Fmov(d22, 0.0);
4730 __ Fmov(d23, 1.0);
4731 __ Fmov(d24, 0.25);
4732 __ Fmov(d25, 4294967296.0);
4733 __ Fmov(d26, -0.0);
4734 __ Fmov(d27, kFP64PositiveInfinity);
4735
4736 __ Fsqrt(s0, s16);
4737 __ Fsqrt(s1, s17);
4738 __ Fsqrt(s2, s18);
4739 __ Fsqrt(s3, s19);
4740 __ Fsqrt(s4, s20);
4741 __ Fsqrt(s5, s21);
4742 __ Fsqrt(d6, d22);
4743 __ Fsqrt(d7, d23);
4744 __ Fsqrt(d8, d24);
4745 __ Fsqrt(d9, d25);
4746 __ Fsqrt(d10, d26);
4747 __ Fsqrt(d11, d27);
4748 END();
4749
4750 RUN();
4751
4752 ASSERT_EQUAL_FP32(0.0, s0);
4753 ASSERT_EQUAL_FP32(1.0, s1);
4754 ASSERT_EQUAL_FP32(0.5, s2);
4755 ASSERT_EQUAL_FP32(256.0, s3);
4756 ASSERT_EQUAL_FP32(-0.0, s4);
4757 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
4758 ASSERT_EQUAL_FP64(0.0, d6);
4759 ASSERT_EQUAL_FP64(1.0, d7);
4760 ASSERT_EQUAL_FP64(0.5, d8);
4761 ASSERT_EQUAL_FP64(65536.0, d9);
4762 ASSERT_EQUAL_FP64(-0.0, d10);
4763 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d11);
4764
4765 TEARDOWN();
4766}
4767
4768
4769TEST(frintn) {
4770 SETUP();
4771
4772 START();
4773 __ Fmov(s16, 1.0);
4774 __ Fmov(s17, 1.1);
4775 __ Fmov(s18, 1.5);
4776 __ Fmov(s19, 1.9);
4777 __ Fmov(s20, 2.5);
4778 __ Fmov(s21, -1.5);
4779 __ Fmov(s22, -2.5);
4780 __ Fmov(s23, kFP32PositiveInfinity);
4781 __ Fmov(s24, kFP32NegativeInfinity);
4782 __ Fmov(s25, 0.0);
4783 __ Fmov(s26, -0.0);
4784
4785 __ Frintn(s0, s16);
4786 __ Frintn(s1, s17);
4787 __ Frintn(s2, s18);
4788 __ Frintn(s3, s19);
4789 __ Frintn(s4, s20);
4790 __ Frintn(s5, s21);
4791 __ Frintn(s6, s22);
4792 __ Frintn(s7, s23);
4793 __ Frintn(s8, s24);
4794 __ Frintn(s9, s25);
4795 __ Frintn(s10, s26);
4796
4797 __ Fmov(d16, 1.0);
4798 __ Fmov(d17, 1.1);
4799 __ Fmov(d18, 1.5);
4800 __ Fmov(d19, 1.9);
4801 __ Fmov(d20, 2.5);
4802 __ Fmov(d21, -1.5);
4803 __ Fmov(d22, -2.5);
4804 __ Fmov(d23, kFP32PositiveInfinity);
4805 __ Fmov(d24, kFP32NegativeInfinity);
4806 __ Fmov(d25, 0.0);
4807 __ Fmov(d26, -0.0);
4808
4809 __ Frintn(d11, d16);
4810 __ Frintn(d12, d17);
4811 __ Frintn(d13, d18);
4812 __ Frintn(d14, d19);
4813 __ Frintn(d15, d20);
4814 __ Frintn(d16, d21);
4815 __ Frintn(d17, d22);
4816 __ Frintn(d18, d23);
4817 __ Frintn(d19, d24);
4818 __ Frintn(d20, d25);
4819 __ Frintn(d21, d26);
4820 END();
4821
4822 RUN();
4823
4824 ASSERT_EQUAL_FP32(1.0, s0);
4825 ASSERT_EQUAL_FP32(1.0, s1);
4826 ASSERT_EQUAL_FP32(2.0, s2);
4827 ASSERT_EQUAL_FP32(2.0, s3);
4828 ASSERT_EQUAL_FP32(2.0, s4);
4829 ASSERT_EQUAL_FP32(-2.0, s5);
4830 ASSERT_EQUAL_FP32(-2.0, s6);
4831 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
4832 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
4833 ASSERT_EQUAL_FP32(0.0, s9);
4834 ASSERT_EQUAL_FP32(-0.0, s10);
4835 ASSERT_EQUAL_FP64(1.0, d11);
4836 ASSERT_EQUAL_FP64(1.0, d12);
4837 ASSERT_EQUAL_FP64(2.0, d13);
4838 ASSERT_EQUAL_FP64(2.0, d14);
4839 ASSERT_EQUAL_FP64(2.0, d15);
4840 ASSERT_EQUAL_FP64(-2.0, d16);
4841 ASSERT_EQUAL_FP64(-2.0, d17);
4842 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
4843 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
4844 ASSERT_EQUAL_FP64(0.0, d20);
4845 ASSERT_EQUAL_FP64(-0.0, d21);
4846
4847 TEARDOWN();
4848}
4849
4850
4851TEST(frintz) {
4852 SETUP();
4853
4854 START();
4855 __ Fmov(s16, 1.0);
4856 __ Fmov(s17, 1.1);
4857 __ Fmov(s18, 1.5);
4858 __ Fmov(s19, 1.9);
4859 __ Fmov(s20, 2.5);
4860 __ Fmov(s21, -1.5);
4861 __ Fmov(s22, -2.5);
4862 __ Fmov(s23, kFP32PositiveInfinity);
4863 __ Fmov(s24, kFP32NegativeInfinity);
4864 __ Fmov(s25, 0.0);
4865 __ Fmov(s26, -0.0);
4866
4867 __ Frintz(s0, s16);
4868 __ Frintz(s1, s17);
4869 __ Frintz(s2, s18);
4870 __ Frintz(s3, s19);
4871 __ Frintz(s4, s20);
4872 __ Frintz(s5, s21);
4873 __ Frintz(s6, s22);
4874 __ Frintz(s7, s23);
4875 __ Frintz(s8, s24);
4876 __ Frintz(s9, s25);
4877 __ Frintz(s10, s26);
4878
4879 __ Fmov(d16, 1.0);
4880 __ Fmov(d17, 1.1);
4881 __ Fmov(d18, 1.5);
4882 __ Fmov(d19, 1.9);
4883 __ Fmov(d20, 2.5);
4884 __ Fmov(d21, -1.5);
4885 __ Fmov(d22, -2.5);
4886 __ Fmov(d23, kFP32PositiveInfinity);
4887 __ Fmov(d24, kFP32NegativeInfinity);
4888 __ Fmov(d25, 0.0);
4889 __ Fmov(d26, -0.0);
4890
4891 __ Frintz(d11, d16);
4892 __ Frintz(d12, d17);
4893 __ Frintz(d13, d18);
4894 __ Frintz(d14, d19);
4895 __ Frintz(d15, d20);
4896 __ Frintz(d16, d21);
4897 __ Frintz(d17, d22);
4898 __ Frintz(d18, d23);
4899 __ Frintz(d19, d24);
4900 __ Frintz(d20, d25);
4901 __ Frintz(d21, d26);
4902 END();
4903
4904 RUN();
4905
4906 ASSERT_EQUAL_FP32(1.0, s0);
4907 ASSERT_EQUAL_FP32(1.0, s1);
4908 ASSERT_EQUAL_FP32(1.0, s2);
4909 ASSERT_EQUAL_FP32(1.0, s3);
4910 ASSERT_EQUAL_FP32(2.0, s4);
4911 ASSERT_EQUAL_FP32(-1.0, s5);
4912 ASSERT_EQUAL_FP32(-2.0, s6);
4913 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
4914 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
4915 ASSERT_EQUAL_FP32(0.0, s9);
4916 ASSERT_EQUAL_FP32(-0.0, s10);
4917 ASSERT_EQUAL_FP64(1.0, d11);
4918 ASSERT_EQUAL_FP64(1.0, d12);
4919 ASSERT_EQUAL_FP64(1.0, d13);
4920 ASSERT_EQUAL_FP64(1.0, d14);
4921 ASSERT_EQUAL_FP64(2.0, d15);
4922 ASSERT_EQUAL_FP64(-1.0, d16);
4923 ASSERT_EQUAL_FP64(-2.0, d17);
4924 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
4925 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
4926 ASSERT_EQUAL_FP64(0.0, d20);
4927 ASSERT_EQUAL_FP64(-0.0, d21);
4928
4929 TEARDOWN();
4930}
4931
4932
armvixl578645f2013-08-15 17:21:42 +01004933TEST(fcvt_ds) {
armvixlad96eda2013-06-14 11:42:37 +01004934 SETUP();
4935
4936 START();
4937 __ Fmov(s16, 1.0);
4938 __ Fmov(s17, 1.1);
4939 __ Fmov(s18, 1.5);
4940 __ Fmov(s19, 1.9);
4941 __ Fmov(s20, 2.5);
4942 __ Fmov(s21, -1.5);
4943 __ Fmov(s22, -2.5);
4944 __ Fmov(s23, kFP32PositiveInfinity);
4945 __ Fmov(s24, kFP32NegativeInfinity);
4946 __ Fmov(s25, 0.0);
4947 __ Fmov(s26, -0.0);
armvixl578645f2013-08-15 17:21:42 +01004948 __ Fmov(s27, FLT_MAX);
4949 __ Fmov(s28, FLT_MIN);
4950 __ Fmov(s29, rawbits_to_float(0x7fc12345)); // Quiet NaN.
4951 __ Fmov(s30, rawbits_to_float(0x7f812345)); // Signalling NaN.
armvixlad96eda2013-06-14 11:42:37 +01004952
4953 __ Fcvt(d0, s16);
4954 __ Fcvt(d1, s17);
4955 __ Fcvt(d2, s18);
4956 __ Fcvt(d3, s19);
4957 __ Fcvt(d4, s20);
4958 __ Fcvt(d5, s21);
4959 __ Fcvt(d6, s22);
4960 __ Fcvt(d7, s23);
4961 __ Fcvt(d8, s24);
4962 __ Fcvt(d9, s25);
4963 __ Fcvt(d10, s26);
armvixl578645f2013-08-15 17:21:42 +01004964 __ Fcvt(d11, s27);
4965 __ Fcvt(d12, s28);
4966 __ Fcvt(d13, s29);
4967 __ Fcvt(d14, s30);
armvixlad96eda2013-06-14 11:42:37 +01004968 END();
4969
4970 RUN();
4971
4972 ASSERT_EQUAL_FP64(1.0f, d0);
4973 ASSERT_EQUAL_FP64(1.1f, d1);
4974 ASSERT_EQUAL_FP64(1.5f, d2);
4975 ASSERT_EQUAL_FP64(1.9f, d3);
4976 ASSERT_EQUAL_FP64(2.5f, d4);
4977 ASSERT_EQUAL_FP64(-1.5f, d5);
4978 ASSERT_EQUAL_FP64(-2.5f, d6);
4979 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
4980 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
4981 ASSERT_EQUAL_FP64(0.0f, d9);
4982 ASSERT_EQUAL_FP64(-0.0f, d10);
armvixl578645f2013-08-15 17:21:42 +01004983 ASSERT_EQUAL_FP64(FLT_MAX, d11);
4984 ASSERT_EQUAL_FP64(FLT_MIN, d12);
4985
4986 // Check that the NaN payload is preserved according to A64 conversion rules:
4987 // - The sign bit is preserved.
4988 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
4989 // - The remaining mantissa bits are copied until they run out.
4990 // - The low-order bits that haven't already been assigned are set to 0.
4991 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
4992 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
armvixlad96eda2013-06-14 11:42:37 +01004993
4994 TEARDOWN();
4995}
4996
4997
armvixl578645f2013-08-15 17:21:42 +01004998TEST(fcvt_sd) {
4999 // There are a huge number of corner-cases to check, so this test iterates
5000 // through a list. The list is then negated and checked again (since the sign
5001 // is irrelevant in ties-to-even rounding), so the list shouldn't include any
5002 // negative values.
5003 //
5004 // Note that this test only checks ties-to-even rounding, because that is all
5005 // that the simulator supports.
5006 struct {double in; float expected;} test[] = {
5007 // Check some simple conversions.
5008 {0.0, 0.0f},
5009 {1.0, 1.0f},
5010 {1.5, 1.5f},
5011 {2.0, 2.0f},
5012 {FLT_MAX, FLT_MAX},
5013 // - The smallest normalized float.
5014 {pow(2, -126), pow(2, -126)},
5015 // - Normal floats that need (ties-to-even) rounding.
5016 // For normalized numbers:
5017 // bit 29 (0x0000000020000000) is the lowest-order bit which will
5018 // fit in the float's mantissa.
5019 {rawbits_to_double(0x3ff0000000000000), rawbits_to_float(0x3f800000)},
5020 {rawbits_to_double(0x3ff0000000000001), rawbits_to_float(0x3f800000)},
5021 {rawbits_to_double(0x3ff0000010000000), rawbits_to_float(0x3f800000)},
5022 {rawbits_to_double(0x3ff0000010000001), rawbits_to_float(0x3f800001)},
5023 {rawbits_to_double(0x3ff0000020000000), rawbits_to_float(0x3f800001)},
5024 {rawbits_to_double(0x3ff0000020000001), rawbits_to_float(0x3f800001)},
5025 {rawbits_to_double(0x3ff0000030000000), rawbits_to_float(0x3f800002)},
5026 {rawbits_to_double(0x3ff0000030000001), rawbits_to_float(0x3f800002)},
5027 {rawbits_to_double(0x3ff0000040000000), rawbits_to_float(0x3f800002)},
5028 {rawbits_to_double(0x3ff0000040000001), rawbits_to_float(0x3f800002)},
5029 {rawbits_to_double(0x3ff0000050000000), rawbits_to_float(0x3f800002)},
5030 {rawbits_to_double(0x3ff0000050000001), rawbits_to_float(0x3f800003)},
5031 {rawbits_to_double(0x3ff0000060000000), rawbits_to_float(0x3f800003)},
5032 // - A mantissa that overflows into the exponent during rounding.
5033 {rawbits_to_double(0x3feffffff0000000), rawbits_to_float(0x3f800000)},
5034 // - The largest double that rounds to a normal float.
5035 {rawbits_to_double(0x47efffffefffffff), rawbits_to_float(0x7f7fffff)},
5036
5037 // Doubles that are too big for a float.
5038 {kFP64PositiveInfinity, kFP32PositiveInfinity},
5039 {DBL_MAX, kFP32PositiveInfinity},
5040 // - The smallest exponent that's too big for a float.
5041 {pow(2, 128), kFP32PositiveInfinity},
5042 // - This exponent is in range, but the value rounds to infinity.
5043 {rawbits_to_double(0x47effffff0000000), kFP32PositiveInfinity},
5044
5045 // Doubles that are too small for a float.
5046 // - The smallest (subnormal) double.
5047 {DBL_MIN, 0.0},
5048 // - The largest double which is too small for a subnormal float.
5049 {rawbits_to_double(0x3690000000000000), rawbits_to_float(0x00000000)},
5050
5051 // Normal doubles that become subnormal floats.
5052 // - The largest subnormal float.
5053 {rawbits_to_double(0x380fffffc0000000), rawbits_to_float(0x007fffff)},
5054 // - The smallest subnormal float.
5055 {rawbits_to_double(0x36a0000000000000), rawbits_to_float(0x00000001)},
5056 // - Subnormal floats that need (ties-to-even) rounding.
5057 // For these subnormals:
5058 // bit 34 (0x0000000400000000) is the lowest-order bit which will
5059 // fit in the float's mantissa.
5060 {rawbits_to_double(0x37c159e000000000), rawbits_to_float(0x00045678)},
5061 {rawbits_to_double(0x37c159e000000001), rawbits_to_float(0x00045678)},
5062 {rawbits_to_double(0x37c159e200000000), rawbits_to_float(0x00045678)},
5063 {rawbits_to_double(0x37c159e200000001), rawbits_to_float(0x00045679)},
5064 {rawbits_to_double(0x37c159e400000000), rawbits_to_float(0x00045679)},
5065 {rawbits_to_double(0x37c159e400000001), rawbits_to_float(0x00045679)},
5066 {rawbits_to_double(0x37c159e600000000), rawbits_to_float(0x0004567a)},
5067 {rawbits_to_double(0x37c159e600000001), rawbits_to_float(0x0004567a)},
5068 {rawbits_to_double(0x37c159e800000000), rawbits_to_float(0x0004567a)},
5069 {rawbits_to_double(0x37c159e800000001), rawbits_to_float(0x0004567a)},
5070 {rawbits_to_double(0x37c159ea00000000), rawbits_to_float(0x0004567a)},
5071 {rawbits_to_double(0x37c159ea00000001), rawbits_to_float(0x0004567b)},
5072 {rawbits_to_double(0x37c159ec00000000), rawbits_to_float(0x0004567b)},
5073 // - The smallest double which rounds up to become a subnormal float.
5074 {rawbits_to_double(0x3690000000000001), rawbits_to_float(0x00000001)},
5075
5076 // Check NaN payload preservation.
5077 {rawbits_to_double(0x7ff82468a0000000), rawbits_to_float(0x7fc12345)},
5078 {rawbits_to_double(0x7ff82468bfffffff), rawbits_to_float(0x7fc12345)},
5079 // - Signalling NaNs become quiet NaNs.
5080 {rawbits_to_double(0x7ff02468a0000000), rawbits_to_float(0x7fc12345)},
5081 {rawbits_to_double(0x7ff02468bfffffff), rawbits_to_float(0x7fc12345)},
5082 {rawbits_to_double(0x7ff000001fffffff), rawbits_to_float(0x7fc00000)},
5083 };
5084 int count = sizeof(test) / sizeof(test[0]);
5085
5086 for (int i = 0; i < count; i++) {
5087 double in = test[i].in;
5088 float expected = test[i].expected;
5089
5090 // We only expect positive input.
5091 ASSERT(signbit(in) == 0);
5092 ASSERT(signbit(expected) == 0);
5093
5094 SETUP();
5095 START();
5096
5097 __ Fmov(d10, in);
5098 __ Fcvt(s20, d10);
5099
5100 __ Fmov(d11, -in);
5101 __ Fcvt(s21, d11);
5102
5103 END();
5104 RUN();
5105 ASSERT_EQUAL_FP32(expected, s20);
5106 ASSERT_EQUAL_FP32(-expected, s21);
5107 TEARDOWN();
5108 }
5109}
5110
5111
armvixlad96eda2013-06-14 11:42:37 +01005112TEST(fcvtms) {
5113 SETUP();
5114
5115 START();
5116 __ Fmov(s0, 1.0);
5117 __ Fmov(s1, 1.1);
5118 __ Fmov(s2, 1.5);
5119 __ Fmov(s3, -1.5);
5120 __ Fmov(s4, kFP32PositiveInfinity);
5121 __ Fmov(s5, kFP32NegativeInfinity);
5122 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
5123 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
5124 __ Fmov(d8, 1.0);
5125 __ Fmov(d9, 1.1);
5126 __ Fmov(d10, 1.5);
5127 __ Fmov(d11, -1.5);
5128 __ Fmov(d12, kFP64PositiveInfinity);
5129 __ Fmov(d13, kFP64NegativeInfinity);
5130 __ Fmov(d14, kWMaxInt - 1);
5131 __ Fmov(d15, kWMinInt + 1);
5132 __ Fmov(s17, 1.1);
5133 __ Fmov(s18, 1.5);
5134 __ Fmov(s19, -1.5);
5135 __ Fmov(s20, kFP32PositiveInfinity);
5136 __ Fmov(s21, kFP32NegativeInfinity);
5137 __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX.
5138 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
5139 __ Fmov(d24, 1.1);
5140 __ Fmov(d25, 1.5);
5141 __ Fmov(d26, -1.5);
5142 __ Fmov(d27, kFP64PositiveInfinity);
5143 __ Fmov(d28, kFP64NegativeInfinity);
5144 __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX.
5145 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
5146
5147 __ Fcvtms(w0, s0);
5148 __ Fcvtms(w1, s1);
5149 __ Fcvtms(w2, s2);
5150 __ Fcvtms(w3, s3);
5151 __ Fcvtms(w4, s4);
5152 __ Fcvtms(w5, s5);
5153 __ Fcvtms(w6, s6);
5154 __ Fcvtms(w7, s7);
5155 __ Fcvtms(w8, d8);
5156 __ Fcvtms(w9, d9);
5157 __ Fcvtms(w10, d10);
5158 __ Fcvtms(w11, d11);
5159 __ Fcvtms(w12, d12);
5160 __ Fcvtms(w13, d13);
5161 __ Fcvtms(w14, d14);
5162 __ Fcvtms(w15, d15);
5163 __ Fcvtms(x17, s17);
5164 __ Fcvtms(x18, s18);
5165 __ Fcvtms(x19, s19);
5166 __ Fcvtms(x20, s20);
5167 __ Fcvtms(x21, s21);
5168 __ Fcvtms(x22, s22);
5169 __ Fcvtms(x23, s23);
5170 __ Fcvtms(x24, d24);
5171 __ Fcvtms(x25, d25);
5172 __ Fcvtms(x26, d26);
5173 __ Fcvtms(x27, d27);
5174 __ Fcvtms(x28, d28);
5175 __ Fcvtms(x29, d29);
5176 __ Fcvtms(x30, d30);
5177 END();
5178
5179 RUN();
5180
5181 ASSERT_EQUAL_64(1, x0);
5182 ASSERT_EQUAL_64(1, x1);
5183 ASSERT_EQUAL_64(1, x2);
5184 ASSERT_EQUAL_64(0xfffffffe, x3);
5185 ASSERT_EQUAL_64(0x7fffffff, x4);
5186 ASSERT_EQUAL_64(0x80000000, x5);
5187 ASSERT_EQUAL_64(0x7fffff80, x6);
5188 ASSERT_EQUAL_64(0x80000080, x7);
5189 ASSERT_EQUAL_64(1, x8);
5190 ASSERT_EQUAL_64(1, x9);
5191 ASSERT_EQUAL_64(1, x10);
5192 ASSERT_EQUAL_64(0xfffffffe, x11);
5193 ASSERT_EQUAL_64(0x7fffffff, x12);
5194 ASSERT_EQUAL_64(0x80000000, x13);
5195 ASSERT_EQUAL_64(0x7ffffffe, x14);
5196 ASSERT_EQUAL_64(0x80000001, x15);
5197 ASSERT_EQUAL_64(1, x17);
5198 ASSERT_EQUAL_64(1, x18);
5199 ASSERT_EQUAL_64(0xfffffffffffffffeUL, x19);
5200 ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20);
5201 ASSERT_EQUAL_64(0x8000000000000000UL, x21);
5202 ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
5203 ASSERT_EQUAL_64(0x8000008000000000UL, x23);
5204 ASSERT_EQUAL_64(1, x24);
5205 ASSERT_EQUAL_64(1, x25);
5206 ASSERT_EQUAL_64(0xfffffffffffffffeUL, x26);
5207 ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27);
5208 ASSERT_EQUAL_64(0x8000000000000000UL, x28);
5209 ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
5210 ASSERT_EQUAL_64(0x8000000000000400UL, x30);
5211
5212 TEARDOWN();
5213}
5214
5215
5216TEST(fcvtmu) {
5217 SETUP();
5218
5219 START();
5220 __ Fmov(s0, 1.0);
5221 __ Fmov(s1, 1.1);
5222 __ Fmov(s2, 1.5);
5223 __ Fmov(s3, -1.5);
5224 __ Fmov(s4, kFP32PositiveInfinity);
5225 __ Fmov(s5, kFP32NegativeInfinity);
5226 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
5227 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
5228 __ Fmov(d8, 1.0);
5229 __ Fmov(d9, 1.1);
5230 __ Fmov(d10, 1.5);
5231 __ Fmov(d11, -1.5);
5232 __ Fmov(d12, kFP64PositiveInfinity);
5233 __ Fmov(d13, kFP64NegativeInfinity);
5234 __ Fmov(d14, kWMaxInt - 1);
5235 __ Fmov(d15, kWMinInt + 1);
5236 __ Fmov(s17, 1.1);
5237 __ Fmov(s18, 1.5);
5238 __ Fmov(s19, -1.5);
5239 __ Fmov(s20, kFP32PositiveInfinity);
5240 __ Fmov(s21, kFP32NegativeInfinity);
5241 __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX.
5242 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
5243 __ Fmov(d24, 1.1);
5244 __ Fmov(d25, 1.5);
5245 __ Fmov(d26, -1.5);
5246 __ Fmov(d27, kFP64PositiveInfinity);
5247 __ Fmov(d28, kFP64NegativeInfinity);
5248 __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX.
5249 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
5250
5251 __ Fcvtmu(w0, s0);
5252 __ Fcvtmu(w1, s1);
5253 __ Fcvtmu(w2, s2);
5254 __ Fcvtmu(w3, s3);
5255 __ Fcvtmu(w4, s4);
5256 __ Fcvtmu(w5, s5);
5257 __ Fcvtmu(w6, s6);
5258 __ Fcvtmu(w7, s7);
5259 __ Fcvtmu(w8, d8);
5260 __ Fcvtmu(w9, d9);
5261 __ Fcvtmu(w10, d10);
5262 __ Fcvtmu(w11, d11);
5263 __ Fcvtmu(w12, d12);
5264 __ Fcvtmu(w13, d13);
5265 __ Fcvtmu(w14, d14);
5266 __ Fcvtmu(x17, s17);
5267 __ Fcvtmu(x18, s18);
5268 __ Fcvtmu(x19, s19);
5269 __ Fcvtmu(x20, s20);
5270 __ Fcvtmu(x21, s21);
5271 __ Fcvtmu(x22, s22);
5272 __ Fcvtmu(x23, s23);
5273 __ Fcvtmu(x24, d24);
5274 __ Fcvtmu(x25, d25);
5275 __ Fcvtmu(x26, d26);
5276 __ Fcvtmu(x27, d27);
5277 __ Fcvtmu(x28, d28);
5278 __ Fcvtmu(x29, d29);
5279 __ Fcvtmu(x30, d30);
5280 END();
5281
5282 RUN();
5283
5284 ASSERT_EQUAL_64(1, x0);
5285 ASSERT_EQUAL_64(1, x1);
5286 ASSERT_EQUAL_64(1, x2);
5287 ASSERT_EQUAL_64(0, x3);
5288 ASSERT_EQUAL_64(0xffffffff, x4);
5289 ASSERT_EQUAL_64(0, x5);
5290 ASSERT_EQUAL_64(0x7fffff80, x6);
5291 ASSERT_EQUAL_64(0, x7);
5292 ASSERT_EQUAL_64(1, x8);
5293 ASSERT_EQUAL_64(1, x9);
5294 ASSERT_EQUAL_64(1, x10);
5295 ASSERT_EQUAL_64(0, x11);
5296 ASSERT_EQUAL_64(0xffffffff, x12);
5297 ASSERT_EQUAL_64(0, x13);
5298 ASSERT_EQUAL_64(0x7ffffffe, x14);
5299 ASSERT_EQUAL_64(1, x17);
5300 ASSERT_EQUAL_64(1, x18);
5301 ASSERT_EQUAL_64(0x0UL, x19);
5302 ASSERT_EQUAL_64(0xffffffffffffffffUL, x20);
5303 ASSERT_EQUAL_64(0x0UL, x21);
5304 ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
5305 ASSERT_EQUAL_64(0x0UL, x23);
5306 ASSERT_EQUAL_64(1, x24);
5307 ASSERT_EQUAL_64(1, x25);
5308 ASSERT_EQUAL_64(0x0UL, x26);
5309 ASSERT_EQUAL_64(0xffffffffffffffffUL, x27);
5310 ASSERT_EQUAL_64(0x0UL, x28);
5311 ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
5312 ASSERT_EQUAL_64(0x0UL, x30);
5313
5314 TEARDOWN();
5315}
5316
5317
5318TEST(fcvtns) {
5319 SETUP();
5320
5321 START();
5322 __ Fmov(s0, 1.0);
5323 __ Fmov(s1, 1.1);
5324 __ Fmov(s2, 1.5);
5325 __ Fmov(s3, -1.5);
5326 __ Fmov(s4, kFP32PositiveInfinity);
5327 __ Fmov(s5, kFP32NegativeInfinity);
5328 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
5329 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
5330 __ Fmov(d8, 1.0);
5331 __ Fmov(d9, 1.1);
5332 __ Fmov(d10, 1.5);
5333 __ Fmov(d11, -1.5);
5334 __ Fmov(d12, kFP64PositiveInfinity);
5335 __ Fmov(d13, kFP64NegativeInfinity);
5336 __ Fmov(d14, kWMaxInt - 1);
5337 __ Fmov(d15, kWMinInt + 1);
5338 __ Fmov(s17, 1.1);
5339 __ Fmov(s18, 1.5);
5340 __ Fmov(s19, -1.5);
5341 __ Fmov(s20, kFP32PositiveInfinity);
5342 __ Fmov(s21, kFP32NegativeInfinity);
5343 __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX.
5344 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
5345 __ Fmov(d24, 1.1);
5346 __ Fmov(d25, 1.5);
5347 __ Fmov(d26, -1.5);
5348 __ Fmov(d27, kFP64PositiveInfinity);
5349 __ Fmov(d28, kFP64NegativeInfinity);
5350 __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX.
5351 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
5352
5353 __ Fcvtns(w0, s0);
5354 __ Fcvtns(w1, s1);
5355 __ Fcvtns(w2, s2);
5356 __ Fcvtns(w3, s3);
5357 __ Fcvtns(w4, s4);
5358 __ Fcvtns(w5, s5);
5359 __ Fcvtns(w6, s6);
5360 __ Fcvtns(w7, s7);
5361 __ Fcvtns(w8, d8);
5362 __ Fcvtns(w9, d9);
5363 __ Fcvtns(w10, d10);
5364 __ Fcvtns(w11, d11);
5365 __ Fcvtns(w12, d12);
5366 __ Fcvtns(w13, d13);
5367 __ Fcvtns(w14, d14);
5368 __ Fcvtns(w15, d15);
5369 __ Fcvtns(x17, s17);
5370 __ Fcvtns(x18, s18);
5371 __ Fcvtns(x19, s19);
5372 __ Fcvtns(x20, s20);
5373 __ Fcvtns(x21, s21);
5374 __ Fcvtns(x22, s22);
5375 __ Fcvtns(x23, s23);
5376 __ Fcvtns(x24, d24);
5377 __ Fcvtns(x25, d25);
5378 __ Fcvtns(x26, d26);
5379 __ Fcvtns(x27, d27);
5380 __ Fcvtns(x28, d28);
5381 __ Fcvtns(x29, d29);
5382 __ Fcvtns(x30, d30);
5383 END();
5384
5385 RUN();
5386
5387 ASSERT_EQUAL_64(1, x0);
5388 ASSERT_EQUAL_64(1, x1);
5389 ASSERT_EQUAL_64(2, x2);
5390 ASSERT_EQUAL_64(0xfffffffe, x3);
5391 ASSERT_EQUAL_64(0x7fffffff, x4);
5392 ASSERT_EQUAL_64(0x80000000, x5);
5393 ASSERT_EQUAL_64(0x7fffff80, x6);
5394 ASSERT_EQUAL_64(0x80000080, x7);
5395 ASSERT_EQUAL_64(1, x8);
5396 ASSERT_EQUAL_64(1, x9);
5397 ASSERT_EQUAL_64(2, x10);
5398 ASSERT_EQUAL_64(0xfffffffe, x11);
5399 ASSERT_EQUAL_64(0x7fffffff, x12);
5400 ASSERT_EQUAL_64(0x80000000, x13);
5401 ASSERT_EQUAL_64(0x7ffffffe, x14);
5402 ASSERT_EQUAL_64(0x80000001, x15);
5403 ASSERT_EQUAL_64(1, x17);
5404 ASSERT_EQUAL_64(2, x18);
5405 ASSERT_EQUAL_64(0xfffffffffffffffeUL, x19);
5406 ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20);
5407 ASSERT_EQUAL_64(0x8000000000000000UL, x21);
5408 ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
5409 ASSERT_EQUAL_64(0x8000008000000000UL, x23);
5410 ASSERT_EQUAL_64(1, x24);
5411 ASSERT_EQUAL_64(2, x25);
5412 ASSERT_EQUAL_64(0xfffffffffffffffeUL, x26);
5413 ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27);
5414 ASSERT_EQUAL_64(0x8000000000000000UL, x28);
5415 ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
5416 ASSERT_EQUAL_64(0x8000000000000400UL, x30);
5417
5418 TEARDOWN();
5419}
5420
5421
5422TEST(fcvtnu) {
5423 SETUP();
5424
5425 START();
5426 __ Fmov(s0, 1.0);
5427 __ Fmov(s1, 1.1);
5428 __ Fmov(s2, 1.5);
5429 __ Fmov(s3, -1.5);
5430 __ Fmov(s4, kFP32PositiveInfinity);
5431 __ Fmov(s5, kFP32NegativeInfinity);
5432 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
5433 __ Fmov(d8, 1.0);
5434 __ Fmov(d9, 1.1);
5435 __ Fmov(d10, 1.5);
5436 __ Fmov(d11, -1.5);
5437 __ Fmov(d12, kFP64PositiveInfinity);
5438 __ Fmov(d13, kFP64NegativeInfinity);
5439 __ Fmov(d14, 0xfffffffe);
5440 __ Fmov(s16, 1.0);
5441 __ Fmov(s17, 1.1);
5442 __ Fmov(s18, 1.5);
5443 __ Fmov(s19, -1.5);
5444 __ Fmov(s20, kFP32PositiveInfinity);
5445 __ Fmov(s21, kFP32NegativeInfinity);
5446 __ Fmov(s22, 0xffffff0000000000UL); // Largest float < UINT64_MAX.
5447 __ Fmov(d24, 1.1);
5448 __ Fmov(d25, 1.5);
5449 __ Fmov(d26, -1.5);
5450 __ Fmov(d27, kFP64PositiveInfinity);
5451 __ Fmov(d28, kFP64NegativeInfinity);
5452 __ Fmov(d29, 0xfffffffffffff800UL); // Largest double < UINT64_MAX.
5453 __ Fmov(s30, 0x100000000UL);
5454
5455 __ Fcvtnu(w0, s0);
5456 __ Fcvtnu(w1, s1);
5457 __ Fcvtnu(w2, s2);
5458 __ Fcvtnu(w3, s3);
5459 __ Fcvtnu(w4, s4);
5460 __ Fcvtnu(w5, s5);
5461 __ Fcvtnu(w6, s6);
5462 __ Fcvtnu(w8, d8);
5463 __ Fcvtnu(w9, d9);
5464 __ Fcvtnu(w10, d10);
5465 __ Fcvtnu(w11, d11);
5466 __ Fcvtnu(w12, d12);
5467 __ Fcvtnu(w13, d13);
5468 __ Fcvtnu(w14, d14);
5469 __ Fcvtnu(w15, d15);
5470 __ Fcvtnu(x16, s16);
5471 __ Fcvtnu(x17, s17);
5472 __ Fcvtnu(x18, s18);
5473 __ Fcvtnu(x19, s19);
5474 __ Fcvtnu(x20, s20);
5475 __ Fcvtnu(x21, s21);
5476 __ Fcvtnu(x22, s22);
5477 __ Fcvtnu(x24, d24);
5478 __ Fcvtnu(x25, d25);
5479 __ Fcvtnu(x26, d26);
5480 __ Fcvtnu(x27, d27);
5481 __ Fcvtnu(x28, d28);
5482 __ Fcvtnu(x29, d29);
5483 __ Fcvtnu(w30, s30);
5484 END();
5485
5486 RUN();
5487
5488 ASSERT_EQUAL_64(1, x0);
5489 ASSERT_EQUAL_64(1, x1);
5490 ASSERT_EQUAL_64(2, x2);
5491 ASSERT_EQUAL_64(0, x3);
5492 ASSERT_EQUAL_64(0xffffffff, x4);
5493 ASSERT_EQUAL_64(0, x5);
5494 ASSERT_EQUAL_64(0xffffff00, x6);
5495 ASSERT_EQUAL_64(1, x8);
5496 ASSERT_EQUAL_64(1, x9);
5497 ASSERT_EQUAL_64(2, x10);
5498 ASSERT_EQUAL_64(0, x11);
5499 ASSERT_EQUAL_64(0xffffffff, x12);
5500 ASSERT_EQUAL_64(0, x13);
5501 ASSERT_EQUAL_64(0xfffffffe, x14);
5502 ASSERT_EQUAL_64(1, x16);
5503 ASSERT_EQUAL_64(1, x17);
5504 ASSERT_EQUAL_64(2, x18);
5505 ASSERT_EQUAL_64(0, x19);
5506 ASSERT_EQUAL_64(0xffffffffffffffffUL, x20);
5507 ASSERT_EQUAL_64(0, x21);
5508 ASSERT_EQUAL_64(0xffffff0000000000UL, x22);
5509 ASSERT_EQUAL_64(1, x24);
5510 ASSERT_EQUAL_64(2, x25);
5511 ASSERT_EQUAL_64(0, x26);
5512 ASSERT_EQUAL_64(0xffffffffffffffffUL, x27);
5513 ASSERT_EQUAL_64(0, x28);
5514 ASSERT_EQUAL_64(0xfffffffffffff800UL, x29);
5515 ASSERT_EQUAL_64(0xffffffff, x30);
5516
5517 TEARDOWN();
5518}
5519
5520
5521TEST(fcvtzs) {
5522 SETUP();
5523
5524 START();
5525 __ Fmov(s0, 1.0);
5526 __ Fmov(s1, 1.1);
5527 __ Fmov(s2, 1.5);
5528 __ Fmov(s3, -1.5);
5529 __ Fmov(s4, kFP32PositiveInfinity);
5530 __ Fmov(s5, kFP32NegativeInfinity);
5531 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
5532 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
5533 __ Fmov(d8, 1.0);
5534 __ Fmov(d9, 1.1);
5535 __ Fmov(d10, 1.5);
5536 __ Fmov(d11, -1.5);
5537 __ Fmov(d12, kFP64PositiveInfinity);
5538 __ Fmov(d13, kFP64NegativeInfinity);
5539 __ Fmov(d14, kWMaxInt - 1);
5540 __ Fmov(d15, kWMinInt + 1);
5541 __ Fmov(s17, 1.1);
5542 __ Fmov(s18, 1.5);
5543 __ Fmov(s19, -1.5);
5544 __ Fmov(s20, kFP32PositiveInfinity);
5545 __ Fmov(s21, kFP32NegativeInfinity);
5546 __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX.
5547 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
5548 __ Fmov(d24, 1.1);
5549 __ Fmov(d25, 1.5);
5550 __ Fmov(d26, -1.5);
5551 __ Fmov(d27, kFP64PositiveInfinity);
5552 __ Fmov(d28, kFP64NegativeInfinity);
5553 __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX.
5554 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
5555
5556 __ Fcvtzs(w0, s0);
5557 __ Fcvtzs(w1, s1);
5558 __ Fcvtzs(w2, s2);
5559 __ Fcvtzs(w3, s3);
5560 __ Fcvtzs(w4, s4);
5561 __ Fcvtzs(w5, s5);
5562 __ Fcvtzs(w6, s6);
5563 __ Fcvtzs(w7, s7);
5564 __ Fcvtzs(w8, d8);
5565 __ Fcvtzs(w9, d9);
5566 __ Fcvtzs(w10, d10);
5567 __ Fcvtzs(w11, d11);
5568 __ Fcvtzs(w12, d12);
5569 __ Fcvtzs(w13, d13);
5570 __ Fcvtzs(w14, d14);
5571 __ Fcvtzs(w15, d15);
5572 __ Fcvtzs(x17, s17);
5573 __ Fcvtzs(x18, s18);
5574 __ Fcvtzs(x19, s19);
5575 __ Fcvtzs(x20, s20);
5576 __ Fcvtzs(x21, s21);
5577 __ Fcvtzs(x22, s22);
5578 __ Fcvtzs(x23, s23);
5579 __ Fcvtzs(x24, d24);
5580 __ Fcvtzs(x25, d25);
5581 __ Fcvtzs(x26, d26);
5582 __ Fcvtzs(x27, d27);
5583 __ Fcvtzs(x28, d28);
5584 __ Fcvtzs(x29, d29);
5585 __ Fcvtzs(x30, d30);
5586 END();
5587
5588 RUN();
5589
5590 ASSERT_EQUAL_64(1, x0);
5591 ASSERT_EQUAL_64(1, x1);
5592 ASSERT_EQUAL_64(1, x2);
5593 ASSERT_EQUAL_64(0xffffffff, x3);
5594 ASSERT_EQUAL_64(0x7fffffff, x4);
5595 ASSERT_EQUAL_64(0x80000000, x5);
5596 ASSERT_EQUAL_64(0x7fffff80, x6);
5597 ASSERT_EQUAL_64(0x80000080, x7);
5598 ASSERT_EQUAL_64(1, x8);
5599 ASSERT_EQUAL_64(1, x9);
5600 ASSERT_EQUAL_64(1, x10);
5601 ASSERT_EQUAL_64(0xffffffff, x11);
5602 ASSERT_EQUAL_64(0x7fffffff, x12);
5603 ASSERT_EQUAL_64(0x80000000, x13);
5604 ASSERT_EQUAL_64(0x7ffffffe, x14);
5605 ASSERT_EQUAL_64(0x80000001, x15);
5606 ASSERT_EQUAL_64(1, x17);
5607 ASSERT_EQUAL_64(1, x18);
5608 ASSERT_EQUAL_64(0xffffffffffffffffUL, x19);
5609 ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20);
5610 ASSERT_EQUAL_64(0x8000000000000000UL, x21);
5611 ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
5612 ASSERT_EQUAL_64(0x8000008000000000UL, x23);
5613 ASSERT_EQUAL_64(1, x24);
5614 ASSERT_EQUAL_64(1, x25);
5615 ASSERT_EQUAL_64(0xffffffffffffffffUL, x26);
5616 ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27);
5617 ASSERT_EQUAL_64(0x8000000000000000UL, x28);
5618 ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
5619 ASSERT_EQUAL_64(0x8000000000000400UL, x30);
5620
5621 TEARDOWN();
5622}
5623
5624TEST(fcvtzu) {
5625 SETUP();
5626
5627 START();
5628 __ Fmov(s0, 1.0);
5629 __ Fmov(s1, 1.1);
5630 __ Fmov(s2, 1.5);
5631 __ Fmov(s3, -1.5);
5632 __ Fmov(s4, kFP32PositiveInfinity);
5633 __ Fmov(s5, kFP32NegativeInfinity);
5634 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
5635 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
5636 __ Fmov(d8, 1.0);
5637 __ Fmov(d9, 1.1);
5638 __ Fmov(d10, 1.5);
5639 __ Fmov(d11, -1.5);
5640 __ Fmov(d12, kFP64PositiveInfinity);
5641 __ Fmov(d13, kFP64NegativeInfinity);
5642 __ Fmov(d14, kWMaxInt - 1);
5643 __ Fmov(d15, kWMinInt + 1);
5644 __ Fmov(s17, 1.1);
5645 __ Fmov(s18, 1.5);
5646 __ Fmov(s19, -1.5);
5647 __ Fmov(s20, kFP32PositiveInfinity);
5648 __ Fmov(s21, kFP32NegativeInfinity);
5649 __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX.
5650 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
5651 __ Fmov(d24, 1.1);
5652 __ Fmov(d25, 1.5);
5653 __ Fmov(d26, -1.5);
5654 __ Fmov(d27, kFP64PositiveInfinity);
5655 __ Fmov(d28, kFP64NegativeInfinity);
5656 __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX.
5657 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
5658
5659 __ Fcvtzu(w0, s0);
5660 __ Fcvtzu(w1, s1);
5661 __ Fcvtzu(w2, s2);
5662 __ Fcvtzu(w3, s3);
5663 __ Fcvtzu(w4, s4);
5664 __ Fcvtzu(w5, s5);
5665 __ Fcvtzu(w6, s6);
5666 __ Fcvtzu(w7, s7);
5667 __ Fcvtzu(w8, d8);
5668 __ Fcvtzu(w9, d9);
5669 __ Fcvtzu(w10, d10);
5670 __ Fcvtzu(w11, d11);
5671 __ Fcvtzu(w12, d12);
5672 __ Fcvtzu(w13, d13);
5673 __ Fcvtzu(w14, d14);
5674 __ Fcvtzu(x17, s17);
5675 __ Fcvtzu(x18, s18);
5676 __ Fcvtzu(x19, s19);
5677 __ Fcvtzu(x20, s20);
5678 __ Fcvtzu(x21, s21);
5679 __ Fcvtzu(x22, s22);
5680 __ Fcvtzu(x23, s23);
5681 __ Fcvtzu(x24, d24);
5682 __ Fcvtzu(x25, d25);
5683 __ Fcvtzu(x26, d26);
5684 __ Fcvtzu(x27, d27);
5685 __ Fcvtzu(x28, d28);
5686 __ Fcvtzu(x29, d29);
5687 __ Fcvtzu(x30, d30);
5688 END();
5689
5690 RUN();
5691
5692 ASSERT_EQUAL_64(1, x0);
5693 ASSERT_EQUAL_64(1, x1);
5694 ASSERT_EQUAL_64(1, x2);
5695 ASSERT_EQUAL_64(0, x3);
5696 ASSERT_EQUAL_64(0xffffffff, x4);
5697 ASSERT_EQUAL_64(0, x5);
5698 ASSERT_EQUAL_64(0x7fffff80, x6);
5699 ASSERT_EQUAL_64(0, x7);
5700 ASSERT_EQUAL_64(1, x8);
5701 ASSERT_EQUAL_64(1, x9);
5702 ASSERT_EQUAL_64(1, x10);
5703 ASSERT_EQUAL_64(0, x11);
5704 ASSERT_EQUAL_64(0xffffffff, x12);
5705 ASSERT_EQUAL_64(0, x13);
5706 ASSERT_EQUAL_64(0x7ffffffe, x14);
5707 ASSERT_EQUAL_64(1, x17);
5708 ASSERT_EQUAL_64(1, x18);
5709 ASSERT_EQUAL_64(0x0UL, x19);
5710 ASSERT_EQUAL_64(0xffffffffffffffffUL, x20);
5711 ASSERT_EQUAL_64(0x0UL, x21);
5712 ASSERT_EQUAL_64(0x7fffff8000000000UL, x22);
5713 ASSERT_EQUAL_64(0x0UL, x23);
5714 ASSERT_EQUAL_64(1, x24);
5715 ASSERT_EQUAL_64(1, x25);
5716 ASSERT_EQUAL_64(0x0UL, x26);
5717 ASSERT_EQUAL_64(0xffffffffffffffffUL, x27);
5718 ASSERT_EQUAL_64(0x0UL, x28);
5719 ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29);
5720 ASSERT_EQUAL_64(0x0UL, x30);
5721
5722 TEARDOWN();
5723}
5724
5725
armvixl578645f2013-08-15 17:21:42 +01005726// Test that scvtf and ucvtf can convert the 64-bit input into the expected
5727// value. All possible values of 'fbits' are tested. The expected value is
5728// modified accordingly in each case.
5729//
5730// The expected value is specified as the bit encoding of the expected double
5731// produced by scvtf (expected_scvtf_bits) as well as ucvtf
5732// (expected_ucvtf_bits).
5733//
5734// Where the input value is representable by int32_t or uint32_t, conversions
5735// from W registers will also be tested.
5736static void TestUScvtfHelper(uint64_t in,
5737 uint64_t expected_scvtf_bits,
5738 uint64_t expected_ucvtf_bits) {
5739 uint64_t u64 = in;
5740 uint32_t u32 = u64 & 0xffffffff;
5741 int64_t s64 = static_cast<int64_t>(in);
5742 int32_t s32 = s64 & 0x7fffffff;
5743
5744 bool cvtf_s32 = (s64 == s32);
5745 bool cvtf_u32 = (u64 == u32);
5746
5747 double results_scvtf_x[65];
5748 double results_ucvtf_x[65];
5749 double results_scvtf_w[33];
5750 double results_ucvtf_w[33];
5751
armvixlad96eda2013-06-14 11:42:37 +01005752 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01005753 START();
armvixlad96eda2013-06-14 11:42:37 +01005754
armvixl578645f2013-08-15 17:21:42 +01005755 __ Mov(x0, reinterpret_cast<int64_t>(results_scvtf_x));
5756 __ Mov(x1, reinterpret_cast<int64_t>(results_ucvtf_x));
5757 __ Mov(x2, reinterpret_cast<int64_t>(results_scvtf_w));
5758 __ Mov(x3, reinterpret_cast<int64_t>(results_ucvtf_w));
5759
5760 __ Mov(x10, s64);
5761
5762 // Corrupt the top word, in case it is accidentally used during W-register
5763 // conversions.
5764 __ Mov(x11, 0x5555555555555555);
5765 __ Bfi(x11, x10, 0, kWRegSize);
5766
5767 // Test integer conversions.
5768 __ Scvtf(d0, x10);
5769 __ Ucvtf(d1, x10);
5770 __ Scvtf(d2, w11);
5771 __ Ucvtf(d3, w11);
5772 __ Str(d0, MemOperand(x0));
5773 __ Str(d1, MemOperand(x1));
5774 __ Str(d2, MemOperand(x2));
5775 __ Str(d3, MemOperand(x3));
5776
5777 // Test all possible values of fbits.
5778 for (int fbits = 1; fbits <= 32; fbits++) {
5779 __ Scvtf(d0, x10, fbits);
5780 __ Ucvtf(d1, x10, fbits);
5781 __ Scvtf(d2, w11, fbits);
5782 __ Ucvtf(d3, w11, fbits);
5783 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
5784 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
5785 __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes));
5786 __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes));
5787 }
5788
5789 // Conversions from W registers can only handle fbits values <= 32, so just
5790 // test conversions from X registers for 32 < fbits <= 64.
5791 for (int fbits = 33; fbits <= 64; fbits++) {
5792 __ Scvtf(d0, x10, fbits);
5793 __ Ucvtf(d1, x10, fbits);
5794 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
5795 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
5796 }
5797
5798 END();
armvixlad96eda2013-06-14 11:42:37 +01005799 RUN();
5800
armvixl578645f2013-08-15 17:21:42 +01005801 // Check the results.
5802 double expected_scvtf_base = rawbits_to_double(expected_scvtf_bits);
5803 double expected_ucvtf_base = rawbits_to_double(expected_ucvtf_bits);
5804
5805 for (int fbits = 0; fbits <= 32; fbits++) {
5806 double expected_scvtf = expected_scvtf_base / pow(2, fbits);
5807 double expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
5808 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
5809 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
5810 if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
5811 if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
5812 }
5813 for (int fbits = 33; fbits <= 64; fbits++) {
5814 double expected_scvtf = expected_scvtf_base / pow(2, fbits);
5815 double expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
5816 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
5817 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
5818 }
armvixlad96eda2013-06-14 11:42:37 +01005819
5820 TEARDOWN();
5821}
5822
5823
armvixl578645f2013-08-15 17:21:42 +01005824TEST(scvtf_ucvtf_double) {
5825 // Simple conversions of positive numbers which require no rounding; the
5826 // results should not depened on the rounding mode, and ucvtf and scvtf should
5827 // produce the same result.
5828 TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000);
5829 TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000);
5830 TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000);
5831 TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000);
5832 TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000);
5833 // Test mantissa extremities.
5834 TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001);
5835 // The largest int32_t that fits in a double.
5836 TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000);
5837 // Values that would be negative if treated as an int32_t.
5838 TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000);
5839 TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000);
5840 TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000);
5841 // The largest int64_t that fits in a double.
5842 TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff);
5843 // Check for bit pattern reproduction.
5844 TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde);
5845 TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000);
5846
5847 // Simple conversions of negative int64_t values. These require no rounding,
5848 // and the results should not depend on the rounding mode.
5849 TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000);
5850 TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000);
5851 TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000);
5852
5853 // Conversions which require rounding.
5854 TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000);
5855 TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000);
5856 TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000);
5857 TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001);
5858 TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001);
5859 TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001);
5860 TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002);
5861 TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002);
5862 TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002);
5863 TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002);
5864 TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002);
5865 TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003);
5866 TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003);
5867 // Check rounding of negative int64_t values (and large uint64_t values).
5868 TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000);
5869 TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000);
5870 TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000);
5871 TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000);
5872 TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000);
5873 TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001);
5874 TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001);
5875 TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001);
5876 TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001);
5877 TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001);
5878 TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001);
5879 TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001);
5880 TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002);
5881 // Round up to produce a result that's too big for the input to represent.
5882 TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000);
5883 TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000);
5884 TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000);
5885 TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000);
5886}
5887
5888
5889// The same as TestUScvtfHelper, but convert to floats.
5890static void TestUScvtf32Helper(uint64_t in,
5891 uint32_t expected_scvtf_bits,
5892 uint32_t expected_ucvtf_bits) {
5893 uint64_t u64 = in;
5894 uint32_t u32 = u64 & 0xffffffff;
5895 int64_t s64 = static_cast<int64_t>(in);
5896 int32_t s32 = s64 & 0x7fffffff;
5897
5898 bool cvtf_s32 = (s64 == s32);
5899 bool cvtf_u32 = (u64 == u32);
5900
5901 float results_scvtf_x[65];
5902 float results_ucvtf_x[65];
5903 float results_scvtf_w[33];
5904 float results_ucvtf_w[33];
5905
armvixlad96eda2013-06-14 11:42:37 +01005906 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01005907 START();
armvixlad96eda2013-06-14 11:42:37 +01005908
armvixl578645f2013-08-15 17:21:42 +01005909 __ Mov(x0, reinterpret_cast<int64_t>(results_scvtf_x));
5910 __ Mov(x1, reinterpret_cast<int64_t>(results_ucvtf_x));
5911 __ Mov(x2, reinterpret_cast<int64_t>(results_scvtf_w));
5912 __ Mov(x3, reinterpret_cast<int64_t>(results_ucvtf_w));
5913
5914 __ Mov(x10, s64);
5915
5916 // Corrupt the top word, in case it is accidentally used during W-register
5917 // conversions.
5918 __ Mov(x11, 0x5555555555555555);
5919 __ Bfi(x11, x10, 0, kWRegSize);
5920
5921 // Test integer conversions.
5922 __ Scvtf(s0, x10);
5923 __ Ucvtf(s1, x10);
5924 __ Scvtf(s2, w11);
5925 __ Ucvtf(s3, w11);
5926 __ Str(s0, MemOperand(x0));
5927 __ Str(s1, MemOperand(x1));
5928 __ Str(s2, MemOperand(x2));
5929 __ Str(s3, MemOperand(x3));
5930
5931 // Test all possible values of fbits.
5932 for (int fbits = 1; fbits <= 32; fbits++) {
5933 __ Scvtf(s0, x10, fbits);
5934 __ Ucvtf(s1, x10, fbits);
5935 __ Scvtf(s2, w11, fbits);
5936 __ Ucvtf(s3, w11, fbits);
5937 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
5938 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
5939 __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes));
5940 __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes));
5941 }
5942
5943 // Conversions from W registers can only handle fbits values <= 32, so just
5944 // test conversions from X registers for 32 < fbits <= 64.
5945 for (int fbits = 33; fbits <= 64; fbits++) {
5946 __ Scvtf(s0, x10, fbits);
5947 __ Ucvtf(s1, x10, fbits);
5948 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
5949 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
5950 }
armvixlad96eda2013-06-14 11:42:37 +01005951
5952 END();
armvixlad96eda2013-06-14 11:42:37 +01005953 RUN();
5954
armvixl578645f2013-08-15 17:21:42 +01005955 // Check the results.
5956 float expected_scvtf_base = rawbits_to_float(expected_scvtf_bits);
5957 float expected_ucvtf_base = rawbits_to_float(expected_ucvtf_bits);
armvixlad96eda2013-06-14 11:42:37 +01005958
armvixl578645f2013-08-15 17:21:42 +01005959 for (int fbits = 0; fbits <= 32; fbits++) {
5960 float expected_scvtf = expected_scvtf_base / pow(2, fbits);
5961 float expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
5962 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
5963 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
5964 if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
5965 if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
5966 break;
5967 }
5968 for (int fbits = 33; fbits <= 64; fbits++) {
5969 break;
5970 float expected_scvtf = expected_scvtf_base / pow(2, fbits);
5971 float expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
5972 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
5973 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
5974 }
armvixlad96eda2013-06-14 11:42:37 +01005975
5976 TEARDOWN();
5977}
5978
5979
armvixl578645f2013-08-15 17:21:42 +01005980TEST(scvtf_ucvtf_float) {
5981 // Simple conversions of positive numbers which require no rounding; the
5982 // results should not depened on the rounding mode, and ucvtf and scvtf should
5983 // produce the same result.
5984 TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000);
5985 TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000);
5986 TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000);
5987 TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000);
5988 TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000);
5989 // Test mantissa extremities.
5990 TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001);
5991 TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001);
5992 // The largest int32_t that fits in a float.
5993 TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff);
5994 // Values that would be negative if treated as an int32_t.
5995 TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff);
5996 TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000);
5997 TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001);
5998 // The largest int64_t that fits in a float.
5999 TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff);
6000 // Check for bit pattern reproduction.
6001 TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543);
6002
6003 // Simple conversions of negative int64_t values. These require no rounding,
6004 // and the results should not depend on the rounding mode.
6005 TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc);
6006 TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000);
6007
6008 // Conversions which require rounding.
6009 TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000);
6010 TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000);
6011 TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000);
6012 TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001);
6013 TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001);
6014 TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001);
6015 TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002);
6016 TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002);
6017 TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002);
6018 TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002);
6019 TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002);
6020 TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003);
6021 TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003);
6022 // Check rounding of negative int64_t values (and large uint64_t values).
6023 TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000);
6024 TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000);
6025 TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000);
6026 TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000);
6027 TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000);
6028 TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001);
6029 TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001);
6030 TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001);
6031 TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001);
6032 TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001);
6033 TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001);
6034 TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001);
6035 TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002);
6036 // Round up to produce a result that's too big for the input to represent.
6037 TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000);
6038 TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000);
6039 TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000);
6040 TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000);
6041 TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000);
6042 TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000);
6043 TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000);
6044 TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000);
6045}
6046
6047
armvixlad96eda2013-06-14 11:42:37 +01006048TEST(system_mrs) {
6049 SETUP();
6050
6051 START();
6052 __ Mov(w0, 0);
6053 __ Mov(w1, 1);
6054 __ Mov(w2, 0x80000000);
6055
6056 // Set the Z and C flags.
6057 __ Cmp(w0, w0);
6058 __ Mrs(x3, NZCV);
6059
6060 // Set the N flag.
6061 __ Cmp(w0, w1);
6062 __ Mrs(x4, NZCV);
6063
6064 // Set the Z, C and V flags.
6065 __ Add(w0, w2, w2, SetFlags);
6066 __ Mrs(x5, NZCV);
armvixl578645f2013-08-15 17:21:42 +01006067
6068 // Read the default FPCR.
6069 __ Mrs(x6, FPCR);
armvixlad96eda2013-06-14 11:42:37 +01006070 END();
6071
6072 RUN();
6073
armvixl578645f2013-08-15 17:21:42 +01006074 // NZCV
armvixlad96eda2013-06-14 11:42:37 +01006075 ASSERT_EQUAL_32(ZCFlag, w3);
6076 ASSERT_EQUAL_32(NFlag, w4);
6077 ASSERT_EQUAL_32(ZCVFlag, w5);
6078
armvixl578645f2013-08-15 17:21:42 +01006079 // FPCR
6080 // The default FPCR on Linux-based platforms is 0.
6081 ASSERT_EQUAL_32(0, w6);
6082
armvixlad96eda2013-06-14 11:42:37 +01006083 TEARDOWN();
6084}
6085
6086
6087TEST(system_msr) {
armvixl578645f2013-08-15 17:21:42 +01006088 // All FPCR fields that must be implemented: AHP, DN, FZ, RMode
6089 const uint64_t fpcr_core = 0x07c00000;
6090
6091 // All FPCR fields (including fields which may be read-as-zero):
6092 // Stride, Len
6093 // IDE, IXE, UFE, OFE, DZE, IOE
6094 const uint64_t fpcr_all = fpcr_core | 0x00379f00;
6095
armvixlad96eda2013-06-14 11:42:37 +01006096 SETUP();
6097
6098 START();
6099 __ Mov(w0, 0);
6100 __ Mov(w1, 0x7fffffff);
6101
6102 __ Mov(x7, 0);
6103
6104 __ Mov(x10, NVFlag);
6105 __ Cmp(w0, w0); // Set Z and C.
6106 __ Msr(NZCV, x10); // Set N and V.
6107 // The Msr should have overwritten every flag set by the Cmp.
6108 __ Cinc(x7, x7, mi); // N
6109 __ Cinc(x7, x7, ne); // !Z
6110 __ Cinc(x7, x7, lo); // !C
6111 __ Cinc(x7, x7, vs); // V
6112
6113 __ Mov(x10, ZCFlag);
6114 __ Cmn(w1, w1); // Set N and V.
6115 __ Msr(NZCV, x10); // Set Z and C.
6116 // The Msr should have overwritten every flag set by the Cmn.
6117 __ Cinc(x7, x7, pl); // !N
6118 __ Cinc(x7, x7, eq); // Z
6119 __ Cinc(x7, x7, hs); // C
6120 __ Cinc(x7, x7, vc); // !V
6121
armvixl578645f2013-08-15 17:21:42 +01006122 // All core FPCR fields must be writable.
6123 __ Mov(x8, fpcr_core);
6124 __ Msr(FPCR, x8);
6125 __ Mrs(x8, FPCR);
6126
6127 // All FPCR fields, including optional ones. This part of the test doesn't
6128 // achieve much other than ensuring that supported fields can be cleared by
6129 // the next test.
6130 __ Mov(x9, fpcr_all);
6131 __ Msr(FPCR, x9);
6132 __ Mrs(x9, FPCR);
6133 __ And(x9, x9, fpcr_core);
6134
6135 // The undefined bits must ignore writes.
6136 // It's conceivable that a future version of the architecture could use these
6137 // fields (making this test fail), but in the meantime this is a useful test
6138 // for the simulator.
6139 __ Mov(x10, ~fpcr_all);
6140 __ Msr(FPCR, x10);
6141 __ Mrs(x10, FPCR);
6142
armvixlad96eda2013-06-14 11:42:37 +01006143 END();
6144
6145 RUN();
6146
6147 // We should have incremented x7 (from 0) exactly 8 times.
6148 ASSERT_EQUAL_64(8, x7);
6149
armvixl578645f2013-08-15 17:21:42 +01006150 ASSERT_EQUAL_64(fpcr_core, x8);
6151 ASSERT_EQUAL_64(fpcr_core, x9);
6152 ASSERT_EQUAL_64(0, x10);
6153
armvixlad96eda2013-06-14 11:42:37 +01006154 TEARDOWN();
6155}
6156
6157
6158TEST(system_nop) {
6159 SETUP();
6160 RegisterDump before;
6161
6162 START();
6163 before.Dump(&masm);
6164 __ Nop();
6165 END();
6166
6167 RUN();
6168
6169 ASSERT_EQUAL_REGISTERS(before);
6170 ASSERT_EQUAL_NZCV(before.flags_nzcv());
6171
6172 TEARDOWN();
6173}
6174
6175
6176TEST(zero_dest) {
6177 SETUP();
6178 RegisterDump before;
6179
6180 START();
6181 // Preserve the stack pointer, in case we clobber it.
6182 __ Mov(x30, sp);
6183 // Initialize the other registers used in this test.
6184 uint64_t literal_base = 0x0100001000100101UL;
6185 __ Mov(x0, 0);
6186 __ Mov(x1, literal_base);
6187 for (unsigned i = 2; i < x30.code(); i++) {
6188 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
6189 }
6190 before.Dump(&masm);
6191
6192 // All of these instructions should be NOPs in these forms, but have
6193 // alternate forms which can write into the stack pointer.
6194 __ add(xzr, x0, x1);
6195 __ add(xzr, x1, xzr);
6196 __ add(xzr, xzr, x1);
6197
6198 __ and_(xzr, x0, x2);
6199 __ and_(xzr, x2, xzr);
6200 __ and_(xzr, xzr, x2);
6201
6202 __ bic(xzr, x0, x3);
6203 __ bic(xzr, x3, xzr);
6204 __ bic(xzr, xzr, x3);
6205
6206 __ eon(xzr, x0, x4);
6207 __ eon(xzr, x4, xzr);
6208 __ eon(xzr, xzr, x4);
6209
6210 __ eor(xzr, x0, x5);
6211 __ eor(xzr, x5, xzr);
6212 __ eor(xzr, xzr, x5);
6213
6214 __ orr(xzr, x0, x6);
6215 __ orr(xzr, x6, xzr);
6216 __ orr(xzr, xzr, x6);
6217
6218 __ sub(xzr, x0, x7);
6219 __ sub(xzr, x7, xzr);
6220 __ sub(xzr, xzr, x7);
6221
6222 // Swap the saved stack pointer with the real one. If sp was written
6223 // during the test, it will show up in x30. This is done because the test
6224 // framework assumes that sp will be valid at the end of the test.
6225 __ Mov(x29, x30);
6226 __ Mov(x30, sp);
6227 __ Mov(sp, x29);
6228 // We used x29 as a scratch register, so reset it to make sure it doesn't
6229 // trigger a test failure.
6230 __ Add(x29, x28, x1);
6231 END();
6232
6233 RUN();
6234
6235 ASSERT_EQUAL_REGISTERS(before);
6236 ASSERT_EQUAL_NZCV(before.flags_nzcv());
6237
6238 TEARDOWN();
6239}
6240
6241
6242TEST(zero_dest_setflags) {
6243 SETUP();
6244 RegisterDump before;
6245
6246 START();
6247 // Preserve the stack pointer, in case we clobber it.
6248 __ Mov(x30, sp);
6249 // Initialize the other registers used in this test.
6250 uint64_t literal_base = 0x0100001000100101UL;
6251 __ Mov(x0, 0);
6252 __ Mov(x1, literal_base);
6253 for (int i = 2; i < 30; i++) {
6254 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
6255 }
6256 before.Dump(&masm);
6257
6258 // All of these instructions should only write to the flags in these forms,
6259 // but have alternate forms which can write into the stack pointer.
6260 __ add(xzr, x0, Operand(x1, UXTX), SetFlags);
6261 __ add(xzr, x1, Operand(xzr, UXTX), SetFlags);
6262 __ add(xzr, x1, 1234, SetFlags);
6263 __ add(xzr, x0, x1, SetFlags);
6264 __ add(xzr, x1, xzr, SetFlags);
6265 __ add(xzr, xzr, x1, SetFlags);
6266
6267 __ and_(xzr, x2, ~0xf, SetFlags);
6268 __ and_(xzr, xzr, ~0xf, SetFlags);
6269 __ and_(xzr, x0, x2, SetFlags);
6270 __ and_(xzr, x2, xzr, SetFlags);
6271 __ and_(xzr, xzr, x2, SetFlags);
6272
6273 __ bic(xzr, x3, ~0xf, SetFlags);
6274 __ bic(xzr, xzr, ~0xf, SetFlags);
6275 __ bic(xzr, x0, x3, SetFlags);
6276 __ bic(xzr, x3, xzr, SetFlags);
6277 __ bic(xzr, xzr, x3, SetFlags);
6278
6279 __ sub(xzr, x0, Operand(x3, UXTX), SetFlags);
6280 __ sub(xzr, x3, Operand(xzr, UXTX), SetFlags);
6281 __ sub(xzr, x3, 1234, SetFlags);
6282 __ sub(xzr, x0, x3, SetFlags);
6283 __ sub(xzr, x3, xzr, SetFlags);
6284 __ sub(xzr, xzr, x3, SetFlags);
6285
6286 // Swap the saved stack pointer with the real one. If sp was written
6287 // during the test, it will show up in x30. This is done because the test
6288 // framework assumes that sp will be valid at the end of the test.
6289 __ Mov(x29, x30);
6290 __ Mov(x30, sp);
6291 __ Mov(sp, x29);
6292 // We used x29 as a scratch register, so reset it to make sure it doesn't
6293 // trigger a test failure.
6294 __ Add(x29, x28, x1);
6295 END();
6296
6297 RUN();
6298
6299 ASSERT_EQUAL_REGISTERS(before);
6300
6301 TEARDOWN();
6302}
6303
6304
6305TEST(register_bit) {
6306 // No code generation takes place in this test, so no need to setup and
6307 // teardown.
6308
6309 // Simple tests.
6310 assert(x0.Bit() == (1UL << 0));
6311 assert(x1.Bit() == (1UL << 1));
6312 assert(x10.Bit() == (1UL << 10));
6313
6314 // AAPCS64 definitions.
6315 assert(lr.Bit() == (1UL << kLinkRegCode));
6316
6317 // Fixed (hardware) definitions.
6318 assert(xzr.Bit() == (1UL << kZeroRegCode));
6319
6320 // Internal ABI definitions.
6321 assert(sp.Bit() == (1UL << kSPRegInternalCode));
6322 assert(sp.Bit() != xzr.Bit());
6323
6324 // xn.Bit() == wn.Bit() at all times, for the same n.
6325 assert(x0.Bit() == w0.Bit());
6326 assert(x1.Bit() == w1.Bit());
6327 assert(x10.Bit() == w10.Bit());
6328 assert(xzr.Bit() == wzr.Bit());
6329 assert(sp.Bit() == wsp.Bit());
6330}
6331
6332
6333TEST(stack_pointer_override) {
6334 // This test generates some stack maintenance code, but the test only checks
6335 // the reported state.
6336 SETUP();
6337 START();
6338
6339 // The default stack pointer in VIXL is sp.
6340 assert(sp.Is(__ StackPointer()));
6341 __ SetStackPointer(x0);
6342 assert(x0.Is(__ StackPointer()));
6343 __ SetStackPointer(x28);
6344 assert(x28.Is(__ StackPointer()));
6345 __ SetStackPointer(sp);
6346 assert(sp.Is(__ StackPointer()));
6347
6348 END();
6349 RUN();
6350 TEARDOWN();
6351}
6352
6353
6354TEST(peek_poke_simple) {
6355 SETUP();
6356 START();
6357
6358 static const RegList x0_to_x3 = x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit();
6359 static const RegList x10_to_x13 = x10.Bit() | x11.Bit() |
6360 x12.Bit() | x13.Bit();
6361
6362 // The literal base is chosen to have two useful properties:
6363 // * When multiplied by small values (such as a register index), this value
6364 // is clearly readable in the result.
6365 // * The value is not formed from repeating fixed-size smaller values, so it
6366 // can be used to detect endianness-related errors.
6367 uint64_t literal_base = 0x0100001000100101UL;
6368
6369 // Initialize the registers.
6370 __ Mov(x0, literal_base);
6371 __ Add(x1, x0, x0);
6372 __ Add(x2, x1, x0);
6373 __ Add(x3, x2, x0);
6374
6375 __ Claim(32);
6376
6377 // Simple exchange.
6378 // After this test:
6379 // x0-x3 should be unchanged.
6380 // w10-w13 should contain the lower words of x0-x3.
6381 __ Poke(x0, 0);
6382 __ Poke(x1, 8);
6383 __ Poke(x2, 16);
6384 __ Poke(x3, 24);
6385 Clobber(&masm, x0_to_x3);
6386 __ Peek(x0, 0);
6387 __ Peek(x1, 8);
6388 __ Peek(x2, 16);
6389 __ Peek(x3, 24);
6390
6391 __ Poke(w0, 0);
6392 __ Poke(w1, 4);
6393 __ Poke(w2, 8);
6394 __ Poke(w3, 12);
6395 Clobber(&masm, x10_to_x13);
6396 __ Peek(w10, 0);
6397 __ Peek(w11, 4);
6398 __ Peek(w12, 8);
6399 __ Peek(w13, 12);
6400
6401 __ Drop(32);
6402
6403 END();
6404 RUN();
6405
6406 ASSERT_EQUAL_64(literal_base * 1, x0);
6407 ASSERT_EQUAL_64(literal_base * 2, x1);
6408 ASSERT_EQUAL_64(literal_base * 3, x2);
6409 ASSERT_EQUAL_64(literal_base * 4, x3);
6410
6411 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
6412 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
6413 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
6414 ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
6415
6416 TEARDOWN();
6417}
6418
6419
6420TEST(peek_poke_unaligned) {
6421 SETUP();
6422 START();
6423
6424 // The literal base is chosen to have two useful properties:
6425 // * When multiplied by small values (such as a register index), this value
6426 // is clearly readable in the result.
6427 // * The value is not formed from repeating fixed-size smaller values, so it
6428 // can be used to detect endianness-related errors.
6429 uint64_t literal_base = 0x0100001000100101UL;
6430
6431 // Initialize the registers.
6432 __ Mov(x0, literal_base);
6433 __ Add(x1, x0, x0);
6434 __ Add(x2, x1, x0);
6435 __ Add(x3, x2, x0);
6436 __ Add(x4, x3, x0);
6437 __ Add(x5, x4, x0);
6438 __ Add(x6, x5, x0);
6439
6440 __ Claim(32);
6441
6442 // Unaligned exchanges.
6443 // After this test:
6444 // x0-x6 should be unchanged.
6445 // w10-w12 should contain the lower words of x0-x2.
6446 __ Poke(x0, 1);
6447 Clobber(&masm, x0.Bit());
6448 __ Peek(x0, 1);
6449 __ Poke(x1, 2);
6450 Clobber(&masm, x1.Bit());
6451 __ Peek(x1, 2);
6452 __ Poke(x2, 3);
6453 Clobber(&masm, x2.Bit());
6454 __ Peek(x2, 3);
6455 __ Poke(x3, 4);
6456 Clobber(&masm, x3.Bit());
6457 __ Peek(x3, 4);
6458 __ Poke(x4, 5);
6459 Clobber(&masm, x4.Bit());
6460 __ Peek(x4, 5);
6461 __ Poke(x5, 6);
6462 Clobber(&masm, x5.Bit());
6463 __ Peek(x5, 6);
6464 __ Poke(x6, 7);
6465 Clobber(&masm, x6.Bit());
6466 __ Peek(x6, 7);
6467
6468 __ Poke(w0, 1);
6469 Clobber(&masm, w10.Bit());
6470 __ Peek(w10, 1);
6471 __ Poke(w1, 2);
6472 Clobber(&masm, w11.Bit());
6473 __ Peek(w11, 2);
6474 __ Poke(w2, 3);
6475 Clobber(&masm, w12.Bit());
6476 __ Peek(w12, 3);
6477
6478 __ Drop(32);
6479
6480 END();
6481 RUN();
6482
6483 ASSERT_EQUAL_64(literal_base * 1, x0);
6484 ASSERT_EQUAL_64(literal_base * 2, x1);
6485 ASSERT_EQUAL_64(literal_base * 3, x2);
6486 ASSERT_EQUAL_64(literal_base * 4, x3);
6487 ASSERT_EQUAL_64(literal_base * 5, x4);
6488 ASSERT_EQUAL_64(literal_base * 6, x5);
6489 ASSERT_EQUAL_64(literal_base * 7, x6);
6490
6491 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
6492 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
6493 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
6494
6495 TEARDOWN();
6496}
6497
6498
6499TEST(peek_poke_endianness) {
6500 SETUP();
6501 START();
6502
6503 // The literal base is chosen to have two useful properties:
6504 // * When multiplied by small values (such as a register index), this value
6505 // is clearly readable in the result.
6506 // * The value is not formed from repeating fixed-size smaller values, so it
6507 // can be used to detect endianness-related errors.
6508 uint64_t literal_base = 0x0100001000100101UL;
6509
6510 // Initialize the registers.
6511 __ Mov(x0, literal_base);
6512 __ Add(x1, x0, x0);
6513
6514 __ Claim(32);
6515
6516 // Endianness tests.
6517 // After this section:
6518 // x4 should match x0[31:0]:x0[63:32]
6519 // w5 should match w1[15:0]:w1[31:16]
6520 __ Poke(x0, 0);
6521 __ Poke(x0, 8);
6522 __ Peek(x4, 4);
6523
6524 __ Poke(w1, 0);
6525 __ Poke(w1, 4);
6526 __ Peek(w5, 2);
6527
6528 __ Drop(32);
6529
6530 END();
6531 RUN();
6532
6533 uint64_t x0_expected = literal_base * 1;
6534 uint64_t x1_expected = literal_base * 2;
6535 uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32);
6536 uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) |
6537 ((x1_expected >> 16) & 0x0000ffff);
6538
6539 ASSERT_EQUAL_64(x0_expected, x0);
6540 ASSERT_EQUAL_64(x1_expected, x1);
6541 ASSERT_EQUAL_64(x4_expected, x4);
6542 ASSERT_EQUAL_64(x5_expected, x5);
6543
6544 TEARDOWN();
6545}
6546
6547
6548TEST(peek_poke_mixed) {
6549 SETUP();
6550 START();
6551
6552 // The literal base is chosen to have two useful properties:
6553 // * When multiplied by small values (such as a register index), this value
6554 // is clearly readable in the result.
6555 // * The value is not formed from repeating fixed-size smaller values, so it
6556 // can be used to detect endianness-related errors.
6557 uint64_t literal_base = 0x0100001000100101UL;
6558
6559 // Initialize the registers.
6560 __ Mov(x0, literal_base);
6561 __ Add(x1, x0, x0);
6562 __ Add(x2, x1, x0);
6563 __ Add(x3, x2, x0);
6564
6565 __ Claim(32);
6566
6567 // Mix with other stack operations.
6568 // After this section:
6569 // x0-x3 should be unchanged.
6570 // x6 should match x1[31:0]:x0[63:32]
6571 // w7 should match x1[15:0]:x0[63:48]
6572 __ Poke(x1, 8);
6573 __ Poke(x0, 0);
6574 {
6575 ASSERT(__ StackPointer().Is(sp));
6576 __ Mov(x4, __ StackPointer());
6577 __ SetStackPointer(x4);
6578
6579 __ Poke(wzr, 0); // Clobber the space we're about to drop.
6580 __ Drop(4);
6581 __ Peek(x6, 0);
6582 __ Claim(8);
6583 __ Peek(w7, 10);
6584 __ Poke(x3, 28);
6585 __ Poke(xzr, 0); // Clobber the space we're about to drop.
6586 __ Drop(8);
6587 __ Poke(x2, 12);
6588 __ Push(w0);
6589
6590 __ Mov(sp, __ StackPointer());
6591 __ SetStackPointer(sp);
6592 }
6593
6594 __ Pop(x0, x1, x2, x3);
6595
6596 END();
6597 RUN();
6598
6599 uint64_t x0_expected = literal_base * 1;
6600 uint64_t x1_expected = literal_base * 2;
6601 uint64_t x2_expected = literal_base * 3;
6602 uint64_t x3_expected = literal_base * 4;
6603 uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32);
6604 uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) |
6605 ((x0_expected >> 48) & 0x0000ffff);
6606
6607 ASSERT_EQUAL_64(x0_expected, x0);
6608 ASSERT_EQUAL_64(x1_expected, x1);
6609 ASSERT_EQUAL_64(x2_expected, x2);
6610 ASSERT_EQUAL_64(x3_expected, x3);
6611 ASSERT_EQUAL_64(x6_expected, x6);
6612 ASSERT_EQUAL_64(x7_expected, x7);
6613
6614 TEARDOWN();
6615}
6616
6617
6618// This enum is used only as an argument to the push-pop test helpers.
6619enum PushPopMethod {
6620 // Push or Pop using the Push and Pop methods, with blocks of up to four
6621 // registers. (Smaller blocks will be used if necessary.)
6622 PushPopByFour,
6623
6624 // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers.
6625 PushPopRegList
6626};
6627
6628
6629// The maximum number of registers that can be used by the PushPopXReg* tests,
6630// where a reg_count field is provided.
6631static int const kPushPopXRegMaxRegCount = -1;
6632
6633// Test a simple push-pop pattern:
6634// * Claim <claim> bytes to set the stack alignment.
6635// * Push <reg_count> registers with size <reg_size>.
6636// * Clobber the register contents.
6637// * Pop <reg_count> registers to restore the original contents.
6638// * Drop <claim> bytes to restore the original stack pointer.
6639//
6640// Different push and pop methods can be specified independently to test for
6641// proper word-endian behaviour.
6642static void PushPopXRegSimpleHelper(int reg_count,
6643 int claim,
6644 int reg_size,
6645 PushPopMethod push_method,
6646 PushPopMethod pop_method) {
6647 SETUP();
6648
6649 START();
6650
6651 // Arbitrarily pick a register to use as a stack pointer.
6652 const Register& stack_pointer = x20;
6653 const RegList allowed = ~stack_pointer.Bit();
6654 if (reg_count == kPushPopXRegMaxRegCount) {
6655 reg_count = CountSetBits(allowed, kNumberOfRegisters);
6656 }
6657 // Work out which registers to use, based on reg_size.
6658 Register r[kNumberOfRegisters];
6659 Register x[kNumberOfRegisters];
6660 RegList list = PopulateRegisterArray(NULL, x, r, reg_size, reg_count,
6661 allowed);
6662
6663 // The literal base is chosen to have two useful properties:
6664 // * When multiplied by small values (such as a register index), this value
6665 // is clearly readable in the result.
6666 // * The value is not formed from repeating fixed-size smaller values, so it
6667 // can be used to detect endianness-related errors.
6668 uint64_t literal_base = 0x0100001000100101UL;
6669
6670 {
6671 ASSERT(__ StackPointer().Is(sp));
6672 __ Mov(stack_pointer, __ StackPointer());
6673 __ SetStackPointer(stack_pointer);
6674
6675 int i;
6676
6677 // Initialize the registers.
6678 for (i = 0; i < reg_count; i++) {
6679 // Always write into the X register, to ensure that the upper word is
6680 // properly ignored by Push when testing W registers.
6681 __ Mov(x[i], literal_base * i);
6682 }
6683
6684 // Claim memory first, as requested.
6685 __ Claim(claim);
6686
6687 switch (push_method) {
6688 case PushPopByFour:
6689 // Push high-numbered registers first (to the highest addresses).
6690 for (i = reg_count; i >= 4; i -= 4) {
6691 __ Push(r[i-1], r[i-2], r[i-3], r[i-4]);
6692 }
6693 // Finish off the leftovers.
6694 switch (i) {
6695 case 3: __ Push(r[2], r[1], r[0]); break;
6696 case 2: __ Push(r[1], r[0]); break;
6697 case 1: __ Push(r[0]); break;
6698 default: ASSERT(i == 0); break;
6699 }
6700 break;
6701 case PushPopRegList:
6702 __ PushSizeRegList(list, reg_size);
6703 break;
6704 }
6705
6706 // Clobber all the registers, to ensure that they get repopulated by Pop.
6707 Clobber(&masm, list);
6708
6709 switch (pop_method) {
6710 case PushPopByFour:
6711 // Pop low-numbered registers first (from the lowest addresses).
6712 for (i = 0; i <= (reg_count-4); i += 4) {
6713 __ Pop(r[i], r[i+1], r[i+2], r[i+3]);
6714 }
6715 // Finish off the leftovers.
6716 switch (reg_count - i) {
6717 case 3: __ Pop(r[i], r[i+1], r[i+2]); break;
6718 case 2: __ Pop(r[i], r[i+1]); break;
6719 case 1: __ Pop(r[i]); break;
6720 default: ASSERT(i == reg_count); break;
6721 }
6722 break;
6723 case PushPopRegList:
6724 __ PopSizeRegList(list, reg_size);
6725 break;
6726 }
6727
6728 // Drop memory to restore stack_pointer.
6729 __ Drop(claim);
6730
6731 __ Mov(sp, __ StackPointer());
6732 __ SetStackPointer(sp);
6733 }
6734
6735 END();
6736
6737 RUN();
6738
6739 // Check that the register contents were preserved.
6740 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
6741 // that the upper word was properly cleared by Pop.
6742 literal_base &= (0xffffffffffffffffUL >> (64-reg_size));
6743 for (int i = 0; i < reg_count; i++) {
6744 if (x[i].Is(xzr)) {
6745 ASSERT_EQUAL_64(0, x[i]);
6746 } else {
6747 ASSERT_EQUAL_64(literal_base * i, x[i]);
6748 }
6749 }
6750
6751 TEARDOWN();
6752}
6753
6754
6755TEST(push_pop_xreg_simple_32) {
6756 for (int claim = 0; claim <= 8; claim++) {
6757 for (int count = 0; count <= 8; count++) {
6758 PushPopXRegSimpleHelper(count, claim, kWRegSize,
6759 PushPopByFour, PushPopByFour);
6760 PushPopXRegSimpleHelper(count, claim, kWRegSize,
6761 PushPopByFour, PushPopRegList);
6762 PushPopXRegSimpleHelper(count, claim, kWRegSize,
6763 PushPopRegList, PushPopByFour);
6764 PushPopXRegSimpleHelper(count, claim, kWRegSize,
6765 PushPopRegList, PushPopRegList);
6766 }
6767 // Test with the maximum number of registers.
6768 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
6769 claim, kWRegSize, PushPopByFour, PushPopByFour);
6770 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
6771 claim, kWRegSize, PushPopByFour, PushPopRegList);
6772 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
6773 claim, kWRegSize, PushPopRegList, PushPopByFour);
6774 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
6775 claim, kWRegSize, PushPopRegList, PushPopRegList);
6776 }
6777}
6778
6779
6780TEST(push_pop_xreg_simple_64) {
6781 for (int claim = 0; claim <= 8; claim++) {
6782 for (int count = 0; count <= 8; count++) {
6783 PushPopXRegSimpleHelper(count, claim, kXRegSize,
6784 PushPopByFour, PushPopByFour);
6785 PushPopXRegSimpleHelper(count, claim, kXRegSize,
6786 PushPopByFour, PushPopRegList);
6787 PushPopXRegSimpleHelper(count, claim, kXRegSize,
6788 PushPopRegList, PushPopByFour);
6789 PushPopXRegSimpleHelper(count, claim, kXRegSize,
6790 PushPopRegList, PushPopRegList);
6791 }
6792 // Test with the maximum number of registers.
6793 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
6794 claim, kXRegSize, PushPopByFour, PushPopByFour);
6795 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
6796 claim, kXRegSize, PushPopByFour, PushPopRegList);
6797 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
6798 claim, kXRegSize, PushPopRegList, PushPopByFour);
6799 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
6800 claim, kXRegSize, PushPopRegList, PushPopRegList);
6801 }
6802}
6803
6804
6805// The maximum number of registers that can be used by the PushPopFPXReg* tests,
6806// where a reg_count field is provided.
6807static int const kPushPopFPXRegMaxRegCount = -1;
6808
6809// Test a simple push-pop pattern:
6810// * Claim <claim> bytes to set the stack alignment.
6811// * Push <reg_count> FP registers with size <reg_size>.
6812// * Clobber the register contents.
6813// * Pop <reg_count> FP registers to restore the original contents.
6814// * Drop <claim> bytes to restore the original stack pointer.
6815//
6816// Different push and pop methods can be specified independently to test for
6817// proper word-endian behaviour.
6818static void PushPopFPXRegSimpleHelper(int reg_count,
6819 int claim,
6820 int reg_size,
6821 PushPopMethod push_method,
6822 PushPopMethod pop_method) {
6823 SETUP();
6824
6825 START();
6826
6827 // We can use any floating-point register. None of them are reserved for
6828 // debug code, for example.
6829 static RegList const allowed = ~0;
6830 if (reg_count == kPushPopFPXRegMaxRegCount) {
6831 reg_count = CountSetBits(allowed, kNumberOfFPRegisters);
6832 }
6833 // Work out which registers to use, based on reg_size.
6834 FPRegister v[kNumberOfRegisters];
6835 FPRegister d[kNumberOfRegisters];
6836 RegList list = PopulateFPRegisterArray(NULL, d, v, reg_size, reg_count,
6837 allowed);
6838
6839 // Arbitrarily pick a register to use as a stack pointer.
6840 const Register& stack_pointer = x10;
6841
6842 // The literal base is chosen to have two useful properties:
6843 // * When multiplied (using an integer) by small values (such as a register
6844 // index), this value is clearly readable in the result.
6845 // * The value is not formed from repeating fixed-size smaller values, so it
6846 // can be used to detect endianness-related errors.
6847 // * It is never a floating-point NaN, and will therefore always compare
6848 // equal to itself.
6849 uint64_t literal_base = 0x0100001000100101UL;
6850
6851 {
6852 ASSERT(__ StackPointer().Is(sp));
6853 __ Mov(stack_pointer, __ StackPointer());
6854 __ SetStackPointer(stack_pointer);
6855
6856 int i;
6857
6858 // Initialize the registers, using X registers to load the literal.
6859 __ Mov(x0, 0);
6860 __ Mov(x1, literal_base);
6861 for (i = 0; i < reg_count; i++) {
6862 // Always write into the D register, to ensure that the upper word is
6863 // properly ignored by Push when testing S registers.
6864 __ Fmov(d[i], x0);
6865 // Calculate the next literal.
6866 __ Add(x0, x0, x1);
6867 }
6868
6869 // Claim memory first, as requested.
6870 __ Claim(claim);
6871
6872 switch (push_method) {
6873 case PushPopByFour:
6874 // Push high-numbered registers first (to the highest addresses).
6875 for (i = reg_count; i >= 4; i -= 4) {
6876 __ Push(v[i-1], v[i-2], v[i-3], v[i-4]);
6877 }
6878 // Finish off the leftovers.
6879 switch (i) {
6880 case 3: __ Push(v[2], v[1], v[0]); break;
6881 case 2: __ Push(v[1], v[0]); break;
6882 case 1: __ Push(v[0]); break;
6883 default: ASSERT(i == 0); break;
6884 }
6885 break;
6886 case PushPopRegList:
6887 __ PushSizeRegList(list, reg_size, CPURegister::kFPRegister);
6888 break;
6889 }
6890
6891 // Clobber all the registers, to ensure that they get repopulated by Pop.
6892 ClobberFP(&masm, list);
6893
6894 switch (pop_method) {
6895 case PushPopByFour:
6896 // Pop low-numbered registers first (from the lowest addresses).
6897 for (i = 0; i <= (reg_count-4); i += 4) {
6898 __ Pop(v[i], v[i+1], v[i+2], v[i+3]);
6899 }
6900 // Finish off the leftovers.
6901 switch (reg_count - i) {
6902 case 3: __ Pop(v[i], v[i+1], v[i+2]); break;
6903 case 2: __ Pop(v[i], v[i+1]); break;
6904 case 1: __ Pop(v[i]); break;
6905 default: ASSERT(i == reg_count); break;
6906 }
6907 break;
6908 case PushPopRegList:
6909 __ PopSizeRegList(list, reg_size, CPURegister::kFPRegister);
6910 break;
6911 }
6912
6913 // Drop memory to restore the stack pointer.
6914 __ Drop(claim);
6915
6916 __ Mov(sp, __ StackPointer());
6917 __ SetStackPointer(sp);
6918 }
6919
6920 END();
6921
6922 RUN();
6923
6924 // Check that the register contents were preserved.
6925 // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
6926 // test that the upper word was properly cleared by Pop.
6927 literal_base &= (0xffffffffffffffffUL >> (64-reg_size));
6928 for (int i = 0; i < reg_count; i++) {
6929 uint64_t literal = literal_base * i;
6930 double expected;
6931 memcpy(&expected, &literal, sizeof(expected));
6932 ASSERT_EQUAL_FP64(expected, d[i]);
6933 }
6934
6935 TEARDOWN();
6936}
6937
6938
6939TEST(push_pop_fp_xreg_simple_32) {
6940 for (int claim = 0; claim <= 8; claim++) {
6941 for (int count = 0; count <= 8; count++) {
6942 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
6943 PushPopByFour, PushPopByFour);
6944 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
6945 PushPopByFour, PushPopRegList);
6946 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
6947 PushPopRegList, PushPopByFour);
6948 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
6949 PushPopRegList, PushPopRegList);
6950 }
6951 // Test with the maximum number of registers.
6952 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
6953 PushPopByFour, PushPopByFour);
6954 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
6955 PushPopByFour, PushPopRegList);
6956 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
6957 PushPopRegList, PushPopByFour);
6958 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
6959 PushPopRegList, PushPopRegList);
6960 }
6961}
6962
6963
6964TEST(push_pop_fp_xreg_simple_64) {
6965 for (int claim = 0; claim <= 8; claim++) {
6966 for (int count = 0; count <= 8; count++) {
6967 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
6968 PushPopByFour, PushPopByFour);
6969 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
6970 PushPopByFour, PushPopRegList);
6971 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
6972 PushPopRegList, PushPopByFour);
6973 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
6974 PushPopRegList, PushPopRegList);
6975 }
6976 // Test with the maximum number of registers.
6977 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
6978 PushPopByFour, PushPopByFour);
6979 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
6980 PushPopByFour, PushPopRegList);
6981 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
6982 PushPopRegList, PushPopByFour);
6983 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
6984 PushPopRegList, PushPopRegList);
6985 }
6986}
6987
6988
6989// Push and pop data using an overlapping combination of Push/Pop and
6990// RegList-based methods.
6991static void PushPopXRegMixedMethodsHelper(int claim, int reg_size) {
6992 SETUP();
6993
6994 // Arbitrarily pick a register to use as a stack pointer.
6995 const Register& stack_pointer = x5;
6996 const RegList allowed = ~stack_pointer.Bit();
6997 // Work out which registers to use, based on reg_size.
6998 Register r[10];
6999 Register x[10];
7000 PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed);
7001
7002 // Calculate some handy register lists.
7003 RegList r0_to_r3 = 0;
7004 for (int i = 0; i <= 3; i++) {
7005 r0_to_r3 |= x[i].Bit();
7006 }
7007 RegList r4_to_r5 = 0;
7008 for (int i = 4; i <= 5; i++) {
7009 r4_to_r5 |= x[i].Bit();
7010 }
7011 RegList r6_to_r9 = 0;
7012 for (int i = 6; i <= 9; i++) {
7013 r6_to_r9 |= x[i].Bit();
7014 }
7015
7016 // The literal base is chosen to have two useful properties:
7017 // * When multiplied by small values (such as a register index), this value
7018 // is clearly readable in the result.
7019 // * The value is not formed from repeating fixed-size smaller values, so it
7020 // can be used to detect endianness-related errors.
7021 uint64_t literal_base = 0x0100001000100101UL;
7022
7023 START();
7024 {
7025 ASSERT(__ StackPointer().Is(sp));
7026 __ Mov(stack_pointer, __ StackPointer());
7027 __ SetStackPointer(stack_pointer);
7028
7029 // Claim memory first, as requested.
7030 __ Claim(claim);
7031
7032 __ Mov(x[3], literal_base * 3);
7033 __ Mov(x[2], literal_base * 2);
7034 __ Mov(x[1], literal_base * 1);
7035 __ Mov(x[0], literal_base * 0);
7036
7037 __ PushSizeRegList(r0_to_r3, reg_size);
7038 __ Push(r[3], r[2]);
7039
7040 Clobber(&masm, r0_to_r3);
7041 __ PopSizeRegList(r0_to_r3, reg_size);
7042
7043 __ Push(r[2], r[1], r[3], r[0]);
7044
7045 Clobber(&masm, r4_to_r5);
7046 __ Pop(r[4], r[5]);
7047 Clobber(&masm, r6_to_r9);
7048 __ Pop(r[6], r[7], r[8], r[9]);
7049
7050 // Drop memory to restore stack_pointer.
7051 __ Drop(claim);
7052
7053 __ Mov(sp, __ StackPointer());
7054 __ SetStackPointer(sp);
7055 }
7056
7057 END();
7058
7059 RUN();
7060
7061 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
7062 // that the upper word was properly cleared by Pop.
7063 literal_base &= (0xffffffffffffffffUL >> (64-reg_size));
7064
7065 ASSERT_EQUAL_64(literal_base * 3, x[9]);
7066 ASSERT_EQUAL_64(literal_base * 2, x[8]);
7067 ASSERT_EQUAL_64(literal_base * 0, x[7]);
7068 ASSERT_EQUAL_64(literal_base * 3, x[6]);
7069 ASSERT_EQUAL_64(literal_base * 1, x[5]);
7070 ASSERT_EQUAL_64(literal_base * 2, x[4]);
7071
7072 TEARDOWN();
7073}
7074
7075
7076TEST(push_pop_xreg_mixed_methods_64) {
7077 for (int claim = 0; claim <= 8; claim++) {
7078 PushPopXRegMixedMethodsHelper(claim, kXRegSize);
7079 }
7080}
7081
7082
7083TEST(push_pop_xreg_mixed_methods_32) {
7084 for (int claim = 0; claim <= 8; claim++) {
7085 PushPopXRegMixedMethodsHelper(claim, kWRegSize);
7086 }
7087}
7088
7089
7090// Push and pop data using overlapping X- and W-sized quantities.
7091static void PushPopXRegWXOverlapHelper(int reg_count, int claim) {
7092 SETUP();
7093
7094 // Arbitrarily pick a register to use as a stack pointer.
7095 const Register& stack_pointer = x10;
7096 const RegList allowed = ~stack_pointer.Bit();
7097 if (reg_count == kPushPopXRegMaxRegCount) {
7098 reg_count = CountSetBits(allowed, kNumberOfRegisters);
7099 }
7100 // Work out which registers to use, based on reg_size.
7101 Register w[kNumberOfRegisters];
7102 Register x[kNumberOfRegisters];
7103 RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed);
7104
7105 // The number of W-sized slots we expect to pop. When we pop, we alternate
7106 // between W and X registers, so we need reg_count*1.5 W-sized slots.
7107 int const requested_w_slots = reg_count + reg_count / 2;
7108
7109 // Track what _should_ be on the stack, using W-sized slots.
7110 static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2;
7111 uint32_t stack[kMaxWSlots];
7112 for (int i = 0; i < kMaxWSlots; i++) {
7113 stack[i] = 0xdeadbeef;
7114 }
7115
7116 // The literal base is chosen to have two useful properties:
7117 // * When multiplied by small values (such as a register index), this value
7118 // is clearly readable in the result.
7119 // * The value is not formed from repeating fixed-size smaller values, so it
7120 // can be used to detect endianness-related errors.
7121 static uint64_t const literal_base = 0x0100001000100101UL;
7122 static uint64_t const literal_base_hi = literal_base >> 32;
7123 static uint64_t const literal_base_lo = literal_base & 0xffffffff;
7124 static uint64_t const literal_base_w = literal_base & 0xffffffff;
7125
7126 START();
7127 {
7128 ASSERT(__ StackPointer().Is(sp));
7129 __ Mov(stack_pointer, __ StackPointer());
7130 __ SetStackPointer(stack_pointer);
7131
7132 // Initialize the registers.
7133 for (int i = 0; i < reg_count; i++) {
7134 // Always write into the X register, to ensure that the upper word is
7135 // properly ignored by Push when testing W registers.
7136 __ Mov(x[i], literal_base * i);
7137 }
7138
7139 // Claim memory first, as requested.
7140 __ Claim(claim);
7141
7142 // The push-pop pattern is as follows:
7143 // Push: Pop:
7144 // x[0](hi) -> w[0]
7145 // x[0](lo) -> x[1](hi)
7146 // w[1] -> x[1](lo)
7147 // w[1] -> w[2]
7148 // x[2](hi) -> x[2](hi)
7149 // x[2](lo) -> x[2](lo)
7150 // x[2](hi) -> w[3]
7151 // x[2](lo) -> x[4](hi)
7152 // x[2](hi) -> x[4](lo)
7153 // x[2](lo) -> w[5]
7154 // w[3] -> x[5](hi)
7155 // w[3] -> x[6](lo)
7156 // w[3] -> w[7]
7157 // w[3] -> x[8](hi)
7158 // x[4](hi) -> x[8](lo)
7159 // x[4](lo) -> w[9]
7160 // ... pattern continues ...
7161 //
7162 // That is, registers are pushed starting with the lower numbers,
7163 // alternating between x and w registers, and pushing i%4+1 copies of each,
7164 // where i is the register number.
7165 // Registers are popped starting with the higher numbers one-by-one,
7166 // alternating between x and w registers, but only popping one at a time.
7167 //
7168 // This pattern provides a wide variety of alignment effects and overlaps.
7169
7170 // ---- Push ----
7171
7172 int active_w_slots = 0;
7173 for (int i = 0; active_w_slots < requested_w_slots; i++) {
7174 ASSERT(i < reg_count);
7175 // In order to test various arguments to PushMultipleTimes, and to try to
7176 // exercise different alignment and overlap effects, we push each
7177 // register a different number of times.
7178 int times = i % 4 + 1;
7179 if (i & 1) {
7180 // Push odd-numbered registers as W registers.
7181 __ PushMultipleTimes(times, w[i]);
7182 // Fill in the expected stack slots.
7183 for (int j = 0; j < times; j++) {
7184 if (w[i].Is(wzr)) {
7185 // The zero register always writes zeroes.
7186 stack[active_w_slots++] = 0;
7187 } else {
7188 stack[active_w_slots++] = literal_base_w * i;
7189 }
7190 }
7191 } else {
7192 // Push even-numbered registers as X registers.
7193 __ PushMultipleTimes(times, x[i]);
7194 // Fill in the expected stack slots.
7195 for (int j = 0; j < times; j++) {
7196 if (x[i].Is(xzr)) {
7197 // The zero register always writes zeroes.
7198 stack[active_w_slots++] = 0;
7199 stack[active_w_slots++] = 0;
7200 } else {
7201 stack[active_w_slots++] = literal_base_hi * i;
7202 stack[active_w_slots++] = literal_base_lo * i;
7203 }
7204 }
7205 }
7206 }
7207 // Because we were pushing several registers at a time, we probably pushed
7208 // more than we needed to.
7209 if (active_w_slots > requested_w_slots) {
7210 __ Drop((active_w_slots - requested_w_slots) * kWRegSizeInBytes);
7211 // Bump the number of active W-sized slots back to where it should be,
7212 // and fill the empty space with a dummy value.
7213 do {
7214 stack[active_w_slots--] = 0xdeadbeef;
7215 } while (active_w_slots > requested_w_slots);
7216 }
7217
7218 // ---- Pop ----
7219
7220 Clobber(&masm, list);
7221
7222 // If popping an even number of registers, the first one will be X-sized.
7223 // Otherwise, the first one will be W-sized.
7224 bool next_is_64 = !(reg_count & 1);
7225 for (int i = reg_count-1; i >= 0; i--) {
7226 if (next_is_64) {
7227 __ Pop(x[i]);
7228 active_w_slots -= 2;
7229 } else {
7230 __ Pop(w[i]);
7231 active_w_slots -= 1;
7232 }
7233 next_is_64 = !next_is_64;
7234 }
7235 ASSERT(active_w_slots == 0);
7236
7237 // Drop memory to restore stack_pointer.
7238 __ Drop(claim);
7239
7240 __ Mov(sp, __ StackPointer());
7241 __ SetStackPointer(sp);
7242 }
7243
7244 END();
7245
7246 RUN();
7247
7248 int slot = 0;
7249 for (int i = 0; i < reg_count; i++) {
7250 // Even-numbered registers were written as W registers.
7251 // Odd-numbered registers were written as X registers.
7252 bool expect_64 = (i & 1);
7253 uint64_t expected;
7254
7255 if (expect_64) {
7256 uint64_t hi = stack[slot++];
7257 uint64_t lo = stack[slot++];
7258 expected = (hi << 32) | lo;
7259 } else {
7260 expected = stack[slot++];
7261 }
7262
7263 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
7264 // test that the upper word was properly cleared by Pop.
7265 if (x[i].Is(xzr)) {
7266 ASSERT_EQUAL_64(0, x[i]);
7267 } else {
7268 ASSERT_EQUAL_64(expected, x[i]);
7269 }
7270 }
7271 ASSERT(slot == requested_w_slots);
7272
7273 TEARDOWN();
7274}
7275
7276
7277TEST(push_pop_xreg_wx_overlap) {
7278 for (int claim = 0; claim <= 8; claim++) {
7279 for (int count = 1; count <= 8; count++) {
7280 PushPopXRegWXOverlapHelper(count, claim);
7281 }
7282 // Test with the maximum number of registers.
7283 PushPopXRegWXOverlapHelper(kPushPopXRegMaxRegCount, claim);
7284 }
7285}
7286
7287
7288TEST(push_pop_sp) {
7289 SETUP();
7290
7291 START();
7292
7293 ASSERT(sp.Is(__ StackPointer()));
7294
7295 __ Mov(x3, 0x3333333333333333UL);
7296 __ Mov(x2, 0x2222222222222222UL);
7297 __ Mov(x1, 0x1111111111111111UL);
7298 __ Mov(x0, 0x0000000000000000UL);
7299 __ Claim(2 * kXRegSizeInBytes);
7300 __ PushXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
7301 __ Push(x3, x2);
7302 __ PopXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
7303 __ Push(x2, x1, x3, x0);
7304 __ Pop(x4, x5);
7305 __ Pop(x6, x7, x8, x9);
7306
7307 __ Claim(2 * kXRegSizeInBytes);
7308 __ PushWRegList(w0.Bit() | w1.Bit() | w2.Bit() | w3.Bit());
7309 __ Push(w3, w1, w2, w0);
7310 __ PopWRegList(w10.Bit() | w11.Bit() | w12.Bit() | w13.Bit());
7311 __ Pop(w14, w15, w16, w17);
7312
7313 __ Claim(2 * kXRegSizeInBytes);
7314 __ Push(w2, w2, w1, w1);
7315 __ Push(x3, x3);
7316 __ Pop(w18, w19, w20, w21);
7317 __ Pop(x22, x23);
7318
7319 __ Claim(2 * kXRegSizeInBytes);
7320 __ PushXRegList(x1.Bit() | x22.Bit());
7321 __ PopXRegList(x24.Bit() | x26.Bit());
7322
7323 __ Claim(2 * kXRegSizeInBytes);
7324 __ PushWRegList(w1.Bit() | w2.Bit() | w4.Bit() | w22.Bit());
7325 __ PopWRegList(w25.Bit() | w27.Bit() | w28.Bit() | w29.Bit());
7326
7327 __ Claim(2 * kXRegSizeInBytes);
7328 __ PushXRegList(0);
7329 __ PopXRegList(0);
7330 __ PushXRegList(0xffffffff);
7331 __ PopXRegList(0xffffffff);
7332 __ Drop(12 * kXRegSizeInBytes);
7333 END();
7334
7335 RUN();
7336
7337 ASSERT_EQUAL_64(0x1111111111111111UL, x3);
7338 ASSERT_EQUAL_64(0x0000000000000000UL, x2);
7339 ASSERT_EQUAL_64(0x3333333333333333UL, x1);
7340 ASSERT_EQUAL_64(0x2222222222222222UL, x0);
7341 ASSERT_EQUAL_64(0x3333333333333333UL, x9);
7342 ASSERT_EQUAL_64(0x2222222222222222UL, x8);
7343 ASSERT_EQUAL_64(0x0000000000000000UL, x7);
7344 ASSERT_EQUAL_64(0x3333333333333333UL, x6);
7345 ASSERT_EQUAL_64(0x1111111111111111UL, x5);
7346 ASSERT_EQUAL_64(0x2222222222222222UL, x4);
7347
7348 ASSERT_EQUAL_32(0x11111111U, w13);
7349 ASSERT_EQUAL_32(0x33333333U, w12);
7350 ASSERT_EQUAL_32(0x00000000U, w11);
7351 ASSERT_EQUAL_32(0x22222222U, w10);
7352 ASSERT_EQUAL_32(0x11111111U, w17);
7353 ASSERT_EQUAL_32(0x00000000U, w16);
7354 ASSERT_EQUAL_32(0x33333333U, w15);
7355 ASSERT_EQUAL_32(0x22222222U, w14);
7356
7357 ASSERT_EQUAL_32(0x11111111U, w18);
7358 ASSERT_EQUAL_32(0x11111111U, w19);
7359 ASSERT_EQUAL_32(0x11111111U, w20);
7360 ASSERT_EQUAL_32(0x11111111U, w21);
7361 ASSERT_EQUAL_64(0x3333333333333333UL, x22);
7362 ASSERT_EQUAL_64(0x0000000000000000UL, x23);
7363
7364 ASSERT_EQUAL_64(0x3333333333333333UL, x24);
7365 ASSERT_EQUAL_64(0x3333333333333333UL, x26);
7366
7367 ASSERT_EQUAL_32(0x33333333U, w25);
7368 ASSERT_EQUAL_32(0x00000000U, w27);
7369 ASSERT_EQUAL_32(0x22222222U, w28);
7370 ASSERT_EQUAL_32(0x33333333U, w29);
7371 TEARDOWN();
7372}
7373
7374
7375TEST(noreg) {
7376 // This test doesn't generate any code, but it verifies some invariants
7377 // related to NoReg.
7378 CHECK(NoReg.Is(NoFPReg));
7379 CHECK(NoFPReg.Is(NoReg));
7380 CHECK(NoReg.Is(NoCPUReg));
7381 CHECK(NoCPUReg.Is(NoReg));
7382 CHECK(NoFPReg.Is(NoCPUReg));
7383 CHECK(NoCPUReg.Is(NoFPReg));
7384
7385 CHECK(NoReg.IsNone());
7386 CHECK(NoFPReg.IsNone());
7387 CHECK(NoCPUReg.IsNone());
7388}
7389
7390
7391TEST(isvalid) {
7392 // This test doesn't generate any code, but it verifies some invariants
7393 // related to IsValid().
7394 CHECK(!NoReg.IsValid());
7395 CHECK(!NoFPReg.IsValid());
7396 CHECK(!NoCPUReg.IsValid());
7397
7398 CHECK(x0.IsValid());
7399 CHECK(w0.IsValid());
7400 CHECK(x30.IsValid());
7401 CHECK(w30.IsValid());
7402 CHECK(xzr.IsValid());
7403 CHECK(wzr.IsValid());
7404
7405 CHECK(sp.IsValid());
7406 CHECK(wsp.IsValid());
7407
7408 CHECK(d0.IsValid());
7409 CHECK(s0.IsValid());
7410 CHECK(d31.IsValid());
7411 CHECK(s31.IsValid());
7412
7413 CHECK(x0.IsValidRegister());
7414 CHECK(w0.IsValidRegister());
7415 CHECK(xzr.IsValidRegister());
7416 CHECK(wzr.IsValidRegister());
7417 CHECK(sp.IsValidRegister());
7418 CHECK(wsp.IsValidRegister());
7419 CHECK(!x0.IsValidFPRegister());
7420 CHECK(!w0.IsValidFPRegister());
7421 CHECK(!xzr.IsValidFPRegister());
7422 CHECK(!wzr.IsValidFPRegister());
7423 CHECK(!sp.IsValidFPRegister());
7424 CHECK(!wsp.IsValidFPRegister());
7425
7426 CHECK(d0.IsValidFPRegister());
7427 CHECK(s0.IsValidFPRegister());
7428 CHECK(!d0.IsValidRegister());
7429 CHECK(!s0.IsValidRegister());
7430
7431 // Test the same as before, but using CPURegister types. This shouldn't make
7432 // any difference.
7433 CHECK(static_cast<CPURegister>(x0).IsValid());
7434 CHECK(static_cast<CPURegister>(w0).IsValid());
7435 CHECK(static_cast<CPURegister>(x30).IsValid());
7436 CHECK(static_cast<CPURegister>(w30).IsValid());
7437 CHECK(static_cast<CPURegister>(xzr).IsValid());
7438 CHECK(static_cast<CPURegister>(wzr).IsValid());
7439
7440 CHECK(static_cast<CPURegister>(sp).IsValid());
7441 CHECK(static_cast<CPURegister>(wsp).IsValid());
7442
7443 CHECK(static_cast<CPURegister>(d0).IsValid());
7444 CHECK(static_cast<CPURegister>(s0).IsValid());
7445 CHECK(static_cast<CPURegister>(d31).IsValid());
7446 CHECK(static_cast<CPURegister>(s31).IsValid());
7447
7448 CHECK(static_cast<CPURegister>(x0).IsValidRegister());
7449 CHECK(static_cast<CPURegister>(w0).IsValidRegister());
7450 CHECK(static_cast<CPURegister>(xzr).IsValidRegister());
7451 CHECK(static_cast<CPURegister>(wzr).IsValidRegister());
7452 CHECK(static_cast<CPURegister>(sp).IsValidRegister());
7453 CHECK(static_cast<CPURegister>(wsp).IsValidRegister());
7454 CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister());
7455 CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister());
7456 CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister());
7457 CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister());
7458 CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister());
7459 CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister());
7460
7461 CHECK(static_cast<CPURegister>(d0).IsValidFPRegister());
7462 CHECK(static_cast<CPURegister>(s0).IsValidFPRegister());
7463 CHECK(!static_cast<CPURegister>(d0).IsValidRegister());
7464 CHECK(!static_cast<CPURegister>(s0).IsValidRegister());
7465}
7466
7467
7468TEST(printf) {
7469#ifdef USE_SIMULATOR
7470 // These tests only run when the debugger is requested.
7471 if (Cctest::run_debugger()) {
7472#endif
7473 SETUP();
7474 START();
7475
7476 char const * test_plain_string = "Printf with no arguments.\n";
7477 char const * test_substring = "'This is a substring.'";
7478 RegisterDump before;
7479
7480 // Initialize x29 to the value of the stack pointer. We will use x29 as a
7481 // temporary stack pointer later, and initializing it in this way allows the
7482 // RegisterDump check to pass.
7483 __ Mov(x29, __ StackPointer());
7484
7485 // Test simple integer arguments.
7486 __ Mov(x0, 1234);
7487 __ Mov(x1, 0x1234);
7488
7489 // Test simple floating-point arguments.
7490 __ Fmov(d0, 1.234);
7491
7492 // Test pointer (string) arguments.
7493 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
7494
7495 // Test the maximum number of arguments, and sign extension.
7496 __ Mov(w3, 0xffffffff);
7497 __ Mov(w4, 0xffffffff);
7498 __ Mov(x5, 0xffffffffffffffff);
7499 __ Mov(x6, 0xffffffffffffffff);
7500 __ Fmov(s1, 1.234);
7501 __ Fmov(s2, 2.345);
7502 __ Fmov(d3, 3.456);
7503 __ Fmov(d4, 4.567);
7504
7505 // Test printing callee-saved registers.
7506 __ Mov(x28, 0x123456789abcdef);
7507 __ Fmov(d10, 42.0);
7508
7509 // Test with three arguments.
7510 __ Mov(x10, 3);
7511 __ Mov(x11, 40);
7512 __ Mov(x12, 500);
7513
7514 // Check that we don't clobber any registers, except those that we explicitly
7515 // write results into.
7516 before.Dump(&masm);
7517
7518 __ Printf(test_plain_string); // NOLINT(runtime/printf)
7519 __ Printf("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
7520 __ Printf("d0: %f\n", d0);
7521 __ Printf("Test %%s: %s\n", x2);
7522 __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
7523 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
7524 w3, w4, x5, x6);
7525 __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
7526 __ Printf("0x%08" PRIx32 ", 0x%016" PRIx64 "\n", x28, x28);
7527 __ Printf("%g\n", d10);
7528
7529 // Test with a different stack pointer.
7530 const Register old_stack_pointer = __ StackPointer();
7531 __ mov(x29, old_stack_pointer);
7532 __ SetStackPointer(x29);
7533 __ Printf("old_stack_pointer: 0x%016" PRIx64 "\n", old_stack_pointer);
7534 __ mov(old_stack_pointer, __ StackPointer());
7535 __ SetStackPointer(old_stack_pointer);
7536
7537 __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
7538
7539 END();
7540 RUN();
7541
7542 // We cannot easily test the output of the Printf sequences, and because
7543 // Printf preserves all registers by default, we can't look at the number of
7544 // bytes that were printed. However, the printf_no_preserve test should check
7545 // that, and here we just test that we didn't clobber any registers.
7546 ASSERT_EQUAL_REGISTERS(before);
7547
7548 TEARDOWN();
7549#ifdef USE_SIMULATOR
7550 }
7551#endif
7552}
7553
7554
7555TEST(printf_no_preserve) {
7556#ifdef USE_SIMULATOR
7557 // These tests only run when the debugger is requested.
7558 if (Cctest::run_debugger()) {
7559#endif
7560 SETUP();
7561 START();
7562
7563 char const * test_plain_string = "Printf with no arguments.\n";
7564 char const * test_substring = "'This is a substring.'";
7565
7566 __ PrintfNoPreserve(test_plain_string);
7567 __ Mov(x19, x0);
7568
7569 // Test simple integer arguments.
7570 __ Mov(x0, 1234);
7571 __ Mov(x1, 0x1234);
7572 __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
7573 __ Mov(x20, x0);
7574
7575 // Test simple floating-point arguments.
7576 __ Fmov(d0, 1.234);
7577 __ PrintfNoPreserve("d0: %f\n", d0);
7578 __ Mov(x21, x0);
7579
7580 // Test pointer (string) arguments.
7581 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
7582 __ PrintfNoPreserve("Test %%s: %s\n", x2);
7583 __ Mov(x22, x0);
7584
7585 // Test the maximum number of arguments, and sign extension.
7586 __ Mov(w3, 0xffffffff);
7587 __ Mov(w4, 0xffffffff);
7588 __ Mov(x5, 0xffffffffffffffff);
7589 __ Mov(x6, 0xffffffffffffffff);
7590 __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
7591 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
7592 w3, w4, x5, x6);
7593 __ Mov(x23, x0);
7594
7595 __ Fmov(s1, 1.234);
7596 __ Fmov(s2, 2.345);
7597 __ Fmov(d3, 3.456);
7598 __ Fmov(d4, 4.567);
7599 __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
7600 __ Mov(x24, x0);
7601
7602 // Test printing callee-saved registers.
7603 __ Mov(x28, 0x123456789abcdef);
7604 __ PrintfNoPreserve("0x%08" PRIx32 ", 0x%016" PRIx64 "\n", x28, x28);
7605 __ Mov(x25, x0);
7606
7607 __ Fmov(d10, 42.0);
7608 __ PrintfNoPreserve("%g\n", d10);
7609 __ Mov(x26, x0);
7610
7611 // Test with a different stack pointer.
7612 const Register old_stack_pointer = __ StackPointer();
7613 __ Mov(x29, old_stack_pointer);
7614 __ SetStackPointer(x29);
7615
7616 __ PrintfNoPreserve("old_stack_pointer: 0x%016" PRIx64 "\n",
7617 old_stack_pointer);
7618 __ Mov(x27, x0);
7619
7620 __ Mov(old_stack_pointer, __ StackPointer());
7621 __ SetStackPointer(old_stack_pointer);
7622
7623 // Test with three arguments.
7624 __ Mov(x3, 3);
7625 __ Mov(x4, 40);
7626 __ Mov(x5, 500);
7627 __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
7628 __ Mov(x28, x0);
7629
7630 END();
7631 RUN();
7632
7633 // We cannot easily test the exact output of the Printf sequences, but we can
7634 // use the return code to check that the string length was correct.
7635
7636 // Printf with no arguments.
7637 ASSERT_EQUAL_64(strlen(test_plain_string), x19);
7638 // x0: 1234, x1: 0x00001234
7639 ASSERT_EQUAL_64(25, x20);
7640 // d0: 1.234000
7641 ASSERT_EQUAL_64(13, x21);
7642 // Test %s: 'This is a substring.'
7643 ASSERT_EQUAL_64(32, x22);
7644 // w3(uint32): 4294967295
7645 // w4(int32): -1
7646 // x5(uint64): 18446744073709551615
7647 // x6(int64): -1
7648 ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
7649 // %f: 1.234000
7650 // %g: 2.345
7651 // %e: 3.456000e+00
7652 // %E: 4.567000E+00
7653 ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
7654 // 0x89abcdef, 0x0123456789abcdef
7655 ASSERT_EQUAL_64(31, x25);
7656 // 42
7657 ASSERT_EQUAL_64(3, x26);
7658 // old_stack_pointer: 0x00007fb037ae2370
7659 // Note: This is an example value, but the field width is fixed here so the
7660 // string length is still predictable.
7661 ASSERT_EQUAL_64(38, x27);
7662 // 3=3, 4=40, 5=500
7663 ASSERT_EQUAL_64(17, x28);
7664
7665 TEARDOWN();
7666#ifdef USE_SIMULATOR
7667 }
7668#endif
7669}
7670
7671
7672#ifndef USE_SIMULATOR
7673TEST(trace) {
7674 // The Trace helper should not generate any code unless the simulator (or
7675 // debugger) is being used.
7676 SETUP();
7677 START();
7678
7679 Label start;
7680 __ Bind(&start);
7681 __ Trace(LOG_ALL, TRACE_ENABLE);
7682 __ Trace(LOG_ALL, TRACE_DISABLE);
7683 CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
7684
7685 END();
7686 TEARDOWN();
7687}
7688#endif
7689
7690
7691#ifndef USE_SIMULATOR
7692TEST(log) {
7693 // The Log helper should not generate any code unless the simulator (or
7694 // debugger) is being used.
7695 SETUP();
7696 START();
7697
7698 Label start;
7699 __ Bind(&start);
7700 __ Log(LOG_ALL);
7701 CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
7702
7703 END();
7704 TEARDOWN();
7705}
7706#endif
7707
7708
7709TEST(instruction_accurate_scope) {
7710 SETUP();
7711 START();
7712
7713 // By default macro instructions are allowed.
7714 ASSERT(masm.AllowMacroInstructions());
7715 {
7716 InstructionAccurateScope scope1(&masm);
7717 ASSERT(!masm.AllowMacroInstructions());
7718 {
7719 InstructionAccurateScope scope2(&masm);
7720 ASSERT(!masm.AllowMacroInstructions());
7721 }
7722 ASSERT(!masm.AllowMacroInstructions());
7723 }
7724 ASSERT(masm.AllowMacroInstructions());
7725
7726 {
7727 InstructionAccurateScope scope(&masm, 2);
7728 __ add(x0, x0, x0);
7729 __ sub(x0, x0, x0);
7730 }
7731
7732 END();
7733 RUN();
7734 TEARDOWN();
7735}
7736
7737
7738TEST(blr_lr) {
7739 // A simple test to check that the simulator correcty handle "blr lr".
7740 SETUP();
7741
7742 START();
7743 Label target;
7744 Label end;
7745
7746 __ Mov(x0, 0x0);
7747 __ Adr(lr, &target);
7748
7749 __ Blr(lr);
7750 __ Mov(x0, 0xdeadbeef);
7751 __ B(&end);
7752
7753 __ Bind(&target);
7754 __ Mov(x0, 0xc001c0de);
7755
7756 __ Bind(&end);
7757 END();
7758
7759 RUN();
7760
7761 ASSERT_EQUAL_64(0xc001c0de, x0);
7762
7763 TEARDOWN();
7764}
7765
7766} // namespace vixl