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

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

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

Powered by Google App Engine
This is Rietveld 408576698