Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: test/cctest/test-assembler-a64.cc

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

Powered by Google App Engine
This is Rietveld 408576698