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