1// Copyright 2013 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <cmath>
32#include <limits>
33
34#include "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"
40#include "src/base/platform/platform.h"
41#include "src/base/utils/random-number-generator.h"
42#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.
118#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;                              \
129  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.
173#define SETUP_SIZE(buf_size)                                   \
174  Isolate* isolate = CcTest::i_isolate();                      \
175  HandleScope scope(isolate);                                  \
176  CHECK(isolate != NULL);                                      \
177  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,               \
181                      v8::internal::CodeObjectRequired::kYes); \
182  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
199#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();                                                \
205  }
206
207#define END()                                                                  \
208  core.Dump(&masm);                                                            \
209  __ PopCalleeSavedRegisters();                                                \
210  __ Ret();                                                                    \
211  __ GetCode(NULL);
212
213#define TEARDOWN()                                                             \
214  v8::base::OS::Free(buf, actual_size);
215
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
237#define CHECK_LITERAL_POOL_SIZE(expected) \
238  CHECK((expected) == (__ LiteralPoolSize()))
239#else
240#define CHECK_LITERAL_POOL_SIZE(expected) ((void)0)
241#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
2977TEST(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) {
3306  CHECK(range_ > 0);
3307  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);
3325  CHECK_LITERAL_POOL_SIZE(0);
3326
3327  __ Ldr(x0, 0x1234567890abcdefUL);
3328  __ Ldr(w1, 0xfedcba09);
3329  __ Ldr(d0, 1.234);
3330  __ Ldr(s1, 2.5);
3331  CHECK_LITERAL_POOL_SIZE(4);
3332
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.
3337  CHECK((code_size + pool_guard_size) <= range);
3338
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
3351  CHECK(code_size == range);
3352  CHECK_LITERAL_POOL_SIZE(4);
3353
3354  // Possibly generate a literal pool.
3355  __ CheckLiteralPool(option);
3356  __ Bind(&label_1);
3357  if (expect_dump) {
3358    CHECK_LITERAL_POOL_SIZE(0);
3359  } else {
3360    CHECK_LITERAL_POOL_SIZE(4);
3361  }
3362
3363  // Force a pool flush to check that a second pool functions correctly.
3364  __ EmitLiteralPool(JumpRequired);
3365  CHECK_LITERAL_POOL_SIZE(0);
3366
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);
3372  CHECK_LITERAL_POOL_SIZE(4);
3373  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);
3719  CHECK_EQ(0u, __ SizeOfCodeGeneratedSince(&blob1));
3720
3721  Label blob2;
3722  __ Bind(&blob2);
3723  __ Add(w3, w3, 0);
3724  CHECK_NE(0u, __ SizeOfCodeGeneratedSince(&blob2));
3725
3726  Label blob3;
3727  __ Bind(&blob3);
3728  __ Sub(w3, w3, wzr);
3729  CHECK_NE(0u, __ SizeOfCodeGeneratedSince(&blob3));
3730
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);
3763  CHECK_EQ(0u, __ SizeOfCodeGeneratedSince(&start));
3764
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);
5450  CHECK(IsSignallingNaN(s1));
5451  CHECK(IsSignallingNaN(s2));
5452  CHECK(IsSignallingNaN(sa));
5453  CHECK(IsQuietNaN(q1));
5454  CHECK(IsQuietNaN(q2));
5455  CHECK(IsQuietNaN(qa));
5456
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;
5464  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));
5470
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);
5476  CHECK(IsQuietNaN(s1_proc_neg));
5477  CHECK(IsQuietNaN(sa_proc_neg));
5478  CHECK(IsQuietNaN(q1_proc_neg));
5479  CHECK(IsQuietNaN(qa_proc_neg));
5480
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);
5533  CHECK(IsSignallingNaN(s1));
5534  CHECK(IsSignallingNaN(s2));
5535  CHECK(IsSignallingNaN(sa));
5536  CHECK(IsQuietNaN(q1));
5537  CHECK(IsQuietNaN(q2));
5538  CHECK(IsQuietNaN(qa));
5539
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;
5547  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));
5553
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);
5559  CHECK(IsQuietNaN(s1_proc_neg));
5560  CHECK(IsQuietNaN(sa_proc_neg));
5561  CHECK(IsQuietNaN(q1_proc_neg));
5562  CHECK(IsQuietNaN(qa_proc_neg));
5563
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
5780  CHECK(IsSignallingNaN(snan));
5781  CHECK(IsQuietNaN(qnan));
5782  CHECK(IsQuietNaN(snan_processed));
5783  CHECK(IsQuietNaN(qnan_processed));
5784
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
5865  CHECK(IsSignallingNaN(snan));
5866  CHECK(IsQuietNaN(qnan));
5867  CHECK(IsQuietNaN(snan_processed));
5868  CHECK(IsQuietNaN(qnan_processed));
5869
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
6507TEST(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
6596TEST(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.
6840    CHECK(std::signbit(in) == 0);
6841    CHECK(std::signbit(expected) == 0);
6842
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);
8154  for (int i = 2; i < x30.code(); i++) {
8155    __ 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  {
8552    CHECK(__ StackPointer().Is(csp));
8553    __ 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  {
8649    CHECK(__ StackPointer().Is(csp));
8650    __ 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;
8678          default:
8679            CHECK(i == 0);
8680            break;
8681        }
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;
8702          default:
8703            CHECK(i == reg_count);
8704            break;
8705        }
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  {
8835    CHECK(__ StackPointer().Is(csp));
8836    __ 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;
8866          default:
8867            CHECK(i == 0);
8868            break;
8869        }
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;
8890          default:
8891            CHECK(i == reg_count);
8892            break;
8893        }
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  {
9016    CHECK(__ StackPointer().Is(csp));
9017    __ 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  {
9121    CHECK(__ StackPointer().Is(csp));
9122    __ 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++) {
9169      CHECK(i < reg_count);
9170      // 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    }
9242    CHECK(active_w_slots == 0);
9243
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  }
9278  CHECK(slot == requested_w_slots);
9279
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
9308  CHECK(csp.Is(__ StackPointer()));
9309
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
9397  CHECK(__ StackPointer().Is(csp));
9398  __ 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
9472  CHECK(__ StackPointer().Is(csp));
9473  __ 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).
10093  CHECK(csp.Is(__ StackPointer()));
10094  __ 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
10251TEST(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);
10346  CHECK(IsSignallingNaN(sn));
10347  CHECK(IsQuietNaN(qn));
10348
10349  // The input NaNs after passing through ProcessNaN.
10350  double sn_proc = rawbits_to_double(0x7ffd555511111111);
10351  double qn_proc = qn;
10352  CHECK(IsQuietNaN(sn_proc));
10353  CHECK(IsQuietNaN(qn_proc));
10354
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);
10422  CHECK(IsSignallingNaN(sn));
10423  CHECK(IsQuietNaN(qn));
10424
10425  // The input NaNs after passing through ProcessNaN.
10426  float sn_proc = rawbits_to_float(0x7fd51111);
10427  float qn_proc = qn;
10428  CHECK(IsQuietNaN(sn_proc));
10429  CHECK(IsQuietNaN(qn_proc));
10430
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) {
10494  CHECK(std::isnan(n) || std::isnan(m));
10495  CHECK(std::isnan(expected));
10496
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);
10533  CHECK(IsSignallingNaN(sn));
10534  CHECK(IsSignallingNaN(sm));
10535  CHECK(IsQuietNaN(qn));
10536  CHECK(IsQuietNaN(qm));
10537
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;
10543  CHECK(IsQuietNaN(sn_proc));
10544  CHECK(IsQuietNaN(sm_proc));
10545  CHECK(IsQuietNaN(qn_proc));
10546  CHECK(IsQuietNaN(qm_proc));
10547
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) {
10566  CHECK(std::isnan(n) || std::isnan(m));
10567  CHECK(std::isnan(expected));
10568
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);
10605  CHECK(IsSignallingNaN(sn));
10606  CHECK(IsSignallingNaN(sm));
10607  CHECK(IsQuietNaN(qn));
10608  CHECK(IsQuietNaN(qm));
10609
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;
10615  CHECK(IsQuietNaN(sn_proc));
10616  CHECK(IsQuietNaN(sm_proc));
10617  CHECK(IsQuietNaN(qn_proc));
10618  CHECK(IsQuietNaN(qm_proc));
10619
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) {
10638  CHECK(std::isnan(n) || std::isnan(m) || std::isnan(a));
10639
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);
10731  CHECK(IsSignallingNaN(sn));
10732  CHECK(IsSignallingNaN(sm));
10733  CHECK(IsSignallingNaN(sa));
10734  CHECK(IsQuietNaN(qn));
10735  CHECK(IsQuietNaN(qm));
10736  CHECK(IsQuietNaN(qa));
10737
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) {
10766  CHECK(std::isnan(n) || std::isnan(m) || std::isnan(a));
10767
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);
10859  CHECK(IsSignallingNaN(sn));
10860  CHECK(IsSignallingNaN(sm));
10861  CHECK(IsSignallingNaN(sa));
10862  CHECK(IsQuietNaN(qn));
10863  CHECK(IsQuietNaN(qm));
10864  CHECK(IsQuietNaN(qa));
10865
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())) {
11102      CHECK(info->data() == constant_pool_size);
11103      ++pool_count;
11104    }
11105    if (RelocInfo::IsVeneerPool(info->rmode())) {
11106      CHECK(info->data() == veneer_pool_size);
11107      ++pool_count;
11108    }
11109  }
11110
11111  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);
11282
11283  TEARDOWN();
11284}
11285