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