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