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/macro-assembler.h"
41#include "test/cctest/cctest.h"
42#include "test/cctest/test-utils-arm64.h"
43
44using namespace v8::internal;
45
46// Test infrastructure.
47//
48// Tests are functions which accept no parameters and have no return values.
49// The testing code should not perform an explicit return once completed. For
50// example to test the mov immediate instruction a very simple test would be:
51//
52//   TEST(mov_x0_one) {
53//     SETUP();
54//
55//     START();
56//     __ mov(x0, Operand(1));
57//     END();
58//
59//     RUN();
60//
61//     CHECK_EQUAL_64(1, x0);
62//
63//     TEARDOWN();
64//   }
65//
66// Within a START ... END block all registers but sp can be modified. sp has to
67// be explicitly saved/restored. The END() macro replaces the function return
68// so it may appear multiple times in a test if the test has multiple exit
69// points.
70//
71// Once the test has been run all integer and floating point registers as well
72// as flags are accessible through a RegisterDump instance, see
73// utils-arm64.cc for more info on RegisterDump.
74//
75// We provide some helper assert to handle common cases:
76//
77//   CHECK_EQUAL_32(int32_t, int_32t)
78//   CHECK_EQUAL_FP32(float, float)
79//   CHECK_EQUAL_32(int32_t, W register)
80//   CHECK_EQUAL_FP32(float, S register)
81//   CHECK_EQUAL_64(int64_t, int_64t)
82//   CHECK_EQUAL_FP64(double, double)
83//   CHECK_EQUAL_64(int64_t, X register)
84//   CHECK_EQUAL_64(X register, X register)
85//   CHECK_EQUAL_FP64(double, D register)
86//
87// e.g. CHECK_EQUAL_64(0.5, d30);
88//
89// If more advance computation is required before the assert then access the
90// RegisterDump named core directly:
91//
92//   CHECK_EQUAL_64(0x1234, core.xreg(0) & 0xffff);
93
94
95#if 0  // TODO(all): enable.
96static v8::Persistent<v8::Context> env;
97
98static void InitializeVM() {
99  if (env.IsEmpty()) {
100    env = v8::Context::New();
101  }
102}
103#endif
104
105#define __ masm.
106
107#define BUF_SIZE 8192
108#define SETUP() SETUP_SIZE(BUF_SIZE)
109
110#define INIT_V8()                                                              \
111  CcTest::InitializeVM();                                                      \
112
113#ifdef USE_SIMULATOR
114
115// Run tests with the simulator.
116#define SETUP_SIZE(buf_size)                    \
117  Isolate* isolate = Isolate::Current();        \
118  HandleScope scope(isolate);                   \
119  DCHECK(isolate != NULL);                      \
120  byte* buf = new byte[buf_size];               \
121  MacroAssembler masm(isolate, buf, buf_size);  \
122  Decoder<DispatchingDecoderVisitor>* decoder = \
123      new Decoder<DispatchingDecoderVisitor>(); \
124  Simulator simulator(decoder);                 \
125  PrintDisassembler* pdis = NULL;               \
126  RegisterDump core;
127
128/*  if (Cctest::trace_sim()) {                                                 \
129    pdis = new PrintDisassembler(stdout);                                      \
130    decoder.PrependVisitor(pdis);                                              \
131  }                                                                            \
132  */
133
134// Reset the assembler and simulator, so that instructions can be generated,
135// but don't actually emit any code. This can be used by tests that need to
136// emit instructions at the start of the buffer. Note that START_AFTER_RESET
137// must be called before any callee-saved register is modified, and before an
138// END is encountered.
139//
140// Most tests should call START, rather than call RESET directly.
141#define RESET()                                                                \
142  __ Reset();                                                                  \
143  simulator.ResetState();
144
145#define START_AFTER_RESET()                                                    \
146  __ SetStackPointer(csp);                                                     \
147  __ PushCalleeSavedRegisters();                                               \
148  __ Debug("Start test.", __LINE__, TRACE_ENABLE | LOG_ALL);
149
150#define START()                                                                \
151  RESET();                                                                     \
152  START_AFTER_RESET();
153
154#define RUN()                                                                  \
155  simulator.RunFrom(reinterpret_cast<Instruction*>(buf))
156
157#define END()                                                                  \
158  __ Debug("End test.", __LINE__, TRACE_DISABLE | LOG_ALL);                    \
159  core.Dump(&masm);                                                            \
160  __ PopCalleeSavedRegisters();                                                \
161  __ Ret();                                                                    \
162  __ GetCode(NULL);
163
164#define TEARDOWN()                                                             \
165  delete pdis;                                                                 \
166  delete[] buf;
167
168#else  // ifdef USE_SIMULATOR.
169// Run the test on real hardware or models.
170#define SETUP_SIZE(buf_size)                                                   \
171  Isolate* isolate = Isolate::Current();                                       \
172  HandleScope scope(isolate);                                                  \
173  DCHECK(isolate != NULL);                                                     \
174  byte* buf = new byte[buf_size];                                              \
175  MacroAssembler masm(isolate, buf, buf_size);                                 \
176  RegisterDump core;
177
178#define RESET()                                                                \
179  __ Reset();                                                                  \
180  /* Reset the machine state (like simulator.ResetState()). */                 \
181  __ Msr(NZCV, xzr);                                                           \
182  __ Msr(FPCR, xzr);
183
184
185#define START_AFTER_RESET()                                                    \
186  __ SetStackPointer(csp);                                                     \
187  __ PushCalleeSavedRegisters();
188
189#define START()                                                                \
190  RESET();                                                                     \
191  START_AFTER_RESET();
192
193#define RUN()                                                \
194  CpuFeatures::FlushICache(buf, masm.SizeOfGeneratedCode()); \
195  {                                                          \
196    void (*test_function)(void);                             \
197    memcpy(&test_function, &buf, sizeof(buf));               \
198    test_function();                                         \
199  }
200
201#define END()                                                                  \
202  core.Dump(&masm);                                                            \
203  __ PopCalleeSavedRegisters();                                                \
204  __ Ret();                                                                    \
205  __ GetCode(NULL);
206
207#define TEARDOWN()                                                             \
208  delete[] buf;
209
210#endif  // ifdef USE_SIMULATOR.
211
212#define CHECK_EQUAL_NZCV(expected)                                            \
213  CHECK(EqualNzcv(expected, core.flags_nzcv()))
214
215#define CHECK_EQUAL_REGISTERS(expected)                                       \
216  CHECK(EqualRegisters(&expected, &core))
217
218#define CHECK_EQUAL_32(expected, result)                                      \
219  CHECK(Equal32(static_cast<uint32_t>(expected), &core, result))
220
221#define CHECK_EQUAL_FP32(expected, result)                                    \
222  CHECK(EqualFP32(expected, &core, result))
223
224#define CHECK_EQUAL_64(expected, result)                                      \
225  CHECK(Equal64(expected, &core, result))
226
227#define CHECK_EQUAL_FP64(expected, result)                                    \
228  CHECK(EqualFP64(expected, &core, result))
229
230#ifdef DEBUG
231#define DCHECK_LITERAL_POOL_SIZE(expected)                                     \
232  CHECK((expected) == (__ LiteralPoolSize()))
233#else
234#define DCHECK_LITERAL_POOL_SIZE(expected)                                     \
235  ((void) 0)
236#endif
237
238
239TEST(stack_ops) {
240  INIT_V8();
241  SETUP();
242
243  START();
244  // save csp.
245  __ Mov(x29, csp);
246
247  // Set the csp to a known value.
248  __ Mov(x16, 0x1000);
249  __ Mov(csp, x16);
250  __ Mov(x0, csp);
251
252  // Add immediate to the csp, and move the result to a normal register.
253  __ Add(csp, csp, Operand(0x50));
254  __ Mov(x1, csp);
255
256  // Add extended to the csp, and move the result to a normal register.
257  __ Mov(x17, 0xfff);
258  __ Add(csp, csp, Operand(x17, SXTB));
259  __ Mov(x2, csp);
260
261  // Create an csp using a logical instruction, and move to normal register.
262  __ Orr(csp, xzr, Operand(0x1fff));
263  __ Mov(x3, csp);
264
265  // Write wcsp using a logical instruction.
266  __ Orr(wcsp, wzr, Operand(0xfffffff8L));
267  __ Mov(x4, csp);
268
269  // Write csp, and read back wcsp.
270  __ Orr(csp, xzr, Operand(0xfffffff8L));
271  __ Mov(w5, wcsp);
272
273  //  restore csp.
274  __ Mov(csp, x29);
275  END();
276
277  RUN();
278
279  CHECK_EQUAL_64(0x1000, x0);
280  CHECK_EQUAL_64(0x1050, x1);
281  CHECK_EQUAL_64(0x104f, x2);
282  CHECK_EQUAL_64(0x1fff, x3);
283  CHECK_EQUAL_64(0xfffffff8, x4);
284  CHECK_EQUAL_64(0xfffffff8, x5);
285
286  TEARDOWN();
287}
288
289
290TEST(mvn) {
291  INIT_V8();
292  SETUP();
293
294  START();
295  __ Mvn(w0, 0xfff);
296  __ Mvn(x1, 0xfff);
297  __ Mvn(w2, Operand(w0, LSL, 1));
298  __ Mvn(x3, Operand(x1, LSL, 2));
299  __ Mvn(w4, Operand(w0, LSR, 3));
300  __ Mvn(x5, Operand(x1, LSR, 4));
301  __ Mvn(w6, Operand(w0, ASR, 11));
302  __ Mvn(x7, Operand(x1, ASR, 12));
303  __ Mvn(w8, Operand(w0, ROR, 13));
304  __ Mvn(x9, Operand(x1, ROR, 14));
305  __ Mvn(w10, Operand(w2, UXTB));
306  __ Mvn(x11, Operand(x2, SXTB, 1));
307  __ Mvn(w12, Operand(w2, UXTH, 2));
308  __ Mvn(x13, Operand(x2, SXTH, 3));
309  __ Mvn(x14, Operand(w2, UXTW, 4));
310  __ Mvn(x15, Operand(w2, SXTW, 4));
311  END();
312
313  RUN();
314
315  CHECK_EQUAL_64(0xfffff000, x0);
316  CHECK_EQUAL_64(0xfffffffffffff000UL, x1);
317  CHECK_EQUAL_64(0x00001fff, x2);
318  CHECK_EQUAL_64(0x0000000000003fffUL, x3);
319  CHECK_EQUAL_64(0xe00001ff, x4);
320  CHECK_EQUAL_64(0xf0000000000000ffUL, x5);
321  CHECK_EQUAL_64(0x00000001, x6);
322  CHECK_EQUAL_64(0x0, x7);
323  CHECK_EQUAL_64(0x7ff80000, x8);
324  CHECK_EQUAL_64(0x3ffc000000000000UL, x9);
325  CHECK_EQUAL_64(0xffffff00, x10);
326  CHECK_EQUAL_64(0x0000000000000001UL, x11);
327  CHECK_EQUAL_64(0xffff8003, x12);
328  CHECK_EQUAL_64(0xffffffffffff0007UL, x13);
329  CHECK_EQUAL_64(0xfffffffffffe000fUL, x14);
330  CHECK_EQUAL_64(0xfffffffffffe000fUL, x15);
331
332  TEARDOWN();
333}
334
335
336TEST(mov) {
337  INIT_V8();
338  SETUP();
339
340  START();
341  __ Mov(x0, 0xffffffffffffffffL);
342  __ Mov(x1, 0xffffffffffffffffL);
343  __ Mov(x2, 0xffffffffffffffffL);
344  __ Mov(x3, 0xffffffffffffffffL);
345
346  __ Mov(x0, 0x0123456789abcdefL);
347
348  __ movz(x1, 0xabcdL << 16);
349  __ movk(x2, 0xabcdL << 32);
350  __ movn(x3, 0xabcdL << 48);
351
352  __ Mov(x4, 0x0123456789abcdefL);
353  __ Mov(x5, x4);
354
355  __ Mov(w6, -1);
356
357  // Test that moves back to the same register have the desired effect. This
358  // is a no-op for X registers, and a truncation for W registers.
359  __ Mov(x7, 0x0123456789abcdefL);
360  __ Mov(x7, x7);
361  __ Mov(x8, 0x0123456789abcdefL);
362  __ Mov(w8, w8);
363  __ Mov(x9, 0x0123456789abcdefL);
364  __ Mov(x9, Operand(x9));
365  __ Mov(x10, 0x0123456789abcdefL);
366  __ Mov(w10, Operand(w10));
367
368  __ Mov(w11, 0xfff);
369  __ Mov(x12, 0xfff);
370  __ Mov(w13, Operand(w11, LSL, 1));
371  __ Mov(x14, Operand(x12, LSL, 2));
372  __ Mov(w15, Operand(w11, LSR, 3));
373  __ Mov(x18, Operand(x12, LSR, 4));
374  __ Mov(w19, Operand(w11, ASR, 11));
375  __ Mov(x20, Operand(x12, ASR, 12));
376  __ Mov(w21, Operand(w11, ROR, 13));
377  __ Mov(x22, Operand(x12, ROR, 14));
378  __ Mov(w23, Operand(w13, UXTB));
379  __ Mov(x24, Operand(x13, SXTB, 1));
380  __ Mov(w25, Operand(w13, UXTH, 2));
381  __ Mov(x26, Operand(x13, SXTH, 3));
382  __ Mov(x27, Operand(w13, UXTW, 4));
383  END();
384
385  RUN();
386
387  CHECK_EQUAL_64(0x0123456789abcdefL, x0);
388  CHECK_EQUAL_64(0x00000000abcd0000L, x1);
389  CHECK_EQUAL_64(0xffffabcdffffffffL, x2);
390  CHECK_EQUAL_64(0x5432ffffffffffffL, x3);
391  CHECK_EQUAL_64(x4, x5);
392  CHECK_EQUAL_32(-1, w6);
393  CHECK_EQUAL_64(0x0123456789abcdefL, x7);
394  CHECK_EQUAL_32(0x89abcdefL, w8);
395  CHECK_EQUAL_64(0x0123456789abcdefL, x9);
396  CHECK_EQUAL_32(0x89abcdefL, w10);
397  CHECK_EQUAL_64(0x00000fff, x11);
398  CHECK_EQUAL_64(0x0000000000000fffUL, x12);
399  CHECK_EQUAL_64(0x00001ffe, x13);
400  CHECK_EQUAL_64(0x0000000000003ffcUL, x14);
401  CHECK_EQUAL_64(0x000001ff, x15);
402  CHECK_EQUAL_64(0x00000000000000ffUL, x18);
403  CHECK_EQUAL_64(0x00000001, x19);
404  CHECK_EQUAL_64(0x0, x20);
405  CHECK_EQUAL_64(0x7ff80000, x21);
406  CHECK_EQUAL_64(0x3ffc000000000000UL, x22);
407  CHECK_EQUAL_64(0x000000fe, x23);
408  CHECK_EQUAL_64(0xfffffffffffffffcUL, x24);
409  CHECK_EQUAL_64(0x00007ff8, x25);
410  CHECK_EQUAL_64(0x000000000000fff0UL, x26);
411  CHECK_EQUAL_64(0x000000000001ffe0UL, x27);
412
413  TEARDOWN();
414}
415
416
417TEST(mov_imm_w) {
418  INIT_V8();
419  SETUP();
420
421  START();
422  __ Mov(w0, 0xffffffffL);
423  __ Mov(w1, 0xffff1234L);
424  __ Mov(w2, 0x1234ffffL);
425  __ Mov(w3, 0x00000000L);
426  __ Mov(w4, 0x00001234L);
427  __ Mov(w5, 0x12340000L);
428  __ Mov(w6, 0x12345678L);
429  __ Mov(w7, (int32_t)0x80000000);
430  __ Mov(w8, (int32_t)0xffff0000);
431  __ Mov(w9, kWMinInt);
432  END();
433
434  RUN();
435
436  CHECK_EQUAL_64(0xffffffffL, x0);
437  CHECK_EQUAL_64(0xffff1234L, x1);
438  CHECK_EQUAL_64(0x1234ffffL, x2);
439  CHECK_EQUAL_64(0x00000000L, x3);
440  CHECK_EQUAL_64(0x00001234L, x4);
441  CHECK_EQUAL_64(0x12340000L, x5);
442  CHECK_EQUAL_64(0x12345678L, x6);
443  CHECK_EQUAL_64(0x80000000L, x7);
444  CHECK_EQUAL_64(0xffff0000L, x8);
445  CHECK_EQUAL_32(kWMinInt, w9);
446
447  TEARDOWN();
448}
449
450
451TEST(mov_imm_x) {
452  INIT_V8();
453  SETUP();
454
455  START();
456  __ Mov(x0, 0xffffffffffffffffL);
457  __ Mov(x1, 0xffffffffffff1234L);
458  __ Mov(x2, 0xffffffff12345678L);
459  __ Mov(x3, 0xffff1234ffff5678L);
460  __ Mov(x4, 0x1234ffffffff5678L);
461  __ Mov(x5, 0x1234ffff5678ffffL);
462  __ Mov(x6, 0x12345678ffffffffL);
463  __ Mov(x7, 0x1234ffffffffffffL);
464  __ Mov(x8, 0x123456789abcffffL);
465  __ Mov(x9, 0x12345678ffff9abcL);
466  __ Mov(x10, 0x1234ffff56789abcL);
467  __ Mov(x11, 0xffff123456789abcL);
468  __ Mov(x12, 0x0000000000000000L);
469  __ Mov(x13, 0x0000000000001234L);
470  __ Mov(x14, 0x0000000012345678L);
471  __ Mov(x15, 0x0000123400005678L);
472  __ Mov(x18, 0x1234000000005678L);
473  __ Mov(x19, 0x1234000056780000L);
474  __ Mov(x20, 0x1234567800000000L);
475  __ Mov(x21, 0x1234000000000000L);
476  __ Mov(x22, 0x123456789abc0000L);
477  __ Mov(x23, 0x1234567800009abcL);
478  __ Mov(x24, 0x1234000056789abcL);
479  __ Mov(x25, 0x0000123456789abcL);
480  __ Mov(x26, 0x123456789abcdef0L);
481  __ Mov(x27, 0xffff000000000001L);
482  __ Mov(x28, 0x8000ffff00000000L);
483  END();
484
485  RUN();
486
487  CHECK_EQUAL_64(0xffffffffffff1234L, x1);
488  CHECK_EQUAL_64(0xffffffff12345678L, x2);
489  CHECK_EQUAL_64(0xffff1234ffff5678L, x3);
490  CHECK_EQUAL_64(0x1234ffffffff5678L, x4);
491  CHECK_EQUAL_64(0x1234ffff5678ffffL, x5);
492  CHECK_EQUAL_64(0x12345678ffffffffL, x6);
493  CHECK_EQUAL_64(0x1234ffffffffffffL, x7);
494  CHECK_EQUAL_64(0x123456789abcffffL, x8);
495  CHECK_EQUAL_64(0x12345678ffff9abcL, x9);
496  CHECK_EQUAL_64(0x1234ffff56789abcL, x10);
497  CHECK_EQUAL_64(0xffff123456789abcL, x11);
498  CHECK_EQUAL_64(0x0000000000000000L, x12);
499  CHECK_EQUAL_64(0x0000000000001234L, x13);
500  CHECK_EQUAL_64(0x0000000012345678L, x14);
501  CHECK_EQUAL_64(0x0000123400005678L, x15);
502  CHECK_EQUAL_64(0x1234000000005678L, x18);
503  CHECK_EQUAL_64(0x1234000056780000L, x19);
504  CHECK_EQUAL_64(0x1234567800000000L, x20);
505  CHECK_EQUAL_64(0x1234000000000000L, x21);
506  CHECK_EQUAL_64(0x123456789abc0000L, x22);
507  CHECK_EQUAL_64(0x1234567800009abcL, x23);
508  CHECK_EQUAL_64(0x1234000056789abcL, x24);
509  CHECK_EQUAL_64(0x0000123456789abcL, x25);
510  CHECK_EQUAL_64(0x123456789abcdef0L, x26);
511  CHECK_EQUAL_64(0xffff000000000001L, x27);
512  CHECK_EQUAL_64(0x8000ffff00000000L, x28);
513
514  TEARDOWN();
515}
516
517
518TEST(orr) {
519  INIT_V8();
520  SETUP();
521
522  START();
523  __ Mov(x0, 0xf0f0);
524  __ Mov(x1, 0xf00000ff);
525
526  __ Orr(x2, x0, Operand(x1));
527  __ Orr(w3, w0, Operand(w1, LSL, 28));
528  __ Orr(x4, x0, Operand(x1, LSL, 32));
529  __ Orr(x5, x0, Operand(x1, LSR, 4));
530  __ Orr(w6, w0, Operand(w1, ASR, 4));
531  __ Orr(x7, x0, Operand(x1, ASR, 4));
532  __ Orr(w8, w0, Operand(w1, ROR, 12));
533  __ Orr(x9, x0, Operand(x1, ROR, 12));
534  __ Orr(w10, w0, Operand(0xf));
535  __ Orr(x11, x0, Operand(0xf0000000f0000000L));
536  END();
537
538  RUN();
539
540  CHECK_EQUAL_64(0xf000f0ff, x2);
541  CHECK_EQUAL_64(0xf000f0f0, x3);
542  CHECK_EQUAL_64(0xf00000ff0000f0f0L, x4);
543  CHECK_EQUAL_64(0x0f00f0ff, x5);
544  CHECK_EQUAL_64(0xff00f0ff, x6);
545  CHECK_EQUAL_64(0x0f00f0ff, x7);
546  CHECK_EQUAL_64(0x0ffff0f0, x8);
547  CHECK_EQUAL_64(0x0ff00000000ff0f0L, x9);
548  CHECK_EQUAL_64(0xf0ff, x10);
549  CHECK_EQUAL_64(0xf0000000f000f0f0L, x11);
550
551  TEARDOWN();
552}
553
554
555TEST(orr_extend) {
556  INIT_V8();
557  SETUP();
558
559  START();
560  __ Mov(x0, 1);
561  __ Mov(x1, 0x8000000080008080UL);
562  __ Orr(w6, w0, Operand(w1, UXTB));
563  __ Orr(x7, x0, Operand(x1, UXTH, 1));
564  __ Orr(w8, w0, Operand(w1, UXTW, 2));
565  __ Orr(x9, x0, Operand(x1, UXTX, 3));
566  __ Orr(w10, w0, Operand(w1, SXTB));
567  __ Orr(x11, x0, Operand(x1, SXTH, 1));
568  __ Orr(x12, x0, Operand(x1, SXTW, 2));
569  __ Orr(x13, x0, Operand(x1, SXTX, 3));
570  END();
571
572  RUN();
573
574  CHECK_EQUAL_64(0x00000081, x6);
575  CHECK_EQUAL_64(0x00010101, x7);
576  CHECK_EQUAL_64(0x00020201, x8);
577  CHECK_EQUAL_64(0x0000000400040401UL, x9);
578  CHECK_EQUAL_64(0x00000000ffffff81UL, x10);
579  CHECK_EQUAL_64(0xffffffffffff0101UL, x11);
580  CHECK_EQUAL_64(0xfffffffe00020201UL, x12);
581  CHECK_EQUAL_64(0x0000000400040401UL, x13);
582
583  TEARDOWN();
584}
585
586
587TEST(bitwise_wide_imm) {
588  INIT_V8();
589  SETUP();
590
591  START();
592  __ Mov(x0, 0);
593  __ Mov(x1, 0xf0f0f0f0f0f0f0f0UL);
594
595  __ Orr(x10, x0, Operand(0x1234567890abcdefUL));
596  __ Orr(w11, w1, Operand(0x90abcdef));
597
598  __ Orr(w12, w0, kWMinInt);
599  __ Eor(w13, w0, kWMinInt);
600  END();
601
602  RUN();
603
604  CHECK_EQUAL_64(0, x0);
605  CHECK_EQUAL_64(0xf0f0f0f0f0f0f0f0UL, x1);
606  CHECK_EQUAL_64(0x1234567890abcdefUL, x10);
607  CHECK_EQUAL_64(0xf0fbfdffUL, x11);
608  CHECK_EQUAL_32(kWMinInt, w12);
609  CHECK_EQUAL_32(kWMinInt, w13);
610
611  TEARDOWN();
612}
613
614
615TEST(orn) {
616  INIT_V8();
617  SETUP();
618
619  START();
620  __ Mov(x0, 0xf0f0);
621  __ Mov(x1, 0xf00000ff);
622
623  __ Orn(x2, x0, Operand(x1));
624  __ Orn(w3, w0, Operand(w1, LSL, 4));
625  __ Orn(x4, x0, Operand(x1, LSL, 4));
626  __ Orn(x5, x0, Operand(x1, LSR, 1));
627  __ Orn(w6, w0, Operand(w1, ASR, 1));
628  __ Orn(x7, x0, Operand(x1, ASR, 1));
629  __ Orn(w8, w0, Operand(w1, ROR, 16));
630  __ Orn(x9, x0, Operand(x1, ROR, 16));
631  __ Orn(w10, w0, Operand(0xffff));
632  __ Orn(x11, x0, Operand(0xffff0000ffffL));
633  END();
634
635  RUN();
636
637  CHECK_EQUAL_64(0xffffffff0ffffff0L, x2);
638  CHECK_EQUAL_64(0xfffff0ff, x3);
639  CHECK_EQUAL_64(0xfffffff0fffff0ffL, x4);
640  CHECK_EQUAL_64(0xffffffff87fffff0L, x5);
641  CHECK_EQUAL_64(0x07fffff0, x6);
642  CHECK_EQUAL_64(0xffffffff87fffff0L, x7);
643  CHECK_EQUAL_64(0xff00ffff, x8);
644  CHECK_EQUAL_64(0xff00ffffffffffffL, x9);
645  CHECK_EQUAL_64(0xfffff0f0, x10);
646  CHECK_EQUAL_64(0xffff0000fffff0f0L, x11);
647
648  TEARDOWN();
649}
650
651
652TEST(orn_extend) {
653  INIT_V8();
654  SETUP();
655
656  START();
657  __ Mov(x0, 1);
658  __ Mov(x1, 0x8000000080008081UL);
659  __ Orn(w6, w0, Operand(w1, UXTB));
660  __ Orn(x7, x0, Operand(x1, UXTH, 1));
661  __ Orn(w8, w0, Operand(w1, UXTW, 2));
662  __ Orn(x9, x0, Operand(x1, UXTX, 3));
663  __ Orn(w10, w0, Operand(w1, SXTB));
664  __ Orn(x11, x0, Operand(x1, SXTH, 1));
665  __ Orn(x12, x0, Operand(x1, SXTW, 2));
666  __ Orn(x13, x0, Operand(x1, SXTX, 3));
667  END();
668
669  RUN();
670
671  CHECK_EQUAL_64(0xffffff7f, x6);
672  CHECK_EQUAL_64(0xfffffffffffefefdUL, x7);
673  CHECK_EQUAL_64(0xfffdfdfb, x8);
674  CHECK_EQUAL_64(0xfffffffbfffbfbf7UL, x9);
675  CHECK_EQUAL_64(0x0000007f, x10);
676  CHECK_EQUAL_64(0x0000fefd, x11);
677  CHECK_EQUAL_64(0x00000001fffdfdfbUL, x12);
678  CHECK_EQUAL_64(0xfffffffbfffbfbf7UL, x13);
679
680  TEARDOWN();
681}
682
683
684TEST(and_) {
685  INIT_V8();
686  SETUP();
687
688  START();
689  __ Mov(x0, 0xfff0);
690  __ Mov(x1, 0xf00000ff);
691
692  __ And(x2, x0, Operand(x1));
693  __ And(w3, w0, Operand(w1, LSL, 4));
694  __ And(x4, x0, Operand(x1, LSL, 4));
695  __ And(x5, x0, Operand(x1, LSR, 1));
696  __ And(w6, w0, Operand(w1, ASR, 20));
697  __ And(x7, x0, Operand(x1, ASR, 20));
698  __ And(w8, w0, Operand(w1, ROR, 28));
699  __ And(x9, x0, Operand(x1, ROR, 28));
700  __ And(w10, w0, Operand(0xff00));
701  __ And(x11, x0, Operand(0xff));
702  END();
703
704  RUN();
705
706  CHECK_EQUAL_64(0x000000f0, x2);
707  CHECK_EQUAL_64(0x00000ff0, x3);
708  CHECK_EQUAL_64(0x00000ff0, x4);
709  CHECK_EQUAL_64(0x00000070, x5);
710  CHECK_EQUAL_64(0x0000ff00, x6);
711  CHECK_EQUAL_64(0x00000f00, x7);
712  CHECK_EQUAL_64(0x00000ff0, x8);
713  CHECK_EQUAL_64(0x00000000, x9);
714  CHECK_EQUAL_64(0x0000ff00, x10);
715  CHECK_EQUAL_64(0x000000f0, x11);
716
717  TEARDOWN();
718}
719
720
721TEST(and_extend) {
722  INIT_V8();
723  SETUP();
724
725  START();
726  __ Mov(x0, 0xffffffffffffffffUL);
727  __ Mov(x1, 0x8000000080008081UL);
728  __ And(w6, w0, Operand(w1, UXTB));
729  __ And(x7, x0, Operand(x1, UXTH, 1));
730  __ And(w8, w0, Operand(w1, UXTW, 2));
731  __ And(x9, x0, Operand(x1, UXTX, 3));
732  __ And(w10, w0, Operand(w1, SXTB));
733  __ And(x11, x0, Operand(x1, SXTH, 1));
734  __ And(x12, x0, Operand(x1, SXTW, 2));
735  __ And(x13, x0, Operand(x1, SXTX, 3));
736  END();
737
738  RUN();
739
740  CHECK_EQUAL_64(0x00000081, x6);
741  CHECK_EQUAL_64(0x00010102, x7);
742  CHECK_EQUAL_64(0x00020204, x8);
743  CHECK_EQUAL_64(0x0000000400040408UL, x9);
744  CHECK_EQUAL_64(0xffffff81, x10);
745  CHECK_EQUAL_64(0xffffffffffff0102UL, x11);
746  CHECK_EQUAL_64(0xfffffffe00020204UL, x12);
747  CHECK_EQUAL_64(0x0000000400040408UL, x13);
748
749  TEARDOWN();
750}
751
752
753TEST(ands) {
754  INIT_V8();
755  SETUP();
756
757  START();
758  __ Mov(x1, 0xf00000ff);
759  __ Ands(w0, w1, Operand(w1));
760  END();
761
762  RUN();
763
764  CHECK_EQUAL_NZCV(NFlag);
765  CHECK_EQUAL_64(0xf00000ff, x0);
766
767  START();
768  __ Mov(x0, 0xfff0);
769  __ Mov(x1, 0xf00000ff);
770  __ Ands(w0, w0, Operand(w1, LSR, 4));
771  END();
772
773  RUN();
774
775  CHECK_EQUAL_NZCV(ZFlag);
776  CHECK_EQUAL_64(0x00000000, x0);
777
778  START();
779  __ Mov(x0, 0x8000000000000000L);
780  __ Mov(x1, 0x00000001);
781  __ Ands(x0, x0, Operand(x1, ROR, 1));
782  END();
783
784  RUN();
785
786  CHECK_EQUAL_NZCV(NFlag);
787  CHECK_EQUAL_64(0x8000000000000000L, x0);
788
789  START();
790  __ Mov(x0, 0xfff0);
791  __ Ands(w0, w0, Operand(0xf));
792  END();
793
794  RUN();
795
796  CHECK_EQUAL_NZCV(ZFlag);
797  CHECK_EQUAL_64(0x00000000, x0);
798
799  START();
800  __ Mov(x0, 0xff000000);
801  __ Ands(w0, w0, Operand(0x80000000));
802  END();
803
804  RUN();
805
806  CHECK_EQUAL_NZCV(NFlag);
807  CHECK_EQUAL_64(0x80000000, x0);
808
809  TEARDOWN();
810}
811
812
813TEST(bic) {
814  INIT_V8();
815  SETUP();
816
817  START();
818  __ Mov(x0, 0xfff0);
819  __ Mov(x1, 0xf00000ff);
820
821  __ Bic(x2, x0, Operand(x1));
822  __ Bic(w3, w0, Operand(w1, LSL, 4));
823  __ Bic(x4, x0, Operand(x1, LSL, 4));
824  __ Bic(x5, x0, Operand(x1, LSR, 1));
825  __ Bic(w6, w0, Operand(w1, ASR, 20));
826  __ Bic(x7, x0, Operand(x1, ASR, 20));
827  __ Bic(w8, w0, Operand(w1, ROR, 28));
828  __ Bic(x9, x0, Operand(x1, ROR, 24));
829  __ Bic(x10, x0, Operand(0x1f));
830  __ Bic(x11, x0, Operand(0x100));
831
832  // Test bic into csp when the constant cannot be encoded in the immediate
833  // field.
834  // Use x20 to preserve csp. We check for the result via x21 because the
835  // test infrastructure requires that csp be restored to its original value.
836  __ Mov(x20, csp);
837  __ Mov(x0, 0xffffff);
838  __ Bic(csp, x0, Operand(0xabcdef));
839  __ Mov(x21, csp);
840  __ Mov(csp, x20);
841  END();
842
843  RUN();
844
845  CHECK_EQUAL_64(0x0000ff00, x2);
846  CHECK_EQUAL_64(0x0000f000, x3);
847  CHECK_EQUAL_64(0x0000f000, x4);
848  CHECK_EQUAL_64(0x0000ff80, x5);
849  CHECK_EQUAL_64(0x000000f0, x6);
850  CHECK_EQUAL_64(0x0000f0f0, x7);
851  CHECK_EQUAL_64(0x0000f000, x8);
852  CHECK_EQUAL_64(0x0000ff00, x9);
853  CHECK_EQUAL_64(0x0000ffe0, x10);
854  CHECK_EQUAL_64(0x0000fef0, x11);
855
856  CHECK_EQUAL_64(0x543210, x21);
857
858  TEARDOWN();
859}
860
861
862TEST(bic_extend) {
863  INIT_V8();
864  SETUP();
865
866  START();
867  __ Mov(x0, 0xffffffffffffffffUL);
868  __ Mov(x1, 0x8000000080008081UL);
869  __ Bic(w6, w0, Operand(w1, UXTB));
870  __ Bic(x7, x0, Operand(x1, UXTH, 1));
871  __ Bic(w8, w0, Operand(w1, UXTW, 2));
872  __ Bic(x9, x0, Operand(x1, UXTX, 3));
873  __ Bic(w10, w0, Operand(w1, SXTB));
874  __ Bic(x11, x0, Operand(x1, SXTH, 1));
875  __ Bic(x12, x0, Operand(x1, SXTW, 2));
876  __ Bic(x13, x0, Operand(x1, SXTX, 3));
877  END();
878
879  RUN();
880
881  CHECK_EQUAL_64(0xffffff7e, x6);
882  CHECK_EQUAL_64(0xfffffffffffefefdUL, x7);
883  CHECK_EQUAL_64(0xfffdfdfb, x8);
884  CHECK_EQUAL_64(0xfffffffbfffbfbf7UL, x9);
885  CHECK_EQUAL_64(0x0000007e, x10);
886  CHECK_EQUAL_64(0x0000fefd, x11);
887  CHECK_EQUAL_64(0x00000001fffdfdfbUL, x12);
888  CHECK_EQUAL_64(0xfffffffbfffbfbf7UL, x13);
889
890  TEARDOWN();
891}
892
893
894TEST(bics) {
895  INIT_V8();
896  SETUP();
897
898  START();
899  __ Mov(x1, 0xffff);
900  __ Bics(w0, w1, Operand(w1));
901  END();
902
903  RUN();
904
905  CHECK_EQUAL_NZCV(ZFlag);
906  CHECK_EQUAL_64(0x00000000, x0);
907
908  START();
909  __ Mov(x0, 0xffffffff);
910  __ Bics(w0, w0, Operand(w0, LSR, 1));
911  END();
912
913  RUN();
914
915  CHECK_EQUAL_NZCV(NFlag);
916  CHECK_EQUAL_64(0x80000000, x0);
917
918  START();
919  __ Mov(x0, 0x8000000000000000L);
920  __ Mov(x1, 0x00000001);
921  __ Bics(x0, x0, Operand(x1, ROR, 1));
922  END();
923
924  RUN();
925
926  CHECK_EQUAL_NZCV(ZFlag);
927  CHECK_EQUAL_64(0x00000000, x0);
928
929  START();
930  __ Mov(x0, 0xffffffffffffffffL);
931  __ Bics(x0, x0, Operand(0x7fffffffffffffffL));
932  END();
933
934  RUN();
935
936  CHECK_EQUAL_NZCV(NFlag);
937  CHECK_EQUAL_64(0x8000000000000000L, x0);
938
939  START();
940  __ Mov(w0, 0xffff0000);
941  __ Bics(w0, w0, Operand(0xfffffff0));
942  END();
943
944  RUN();
945
946  CHECK_EQUAL_NZCV(ZFlag);
947  CHECK_EQUAL_64(0x00000000, x0);
948
949  TEARDOWN();
950}
951
952
953TEST(eor) {
954  INIT_V8();
955  SETUP();
956
957  START();
958  __ Mov(x0, 0xfff0);
959  __ Mov(x1, 0xf00000ff);
960
961  __ Eor(x2, x0, Operand(x1));
962  __ Eor(w3, w0, Operand(w1, LSL, 4));
963  __ Eor(x4, x0, Operand(x1, LSL, 4));
964  __ Eor(x5, x0, Operand(x1, LSR, 1));
965  __ Eor(w6, w0, Operand(w1, ASR, 20));
966  __ Eor(x7, x0, Operand(x1, ASR, 20));
967  __ Eor(w8, w0, Operand(w1, ROR, 28));
968  __ Eor(x9, x0, Operand(x1, ROR, 28));
969  __ Eor(w10, w0, Operand(0xff00ff00));
970  __ Eor(x11, x0, Operand(0xff00ff00ff00ff00L));
971  END();
972
973  RUN();
974
975  CHECK_EQUAL_64(0xf000ff0f, x2);
976  CHECK_EQUAL_64(0x0000f000, x3);
977  CHECK_EQUAL_64(0x0000000f0000f000L, x4);
978  CHECK_EQUAL_64(0x7800ff8f, x5);
979  CHECK_EQUAL_64(0xffff00f0, x6);
980  CHECK_EQUAL_64(0x0000f0f0, x7);
981  CHECK_EQUAL_64(0x0000f00f, x8);
982  CHECK_EQUAL_64(0x00000ff00000ffffL, x9);
983  CHECK_EQUAL_64(0xff0000f0, x10);
984  CHECK_EQUAL_64(0xff00ff00ff0000f0L, x11);
985
986  TEARDOWN();
987}
988
989
990TEST(eor_extend) {
991  INIT_V8();
992  SETUP();
993
994  START();
995  __ Mov(x0, 0x1111111111111111UL);
996  __ Mov(x1, 0x8000000080008081UL);
997  __ Eor(w6, w0, Operand(w1, UXTB));
998  __ Eor(x7, x0, Operand(x1, UXTH, 1));
999  __ Eor(w8, w0, Operand(w1, UXTW, 2));
1000  __ Eor(x9, x0, Operand(x1, UXTX, 3));
1001  __ Eor(w10, w0, Operand(w1, SXTB));
1002  __ Eor(x11, x0, Operand(x1, SXTH, 1));
1003  __ Eor(x12, x0, Operand(x1, SXTW, 2));
1004  __ Eor(x13, x0, Operand(x1, SXTX, 3));
1005  END();
1006
1007  RUN();
1008
1009  CHECK_EQUAL_64(0x11111190, x6);
1010  CHECK_EQUAL_64(0x1111111111101013UL, x7);
1011  CHECK_EQUAL_64(0x11131315, x8);
1012  CHECK_EQUAL_64(0x1111111511151519UL, x9);
1013  CHECK_EQUAL_64(0xeeeeee90, x10);
1014  CHECK_EQUAL_64(0xeeeeeeeeeeee1013UL, x11);
1015  CHECK_EQUAL_64(0xeeeeeeef11131315UL, x12);
1016  CHECK_EQUAL_64(0x1111111511151519UL, x13);
1017
1018  TEARDOWN();
1019}
1020
1021
1022TEST(eon) {
1023  INIT_V8();
1024  SETUP();
1025
1026  START();
1027  __ Mov(x0, 0xfff0);
1028  __ Mov(x1, 0xf00000ff);
1029
1030  __ Eon(x2, x0, Operand(x1));
1031  __ Eon(w3, w0, Operand(w1, LSL, 4));
1032  __ Eon(x4, x0, Operand(x1, LSL, 4));
1033  __ Eon(x5, x0, Operand(x1, LSR, 1));
1034  __ Eon(w6, w0, Operand(w1, ASR, 20));
1035  __ Eon(x7, x0, Operand(x1, ASR, 20));
1036  __ Eon(w8, w0, Operand(w1, ROR, 28));
1037  __ Eon(x9, x0, Operand(x1, ROR, 28));
1038  __ Eon(w10, w0, Operand(0x03c003c0));
1039  __ Eon(x11, x0, Operand(0x0000100000001000L));
1040  END();
1041
1042  RUN();
1043
1044  CHECK_EQUAL_64(0xffffffff0fff00f0L, x2);
1045  CHECK_EQUAL_64(0xffff0fff, x3);
1046  CHECK_EQUAL_64(0xfffffff0ffff0fffL, x4);
1047  CHECK_EQUAL_64(0xffffffff87ff0070L, x5);
1048  CHECK_EQUAL_64(0x0000ff0f, x6);
1049  CHECK_EQUAL_64(0xffffffffffff0f0fL, x7);
1050  CHECK_EQUAL_64(0xffff0ff0, x8);
1051  CHECK_EQUAL_64(0xfffff00fffff0000L, x9);
1052  CHECK_EQUAL_64(0xfc3f03cf, x10);
1053  CHECK_EQUAL_64(0xffffefffffff100fL, x11);
1054
1055  TEARDOWN();
1056}
1057
1058
1059TEST(eon_extend) {
1060  INIT_V8();
1061  SETUP();
1062
1063  START();
1064  __ Mov(x0, 0x1111111111111111UL);
1065  __ Mov(x1, 0x8000000080008081UL);
1066  __ Eon(w6, w0, Operand(w1, UXTB));
1067  __ Eon(x7, x0, Operand(x1, UXTH, 1));
1068  __ Eon(w8, w0, Operand(w1, UXTW, 2));
1069  __ Eon(x9, x0, Operand(x1, UXTX, 3));
1070  __ Eon(w10, w0, Operand(w1, SXTB));
1071  __ Eon(x11, x0, Operand(x1, SXTH, 1));
1072  __ Eon(x12, x0, Operand(x1, SXTW, 2));
1073  __ Eon(x13, x0, Operand(x1, SXTX, 3));
1074  END();
1075
1076  RUN();
1077
1078  CHECK_EQUAL_64(0xeeeeee6f, x6);
1079  CHECK_EQUAL_64(0xeeeeeeeeeeefefecUL, x7);
1080  CHECK_EQUAL_64(0xeeececea, x8);
1081  CHECK_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x9);
1082  CHECK_EQUAL_64(0x1111116f, x10);
1083  CHECK_EQUAL_64(0x111111111111efecUL, x11);
1084  CHECK_EQUAL_64(0x11111110eeececeaUL, x12);
1085  CHECK_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x13);
1086
1087  TEARDOWN();
1088}
1089
1090
1091TEST(mul) {
1092  INIT_V8();
1093  SETUP();
1094
1095  START();
1096  __ Mov(x16, 0);
1097  __ Mov(x17, 1);
1098  __ Mov(x18, 0xffffffff);
1099  __ Mov(x19, 0xffffffffffffffffUL);
1100
1101  __ Mul(w0, w16, w16);
1102  __ Mul(w1, w16, w17);
1103  __ Mul(w2, w17, w18);
1104  __ Mul(w3, w18, w19);
1105  __ Mul(x4, x16, x16);
1106  __ Mul(x5, x17, x18);
1107  __ Mul(x6, x18, x19);
1108  __ Mul(x7, x19, x19);
1109  __ Smull(x8, w17, w18);
1110  __ Smull(x9, w18, w18);
1111  __ Smull(x10, w19, w19);
1112  __ Mneg(w11, w16, w16);
1113  __ Mneg(w12, w16, w17);
1114  __ Mneg(w13, w17, w18);
1115  __ Mneg(w14, w18, w19);
1116  __ Mneg(x20, x16, x16);
1117  __ Mneg(x21, x17, x18);
1118  __ Mneg(x22, x18, x19);
1119  __ Mneg(x23, x19, x19);
1120  END();
1121
1122  RUN();
1123
1124  CHECK_EQUAL_64(0, x0);
1125  CHECK_EQUAL_64(0, x1);
1126  CHECK_EQUAL_64(0xffffffff, x2);
1127  CHECK_EQUAL_64(1, x3);
1128  CHECK_EQUAL_64(0, x4);
1129  CHECK_EQUAL_64(0xffffffff, x5);
1130  CHECK_EQUAL_64(0xffffffff00000001UL, x6);
1131  CHECK_EQUAL_64(1, x7);
1132  CHECK_EQUAL_64(0xffffffffffffffffUL, x8);
1133  CHECK_EQUAL_64(1, x9);
1134  CHECK_EQUAL_64(1, x10);
1135  CHECK_EQUAL_64(0, x11);
1136  CHECK_EQUAL_64(0, x12);
1137  CHECK_EQUAL_64(1, x13);
1138  CHECK_EQUAL_64(0xffffffff, x14);
1139  CHECK_EQUAL_64(0, x20);
1140  CHECK_EQUAL_64(0xffffffff00000001UL, x21);
1141  CHECK_EQUAL_64(0xffffffff, x22);
1142  CHECK_EQUAL_64(0xffffffffffffffffUL, x23);
1143
1144  TEARDOWN();
1145}
1146
1147
1148static void SmullHelper(int64_t expected, int64_t a, int64_t b) {
1149  SETUP();
1150  START();
1151  __ Mov(w0, a);
1152  __ Mov(w1, b);
1153  __ Smull(x2, w0, w1);
1154  END();
1155  RUN();
1156  CHECK_EQUAL_64(expected, x2);
1157  TEARDOWN();
1158}
1159
1160
1161TEST(smull) {
1162  INIT_V8();
1163  SmullHelper(0, 0, 0);
1164  SmullHelper(1, 1, 1);
1165  SmullHelper(-1, -1, 1);
1166  SmullHelper(1, -1, -1);
1167  SmullHelper(0xffffffff80000000, 0x80000000, 1);
1168  SmullHelper(0x0000000080000000, 0x00010000, 0x00008000);
1169}
1170
1171
1172TEST(madd) {
1173  INIT_V8();
1174  SETUP();
1175
1176  START();
1177  __ Mov(x16, 0);
1178  __ Mov(x17, 1);
1179  __ Mov(x18, 0xffffffff);
1180  __ Mov(x19, 0xffffffffffffffffUL);
1181
1182  __ Madd(w0, w16, w16, w16);
1183  __ Madd(w1, w16, w16, w17);
1184  __ Madd(w2, w16, w16, w18);
1185  __ Madd(w3, w16, w16, w19);
1186  __ Madd(w4, w16, w17, w17);
1187  __ Madd(w5, w17, w17, w18);
1188  __ Madd(w6, w17, w17, w19);
1189  __ Madd(w7, w17, w18, w16);
1190  __ Madd(w8, w17, w18, w18);
1191  __ Madd(w9, w18, w18, w17);
1192  __ Madd(w10, w18, w19, w18);
1193  __ Madd(w11, w19, w19, w19);
1194
1195  __ Madd(x12, x16, x16, x16);
1196  __ Madd(x13, x16, x16, x17);
1197  __ Madd(x14, x16, x16, x18);
1198  __ Madd(x15, x16, x16, x19);
1199  __ Madd(x20, x16, x17, x17);
1200  __ Madd(x21, x17, x17, x18);
1201  __ Madd(x22, x17, x17, x19);
1202  __ Madd(x23, x17, x18, x16);
1203  __ Madd(x24, x17, x18, x18);
1204  __ Madd(x25, x18, x18, x17);
1205  __ Madd(x26, x18, x19, x18);
1206  __ Madd(x27, x19, x19, x19);
1207
1208  END();
1209
1210  RUN();
1211
1212  CHECK_EQUAL_64(0, x0);
1213  CHECK_EQUAL_64(1, x1);
1214  CHECK_EQUAL_64(0xffffffff, x2);
1215  CHECK_EQUAL_64(0xffffffff, x3);
1216  CHECK_EQUAL_64(1, x4);
1217  CHECK_EQUAL_64(0, x5);
1218  CHECK_EQUAL_64(0, x6);
1219  CHECK_EQUAL_64(0xffffffff, x7);
1220  CHECK_EQUAL_64(0xfffffffe, x8);
1221  CHECK_EQUAL_64(2, x9);
1222  CHECK_EQUAL_64(0, x10);
1223  CHECK_EQUAL_64(0, x11);
1224
1225  CHECK_EQUAL_64(0, x12);
1226  CHECK_EQUAL_64(1, x13);
1227  CHECK_EQUAL_64(0xffffffff, x14);
1228  CHECK_EQUAL_64(0xffffffffffffffff, x15);
1229  CHECK_EQUAL_64(1, x20);
1230  CHECK_EQUAL_64(0x100000000UL, x21);
1231  CHECK_EQUAL_64(0, x22);
1232  CHECK_EQUAL_64(0xffffffff, x23);
1233  CHECK_EQUAL_64(0x1fffffffe, x24);
1234  CHECK_EQUAL_64(0xfffffffe00000002UL, x25);
1235  CHECK_EQUAL_64(0, x26);
1236  CHECK_EQUAL_64(0, x27);
1237
1238  TEARDOWN();
1239}
1240
1241
1242TEST(msub) {
1243  INIT_V8();
1244  SETUP();
1245
1246  START();
1247  __ Mov(x16, 0);
1248  __ Mov(x17, 1);
1249  __ Mov(x18, 0xffffffff);
1250  __ Mov(x19, 0xffffffffffffffffUL);
1251
1252  __ Msub(w0, w16, w16, w16);
1253  __ Msub(w1, w16, w16, w17);
1254  __ Msub(w2, w16, w16, w18);
1255  __ Msub(w3, w16, w16, w19);
1256  __ Msub(w4, w16, w17, w17);
1257  __ Msub(w5, w17, w17, w18);
1258  __ Msub(w6, w17, w17, w19);
1259  __ Msub(w7, w17, w18, w16);
1260  __ Msub(w8, w17, w18, w18);
1261  __ Msub(w9, w18, w18, w17);
1262  __ Msub(w10, w18, w19, w18);
1263  __ Msub(w11, w19, w19, w19);
1264
1265  __ Msub(x12, x16, x16, x16);
1266  __ Msub(x13, x16, x16, x17);
1267  __ Msub(x14, x16, x16, x18);
1268  __ Msub(x15, x16, x16, x19);
1269  __ Msub(x20, x16, x17, x17);
1270  __ Msub(x21, x17, x17, x18);
1271  __ Msub(x22, x17, x17, x19);
1272  __ Msub(x23, x17, x18, x16);
1273  __ Msub(x24, x17, x18, x18);
1274  __ Msub(x25, x18, x18, x17);
1275  __ Msub(x26, x18, x19, x18);
1276  __ Msub(x27, x19, x19, x19);
1277
1278  END();
1279
1280  RUN();
1281
1282  CHECK_EQUAL_64(0, x0);
1283  CHECK_EQUAL_64(1, x1);
1284  CHECK_EQUAL_64(0xffffffff, x2);
1285  CHECK_EQUAL_64(0xffffffff, x3);
1286  CHECK_EQUAL_64(1, x4);
1287  CHECK_EQUAL_64(0xfffffffe, x5);
1288  CHECK_EQUAL_64(0xfffffffe, x6);
1289  CHECK_EQUAL_64(1, x7);
1290  CHECK_EQUAL_64(0, x8);
1291  CHECK_EQUAL_64(0, x9);
1292  CHECK_EQUAL_64(0xfffffffe, x10);
1293  CHECK_EQUAL_64(0xfffffffe, x11);
1294
1295  CHECK_EQUAL_64(0, x12);
1296  CHECK_EQUAL_64(1, x13);
1297  CHECK_EQUAL_64(0xffffffff, x14);
1298  CHECK_EQUAL_64(0xffffffffffffffffUL, x15);
1299  CHECK_EQUAL_64(1, x20);
1300  CHECK_EQUAL_64(0xfffffffeUL, x21);
1301  CHECK_EQUAL_64(0xfffffffffffffffeUL, x22);
1302  CHECK_EQUAL_64(0xffffffff00000001UL, x23);
1303  CHECK_EQUAL_64(0, x24);
1304  CHECK_EQUAL_64(0x200000000UL, x25);
1305  CHECK_EQUAL_64(0x1fffffffeUL, x26);
1306  CHECK_EQUAL_64(0xfffffffffffffffeUL, x27);
1307
1308  TEARDOWN();
1309}
1310
1311
1312TEST(smulh) {
1313  INIT_V8();
1314  SETUP();
1315
1316  START();
1317  __ Mov(x20, 0);
1318  __ Mov(x21, 1);
1319  __ Mov(x22, 0x0000000100000000L);
1320  __ Mov(x23, 0x12345678);
1321  __ Mov(x24, 0x0123456789abcdefL);
1322  __ Mov(x25, 0x0000000200000000L);
1323  __ Mov(x26, 0x8000000000000000UL);
1324  __ Mov(x27, 0xffffffffffffffffUL);
1325  __ Mov(x28, 0x5555555555555555UL);
1326  __ Mov(x29, 0xaaaaaaaaaaaaaaaaUL);
1327
1328  __ Smulh(x0, x20, x24);
1329  __ Smulh(x1, x21, x24);
1330  __ Smulh(x2, x22, x23);
1331  __ Smulh(x3, x22, x24);
1332  __ Smulh(x4, x24, x25);
1333  __ Smulh(x5, x23, x27);
1334  __ Smulh(x6, x26, x26);
1335  __ Smulh(x7, x26, x27);
1336  __ Smulh(x8, x27, x27);
1337  __ Smulh(x9, x28, x28);
1338  __ Smulh(x10, x28, x29);
1339  __ Smulh(x11, x29, x29);
1340  END();
1341
1342  RUN();
1343
1344  CHECK_EQUAL_64(0, x0);
1345  CHECK_EQUAL_64(0, x1);
1346  CHECK_EQUAL_64(0, x2);
1347  CHECK_EQUAL_64(0x01234567, x3);
1348  CHECK_EQUAL_64(0x02468acf, x4);
1349  CHECK_EQUAL_64(0xffffffffffffffffUL, x5);
1350  CHECK_EQUAL_64(0x4000000000000000UL, x6);
1351  CHECK_EQUAL_64(0, x7);
1352  CHECK_EQUAL_64(0, x8);
1353  CHECK_EQUAL_64(0x1c71c71c71c71c71UL, x9);
1354  CHECK_EQUAL_64(0xe38e38e38e38e38eUL, x10);
1355  CHECK_EQUAL_64(0x1c71c71c71c71c72UL, x11);
1356
1357  TEARDOWN();
1358}
1359
1360
1361TEST(smaddl_umaddl) {
1362  INIT_V8();
1363  SETUP();
1364
1365  START();
1366  __ Mov(x17, 1);
1367  __ Mov(x18, 0xffffffff);
1368  __ Mov(x19, 0xffffffffffffffffUL);
1369  __ Mov(x20, 4);
1370  __ Mov(x21, 0x200000000UL);
1371
1372  __ Smaddl(x9, w17, w18, x20);
1373  __ Smaddl(x10, w18, w18, x20);
1374  __ Smaddl(x11, w19, w19, x20);
1375  __ Smaddl(x12, w19, w19, x21);
1376  __ Umaddl(x13, w17, w18, x20);
1377  __ Umaddl(x14, w18, w18, x20);
1378  __ Umaddl(x15, w19, w19, x20);
1379  __ Umaddl(x22, w19, w19, x21);
1380  END();
1381
1382  RUN();
1383
1384  CHECK_EQUAL_64(3, x9);
1385  CHECK_EQUAL_64(5, x10);
1386  CHECK_EQUAL_64(5, x11);
1387  CHECK_EQUAL_64(0x200000001UL, x12);
1388  CHECK_EQUAL_64(0x100000003UL, x13);
1389  CHECK_EQUAL_64(0xfffffffe00000005UL, x14);
1390  CHECK_EQUAL_64(0xfffffffe00000005UL, x15);
1391  CHECK_EQUAL_64(0x1, x22);
1392
1393  TEARDOWN();
1394}
1395
1396
1397TEST(smsubl_umsubl) {
1398  INIT_V8();
1399  SETUP();
1400
1401  START();
1402  __ Mov(x17, 1);
1403  __ Mov(x18, 0xffffffff);
1404  __ Mov(x19, 0xffffffffffffffffUL);
1405  __ Mov(x20, 4);
1406  __ Mov(x21, 0x200000000UL);
1407
1408  __ Smsubl(x9, w17, w18, x20);
1409  __ Smsubl(x10, w18, w18, x20);
1410  __ Smsubl(x11, w19, w19, x20);
1411  __ Smsubl(x12, w19, w19, x21);
1412  __ Umsubl(x13, w17, w18, x20);
1413  __ Umsubl(x14, w18, w18, x20);
1414  __ Umsubl(x15, w19, w19, x20);
1415  __ Umsubl(x22, w19, w19, x21);
1416  END();
1417
1418  RUN();
1419
1420  CHECK_EQUAL_64(5, x9);
1421  CHECK_EQUAL_64(3, x10);
1422  CHECK_EQUAL_64(3, x11);
1423  CHECK_EQUAL_64(0x1ffffffffUL, x12);
1424  CHECK_EQUAL_64(0xffffffff00000005UL, x13);
1425  CHECK_EQUAL_64(0x200000003UL, x14);
1426  CHECK_EQUAL_64(0x200000003UL, x15);
1427  CHECK_EQUAL_64(0x3ffffffffUL, x22);
1428
1429  TEARDOWN();
1430}
1431
1432
1433TEST(div) {
1434  INIT_V8();
1435  SETUP();
1436
1437  START();
1438  __ Mov(x16, 1);
1439  __ Mov(x17, 0xffffffff);
1440  __ Mov(x18, 0xffffffffffffffffUL);
1441  __ Mov(x19, 0x80000000);
1442  __ Mov(x20, 0x8000000000000000UL);
1443  __ Mov(x21, 2);
1444
1445  __ Udiv(w0, w16, w16);
1446  __ Udiv(w1, w17, w16);
1447  __ Sdiv(w2, w16, w16);
1448  __ Sdiv(w3, w16, w17);
1449  __ Sdiv(w4, w17, w18);
1450
1451  __ Udiv(x5, x16, x16);
1452  __ Udiv(x6, x17, x18);
1453  __ Sdiv(x7, x16, x16);
1454  __ Sdiv(x8, x16, x17);
1455  __ Sdiv(x9, x17, x18);
1456
1457  __ Udiv(w10, w19, w21);
1458  __ Sdiv(w11, w19, w21);
1459  __ Udiv(x12, x19, x21);
1460  __ Sdiv(x13, x19, x21);
1461  __ Udiv(x14, x20, x21);
1462  __ Sdiv(x15, x20, x21);
1463
1464  __ Udiv(w22, w19, w17);
1465  __ Sdiv(w23, w19, w17);
1466  __ Udiv(x24, x20, x18);
1467  __ Sdiv(x25, x20, x18);
1468
1469  __ Udiv(x26, x16, x21);
1470  __ Sdiv(x27, x16, x21);
1471  __ Udiv(x28, x18, x21);
1472  __ Sdiv(x29, x18, x21);
1473
1474  __ Mov(x17, 0);
1475  __ Udiv(w18, w16, w17);
1476  __ Sdiv(w19, w16, w17);
1477  __ Udiv(x20, x16, x17);
1478  __ Sdiv(x21, x16, x17);
1479  END();
1480
1481  RUN();
1482
1483  CHECK_EQUAL_64(1, x0);
1484  CHECK_EQUAL_64(0xffffffff, x1);
1485  CHECK_EQUAL_64(1, x2);
1486  CHECK_EQUAL_64(0xffffffff, x3);
1487  CHECK_EQUAL_64(1, x4);
1488  CHECK_EQUAL_64(1, x5);
1489  CHECK_EQUAL_64(0, x6);
1490  CHECK_EQUAL_64(1, x7);
1491  CHECK_EQUAL_64(0, x8);
1492  CHECK_EQUAL_64(0xffffffff00000001UL, x9);
1493  CHECK_EQUAL_64(0x40000000, x10);
1494  CHECK_EQUAL_64(0xC0000000, x11);
1495  CHECK_EQUAL_64(0x40000000, x12);
1496  CHECK_EQUAL_64(0x40000000, x13);
1497  CHECK_EQUAL_64(0x4000000000000000UL, x14);
1498  CHECK_EQUAL_64(0xC000000000000000UL, x15);
1499  CHECK_EQUAL_64(0, x22);
1500  CHECK_EQUAL_64(0x80000000, x23);
1501  CHECK_EQUAL_64(0, x24);
1502  CHECK_EQUAL_64(0x8000000000000000UL, x25);
1503  CHECK_EQUAL_64(0, x26);
1504  CHECK_EQUAL_64(0, x27);
1505  CHECK_EQUAL_64(0x7fffffffffffffffUL, x28);
1506  CHECK_EQUAL_64(0, x29);
1507  CHECK_EQUAL_64(0, x18);
1508  CHECK_EQUAL_64(0, x19);
1509  CHECK_EQUAL_64(0, x20);
1510  CHECK_EQUAL_64(0, x21);
1511
1512  TEARDOWN();
1513}
1514
1515
1516TEST(rbit_rev) {
1517  INIT_V8();
1518  SETUP();
1519
1520  START();
1521  __ Mov(x24, 0xfedcba9876543210UL);
1522  __ Rbit(w0, w24);
1523  __ Rbit(x1, x24);
1524  __ Rev16(w2, w24);
1525  __ Rev16(x3, x24);
1526  __ Rev(w4, w24);
1527  __ Rev32(x5, x24);
1528  __ Rev(x6, x24);
1529  END();
1530
1531  RUN();
1532
1533  CHECK_EQUAL_64(0x084c2a6e, x0);
1534  CHECK_EQUAL_64(0x084c2a6e195d3b7fUL, x1);
1535  CHECK_EQUAL_64(0x54761032, x2);
1536  CHECK_EQUAL_64(0xdcfe98ba54761032UL, x3);
1537  CHECK_EQUAL_64(0x10325476, x4);
1538  CHECK_EQUAL_64(0x98badcfe10325476UL, x5);
1539  CHECK_EQUAL_64(0x1032547698badcfeUL, x6);
1540
1541  TEARDOWN();
1542}
1543
1544
1545TEST(clz_cls) {
1546  INIT_V8();
1547  SETUP();
1548
1549  START();
1550  __ Mov(x24, 0x0008000000800000UL);
1551  __ Mov(x25, 0xff800000fff80000UL);
1552  __ Mov(x26, 0);
1553  __ Clz(w0, w24);
1554  __ Clz(x1, x24);
1555  __ Clz(w2, w25);
1556  __ Clz(x3, x25);
1557  __ Clz(w4, w26);
1558  __ Clz(x5, x26);
1559  __ Cls(w6, w24);
1560  __ Cls(x7, x24);
1561  __ Cls(w8, w25);
1562  __ Cls(x9, x25);
1563  __ Cls(w10, w26);
1564  __ Cls(x11, x26);
1565  END();
1566
1567  RUN();
1568
1569  CHECK_EQUAL_64(8, x0);
1570  CHECK_EQUAL_64(12, x1);
1571  CHECK_EQUAL_64(0, x2);
1572  CHECK_EQUAL_64(0, x3);
1573  CHECK_EQUAL_64(32, x4);
1574  CHECK_EQUAL_64(64, x5);
1575  CHECK_EQUAL_64(7, x6);
1576  CHECK_EQUAL_64(11, x7);
1577  CHECK_EQUAL_64(12, x8);
1578  CHECK_EQUAL_64(8, x9);
1579  CHECK_EQUAL_64(31, x10);
1580  CHECK_EQUAL_64(63, x11);
1581
1582  TEARDOWN();
1583}
1584
1585
1586TEST(label) {
1587  INIT_V8();
1588  SETUP();
1589
1590  Label label_1, label_2, label_3, label_4;
1591
1592  START();
1593  __ Mov(x0, 0x1);
1594  __ Mov(x1, 0x0);
1595  __ Mov(x22, lr);    // Save lr.
1596
1597  __ B(&label_1);
1598  __ B(&label_1);
1599  __ B(&label_1);     // Multiple branches to the same label.
1600  __ Mov(x0, 0x0);
1601  __ Bind(&label_2);
1602  __ B(&label_3);     // Forward branch.
1603  __ Mov(x0, 0x0);
1604  __ Bind(&label_1);
1605  __ B(&label_2);     // Backward branch.
1606  __ Mov(x0, 0x0);
1607  __ Bind(&label_3);
1608  __ Bl(&label_4);
1609  END();
1610
1611  __ Bind(&label_4);
1612  __ Mov(x1, 0x1);
1613  __ Mov(lr, x22);
1614  END();
1615
1616  RUN();
1617
1618  CHECK_EQUAL_64(0x1, x0);
1619  CHECK_EQUAL_64(0x1, x1);
1620
1621  TEARDOWN();
1622}
1623
1624
1625TEST(branch_at_start) {
1626  INIT_V8();
1627  SETUP();
1628
1629  Label good, exit;
1630
1631  // Test that branches can exist at the start of the buffer. (This is a
1632  // boundary condition in the label-handling code.) To achieve this, we have
1633  // to work around the code generated by START.
1634  RESET();
1635  __ B(&good);
1636
1637  START_AFTER_RESET();
1638  __ Mov(x0, 0x0);
1639  END();
1640
1641  __ Bind(&exit);
1642  START_AFTER_RESET();
1643  __ Mov(x0, 0x1);
1644  END();
1645
1646  __ Bind(&good);
1647  __ B(&exit);
1648  END();
1649
1650  RUN();
1651
1652  CHECK_EQUAL_64(0x1, x0);
1653  TEARDOWN();
1654}
1655
1656
1657TEST(adr) {
1658  INIT_V8();
1659  SETUP();
1660
1661  Label label_1, label_2, label_3, label_4;
1662
1663  START();
1664  __ Mov(x0, 0x0);        // Set to non-zero to indicate failure.
1665  __ Adr(x1, &label_3);   // Set to zero to indicate success.
1666
1667  __ Adr(x2, &label_1);   // Multiple forward references to the same label.
1668  __ Adr(x3, &label_1);
1669  __ Adr(x4, &label_1);
1670
1671  __ Bind(&label_2);
1672  __ Eor(x5, x2, Operand(x3));  // Ensure that x2,x3 and x4 are identical.
1673  __ Eor(x6, x2, Operand(x4));
1674  __ Orr(x0, x0, Operand(x5));
1675  __ Orr(x0, x0, Operand(x6));
1676  __ Br(x2);  // label_1, label_3
1677
1678  __ Bind(&label_3);
1679  __ Adr(x2, &label_3);   // Self-reference (offset 0).
1680  __ Eor(x1, x1, Operand(x2));
1681  __ Adr(x2, &label_4);   // Simple forward reference.
1682  __ Br(x2);  // label_4
1683
1684  __ Bind(&label_1);
1685  __ Adr(x2, &label_3);   // Multiple reverse references to the same label.
1686  __ Adr(x3, &label_3);
1687  __ Adr(x4, &label_3);
1688  __ Adr(x5, &label_2);   // Simple reverse reference.
1689  __ Br(x5);  // label_2
1690
1691  __ Bind(&label_4);
1692  END();
1693
1694  RUN();
1695
1696  CHECK_EQUAL_64(0x0, x0);
1697  CHECK_EQUAL_64(0x0, x1);
1698
1699  TEARDOWN();
1700}
1701
1702
1703TEST(adr_far) {
1704  INIT_V8();
1705
1706  int max_range = 1 << (Instruction::ImmPCRelRangeBitwidth - 1);
1707  SETUP_SIZE(max_range + 1000 * kInstructionSize);
1708
1709  Label done, fail;
1710  Label test_near, near_forward, near_backward;
1711  Label test_far, far_forward, far_backward;
1712
1713  START();
1714  __ Mov(x0, 0x0);
1715
1716  __ Bind(&test_near);
1717  __ Adr(x10, &near_forward, MacroAssembler::kAdrFar);
1718  __ Br(x10);
1719  __ B(&fail);
1720  __ Bind(&near_backward);
1721  __ Orr(x0, x0, 1 << 1);
1722  __ B(&test_far);
1723
1724  __ Bind(&near_forward);
1725  __ Orr(x0, x0, 1 << 0);
1726  __ Adr(x10, &near_backward, MacroAssembler::kAdrFar);
1727  __ Br(x10);
1728
1729  __ Bind(&test_far);
1730  __ Adr(x10, &far_forward, MacroAssembler::kAdrFar);
1731  __ Br(x10);
1732  __ B(&fail);
1733  __ Bind(&far_backward);
1734  __ Orr(x0, x0, 1 << 3);
1735  __ B(&done);
1736
1737  for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
1738    if (i % 100 == 0) {
1739      // If we do land in this code, we do not want to execute so many nops
1740      // before reaching the end of test (especially if tracing is activated).
1741      __ b(&fail);
1742    } else {
1743      __ nop();
1744    }
1745  }
1746
1747
1748  __ Bind(&far_forward);
1749  __ Orr(x0, x0, 1 << 2);
1750  __ Adr(x10, &far_backward, MacroAssembler::kAdrFar);
1751  __ Br(x10);
1752
1753  __ B(&done);
1754  __ Bind(&fail);
1755  __ Orr(x0, x0, 1 << 4);
1756  __ Bind(&done);
1757
1758  END();
1759
1760  RUN();
1761
1762  CHECK_EQUAL_64(0xf, x0);
1763
1764  TEARDOWN();
1765}
1766
1767
1768TEST(branch_cond) {
1769  INIT_V8();
1770  SETUP();
1771
1772  Label wrong;
1773
1774  START();
1775  __ Mov(x0, 0x1);
1776  __ Mov(x1, 0x1);
1777  __ Mov(x2, 0x8000000000000000L);
1778
1779  // For each 'cmp' instruction below, condition codes other than the ones
1780  // following it would branch.
1781
1782  __ Cmp(x1, 0);
1783  __ B(&wrong, eq);
1784  __ B(&wrong, lo);
1785  __ B(&wrong, mi);
1786  __ B(&wrong, vs);
1787  __ B(&wrong, ls);
1788  __ B(&wrong, lt);
1789  __ B(&wrong, le);
1790  Label ok_1;
1791  __ B(&ok_1, ne);
1792  __ Mov(x0, 0x0);
1793  __ Bind(&ok_1);
1794
1795  __ Cmp(x1, 1);
1796  __ B(&wrong, ne);
1797  __ B(&wrong, lo);
1798  __ B(&wrong, mi);
1799  __ B(&wrong, vs);
1800  __ B(&wrong, hi);
1801  __ B(&wrong, lt);
1802  __ B(&wrong, gt);
1803  Label ok_2;
1804  __ B(&ok_2, pl);
1805  __ Mov(x0, 0x0);
1806  __ Bind(&ok_2);
1807
1808  __ Cmp(x1, 2);
1809  __ B(&wrong, eq);
1810  __ B(&wrong, hs);
1811  __ B(&wrong, pl);
1812  __ B(&wrong, vs);
1813  __ B(&wrong, hi);
1814  __ B(&wrong, ge);
1815  __ B(&wrong, gt);
1816  Label ok_3;
1817  __ B(&ok_3, vc);
1818  __ Mov(x0, 0x0);
1819  __ Bind(&ok_3);
1820
1821  __ Cmp(x2, 1);
1822  __ B(&wrong, eq);
1823  __ B(&wrong, lo);
1824  __ B(&wrong, mi);
1825  __ B(&wrong, vc);
1826  __ B(&wrong, ls);
1827  __ B(&wrong, ge);
1828  __ B(&wrong, gt);
1829  Label ok_4;
1830  __ B(&ok_4, le);
1831  __ Mov(x0, 0x0);
1832  __ Bind(&ok_4);
1833
1834  Label ok_5;
1835  __ b(&ok_5, al);
1836  __ Mov(x0, 0x0);
1837  __ Bind(&ok_5);
1838
1839  Label ok_6;
1840  __ b(&ok_6, nv);
1841  __ Mov(x0, 0x0);
1842  __ Bind(&ok_6);
1843
1844  END();
1845
1846  __ Bind(&wrong);
1847  __ Mov(x0, 0x0);
1848  END();
1849
1850  RUN();
1851
1852  CHECK_EQUAL_64(0x1, x0);
1853
1854  TEARDOWN();
1855}
1856
1857
1858TEST(branch_to_reg) {
1859  INIT_V8();
1860  SETUP();
1861
1862  // Test br.
1863  Label fn1, after_fn1;
1864
1865  START();
1866  __ Mov(x29, lr);
1867
1868  __ Mov(x1, 0);
1869  __ B(&after_fn1);
1870
1871  __ Bind(&fn1);
1872  __ Mov(x0, lr);
1873  __ Mov(x1, 42);
1874  __ Br(x0);
1875
1876  __ Bind(&after_fn1);
1877  __ Bl(&fn1);
1878
1879  // Test blr.
1880  Label fn2, after_fn2;
1881
1882  __ Mov(x2, 0);
1883  __ B(&after_fn2);
1884
1885  __ Bind(&fn2);
1886  __ Mov(x0, lr);
1887  __ Mov(x2, 84);
1888  __ Blr(x0);
1889
1890  __ Bind(&after_fn2);
1891  __ Bl(&fn2);
1892  __ Mov(x3, lr);
1893
1894  __ Mov(lr, x29);
1895  END();
1896
1897  RUN();
1898
1899  CHECK_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
1900  CHECK_EQUAL_64(42, x1);
1901  CHECK_EQUAL_64(84, x2);
1902
1903  TEARDOWN();
1904}
1905
1906
1907TEST(compare_branch) {
1908  INIT_V8();
1909  SETUP();
1910
1911  START();
1912  __ Mov(x0, 0);
1913  __ Mov(x1, 0);
1914  __ Mov(x2, 0);
1915  __ Mov(x3, 0);
1916  __ Mov(x4, 0);
1917  __ Mov(x5, 0);
1918  __ Mov(x16, 0);
1919  __ Mov(x17, 42);
1920
1921  Label zt, zt_end;
1922  __ Cbz(w16, &zt);
1923  __ B(&zt_end);
1924  __ Bind(&zt);
1925  __ Mov(x0, 1);
1926  __ Bind(&zt_end);
1927
1928  Label zf, zf_end;
1929  __ Cbz(x17, &zf);
1930  __ B(&zf_end);
1931  __ Bind(&zf);
1932  __ Mov(x1, 1);
1933  __ Bind(&zf_end);
1934
1935  Label nzt, nzt_end;
1936  __ Cbnz(w17, &nzt);
1937  __ B(&nzt_end);
1938  __ Bind(&nzt);
1939  __ Mov(x2, 1);
1940  __ Bind(&nzt_end);
1941
1942  Label nzf, nzf_end;
1943  __ Cbnz(x16, &nzf);
1944  __ B(&nzf_end);
1945  __ Bind(&nzf);
1946  __ Mov(x3, 1);
1947  __ Bind(&nzf_end);
1948
1949  __ Mov(x18, 0xffffffff00000000UL);
1950
1951  Label a, a_end;
1952  __ Cbz(w18, &a);
1953  __ B(&a_end);
1954  __ Bind(&a);
1955  __ Mov(x4, 1);
1956  __ Bind(&a_end);
1957
1958  Label b, b_end;
1959  __ Cbnz(w18, &b);
1960  __ B(&b_end);
1961  __ Bind(&b);
1962  __ Mov(x5, 1);
1963  __ Bind(&b_end);
1964
1965  END();
1966
1967  RUN();
1968
1969  CHECK_EQUAL_64(1, x0);
1970  CHECK_EQUAL_64(0, x1);
1971  CHECK_EQUAL_64(1, x2);
1972  CHECK_EQUAL_64(0, x3);
1973  CHECK_EQUAL_64(1, x4);
1974  CHECK_EQUAL_64(0, x5);
1975
1976  TEARDOWN();
1977}
1978
1979
1980TEST(test_branch) {
1981  INIT_V8();
1982  SETUP();
1983
1984  START();
1985  __ Mov(x0, 0);
1986  __ Mov(x1, 0);
1987  __ Mov(x2, 0);
1988  __ Mov(x3, 0);
1989  __ Mov(x16, 0xaaaaaaaaaaaaaaaaUL);
1990
1991  Label bz, bz_end;
1992  __ Tbz(w16, 0, &bz);
1993  __ B(&bz_end);
1994  __ Bind(&bz);
1995  __ Mov(x0, 1);
1996  __ Bind(&bz_end);
1997
1998  Label bo, bo_end;
1999  __ Tbz(x16, 63, &bo);
2000  __ B(&bo_end);
2001  __ Bind(&bo);
2002  __ Mov(x1, 1);
2003  __ Bind(&bo_end);
2004
2005  Label nbz, nbz_end;
2006  __ Tbnz(x16, 61, &nbz);
2007  __ B(&nbz_end);
2008  __ Bind(&nbz);
2009  __ Mov(x2, 1);
2010  __ Bind(&nbz_end);
2011
2012  Label nbo, nbo_end;
2013  __ Tbnz(w16, 2, &nbo);
2014  __ B(&nbo_end);
2015  __ Bind(&nbo);
2016  __ Mov(x3, 1);
2017  __ Bind(&nbo_end);
2018  END();
2019
2020  RUN();
2021
2022  CHECK_EQUAL_64(1, x0);
2023  CHECK_EQUAL_64(0, x1);
2024  CHECK_EQUAL_64(1, x2);
2025  CHECK_EQUAL_64(0, x3);
2026
2027  TEARDOWN();
2028}
2029
2030
2031TEST(far_branch_backward) {
2032  INIT_V8();
2033
2034  // Test that the MacroAssembler correctly resolves backward branches to labels
2035  // that are outside the immediate range of branch instructions.
2036  int max_range =
2037    std::max(Instruction::ImmBranchRange(TestBranchType),
2038             std::max(Instruction::ImmBranchRange(CompareBranchType),
2039                      Instruction::ImmBranchRange(CondBranchType)));
2040
2041  SETUP_SIZE(max_range + 1000 * kInstructionSize);
2042
2043  START();
2044
2045  Label done, fail;
2046  Label test_tbz, test_cbz, test_bcond;
2047  Label success_tbz, success_cbz, success_bcond;
2048
2049  __ Mov(x0, 0);
2050  __ Mov(x1, 1);
2051  __ Mov(x10, 0);
2052
2053  __ B(&test_tbz);
2054  __ Bind(&success_tbz);
2055  __ Orr(x0, x0, 1 << 0);
2056  __ B(&test_cbz);
2057  __ Bind(&success_cbz);
2058  __ Orr(x0, x0, 1 << 1);
2059  __ B(&test_bcond);
2060  __ Bind(&success_bcond);
2061  __ Orr(x0, x0, 1 << 2);
2062
2063  __ B(&done);
2064
2065  // Generate enough code to overflow the immediate range of the three types of
2066  // branches below.
2067  for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
2068    if (i % 100 == 0) {
2069      // If we do land in this code, we do not want to execute so many nops
2070      // before reaching the end of test (especially if tracing is activated).
2071      __ B(&fail);
2072    } else {
2073      __ Nop();
2074    }
2075  }
2076  __ B(&fail);
2077
2078  __ Bind(&test_tbz);
2079  __ Tbz(x10, 7, &success_tbz);
2080  __ Bind(&test_cbz);
2081  __ Cbz(x10, &success_cbz);
2082  __ Bind(&test_bcond);
2083  __ Cmp(x10, 0);
2084  __ B(eq, &success_bcond);
2085
2086  // For each out-of-range branch instructions, at least two instructions should
2087  // have been generated.
2088  CHECK_GE(7 * kInstructionSize, __ SizeOfCodeGeneratedSince(&test_tbz));
2089
2090  __ Bind(&fail);
2091  __ Mov(x1, 0);
2092  __ Bind(&done);
2093
2094  END();
2095
2096  RUN();
2097
2098  CHECK_EQUAL_64(0x7, x0);
2099  CHECK_EQUAL_64(0x1, x1);
2100
2101  TEARDOWN();
2102}
2103
2104
2105TEST(far_branch_simple_veneer) {
2106  INIT_V8();
2107
2108  // Test that the MacroAssembler correctly emits veneers for forward branches
2109  // to labels that are outside the immediate range of branch instructions.
2110  int max_range =
2111    std::max(Instruction::ImmBranchRange(TestBranchType),
2112             std::max(Instruction::ImmBranchRange(CompareBranchType),
2113                      Instruction::ImmBranchRange(CondBranchType)));
2114
2115  SETUP_SIZE(max_range + 1000 * kInstructionSize);
2116
2117  START();
2118
2119  Label done, fail;
2120  Label test_tbz, test_cbz, test_bcond;
2121  Label success_tbz, success_cbz, success_bcond;
2122
2123  __ Mov(x0, 0);
2124  __ Mov(x1, 1);
2125  __ Mov(x10, 0);
2126
2127  __ Bind(&test_tbz);
2128  __ Tbz(x10, 7, &success_tbz);
2129  __ Bind(&test_cbz);
2130  __ Cbz(x10, &success_cbz);
2131  __ Bind(&test_bcond);
2132  __ Cmp(x10, 0);
2133  __ B(eq, &success_bcond);
2134
2135  // Generate enough code to overflow the immediate range of the three types of
2136  // branches below.
2137  for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
2138    if (i % 100 == 0) {
2139      // If we do land in this code, we do not want to execute so many nops
2140      // before reaching the end of test (especially if tracing is activated).
2141      // Also, the branches give the MacroAssembler the opportunity to emit the
2142      // veneers.
2143      __ B(&fail);
2144    } else {
2145      __ Nop();
2146    }
2147  }
2148  __ B(&fail);
2149
2150  __ Bind(&success_tbz);
2151  __ Orr(x0, x0, 1 << 0);
2152  __ B(&test_cbz);
2153  __ Bind(&success_cbz);
2154  __ Orr(x0, x0, 1 << 1);
2155  __ B(&test_bcond);
2156  __ Bind(&success_bcond);
2157  __ Orr(x0, x0, 1 << 2);
2158
2159  __ B(&done);
2160  __ Bind(&fail);
2161  __ Mov(x1, 0);
2162  __ Bind(&done);
2163
2164  END();
2165
2166  RUN();
2167
2168  CHECK_EQUAL_64(0x7, x0);
2169  CHECK_EQUAL_64(0x1, x1);
2170
2171  TEARDOWN();
2172}
2173
2174
2175TEST(far_branch_veneer_link_chain) {
2176  INIT_V8();
2177
2178  // Test that the MacroAssembler correctly emits veneers for forward branches
2179  // that target out-of-range labels and are part of multiple instructions
2180  // jumping to that label.
2181  //
2182  // We test the three situations with the different types of instruction:
2183  // (1)- When the branch is at the start of the chain with tbz.
2184  // (2)- When the branch is in the middle of the chain with cbz.
2185  // (3)- When the branch is at the end of the chain with bcond.
2186  int max_range =
2187    std::max(Instruction::ImmBranchRange(TestBranchType),
2188             std::max(Instruction::ImmBranchRange(CompareBranchType),
2189                      Instruction::ImmBranchRange(CondBranchType)));
2190
2191  SETUP_SIZE(max_range + 1000 * kInstructionSize);
2192
2193  START();
2194
2195  Label skip, fail, done;
2196  Label test_tbz, test_cbz, test_bcond;
2197  Label success_tbz, success_cbz, success_bcond;
2198
2199  __ Mov(x0, 0);
2200  __ Mov(x1, 1);
2201  __ Mov(x10, 0);
2202
2203  __ B(&skip);
2204  // Branches at the start of the chain for situations (2) and (3).
2205  __ B(&success_cbz);
2206  __ B(&success_bcond);
2207  __ Nop();
2208  __ B(&success_bcond);
2209  __ B(&success_cbz);
2210  __ Bind(&skip);
2211
2212  __ Bind(&test_tbz);
2213  __ Tbz(x10, 7, &success_tbz);
2214  __ Bind(&test_cbz);
2215  __ Cbz(x10, &success_cbz);
2216  __ Bind(&test_bcond);
2217  __ Cmp(x10, 0);
2218  __ B(eq, &success_bcond);
2219
2220  skip.Unuse();
2221  __ B(&skip);
2222  // Branches at the end of the chain for situations (1) and (2).
2223  __ B(&success_cbz);
2224  __ B(&success_tbz);
2225  __ Nop();
2226  __ B(&success_tbz);
2227  __ B(&success_cbz);
2228  __ Bind(&skip);
2229
2230  // Generate enough code to overflow the immediate range of the three types of
2231  // branches below.
2232  for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
2233    if (i % 100 == 0) {
2234      // If we do land in this code, we do not want to execute so many nops
2235      // before reaching the end of test (especially if tracing is activated).
2236      // Also, the branches give the MacroAssembler the opportunity to emit the
2237      // veneers.
2238      __ B(&fail);
2239    } else {
2240      __ Nop();
2241    }
2242  }
2243  __ B(&fail);
2244
2245  __ Bind(&success_tbz);
2246  __ Orr(x0, x0, 1 << 0);
2247  __ B(&test_cbz);
2248  __ Bind(&success_cbz);
2249  __ Orr(x0, x0, 1 << 1);
2250  __ B(&test_bcond);
2251  __ Bind(&success_bcond);
2252  __ Orr(x0, x0, 1 << 2);
2253
2254  __ B(&done);
2255  __ Bind(&fail);
2256  __ Mov(x1, 0);
2257  __ Bind(&done);
2258
2259  END();
2260
2261  RUN();
2262
2263  CHECK_EQUAL_64(0x7, x0);
2264  CHECK_EQUAL_64(0x1, x1);
2265
2266  TEARDOWN();
2267}
2268
2269
2270TEST(far_branch_veneer_broken_link_chain) {
2271  INIT_V8();
2272
2273  // Check that the MacroAssembler correctly handles the situation when removing
2274  // a branch from the link chain of a label and the two links on each side of
2275  // the removed branch cannot be linked together (out of range).
2276  //
2277  // We test with tbz because it has a small range.
2278  int max_range = Instruction::ImmBranchRange(TestBranchType);
2279  int inter_range = max_range / 2 + max_range / 10;
2280
2281  SETUP_SIZE(3 * inter_range + 1000 * kInstructionSize);
2282
2283  START();
2284
2285  Label skip, fail, done;
2286  Label test_1, test_2, test_3;
2287  Label far_target;
2288
2289  __ Mov(x0, 0);  // Indicates the origin of the branch.
2290  __ Mov(x1, 1);
2291  __ Mov(x10, 0);
2292
2293  // First instruction in the label chain.
2294  __ Bind(&test_1);
2295  __ Mov(x0, 1);
2296  __ B(&far_target);
2297
2298  for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) {
2299    if (i % 100 == 0) {
2300      // Do not allow generating veneers. They should not be needed.
2301      __ b(&fail);
2302    } else {
2303      __ Nop();
2304    }
2305  }
2306
2307  // Will need a veneer to point to reach the target.
2308  __ Bind(&test_2);
2309  __ Mov(x0, 2);
2310  __ Tbz(x10, 7, &far_target);
2311
2312  for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) {
2313    if (i % 100 == 0) {
2314      // Do not allow generating veneers. They should not be needed.
2315      __ b(&fail);
2316    } else {
2317      __ Nop();
2318    }
2319  }
2320
2321  // Does not need a veneer to reach the target, but the initial branch
2322  // instruction is out of range.
2323  __ Bind(&test_3);
2324  __ Mov(x0, 3);
2325  __ Tbz(x10, 7, &far_target);
2326
2327  for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) {
2328    if (i % 100 == 0) {
2329      // Allow generating veneers.
2330      __ B(&fail);
2331    } else {
2332      __ Nop();
2333    }
2334  }
2335
2336  __ B(&fail);
2337
2338  __ Bind(&far_target);
2339  __ Cmp(x0, 1);
2340  __ B(eq, &test_2);
2341  __ Cmp(x0, 2);
2342  __ B(eq, &test_3);
2343
2344  __ B(&done);
2345  __ Bind(&fail);
2346  __ Mov(x1, 0);
2347  __ Bind(&done);
2348
2349  END();
2350
2351  RUN();
2352
2353  CHECK_EQUAL_64(0x3, x0);
2354  CHECK_EQUAL_64(0x1, x1);
2355
2356  TEARDOWN();
2357}
2358
2359
2360TEST(branch_type) {
2361  INIT_V8();
2362
2363  SETUP();
2364
2365  Label fail, done;
2366
2367  START();
2368  __ Mov(x0, 0x0);
2369  __ Mov(x10, 0x7);
2370  __ Mov(x11, 0x0);
2371
2372  // Test non taken branches.
2373  __ Cmp(x10, 0x7);
2374  __ B(&fail, ne);
2375  __ B(&fail, never);
2376  __ B(&fail, reg_zero, x10);
2377  __ B(&fail, reg_not_zero, x11);
2378  __ B(&fail, reg_bit_clear, x10, 0);
2379  __ B(&fail, reg_bit_set, x10, 3);
2380
2381  // Test taken branches.
2382  Label l1, l2, l3, l4, l5;
2383  __ Cmp(x10, 0x7);
2384  __ B(&l1, eq);
2385  __ B(&fail);
2386  __ Bind(&l1);
2387  __ B(&l2, always);
2388  __ B(&fail);
2389  __ Bind(&l2);
2390  __ B(&l3, reg_not_zero, x10);
2391  __ B(&fail);
2392  __ Bind(&l3);
2393  __ B(&l4, reg_bit_clear, x10, 15);
2394  __ B(&fail);
2395  __ Bind(&l4);
2396  __ B(&l5, reg_bit_set, x10, 1);
2397  __ B(&fail);
2398  __ Bind(&l5);
2399
2400  __ B(&done);
2401
2402  __ Bind(&fail);
2403  __ Mov(x0, 0x1);
2404
2405  __ Bind(&done);
2406
2407  END();
2408
2409  RUN();
2410
2411  CHECK_EQUAL_64(0x0, x0);
2412
2413  TEARDOWN();
2414}
2415
2416
2417TEST(ldr_str_offset) {
2418  INIT_V8();
2419  SETUP();
2420
2421  uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL};
2422  uint64_t dst[5] = {0, 0, 0, 0, 0};
2423  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2424  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2425
2426  START();
2427  __ Mov(x17, src_base);
2428  __ Mov(x18, dst_base);
2429  __ Ldr(w0, MemOperand(x17));
2430  __ Str(w0, MemOperand(x18));
2431  __ Ldr(w1, MemOperand(x17, 4));
2432  __ Str(w1, MemOperand(x18, 12));
2433  __ Ldr(x2, MemOperand(x17, 8));
2434  __ Str(x2, MemOperand(x18, 16));
2435  __ Ldrb(w3, MemOperand(x17, 1));
2436  __ Strb(w3, MemOperand(x18, 25));
2437  __ Ldrh(w4, MemOperand(x17, 2));
2438  __ Strh(w4, MemOperand(x18, 33));
2439  END();
2440
2441  RUN();
2442
2443  CHECK_EQUAL_64(0x76543210, x0);
2444  CHECK_EQUAL_64(0x76543210, dst[0]);
2445  CHECK_EQUAL_64(0xfedcba98, x1);
2446  CHECK_EQUAL_64(0xfedcba9800000000UL, dst[1]);
2447  CHECK_EQUAL_64(0x0123456789abcdefUL, x2);
2448  CHECK_EQUAL_64(0x0123456789abcdefUL, dst[2]);
2449  CHECK_EQUAL_64(0x32, x3);
2450  CHECK_EQUAL_64(0x3200, dst[3]);
2451  CHECK_EQUAL_64(0x7654, x4);
2452  CHECK_EQUAL_64(0x765400, dst[4]);
2453  CHECK_EQUAL_64(src_base, x17);
2454  CHECK_EQUAL_64(dst_base, x18);
2455
2456  TEARDOWN();
2457}
2458
2459
2460TEST(ldr_str_wide) {
2461  INIT_V8();
2462  SETUP();
2463
2464  uint32_t src[8192];
2465  uint32_t dst[8192];
2466  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2467  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2468  memset(src, 0xaa, 8192 * sizeof(src[0]));
2469  memset(dst, 0xaa, 8192 * sizeof(dst[0]));
2470  src[0] = 0;
2471  src[6144] = 6144;
2472  src[8191] = 8191;
2473
2474  START();
2475  __ Mov(x22, src_base);
2476  __ Mov(x23, dst_base);
2477  __ Mov(x24, src_base);
2478  __ Mov(x25, dst_base);
2479  __ Mov(x26, src_base);
2480  __ Mov(x27, dst_base);
2481
2482  __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
2483  __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
2484  __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
2485  __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
2486  __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
2487  __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
2488  END();
2489
2490  RUN();
2491
2492  CHECK_EQUAL_32(8191, w0);
2493  CHECK_EQUAL_32(8191, dst[8191]);
2494  CHECK_EQUAL_64(src_base, x22);
2495  CHECK_EQUAL_64(dst_base, x23);
2496  CHECK_EQUAL_32(0, w1);
2497  CHECK_EQUAL_32(0, dst[0]);
2498  CHECK_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
2499  CHECK_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
2500  CHECK_EQUAL_32(6144, w2);
2501  CHECK_EQUAL_32(6144, dst[6144]);
2502  CHECK_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
2503  CHECK_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
2504
2505  TEARDOWN();
2506}
2507
2508
2509TEST(ldr_str_preindex) {
2510  INIT_V8();
2511  SETUP();
2512
2513  uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL};
2514  uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2515  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2516  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2517
2518  START();
2519  __ Mov(x17, src_base);
2520  __ Mov(x18, dst_base);
2521  __ Mov(x19, src_base);
2522  __ Mov(x20, dst_base);
2523  __ Mov(x21, src_base + 16);
2524  __ Mov(x22, dst_base + 40);
2525  __ Mov(x23, src_base);
2526  __ Mov(x24, dst_base);
2527  __ Mov(x25, src_base);
2528  __ Mov(x26, dst_base);
2529  __ Ldr(w0, MemOperand(x17, 4, PreIndex));
2530  __ Str(w0, MemOperand(x18, 12, PreIndex));
2531  __ Ldr(x1, MemOperand(x19, 8, PreIndex));
2532  __ Str(x1, MemOperand(x20, 16, PreIndex));
2533  __ Ldr(w2, MemOperand(x21, -4, PreIndex));
2534  __ Str(w2, MemOperand(x22, -4, PreIndex));
2535  __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
2536  __ Strb(w3, MemOperand(x24, 25, PreIndex));
2537  __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
2538  __ Strh(w4, MemOperand(x26, 41, PreIndex));
2539  END();
2540
2541  RUN();
2542
2543  CHECK_EQUAL_64(0xfedcba98, x0);
2544  CHECK_EQUAL_64(0xfedcba9800000000UL, dst[1]);
2545  CHECK_EQUAL_64(0x0123456789abcdefUL, x1);
2546  CHECK_EQUAL_64(0x0123456789abcdefUL, dst[2]);
2547  CHECK_EQUAL_64(0x01234567, x2);
2548  CHECK_EQUAL_64(0x0123456700000000UL, dst[4]);
2549  CHECK_EQUAL_64(0x32, x3);
2550  CHECK_EQUAL_64(0x3200, dst[3]);
2551  CHECK_EQUAL_64(0x9876, x4);
2552  CHECK_EQUAL_64(0x987600, dst[5]);
2553  CHECK_EQUAL_64(src_base + 4, x17);
2554  CHECK_EQUAL_64(dst_base + 12, x18);
2555  CHECK_EQUAL_64(src_base + 8, x19);
2556  CHECK_EQUAL_64(dst_base + 16, x20);
2557  CHECK_EQUAL_64(src_base + 12, x21);
2558  CHECK_EQUAL_64(dst_base + 36, x22);
2559  CHECK_EQUAL_64(src_base + 1, x23);
2560  CHECK_EQUAL_64(dst_base + 25, x24);
2561  CHECK_EQUAL_64(src_base + 3, x25);
2562  CHECK_EQUAL_64(dst_base + 41, x26);
2563
2564  TEARDOWN();
2565}
2566
2567
2568TEST(ldr_str_postindex) {
2569  INIT_V8();
2570  SETUP();
2571
2572  uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL};
2573  uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2574  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2575  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2576
2577  START();
2578  __ Mov(x17, src_base + 4);
2579  __ Mov(x18, dst_base + 12);
2580  __ Mov(x19, src_base + 8);
2581  __ Mov(x20, dst_base + 16);
2582  __ Mov(x21, src_base + 8);
2583  __ Mov(x22, dst_base + 32);
2584  __ Mov(x23, src_base + 1);
2585  __ Mov(x24, dst_base + 25);
2586  __ Mov(x25, src_base + 3);
2587  __ Mov(x26, dst_base + 41);
2588  __ Ldr(w0, MemOperand(x17, 4, PostIndex));
2589  __ Str(w0, MemOperand(x18, 12, PostIndex));
2590  __ Ldr(x1, MemOperand(x19, 8, PostIndex));
2591  __ Str(x1, MemOperand(x20, 16, PostIndex));
2592  __ Ldr(x2, MemOperand(x21, -8, PostIndex));
2593  __ Str(x2, MemOperand(x22, -32, PostIndex));
2594  __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
2595  __ Strb(w3, MemOperand(x24, 5, PostIndex));
2596  __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
2597  __ Strh(w4, MemOperand(x26, -41, PostIndex));
2598  END();
2599
2600  RUN();
2601
2602  CHECK_EQUAL_64(0xfedcba98, x0);
2603  CHECK_EQUAL_64(0xfedcba9800000000UL, dst[1]);
2604  CHECK_EQUAL_64(0x0123456789abcdefUL, x1);
2605  CHECK_EQUAL_64(0x0123456789abcdefUL, dst[2]);
2606  CHECK_EQUAL_64(0x0123456789abcdefUL, x2);
2607  CHECK_EQUAL_64(0x0123456789abcdefUL, dst[4]);
2608  CHECK_EQUAL_64(0x32, x3);
2609  CHECK_EQUAL_64(0x3200, dst[3]);
2610  CHECK_EQUAL_64(0x9876, x4);
2611  CHECK_EQUAL_64(0x987600, dst[5]);
2612  CHECK_EQUAL_64(src_base + 8, x17);
2613  CHECK_EQUAL_64(dst_base + 24, x18);
2614  CHECK_EQUAL_64(src_base + 16, x19);
2615  CHECK_EQUAL_64(dst_base + 32, x20);
2616  CHECK_EQUAL_64(src_base, x21);
2617  CHECK_EQUAL_64(dst_base, x22);
2618  CHECK_EQUAL_64(src_base + 2, x23);
2619  CHECK_EQUAL_64(dst_base + 30, x24);
2620  CHECK_EQUAL_64(src_base, x25);
2621  CHECK_EQUAL_64(dst_base, x26);
2622
2623  TEARDOWN();
2624}
2625
2626
2627TEST(load_signed) {
2628  INIT_V8();
2629  SETUP();
2630
2631  uint32_t src[2] = {0x80008080, 0x7fff7f7f};
2632  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2633
2634  START();
2635  __ Mov(x24, src_base);
2636  __ Ldrsb(w0, MemOperand(x24));
2637  __ Ldrsb(w1, MemOperand(x24, 4));
2638  __ Ldrsh(w2, MemOperand(x24));
2639  __ Ldrsh(w3, MemOperand(x24, 4));
2640  __ Ldrsb(x4, MemOperand(x24));
2641  __ Ldrsb(x5, MemOperand(x24, 4));
2642  __ Ldrsh(x6, MemOperand(x24));
2643  __ Ldrsh(x7, MemOperand(x24, 4));
2644  __ Ldrsw(x8, MemOperand(x24));
2645  __ Ldrsw(x9, MemOperand(x24, 4));
2646  END();
2647
2648  RUN();
2649
2650  CHECK_EQUAL_64(0xffffff80, x0);
2651  CHECK_EQUAL_64(0x0000007f, x1);
2652  CHECK_EQUAL_64(0xffff8080, x2);
2653  CHECK_EQUAL_64(0x00007f7f, x3);
2654  CHECK_EQUAL_64(0xffffffffffffff80UL, x4);
2655  CHECK_EQUAL_64(0x000000000000007fUL, x5);
2656  CHECK_EQUAL_64(0xffffffffffff8080UL, x6);
2657  CHECK_EQUAL_64(0x0000000000007f7fUL, x7);
2658  CHECK_EQUAL_64(0xffffffff80008080UL, x8);
2659  CHECK_EQUAL_64(0x000000007fff7f7fUL, x9);
2660
2661  TEARDOWN();
2662}
2663
2664
2665TEST(load_store_regoffset) {
2666  INIT_V8();
2667  SETUP();
2668
2669  uint32_t src[3] = {1, 2, 3};
2670  uint32_t dst[4] = {0, 0, 0, 0};
2671  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2672  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2673
2674  START();
2675  __ Mov(x16, src_base);
2676  __ Mov(x17, dst_base);
2677  __ Mov(x18, src_base + 3 * sizeof(src[0]));
2678  __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
2679  __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
2680  __ Mov(x24, 0);
2681  __ Mov(x25, 4);
2682  __ Mov(x26, -4);
2683  __ Mov(x27, 0xfffffffc);  // 32-bit -4.
2684  __ Mov(x28, 0xfffffffe);  // 32-bit -2.
2685  __ Mov(x29, 0xffffffff);  // 32-bit -1.
2686
2687  __ Ldr(w0, MemOperand(x16, x24));
2688  __ Ldr(x1, MemOperand(x16, x25));
2689  __ Ldr(w2, MemOperand(x18, x26));
2690  __ Ldr(w3, MemOperand(x18, x27, SXTW));
2691  __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
2692  __ Str(w0, MemOperand(x17, x24));
2693  __ Str(x1, MemOperand(x17, x25));
2694  __ Str(w2, MemOperand(x20, x29, SXTW, 2));
2695  END();
2696
2697  RUN();
2698
2699  CHECK_EQUAL_64(1, x0);
2700  CHECK_EQUAL_64(0x0000000300000002UL, x1);
2701  CHECK_EQUAL_64(3, x2);
2702  CHECK_EQUAL_64(3, x3);
2703  CHECK_EQUAL_64(2, x4);
2704  CHECK_EQUAL_32(1, dst[0]);
2705  CHECK_EQUAL_32(2, dst[1]);
2706  CHECK_EQUAL_32(3, dst[2]);
2707  CHECK_EQUAL_32(3, dst[3]);
2708
2709  TEARDOWN();
2710}
2711
2712
2713TEST(load_store_float) {
2714  INIT_V8();
2715  SETUP();
2716
2717  float src[3] = {1.0, 2.0, 3.0};
2718  float dst[3] = {0.0, 0.0, 0.0};
2719  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2720  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2721
2722  START();
2723  __ Mov(x17, src_base);
2724  __ Mov(x18, dst_base);
2725  __ Mov(x19, src_base);
2726  __ Mov(x20, dst_base);
2727  __ Mov(x21, src_base);
2728  __ Mov(x22, dst_base);
2729  __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
2730  __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2731  __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
2732  __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2733  __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2734  __ Str(s2, MemOperand(x22, sizeof(dst[0])));
2735  END();
2736
2737  RUN();
2738
2739  CHECK_EQUAL_FP32(2.0, s0);
2740  CHECK_EQUAL_FP32(2.0, dst[0]);
2741  CHECK_EQUAL_FP32(1.0, s1);
2742  CHECK_EQUAL_FP32(1.0, dst[2]);
2743  CHECK_EQUAL_FP32(3.0, s2);
2744  CHECK_EQUAL_FP32(3.0, dst[1]);
2745  CHECK_EQUAL_64(src_base, x17);
2746  CHECK_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2747  CHECK_EQUAL_64(src_base + sizeof(src[0]), x19);
2748  CHECK_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2749  CHECK_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2750  CHECK_EQUAL_64(dst_base, x22);
2751
2752  TEARDOWN();
2753}
2754
2755
2756TEST(load_store_double) {
2757  INIT_V8();
2758  SETUP();
2759
2760  double src[3] = {1.0, 2.0, 3.0};
2761  double dst[3] = {0.0, 0.0, 0.0};
2762  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2763  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2764
2765  START();
2766  __ Mov(x17, src_base);
2767  __ Mov(x18, dst_base);
2768  __ Mov(x19, src_base);
2769  __ Mov(x20, dst_base);
2770  __ Mov(x21, src_base);
2771  __ Mov(x22, dst_base);
2772  __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
2773  __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2774  __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
2775  __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2776  __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2777  __ Str(d2, MemOperand(x22, sizeof(dst[0])));
2778  END();
2779
2780  RUN();
2781
2782  CHECK_EQUAL_FP64(2.0, d0);
2783  CHECK_EQUAL_FP64(2.0, dst[0]);
2784  CHECK_EQUAL_FP64(1.0, d1);
2785  CHECK_EQUAL_FP64(1.0, dst[2]);
2786  CHECK_EQUAL_FP64(3.0, d2);
2787  CHECK_EQUAL_FP64(3.0, dst[1]);
2788  CHECK_EQUAL_64(src_base, x17);
2789  CHECK_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2790  CHECK_EQUAL_64(src_base + sizeof(src[0]), x19);
2791  CHECK_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2792  CHECK_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2793  CHECK_EQUAL_64(dst_base, x22);
2794
2795  TEARDOWN();
2796}
2797
2798
2799TEST(ldp_stp_float) {
2800  INIT_V8();
2801  SETUP();
2802
2803  float src[2] = {1.0, 2.0};
2804  float dst[3] = {0.0, 0.0, 0.0};
2805  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2806  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2807
2808  START();
2809  __ Mov(x16, src_base);
2810  __ Mov(x17, dst_base);
2811  __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2812  __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2813  END();
2814
2815  RUN();
2816
2817  CHECK_EQUAL_FP32(1.0, s31);
2818  CHECK_EQUAL_FP32(2.0, s0);
2819  CHECK_EQUAL_FP32(0.0, dst[0]);
2820  CHECK_EQUAL_FP32(2.0, dst[1]);
2821  CHECK_EQUAL_FP32(1.0, dst[2]);
2822  CHECK_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2823  CHECK_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2824
2825  TEARDOWN();
2826}
2827
2828
2829TEST(ldp_stp_double) {
2830  INIT_V8();
2831  SETUP();
2832
2833  double src[2] = {1.0, 2.0};
2834  double dst[3] = {0.0, 0.0, 0.0};
2835  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2836  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2837
2838  START();
2839  __ Mov(x16, src_base);
2840  __ Mov(x17, dst_base);
2841  __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2842  __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2843  END();
2844
2845  RUN();
2846
2847  CHECK_EQUAL_FP64(1.0, d31);
2848  CHECK_EQUAL_FP64(2.0, d0);
2849  CHECK_EQUAL_FP64(0.0, dst[0]);
2850  CHECK_EQUAL_FP64(2.0, dst[1]);
2851  CHECK_EQUAL_FP64(1.0, dst[2]);
2852  CHECK_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2853  CHECK_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2854
2855  TEARDOWN();
2856}
2857
2858
2859TEST(ldp_stp_offset) {
2860  INIT_V8();
2861  SETUP();
2862
2863  uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL,
2864                     0xffeeddccbbaa9988UL};
2865  uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2866  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2867  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2868
2869  START();
2870  __ Mov(x16, src_base);
2871  __ Mov(x17, dst_base);
2872  __ Mov(x18, src_base + 24);
2873  __ Mov(x19, dst_base + 56);
2874  __ Ldp(w0, w1, MemOperand(x16));
2875  __ Ldp(w2, w3, MemOperand(x16, 4));
2876  __ Ldp(x4, x5, MemOperand(x16, 8));
2877  __ Ldp(w6, w7, MemOperand(x18, -12));
2878  __ Ldp(x8, x9, MemOperand(x18, -16));
2879  __ Stp(w0, w1, MemOperand(x17));
2880  __ Stp(w2, w3, MemOperand(x17, 8));
2881  __ Stp(x4, x5, MemOperand(x17, 16));
2882  __ Stp(w6, w7, MemOperand(x19, -24));
2883  __ Stp(x8, x9, MemOperand(x19, -16));
2884  END();
2885
2886  RUN();
2887
2888  CHECK_EQUAL_64(0x44556677, x0);
2889  CHECK_EQUAL_64(0x00112233, x1);
2890  CHECK_EQUAL_64(0x0011223344556677UL, dst[0]);
2891  CHECK_EQUAL_64(0x00112233, x2);
2892  CHECK_EQUAL_64(0xccddeeff, x3);
2893  CHECK_EQUAL_64(0xccddeeff00112233UL, dst[1]);
2894  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
2895  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
2896  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
2897  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
2898  CHECK_EQUAL_64(0x8899aabb, x6);
2899  CHECK_EQUAL_64(0xbbaa9988, x7);
2900  CHECK_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
2901  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x8);
2902  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
2903  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x9);
2904  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
2905  CHECK_EQUAL_64(src_base, x16);
2906  CHECK_EQUAL_64(dst_base, x17);
2907  CHECK_EQUAL_64(src_base + 24, x18);
2908  CHECK_EQUAL_64(dst_base + 56, x19);
2909
2910  TEARDOWN();
2911}
2912
2913
2914TEST(ldp_stp_offset_wide) {
2915  INIT_V8();
2916  SETUP();
2917
2918  uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2919                     0xffeeddccbbaa9988};
2920  uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2921  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2922  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2923  // Move base too far from the array to force multiple instructions
2924  // to be emitted.
2925  const int64_t base_offset = 1024;
2926
2927  START();
2928  __ Mov(x20, src_base - base_offset);
2929  __ Mov(x21, dst_base - base_offset);
2930  __ Mov(x18, src_base + base_offset + 24);
2931  __ Mov(x19, dst_base + base_offset + 56);
2932  __ Ldp(w0, w1, MemOperand(x20, base_offset));
2933  __ Ldp(w2, w3, MemOperand(x20, base_offset + 4));
2934  __ Ldp(x4, x5, MemOperand(x20, base_offset + 8));
2935  __ Ldp(w6, w7, MemOperand(x18, -12 - base_offset));
2936  __ Ldp(x8, x9, MemOperand(x18, -16 - base_offset));
2937  __ Stp(w0, w1, MemOperand(x21, base_offset));
2938  __ Stp(w2, w3, MemOperand(x21, base_offset + 8));
2939  __ Stp(x4, x5, MemOperand(x21, base_offset + 16));
2940  __ Stp(w6, w7, MemOperand(x19, -24 - base_offset));
2941  __ Stp(x8, x9, MemOperand(x19, -16 - base_offset));
2942  END();
2943
2944  RUN();
2945
2946  CHECK_EQUAL_64(0x44556677, x0);
2947  CHECK_EQUAL_64(0x00112233, x1);
2948  CHECK_EQUAL_64(0x0011223344556677UL, dst[0]);
2949  CHECK_EQUAL_64(0x00112233, x2);
2950  CHECK_EQUAL_64(0xccddeeff, x3);
2951  CHECK_EQUAL_64(0xccddeeff00112233UL, dst[1]);
2952  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
2953  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
2954  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
2955  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
2956  CHECK_EQUAL_64(0x8899aabb, x6);
2957  CHECK_EQUAL_64(0xbbaa9988, x7);
2958  CHECK_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
2959  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x8);
2960  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
2961  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x9);
2962  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
2963  CHECK_EQUAL_64(src_base - base_offset, x20);
2964  CHECK_EQUAL_64(dst_base - base_offset, x21);
2965  CHECK_EQUAL_64(src_base + base_offset + 24, x18);
2966  CHECK_EQUAL_64(dst_base + base_offset + 56, x19);
2967
2968  TEARDOWN();
2969}
2970
2971
2972TEST(ldnp_stnp_offset) {
2973  INIT_V8();
2974  SETUP();
2975
2976  uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL,
2977                     0xffeeddccbbaa9988UL};
2978  uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2979  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2980  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2981
2982  START();
2983  __ Mov(x16, src_base);
2984  __ Mov(x17, dst_base);
2985  __ Mov(x18, src_base + 24);
2986  __ Mov(x19, dst_base + 56);
2987  __ Ldnp(w0, w1, MemOperand(x16));
2988  __ Ldnp(w2, w3, MemOperand(x16, 4));
2989  __ Ldnp(x4, x5, MemOperand(x16, 8));
2990  __ Ldnp(w6, w7, MemOperand(x18, -12));
2991  __ Ldnp(x8, x9, MemOperand(x18, -16));
2992  __ Stnp(w0, w1, MemOperand(x17));
2993  __ Stnp(w2, w3, MemOperand(x17, 8));
2994  __ Stnp(x4, x5, MemOperand(x17, 16));
2995  __ Stnp(w6, w7, MemOperand(x19, -24));
2996  __ Stnp(x8, x9, MemOperand(x19, -16));
2997  END();
2998
2999  RUN();
3000
3001  CHECK_EQUAL_64(0x44556677, x0);
3002  CHECK_EQUAL_64(0x00112233, x1);
3003  CHECK_EQUAL_64(0x0011223344556677UL, dst[0]);
3004  CHECK_EQUAL_64(0x00112233, x2);
3005  CHECK_EQUAL_64(0xccddeeff, x3);
3006  CHECK_EQUAL_64(0xccddeeff00112233UL, dst[1]);
3007  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
3008  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[2]);
3009  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
3010  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]);
3011  CHECK_EQUAL_64(0x8899aabb, x6);
3012  CHECK_EQUAL_64(0xbbaa9988, x7);
3013  CHECK_EQUAL_64(0xbbaa99888899aabbUL, dst[4]);
3014  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x8);
3015  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[5]);
3016  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x9);
3017  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]);
3018  CHECK_EQUAL_64(src_base, x16);
3019  CHECK_EQUAL_64(dst_base, x17);
3020  CHECK_EQUAL_64(src_base + 24, x18);
3021  CHECK_EQUAL_64(dst_base + 56, x19);
3022
3023  TEARDOWN();
3024}
3025
3026
3027TEST(ldp_stp_preindex) {
3028  INIT_V8();
3029  SETUP();
3030
3031  uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL,
3032                     0xffeeddccbbaa9988UL};
3033  uint64_t dst[5] = {0, 0, 0, 0, 0};
3034  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3035  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3036
3037  START();
3038  __ Mov(x16, src_base);
3039  __ Mov(x17, dst_base);
3040  __ Mov(x18, dst_base + 16);
3041  __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
3042  __ Mov(x19, x16);
3043  __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
3044  __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
3045  __ Mov(x20, x17);
3046  __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
3047  __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
3048  __ Mov(x21, x16);
3049  __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
3050  __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
3051  __ Mov(x22, x18);
3052  __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
3053  END();
3054
3055  RUN();
3056
3057  CHECK_EQUAL_64(0x00112233, x0);
3058  CHECK_EQUAL_64(0xccddeeff, x1);
3059  CHECK_EQUAL_64(0x44556677, x2);
3060  CHECK_EQUAL_64(0x00112233, x3);
3061  CHECK_EQUAL_64(0xccddeeff00112233UL, dst[0]);
3062  CHECK_EQUAL_64(0x0000000000112233UL, dst[1]);
3063  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
3064  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
3065  CHECK_EQUAL_64(0x0011223344556677UL, x6);
3066  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x7);
3067  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
3068  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
3069  CHECK_EQUAL_64(0x0011223344556677UL, dst[4]);
3070  CHECK_EQUAL_64(src_base, x16);
3071  CHECK_EQUAL_64(dst_base, x17);
3072  CHECK_EQUAL_64(dst_base + 16, x18);
3073  CHECK_EQUAL_64(src_base + 4, x19);
3074  CHECK_EQUAL_64(dst_base + 4, x20);
3075  CHECK_EQUAL_64(src_base + 8, x21);
3076  CHECK_EQUAL_64(dst_base + 24, x22);
3077
3078  TEARDOWN();
3079}
3080
3081
3082TEST(ldp_stp_preindex_wide) {
3083  INIT_V8();
3084  SETUP();
3085
3086  uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
3087                     0xffeeddccbbaa9988};
3088  uint64_t dst[5] = {0, 0, 0, 0, 0};
3089  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3090  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3091  // Move base too far from the array to force multiple instructions
3092  // to be emitted.
3093  const int64_t base_offset = 1024;
3094
3095  START();
3096  __ Mov(x24, src_base - base_offset);
3097  __ Mov(x25, dst_base + base_offset);
3098  __ Mov(x18, dst_base + base_offset + 16);
3099  __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PreIndex));
3100  __ Mov(x19, x24);
3101  __ Mov(x24, src_base - base_offset + 4);
3102  __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PreIndex));
3103  __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PreIndex));
3104  __ Mov(x20, x25);
3105  __ Mov(x25, dst_base + base_offset + 4);
3106  __ Mov(x24, src_base - base_offset);
3107  __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PreIndex));
3108  __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PreIndex));
3109  __ Mov(x21, x24);
3110  __ Mov(x24, src_base - base_offset + 8);
3111  __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PreIndex));
3112  __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PreIndex));
3113  __ Mov(x22, x18);
3114  __ Mov(x18, dst_base + base_offset + 16 + 8);
3115  __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PreIndex));
3116  END();
3117
3118  RUN();
3119
3120  CHECK_EQUAL_64(0x00112233, x0);
3121  CHECK_EQUAL_64(0xccddeeff, x1);
3122  CHECK_EQUAL_64(0x44556677, x2);
3123  CHECK_EQUAL_64(0x00112233, x3);
3124  CHECK_EQUAL_64(0xccddeeff00112233UL, dst[0]);
3125  CHECK_EQUAL_64(0x0000000000112233UL, dst[1]);
3126  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4);
3127  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5);
3128  CHECK_EQUAL_64(0x0011223344556677UL, x6);
3129  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x7);
3130  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
3131  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
3132  CHECK_EQUAL_64(0x0011223344556677UL, dst[4]);
3133  CHECK_EQUAL_64(src_base, x24);
3134  CHECK_EQUAL_64(dst_base, x25);
3135  CHECK_EQUAL_64(dst_base + 16, x18);
3136  CHECK_EQUAL_64(src_base + 4, x19);
3137  CHECK_EQUAL_64(dst_base + 4, x20);
3138  CHECK_EQUAL_64(src_base + 8, x21);
3139  CHECK_EQUAL_64(dst_base + 24, x22);
3140
3141  TEARDOWN();
3142}
3143
3144
3145TEST(ldp_stp_postindex) {
3146  INIT_V8();
3147  SETUP();
3148
3149  uint64_t src[4] = {0x0011223344556677UL, 0x8899aabbccddeeffUL,
3150                     0xffeeddccbbaa9988UL, 0x7766554433221100UL};
3151  uint64_t dst[5] = {0, 0, 0, 0, 0};
3152  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3153  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3154
3155  START();
3156  __ Mov(x16, src_base);
3157  __ Mov(x17, dst_base);
3158  __ Mov(x18, dst_base + 16);
3159  __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
3160  __ Mov(x19, x16);
3161  __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
3162  __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
3163  __ Mov(x20, x17);
3164  __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
3165  __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
3166  __ Mov(x21, x16);
3167  __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
3168  __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
3169  __ Mov(x22, x18);
3170  __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
3171  END();
3172
3173  RUN();
3174
3175  CHECK_EQUAL_64(0x44556677, x0);
3176  CHECK_EQUAL_64(0x00112233, x1);
3177  CHECK_EQUAL_64(0x00112233, x2);
3178  CHECK_EQUAL_64(0xccddeeff, x3);
3179  CHECK_EQUAL_64(0x4455667700112233UL, dst[0]);
3180  CHECK_EQUAL_64(0x0000000000112233UL, dst[1]);
3181  CHECK_EQUAL_64(0x0011223344556677UL, x4);
3182  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x5);
3183  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x6);
3184  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x7);
3185  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
3186  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
3187  CHECK_EQUAL_64(0x0011223344556677UL, dst[4]);
3188  CHECK_EQUAL_64(src_base, x16);
3189  CHECK_EQUAL_64(dst_base, x17);
3190  CHECK_EQUAL_64(dst_base + 16, x18);
3191  CHECK_EQUAL_64(src_base + 4, x19);
3192  CHECK_EQUAL_64(dst_base + 4, x20);
3193  CHECK_EQUAL_64(src_base + 8, x21);
3194  CHECK_EQUAL_64(dst_base + 24, x22);
3195
3196  TEARDOWN();
3197}
3198
3199
3200TEST(ldp_stp_postindex_wide) {
3201  INIT_V8();
3202  SETUP();
3203
3204  uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff, 0xffeeddccbbaa9988,
3205                     0x7766554433221100};
3206  uint64_t dst[5] = {0, 0, 0, 0, 0};
3207  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3208  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3209  // Move base too far from the array to force multiple instructions
3210  // to be emitted.
3211  const int64_t base_offset = 1024;
3212
3213  START();
3214  __ Mov(x24, src_base);
3215  __ Mov(x25, dst_base);
3216  __ Mov(x18, dst_base + 16);
3217  __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PostIndex));
3218  __ Mov(x19, x24);
3219  __ Sub(x24, x24, base_offset);
3220  __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PostIndex));
3221  __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PostIndex));
3222  __ Mov(x20, x25);
3223  __ Sub(x24, x24, base_offset);
3224  __ Add(x25, x25, base_offset);
3225  __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PostIndex));
3226  __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PostIndex));
3227  __ Mov(x21, x24);
3228  __ Sub(x24, x24, base_offset);
3229  __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PostIndex));
3230  __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PostIndex));
3231  __ Mov(x22, x18);
3232  __ Add(x18, x18, base_offset);
3233  __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PostIndex));
3234  END();
3235
3236  RUN();
3237
3238  CHECK_EQUAL_64(0x44556677, x0);
3239  CHECK_EQUAL_64(0x00112233, x1);
3240  CHECK_EQUAL_64(0x00112233, x2);
3241  CHECK_EQUAL_64(0xccddeeff, x3);
3242  CHECK_EQUAL_64(0x4455667700112233UL, dst[0]);
3243  CHECK_EQUAL_64(0x0000000000112233UL, dst[1]);
3244  CHECK_EQUAL_64(0x0011223344556677UL, x4);
3245  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x5);
3246  CHECK_EQUAL_64(0x8899aabbccddeeffUL, x6);
3247  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x7);
3248  CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]);
3249  CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[3]);
3250  CHECK_EQUAL_64(0x0011223344556677UL, dst[4]);
3251  CHECK_EQUAL_64(src_base + base_offset, x24);
3252  CHECK_EQUAL_64(dst_base - base_offset, x25);
3253  CHECK_EQUAL_64(dst_base - base_offset + 16, x18);
3254  CHECK_EQUAL_64(src_base + base_offset + 4, x19);
3255  CHECK_EQUAL_64(dst_base - base_offset + 4, x20);
3256  CHECK_EQUAL_64(src_base + base_offset + 8, x21);
3257  CHECK_EQUAL_64(dst_base - base_offset + 24, x22);
3258
3259  TEARDOWN();
3260}
3261
3262
3263TEST(ldp_sign_extend) {
3264  INIT_V8();
3265  SETUP();
3266
3267  uint32_t src[2] = {0x80000000, 0x7fffffff};
3268  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3269
3270  START();
3271  __ Mov(x24, src_base);
3272  __ Ldpsw(x0, x1, MemOperand(x24));
3273  END();
3274
3275  RUN();
3276
3277  CHECK_EQUAL_64(0xffffffff80000000UL, x0);
3278  CHECK_EQUAL_64(0x000000007fffffffUL, x1);
3279
3280  TEARDOWN();
3281}
3282
3283
3284TEST(ldur_stur) {
3285  INIT_V8();
3286  SETUP();
3287
3288  int64_t src[2] = {0x0123456789abcdefUL, 0x0123456789abcdefUL};
3289  int64_t dst[5] = {0, 0, 0, 0, 0};
3290  uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3291  uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3292
3293  START();
3294  __ Mov(x17, src_base);
3295  __ Mov(x18, dst_base);
3296  __ Mov(x19, src_base + 16);
3297  __ Mov(x20, dst_base + 32);
3298  __ Mov(x21, dst_base + 40);
3299  __ Ldr(w0, MemOperand(x17, 1));
3300  __ Str(w0, MemOperand(x18, 2));
3301  __ Ldr(x1, MemOperand(x17, 3));
3302  __ Str(x1, MemOperand(x18, 9));
3303  __ Ldr(w2, MemOperand(x19, -9));
3304  __ Str(w2, MemOperand(x20, -5));
3305  __ Ldrb(w3, MemOperand(x19, -1));
3306  __ Strb(w3, MemOperand(x21, -1));
3307  END();
3308
3309  RUN();
3310
3311  CHECK_EQUAL_64(0x6789abcd, x0);
3312  CHECK_EQUAL_64(0x6789abcd0000L, dst[0]);
3313  CHECK_EQUAL_64(0xabcdef0123456789L, x1);
3314  CHECK_EQUAL_64(0xcdef012345678900L, dst[1]);
3315  CHECK_EQUAL_64(0x000000ab, dst[2]);
3316  CHECK_EQUAL_64(0xabcdef01, x2);
3317  CHECK_EQUAL_64(0x00abcdef01000000L, dst[3]);
3318  CHECK_EQUAL_64(0x00000001, x3);
3319  CHECK_EQUAL_64(0x0100000000000000L, dst[4]);
3320  CHECK_EQUAL_64(src_base, x17);
3321  CHECK_EQUAL_64(dst_base, x18);
3322  CHECK_EQUAL_64(src_base + 16, x19);
3323  CHECK_EQUAL_64(dst_base + 32, x20);
3324
3325  TEARDOWN();
3326}
3327
3328
3329#if 0  // TODO(all) enable.
3330// TODO(rodolph): Adapt w16 Literal tests for RelocInfo.
3331TEST(ldr_literal) {
3332  INIT_V8();
3333  SETUP();
3334
3335  START();
3336  __ Ldr(x2, 0x1234567890abcdefUL);
3337  __ Ldr(w3, 0xfedcba09);
3338  __ Ldr(d13, 1.234);
3339  __ Ldr(s25, 2.5);
3340  END();
3341
3342  RUN();
3343
3344  CHECK_EQUAL_64(0x1234567890abcdefUL, x2);
3345  CHECK_EQUAL_64(0xfedcba09, x3);
3346  CHECK_EQUAL_FP64(1.234, d13);
3347  CHECK_EQUAL_FP32(2.5, s25);
3348
3349  TEARDOWN();
3350}
3351
3352
3353static void LdrLiteralRangeHelper(ptrdiff_t range_,
3354                                  LiteralPoolEmitOption option,
3355                                  bool expect_dump) {
3356  DCHECK(range_ > 0);
3357  SETUP_SIZE(range_ + 1024);
3358
3359  Label label_1, label_2;
3360
3361  size_t range = static_cast<size_t>(range_);
3362  size_t code_size = 0;
3363  size_t pool_guard_size;
3364
3365  if (option == NoJumpRequired) {
3366    // Space for an explicit branch.
3367    pool_guard_size = sizeof(Instr);
3368  } else {
3369    pool_guard_size = 0;
3370  }
3371
3372  START();
3373  // Force a pool dump so the pool starts off empty.
3374  __ EmitLiteralPool(JumpRequired);
3375  DCHECK_LITERAL_POOL_SIZE(0);
3376
3377  __ Ldr(x0, 0x1234567890abcdefUL);
3378  __ Ldr(w1, 0xfedcba09);
3379  __ Ldr(d0, 1.234);
3380  __ Ldr(s1, 2.5);
3381  DCHECK_LITERAL_POOL_SIZE(4);
3382
3383  code_size += 4 * sizeof(Instr);
3384
3385  // Check that the requested range (allowing space for a branch over the pool)
3386  // can be handled by this test.
3387  DCHECK((code_size + pool_guard_size) <= range);
3388
3389  // Emit NOPs up to 'range', leaving space for the pool guard.
3390  while ((code_size + pool_guard_size) < range) {
3391    __ Nop();
3392    code_size += sizeof(Instr);
3393  }
3394
3395  // Emit the guard sequence before the literal pool.
3396  if (option == NoJumpRequired) {
3397    __ B(&label_1);
3398    code_size += sizeof(Instr);
3399  }
3400
3401  DCHECK(code_size == range);
3402  DCHECK_LITERAL_POOL_SIZE(4);
3403
3404  // Possibly generate a literal pool.
3405  __ CheckLiteralPool(option);
3406  __ Bind(&label_1);
3407  if (expect_dump) {
3408    DCHECK_LITERAL_POOL_SIZE(0);
3409  } else {
3410    DCHECK_LITERAL_POOL_SIZE(4);
3411  }
3412
3413  // Force a pool flush to check that a second pool functions correctly.
3414  __ EmitLiteralPool(JumpRequired);
3415  DCHECK_LITERAL_POOL_SIZE(0);
3416
3417  // These loads should be after the pool (and will require a new one).
3418  __ Ldr(x4, 0x34567890abcdef12UL);
3419  __ Ldr(w5, 0xdcba09fe);
3420  __ Ldr(d4, 123.4);
3421  __ Ldr(s5, 250.0);
3422  DCHECK_LITERAL_POOL_SIZE(4);
3423  END();
3424
3425  RUN();
3426
3427  // Check that the literals loaded correctly.
3428  CHECK_EQUAL_64(0x1234567890abcdefUL, x0);
3429  CHECK_EQUAL_64(0xfedcba09, x1);
3430  CHECK_EQUAL_FP64(1.234, d0);
3431  CHECK_EQUAL_FP32(2.5, s1);
3432  CHECK_EQUAL_64(0x34567890abcdef12UL, x4);
3433  CHECK_EQUAL_64(0xdcba09fe, x5);
3434  CHECK_EQUAL_FP64(123.4, d4);
3435  CHECK_EQUAL_FP32(250.0, s5);
3436
3437  TEARDOWN();
3438}
3439
3440
3441TEST(ldr_literal_range_1) {
3442  INIT_V8();
3443  LdrLiteralRangeHelper(kRecommendedLiteralPoolRange,
3444                        NoJumpRequired,
3445                        true);
3446}
3447
3448
3449TEST(ldr_literal_range_2) {
3450  INIT_V8();
3451  LdrLiteralRangeHelper(kRecommendedLiteralPoolRange-sizeof(Instr),
3452                        NoJumpRequired,
3453                        false);
3454}
3455
3456
3457TEST(ldr_literal_range_3) {
3458  INIT_V8();
3459  LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange,
3460                        JumpRequired,
3461                        true);
3462}
3463
3464
3465TEST(ldr_literal_range_4) {
3466  INIT_V8();
3467  LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange-sizeof(Instr),
3468                        JumpRequired,
3469                        false);
3470}
3471
3472
3473TEST(ldr_literal_range_5) {
3474  INIT_V8();
3475  LdrLiteralRangeHelper(kLiteralPoolCheckInterval,
3476                        JumpRequired,
3477                        false);
3478}
3479
3480
3481TEST(ldr_literal_range_6) {
3482  INIT_V8();
3483  LdrLiteralRangeHelper(kLiteralPoolCheckInterval-sizeof(Instr),
3484                        JumpRequired,
3485                        false);
3486}
3487#endif
3488
3489TEST(add_sub_imm) {
3490  INIT_V8();
3491  SETUP();
3492
3493  START();
3494  __ Mov(x0, 0x0);
3495  __ Mov(x1, 0x1111);
3496  __ Mov(x2, 0xffffffffffffffffL);
3497  __ Mov(x3, 0x8000000000000000L);
3498
3499  __ Add(x10, x0, Operand(0x123));
3500  __ Add(x11, x1, Operand(0x122000));
3501  __ Add(x12, x0, Operand(0xabc << 12));
3502  __ Add(x13, x2, Operand(1));
3503
3504  __ Add(w14, w0, Operand(0x123));
3505  __ Add(w15, w1, Operand(0x122000));
3506  __ Add(w16, w0, Operand(0xabc << 12));
3507  __ Add(w17, w2, Operand(1));
3508
3509  __ Sub(x20, x0, Operand(0x1));
3510  __ Sub(x21, x1, Operand(0x111));
3511  __ Sub(x22, x1, Operand(0x1 << 12));
3512  __ Sub(x23, x3, Operand(1));
3513
3514  __ Sub(w24, w0, Operand(0x1));
3515  __ Sub(w25, w1, Operand(0x111));
3516  __ Sub(w26, w1, Operand(0x1 << 12));
3517  __ Sub(w27, w3, Operand(1));
3518  END();
3519
3520  RUN();
3521
3522  CHECK_EQUAL_64(0x123, x10);
3523  CHECK_EQUAL_64(0x123111, x11);
3524  CHECK_EQUAL_64(0xabc000, x12);
3525  CHECK_EQUAL_64(0x0, x13);
3526
3527  CHECK_EQUAL_32(0x123, w14);
3528  CHECK_EQUAL_32(0x123111, w15);
3529  CHECK_EQUAL_32(0xabc000, w16);
3530  CHECK_EQUAL_32(0x0, w17);
3531
3532  CHECK_EQUAL_64(0xffffffffffffffffL, x20);
3533  CHECK_EQUAL_64(0x1000, x21);
3534  CHECK_EQUAL_64(0x111, x22);
3535  CHECK_EQUAL_64(0x7fffffffffffffffL, x23);
3536
3537  CHECK_EQUAL_32(0xffffffff, w24);
3538  CHECK_EQUAL_32(0x1000, w25);
3539  CHECK_EQUAL_32(0x111, w26);
3540  CHECK_EQUAL_32(0xffffffff, w27);
3541
3542  TEARDOWN();
3543}
3544
3545
3546TEST(add_sub_wide_imm) {
3547  INIT_V8();
3548  SETUP();
3549
3550  START();
3551  __ Mov(x0, 0x0);
3552  __ Mov(x1, 0x1);
3553
3554  __ Add(x10, x0, Operand(0x1234567890abcdefUL));
3555  __ Add(x11, x1, Operand(0xffffffff));
3556
3557  __ Add(w12, w0, Operand(0x12345678));
3558  __ Add(w13, w1, Operand(0xffffffff));
3559
3560  __ Add(w18, w0, Operand(kWMinInt));
3561  __ Sub(w19, w0, Operand(kWMinInt));
3562
3563  __ Sub(x20, x0, Operand(0x1234567890abcdefUL));
3564  __ Sub(w21, w0, Operand(0x12345678));
3565  END();
3566
3567  RUN();
3568
3569  CHECK_EQUAL_64(0x1234567890abcdefUL, x10);
3570  CHECK_EQUAL_64(0x100000000UL, x11);
3571
3572  CHECK_EQUAL_32(0x12345678, w12);
3573  CHECK_EQUAL_64(0x0, x13);
3574
3575  CHECK_EQUAL_32(kWMinInt, w18);
3576  CHECK_EQUAL_32(kWMinInt, w19);
3577
3578  CHECK_EQUAL_64(-0x1234567890abcdefUL, x20);
3579  CHECK_EQUAL_32(-0x12345678, w21);
3580
3581  TEARDOWN();
3582}
3583
3584
3585TEST(add_sub_shifted) {
3586  INIT_V8();
3587  SETUP();
3588
3589  START();
3590  __ Mov(x0, 0);
3591  __ Mov(x1, 0x0123456789abcdefL);
3592  __ Mov(x2, 0xfedcba9876543210L);
3593  __ Mov(x3, 0xffffffffffffffffL);
3594
3595  __ Add(x10, x1, Operand(x2));
3596  __ Add(x11, x0, Operand(x1, LSL, 8));
3597  __ Add(x12, x0, Operand(x1, LSR, 8));
3598  __ Add(x13, x0, Operand(x1, ASR, 8));
3599  __ Add(x14, x0, Operand(x2, ASR, 8));
3600  __ Add(w15, w0, Operand(w1, ASR, 8));
3601  __ Add(w18, w3, Operand(w1, ROR, 8));
3602  __ Add(x19, x3, Operand(x1, ROR, 8));
3603
3604  __ Sub(x20, x3, Operand(x2));
3605  __ Sub(x21, x3, Operand(x1, LSL, 8));
3606  __ Sub(x22, x3, Operand(x1, LSR, 8));
3607  __ Sub(x23, x3, Operand(x1, ASR, 8));
3608  __ Sub(x24, x3, Operand(x2, ASR, 8));
3609  __ Sub(w25, w3, Operand(w1, ASR, 8));
3610  __ Sub(w26, w3, Operand(w1, ROR, 8));
3611  __ Sub(x27, x3, Operand(x1, ROR, 8));
3612  END();
3613
3614  RUN();
3615
3616  CHECK_EQUAL_64(0xffffffffffffffffL, x10);
3617  CHECK_EQUAL_64(0x23456789abcdef00L, x11);
3618  CHECK_EQUAL_64(0x000123456789abcdL, x12);
3619  CHECK_EQUAL_64(0x000123456789abcdL, x13);
3620  CHECK_EQUAL_64(0xfffedcba98765432L, x14);
3621  CHECK_EQUAL_64(0xff89abcd, x15);
3622  CHECK_EQUAL_64(0xef89abcc, x18);
3623  CHECK_EQUAL_64(0xef0123456789abccL, x19);
3624
3625  CHECK_EQUAL_64(0x0123456789abcdefL, x20);
3626  CHECK_EQUAL_64(0xdcba9876543210ffL, x21);
3627  CHECK_EQUAL_64(0xfffedcba98765432L, x22);
3628  CHECK_EQUAL_64(0xfffedcba98765432L, x23);
3629  CHECK_EQUAL_64(0x000123456789abcdL, x24);
3630  CHECK_EQUAL_64(0x00765432, x25);
3631  CHECK_EQUAL_64(0x10765432, x26);
3632  CHECK_EQUAL_64(0x10fedcba98765432L, x27);
3633
3634  TEARDOWN();
3635}
3636
3637
3638TEST(add_sub_extended) {
3639  INIT_V8();
3640  SETUP();
3641
3642  START();
3643  __ Mov(x0, 0);
3644  __ Mov(x1, 0x0123456789abcdefL);
3645  __ Mov(x2, 0xfedcba9876543210L);
3646  __ Mov(w3, 0x80);
3647
3648  __ Add(x10, x0, Operand(x1, UXTB, 0));
3649  __ Add(x11, x0, Operand(x1, UXTB, 1));
3650  __ Add(x12, x0, Operand(x1, UXTH, 2));
3651  __ Add(x13, x0, Operand(x1, UXTW, 4));
3652
3653  __ Add(x14, x0, Operand(x1, SXTB, 0));
3654  __ Add(x15, x0, Operand(x1, SXTB, 1));
3655  __ Add(x16, x0, Operand(x1, SXTH, 2));
3656  __ Add(x17, x0, Operand(x1, SXTW, 3));
3657  __ Add(x18, x0, Operand(x2, SXTB, 0));
3658  __ Add(x19, x0, Operand(x2, SXTB, 1));
3659  __ Add(x20, x0, Operand(x2, SXTH, 2));
3660  __ Add(x21, x0, Operand(x2, SXTW, 3));
3661
3662  __ Add(x22, x1, Operand(x2, SXTB, 1));
3663  __ Sub(x23, x1, Operand(x2, SXTB, 1));
3664
3665  __ Add(w24, w1, Operand(w2, UXTB, 2));
3666  __ Add(w25, w0, Operand(w1, SXTB, 0));
3667  __ Add(w26, w0, Operand(w1, SXTB, 1));
3668  __ Add(w27, w2, Operand(w1, SXTW, 3));
3669
3670  __ Add(w28, w0, Operand(w1, SXTW, 3));
3671  __ Add(x29, x0, Operand(w1, SXTW, 3));
3672
3673  __ Sub(x30, x0, Operand(w3, SXTB, 1));
3674  END();
3675
3676  RUN();
3677
3678  CHECK_EQUAL_64(0xefL, x10);
3679  CHECK_EQUAL_64(0x1deL, x11);
3680  CHECK_EQUAL_64(0x337bcL, x12);
3681  CHECK_EQUAL_64(0x89abcdef0L, x13);
3682
3683  CHECK_EQUAL_64(0xffffffffffffffefL, x14);
3684  CHECK_EQUAL_64(0xffffffffffffffdeL, x15);
3685  CHECK_EQUAL_64(0xffffffffffff37bcL, x16);
3686  CHECK_EQUAL_64(0xfffffffc4d5e6f78L, x17);
3687  CHECK_EQUAL_64(0x10L, x18);
3688  CHECK_EQUAL_64(0x20L, x19);
3689  CHECK_EQUAL_64(0xc840L, x20);
3690  CHECK_EQUAL_64(0x3b2a19080L, x21);
3691
3692  CHECK_EQUAL_64(0x0123456789abce0fL, x22);
3693  CHECK_EQUAL_64(0x0123456789abcdcfL, x23);
3694
3695  CHECK_EQUAL_32(0x89abce2f, w24);
3696  CHECK_EQUAL_32(0xffffffef, w25);
3697  CHECK_EQUAL_32(0xffffffde, w26);
3698  CHECK_EQUAL_32(0xc3b2a188, w27);
3699
3700  CHECK_EQUAL_32(0x4d5e6f78, w28);
3701  CHECK_EQUAL_64(0xfffffffc4d5e6f78L, x29);
3702
3703  CHECK_EQUAL_64(256, x30);
3704
3705  TEARDOWN();
3706}
3707
3708
3709TEST(add_sub_negative) {
3710  INIT_V8();
3711  SETUP();
3712
3713  START();
3714  __ Mov(x0, 0);
3715  __ Mov(x1, 4687);
3716  __ Mov(x2, 0x1122334455667788);
3717  __ Mov(w3, 0x11223344);
3718  __ Mov(w4, 400000);
3719
3720  __ Add(x10, x0, -42);
3721  __ Add(x11, x1, -687);
3722  __ Add(x12, x2, -0x88);
3723
3724  __ Sub(x13, x0, -600);
3725  __ Sub(x14, x1, -313);
3726  __ Sub(x15, x2, -0x555);
3727
3728  __ Add(w19, w3, -0x344);
3729  __ Add(w20, w4, -2000);
3730
3731  __ Sub(w21, w3, -0xbc);
3732  __ Sub(w22, w4, -2000);
3733  END();
3734
3735  RUN();
3736
3737  CHECK_EQUAL_64(-42, x10);
3738  CHECK_EQUAL_64(4000, x11);
3739  CHECK_EQUAL_64(0x1122334455667700, x12);
3740
3741  CHECK_EQUAL_64(600, x13);
3742  CHECK_EQUAL_64(5000, x14);
3743  CHECK_EQUAL_64(0x1122334455667cdd, x15);
3744
3745  CHECK_EQUAL_32(0x11223000, w19);
3746  CHECK_EQUAL_32(398000, w20);
3747
3748  CHECK_EQUAL_32(0x11223400, w21);
3749  CHECK_EQUAL_32(402000, w22);
3750
3751  TEARDOWN();
3752}
3753
3754
3755TEST(add_sub_zero) {
3756  INIT_V8();
3757  SETUP();
3758
3759  START();
3760  __ Mov(x0, 0);
3761  __ Mov(x1, 0);
3762  __ Mov(x2, 0);
3763
3764  Label blob1;
3765  __ Bind(&blob1);
3766  __ Add(x0, x0, 0);
3767  __ Sub(x1, x1, 0);
3768  __ Sub(x2, x2, xzr);
3769  CHECK_EQ(0, __ SizeOfCodeGeneratedSince(&blob1));
3770
3771  Label blob2;
3772  __ Bind(&blob2);
3773  __ Add(w3, w3, 0);
3774  CHECK_NE(0, __ SizeOfCodeGeneratedSince(&blob2));
3775
3776  Label blob3;
3777  __ Bind(&blob3);
3778  __ Sub(w3, w3, wzr);
3779  CHECK_NE(0, __ SizeOfCodeGeneratedSince(&blob3));
3780
3781  END();
3782
3783  RUN();
3784
3785  CHECK_EQUAL_64(0, x0);
3786  CHECK_EQUAL_64(0, x1);
3787  CHECK_EQUAL_64(0, x2);
3788
3789  TEARDOWN();
3790}
3791
3792
3793TEST(claim_drop_zero) {
3794  INIT_V8();
3795  SETUP();
3796
3797  START();
3798
3799  Label start;
3800  __ Bind(&start);
3801  __ Claim(0);
3802  __ Drop(0);
3803  __ Claim(xzr, 8);
3804  __ Drop(xzr, 8);
3805  __ Claim(xzr, 0);
3806  __ Drop(xzr, 0);
3807  __ Claim(x7, 0);
3808  __ Drop(x7, 0);
3809  __ ClaimBySMI(xzr, 8);
3810  __ DropBySMI(xzr, 8);
3811  __ ClaimBySMI(xzr, 0);
3812  __ DropBySMI(xzr, 0);
3813  CHECK_EQ(0, __ SizeOfCodeGeneratedSince(&start));
3814
3815  END();
3816
3817  RUN();
3818
3819  TEARDOWN();
3820}
3821
3822
3823TEST(neg) {
3824  INIT_V8();
3825  SETUP();
3826
3827  START();
3828  __ Mov(x0, 0xf123456789abcdefL);
3829
3830  // Immediate.
3831  __ Neg(x1, 0x123);
3832  __ Neg(w2, 0x123);
3833
3834  // Shifted.
3835  __ Neg(x3, Operand(x0, LSL, 1));
3836  __ Neg(w4, Operand(w0, LSL, 2));
3837  __ Neg(x5, Operand(x0, LSR, 3));
3838  __ Neg(w6, Operand(w0, LSR, 4));
3839  __ Neg(x7, Operand(x0, ASR, 5));
3840  __ Neg(w8, Operand(w0, ASR, 6));
3841
3842  // Extended.
3843  __ Neg(w9, Operand(w0, UXTB));
3844  __ Neg(x10, Operand(x0, SXTB, 1));
3845  __ Neg(w11, Operand(w0, UXTH, 2));
3846  __ Neg(x12, Operand(x0, SXTH, 3));
3847  __ Neg(w13, Operand(w0, UXTW, 4));
3848  __ Neg(x14, Operand(x0, SXTW, 4));
3849  END();
3850
3851  RUN();
3852
3853  CHECK_EQUAL_64(0xfffffffffffffeddUL, x1);
3854  CHECK_EQUAL_64(0xfffffedd, x2);
3855  CHECK_EQUAL_64(0x1db97530eca86422UL, x3);
3856  CHECK_EQUAL_64(0xd950c844, x4);
3857  CHECK_EQUAL_64(0xe1db97530eca8643UL, x5);
3858  CHECK_EQUAL_64(0xf7654322, x6);
3859  CHECK_EQUAL_64(0x0076e5d4c3b2a191UL, x7);
3860  CHECK_EQUAL_64(0x01d950c9, x8);
3861  CHECK_EQUAL_64(0xffffff11, x9);
3862  CHECK_EQUAL_64(0x0000000000000022UL, x10);
3863  CHECK_EQUAL_64(0xfffcc844, x11);
3864  CHECK_EQUAL_64(0x0000000000019088UL, x12);
3865  CHECK_EQUAL_64(0x65432110, x13);
3866  CHECK_EQUAL_64(0x0000000765432110UL, x14);
3867
3868  TEARDOWN();
3869}
3870
3871
3872TEST(adc_sbc_shift) {
3873  INIT_V8();
3874  SETUP();
3875
3876  START();
3877  __ Mov(x0, 0);
3878  __ Mov(x1, 1);
3879  __ Mov(x2, 0x0123456789abcdefL);
3880  __ Mov(x3, 0xfedcba9876543210L);
3881  __ Mov(x4, 0xffffffffffffffffL);
3882
3883  // Clear the C flag.
3884  __ Adds(x0, x0, Operand(0));
3885
3886  __ Adc(x5, x2, Operand(x3));
3887  __ Adc(x6, x0, Operand(x1, LSL, 60));
3888  __ Sbc(x7, x4, Operand(x3, LSR, 4));
3889  __ Adc(x8, x2, Operand(x3, ASR, 4));
3890  __ Adc(x9, x2, Operand(x3, ROR, 8));
3891
3892  __ Adc(w10, w2, Operand(w3));
3893  __ Adc(w11, w0, Operand(w1, LSL, 30));
3894  __ Sbc(w12, w4, Operand(w3, LSR, 4));
3895  __ Adc(w13, w2, Operand(w3, ASR, 4));
3896  __ Adc(w14, w2, Operand(w3, ROR, 8));
3897
3898  // Set the C flag.
3899  __ Cmp(w0, Operand(w0));
3900
3901  __ Adc(x18, x2, Operand(x3));
3902  __ Adc(x19, x0, Operand(x1, LSL, 60));
3903  __ Sbc(x20, x4, Operand(x3, LSR, 4));
3904  __ Adc(x21, x2, Operand(x3, ASR, 4));
3905  __ Adc(x22, x2, Operand(x3, ROR, 8));
3906
3907  __ Adc(w23, w2, Operand(w3));
3908  __ Adc(w24, w0, Operand(w1, LSL, 30));
3909  __ Sbc(w25, w4, Operand(w3, LSR, 4));
3910  __ Adc(w26, w2, Operand(w3, ASR, 4));
3911  __ Adc(w27, w2, Operand(w3, ROR, 8));
3912  END();
3913
3914  RUN();
3915
3916  CHECK_EQUAL_64(0xffffffffffffffffL, x5);
3917  CHECK_EQUAL_64(1L << 60, x6);
3918  CHECK_EQUAL_64(0xf0123456789abcddL, x7);
3919  CHECK_EQUAL_64(0x0111111111111110L, x8);
3920  CHECK_EQUAL_64(0x1222222222222221L, x9);
3921
3922  CHECK_EQUAL_32(0xffffffff, w10);
3923  CHECK_EQUAL_32(1 << 30, w11);
3924  CHECK_EQUAL_32(0xf89abcdd, w12);
3925  CHECK_EQUAL_32(0x91111110, w13);
3926  CHECK_EQUAL_32(0x9a222221, w14);
3927
3928  CHECK_EQUAL_64(0xffffffffffffffffL + 1, x18);
3929  CHECK_EQUAL_64((1L << 60) + 1, x19);
3930  CHECK_EQUAL_64(0xf0123456789abcddL + 1, x20);
3931  CHECK_EQUAL_64(0x0111111111111110L + 1, x21);
3932  CHECK_EQUAL_64(0x1222222222222221L + 1, x22);
3933
3934  CHECK_EQUAL_32(0xffffffff + 1, w23);
3935  CHECK_EQUAL_32((1 << 30) + 1, w24);
3936  CHECK_EQUAL_32(0xf89abcdd + 1, w25);
3937  CHECK_EQUAL_32(0x91111110 + 1, w26);
3938  CHECK_EQUAL_32(0x9a222221 + 1, w27);
3939
3940  // Check that adc correctly sets the condition flags.
3941  START();
3942  __ Mov(x0, 1);
3943  __ Mov(x1, 0xffffffffffffffffL);
3944  // Clear the C flag.
3945  __ Adds(x0, x0, Operand(0));
3946  __ Adcs(x10, x0, Operand(x1));
3947  END();
3948
3949  RUN();
3950
3951  CHECK_EQUAL_NZCV(ZCFlag);
3952  CHECK_EQUAL_64(0, x10);
3953
3954  START();
3955  __ Mov(x0, 1);
3956  __ Mov(x1, 0x8000000000000000L);
3957  // Clear the C flag.
3958  __ Adds(x0, x0, Operand(0));
3959  __ Adcs(x10, x0, Operand(x1, ASR, 63));
3960  END();
3961
3962  RUN();
3963
3964  CHECK_EQUAL_NZCV(ZCFlag);
3965  CHECK_EQUAL_64(0, x10);
3966
3967  START();
3968  __ Mov(x0, 0x10);
3969  __ Mov(x1, 0x07ffffffffffffffL);
3970  // Clear the C flag.
3971  __ Adds(x0, x0, Operand(0));
3972  __ Adcs(x10, x0, Operand(x1, LSL, 4));
3973  END();
3974
3975  RUN();
3976
3977  CHECK_EQUAL_NZCV(NVFlag);
3978  CHECK_EQUAL_64(0x8000000000000000L, x10);
3979
3980  // Check that sbc correctly sets the condition flags.
3981  START();
3982  __ Mov(x0, 0);
3983  __ Mov(x1, 0xffffffffffffffffL);
3984  // Clear the C flag.
3985  __ Adds(x0, x0, Operand(0));
3986  __ Sbcs(x10, x0, Operand(x1));
3987  END();
3988
3989  RUN();
3990
3991  CHECK_EQUAL_NZCV(ZFlag);
3992  CHECK_EQUAL_64(0, x10);
3993
3994  START();
3995  __ Mov(x0, 1);
3996  __ Mov(x1, 0xffffffffffffffffL);
3997  // Clear the C flag.
3998  __ Adds(x0, x0, Operand(0));
3999  __ Sbcs(x10, x0, Operand(x1, LSR, 1));
4000  END();
4001
4002  RUN();
4003
4004  CHECK_EQUAL_NZCV(NFlag);
4005  CHECK_EQUAL_64(0x8000000000000001L, x10);
4006
4007  START();
4008  __ Mov(x0, 0);
4009  // Clear the C flag.
4010  __ Adds(x0, x0, Operand(0));
4011  __ Sbcs(x10, x0, Operand(0xffffffffffffffffL));
4012  END();
4013
4014  RUN();
4015
4016  CHECK_EQUAL_NZCV(ZFlag);
4017  CHECK_EQUAL_64(0, x10);
4018
4019  START()
4020  __ Mov(w0, 0x7fffffff);
4021  // Clear the C flag.
4022  __ Adds(x0, x0, Operand(0));
4023  __ Ngcs(w10, w0);
4024  END();
4025
4026  RUN();
4027
4028  CHECK_EQUAL_NZCV(NFlag);
4029  CHECK_EQUAL_64(0x80000000, x10);
4030
4031  START();
4032  // Clear the C flag.
4033  __ Adds(x0, x0, Operand(0));
4034  __ Ngcs(x10, 0x7fffffffffffffffL);
4035  END();
4036
4037  RUN();
4038
4039  CHECK_EQUAL_NZCV(NFlag);
4040  CHECK_EQUAL_64(0x8000000000000000L, x10);
4041
4042  START()
4043  __ Mov(x0, 0);
4044  // Set the C flag.
4045  __ Cmp(x0, Operand(x0));
4046  __ Sbcs(x10, x0, Operand(1));
4047  END();
4048
4049  RUN();
4050
4051  CHECK_EQUAL_NZCV(NFlag);
4052  CHECK_EQUAL_64(0xffffffffffffffffL, x10);
4053
4054  START()
4055  __ Mov(x0, 0);
4056  // Set the C flag.
4057  __ Cmp(x0, Operand(x0));
4058  __ Ngcs(x10, 0x7fffffffffffffffL);
4059  END();
4060
4061  RUN();
4062
4063  CHECK_EQUAL_NZCV(NFlag);
4064  CHECK_EQUAL_64(0x8000000000000001L, x10);
4065
4066  TEARDOWN();
4067}
4068
4069
4070TEST(adc_sbc_extend) {
4071  INIT_V8();
4072  SETUP();
4073
4074  START();
4075  // Clear the C flag.
4076  __ Adds(x0, x0, Operand(0));
4077
4078  __ Mov(x0, 0);
4079  __ Mov(x1, 1);
4080  __ Mov(x2, 0x0123456789abcdefL);
4081
4082  __ Adc(x10, x1, Operand(w2, UXTB, 1));
4083  __ Adc(x11, x1, Operand(x2, SXTH, 2));
4084  __ Sbc(x12, x1, Operand(w2, UXTW, 4));
4085  __ Adc(x13, x1, Operand(x2, UXTX, 4));
4086
4087  __ Adc(w14, w1, Operand(w2, UXTB, 1));
4088  __ Adc(w15, w1, Operand(w2, SXTH, 2));
4089  __ Adc(w9, w1, Operand(w2, UXTW, 4));
4090
4091  // Set the C flag.
4092  __ Cmp(w0, Operand(w0));
4093
4094  __ Adc(x20, x1, Operand(w2, UXTB, 1));
4095  __ Adc(x21, x1, Operand(x2, SXTH, 2));
4096  __ Sbc(x22, x1, Operand(w2, UXTW, 4));
4097  __ Adc(x23, x1, Operand(x2, UXTX, 4));
4098
4099  __ Adc(w24, w1, Operand(w2, UXTB, 1));
4100  __ Adc(w25, w1, Operand(w2, SXTH, 2));
4101  __ Adc(w26, w1, Operand(w2, UXTW, 4));
4102  END();
4103
4104  RUN();
4105
4106  CHECK_EQUAL_64(0x1df, x10);
4107  CHECK_EQUAL_64(0xffffffffffff37bdL, x11);
4108  CHECK_EQUAL_64(0xfffffff765432110L, x12);
4109  CHECK_EQUAL_64(0x123456789abcdef1L, x13);
4110
4111  CHECK_EQUAL_32(0x1df, w14);
4112  CHECK_EQUAL_32(0xffff37bd, w15);
4113  CHECK_EQUAL_32(0x9abcdef1, w9);
4114
4115  CHECK_EQUAL_64(0x1df + 1, x20);
4116  CHECK_EQUAL_64(0xffffffffffff37bdL + 1, x21);
4117  CHECK_EQUAL_64(0xfffffff765432110L + 1, x22);
4118  CHECK_EQUAL_64(0x123456789abcdef1L + 1, x23);
4119
4120  CHECK_EQUAL_32(0x1df + 1, w24);
4121  CHECK_EQUAL_32(0xffff37bd + 1, w25);
4122  CHECK_EQUAL_32(0x9abcdef1 + 1, w26);
4123
4124  // Check that adc correctly sets the condition flags.
4125  START();
4126  __ Mov(x0, 0xff);
4127  __ Mov(x1, 0xffffffffffffffffL);
4128  // Clear the C flag.
4129  __ Adds(x0, x0, Operand(0));
4130  __ Adcs(x10, x0, Operand(x1, SXTX, 1));
4131  END();
4132
4133  RUN();
4134
4135  CHECK_EQUAL_NZCV(CFlag);
4136
4137  START();
4138  __ Mov(x0, 0x7fffffffffffffffL);
4139  __ Mov(x1, 1);
4140  // Clear the C flag.
4141  __ Adds(x0, x0, Operand(0));
4142  __ Adcs(x10, x0, Operand(x1, UXTB, 2));
4143  END();
4144
4145  RUN();
4146
4147  CHECK_EQUAL_NZCV(NVFlag);
4148
4149  START();
4150  __ Mov(x0, 0x7fffffffffffffffL);
4151  // Clear the C flag.
4152  __ Adds(x0, x0, Operand(0));
4153  __ Adcs(x10, x0, Operand(1));
4154  END();
4155
4156  RUN();
4157
4158  CHECK_EQUAL_NZCV(NVFlag);
4159
4160  TEARDOWN();
4161}
4162
4163
4164TEST(adc_sbc_wide_imm) {
4165  INIT_V8();
4166  SETUP();
4167
4168  START();
4169  __ Mov(x0, 0);
4170
4171  // Clear the C flag.
4172  __ Adds(x0, x0, Operand(0));
4173
4174  __ Adc(x7, x0, Operand(0x1234567890abcdefUL));
4175  __ Adc(w8, w0, Operand(0xffffffff));
4176  __ Sbc(x9, x0, Operand(0x1234567890abcdefUL));
4177  __ Sbc(w10, w0, Operand(0xffffffff));
4178  __ Ngc(x11, Operand(0xffffffff00000000UL));
4179  __ Ngc(w12, Operand(0xffff0000));
4180
4181  // Set the C flag.
4182  __ Cmp(w0, Operand(w0));
4183
4184  __ Adc(x18, x0, Operand(0x1234567890abcdefUL));
4185  __ Adc(w19, w0, Operand(0xffffffff));
4186  __ Sbc(x20, x0, Operand(0x1234567890abcdefUL));
4187  __ Sbc(w21, w0, Operand(0xffffffff));
4188  __ Ngc(x22, Operand(0xffffffff00000000UL));
4189  __ Ngc(w23, Operand(0xffff0000));
4190  END();
4191
4192  RUN();
4193
4194  CHECK_EQUAL_64(0x1234567890abcdefUL, x7);
4195  CHECK_EQUAL_64(0xffffffff, x8);
4196  CHECK_EQUAL_64(0xedcba9876f543210UL, x9);
4197  CHECK_EQUAL_64(0, x10);
4198  CHECK_EQUAL_64(0xffffffff, x11);
4199  CHECK_EQUAL_64(0xffff, x12);
4200
4201  CHECK_EQUAL_64(0x1234567890abcdefUL + 1, x18);
4202  CHECK_EQUAL_64(0, x19);
4203  CHECK_EQUAL_64(0xedcba9876f543211UL, x20);
4204  CHECK_EQUAL_64(1, x21);
4205  CHECK_EQUAL_64(0x100000000UL, x22);
4206  CHECK_EQUAL_64(0x10000, x23);
4207
4208  TEARDOWN();
4209}
4210
4211
4212TEST(flags) {
4213  INIT_V8();
4214  SETUP();
4215
4216  START();
4217  __ Mov(x0, 0);
4218  __ Mov(x1, 0x1111111111111111L);
4219  __ Neg(x10, Operand(x0));
4220  __ Neg(x11, Operand(x1));
4221  __ Neg(w12, Operand(w1));
4222  // Clear the C flag.
4223  __ Adds(x0, x0, Operand(0));
4224  __ Ngc(x13, Operand(x0));
4225  // Set the C flag.
4226  __ Cmp(x0, Operand(x0));
4227  __ Ngc(w14, Operand(w0));
4228  END();
4229
4230  RUN();
4231
4232  CHECK_EQUAL_64(0, x10);
4233  CHECK_EQUAL_64(-0x1111111111111111L, x11);
4234  CHECK_EQUAL_32(-0x11111111, w12);
4235  CHECK_EQUAL_64(-1L, x13);
4236  CHECK_EQUAL_32(0, w14);
4237
4238  START();
4239  __ Mov(x0, 0);
4240  __ Cmp(x0, Operand(x0));
4241  END();
4242
4243  RUN();
4244
4245  CHECK_EQUAL_NZCV(ZCFlag);
4246
4247  START();
4248  __ Mov(w0, 0);
4249  __ Cmp(w0, Operand(w0));
4250  END();
4251
4252  RUN();
4253
4254  CHECK_EQUAL_NZCV(ZCFlag);
4255
4256  START();
4257  __ Mov(x0, 0);
4258  __ Mov(x1, 0x1111111111111111L);
4259  __ Cmp(x0, Operand(x1));
4260  END();
4261
4262  RUN();
4263
4264  CHECK_EQUAL_NZCV(NFlag);
4265
4266  START();
4267  __ Mov(w0, 0);
4268  __ Mov(w1, 0x11111111);
4269  __ Cmp(w0, Operand(w1));
4270  END();
4271
4272  RUN();
4273
4274  CHECK_EQUAL_NZCV(NFlag);
4275
4276  START();
4277  __ Mov(x1, 0x1111111111111111L);
4278  __ Cmp(x1, Operand(0));
4279  END();
4280
4281  RUN();
4282
4283  CHECK_EQUAL_NZCV(CFlag);
4284
4285  START();
4286  __ Mov(w1, 0x11111111);
4287  __ Cmp(w1, Operand(0));
4288  END();
4289
4290  RUN();
4291
4292  CHECK_EQUAL_NZCV(CFlag);
4293
4294  START();
4295  __ Mov(x0, 1);
4296  __ Mov(x1, 0x7fffffffffffffffL);
4297  __ Cmn(x1, Operand(x0));
4298  END();
4299
4300  RUN();
4301
4302  CHECK_EQUAL_NZCV(NVFlag);
4303
4304  START();
4305  __ Mov(w0, 1);
4306  __ Mov(w1, 0x7fffffff);
4307  __ Cmn(w1, Operand(w0));
4308  END();
4309
4310  RUN();
4311
4312  CHECK_EQUAL_NZCV(NVFlag);
4313
4314  START();
4315  __ Mov(x0, 1);
4316  __ Mov(x1, 0xffffffffffffffffL);
4317  __ Cmn(x1, Operand(x0));
4318  END();
4319
4320  RUN();
4321
4322  CHECK_EQUAL_NZCV(ZCFlag);
4323
4324  START();
4325  __ Mov(w0, 1);
4326  __ Mov(w1, 0xffffffff);
4327  __ Cmn(w1, Operand(w0));
4328  END();
4329
4330  RUN();
4331
4332  CHECK_EQUAL_NZCV(ZCFlag);
4333
4334  START();
4335  __ Mov(w0, 0);
4336  __ Mov(w1, 1);
4337  // Clear the C flag.
4338  __ Adds(w0, w0, Operand(0));
4339  __ Ngcs(w0, Operand(w1));
4340  END();
4341
4342  RUN();
4343
4344  CHECK_EQUAL_NZCV(NFlag);
4345
4346  START();
4347  __ Mov(w0, 0);
4348  __ Mov(w1, 0);
4349  // Set the C flag.
4350  __ Cmp(w0, Operand(w0));
4351  __ Ngcs(w0, Operand(w1));
4352  END();
4353
4354  RUN();
4355
4356  CHECK_EQUAL_NZCV(ZCFlag);
4357
4358  TEARDOWN();
4359}
4360
4361
4362TEST(cmp_shift) {
4363  INIT_V8();
4364  SETUP();
4365
4366  START();
4367  __ Mov(x18, 0xf0000000);
4368  __ Mov(x19, 0xf000000010000000UL);
4369  __ Mov(x20, 0xf0000000f0000000UL);
4370  __ Mov(x21, 0x7800000078000000UL);
4371  __ Mov(x22, 0x3c0000003c000000UL);
4372  __ Mov(x23, 0x8000000780000000UL);
4373  __ Mov(x24, 0x0000000f00000000UL);
4374  __ Mov(x25, 0x00000003c0000000UL);
4375  __ Mov(x26, 0x8000000780000000UL);
4376  __ Mov(x27, 0xc0000003);
4377
4378  __ Cmp(w20, Operand(w21, LSL, 1));
4379  __ Mrs(x0, NZCV);
4380
4381  __ Cmp(x20, Operand(x22, LSL, 2));
4382  __ Mrs(x1, NZCV);
4383
4384  __ Cmp(w19, Operand(w23, LSR, 3));
4385  __ Mrs(x2, NZCV);
4386
4387  __ Cmp(x18, Operand(x24, LSR, 4));
4388  __ Mrs(x3, NZCV);
4389
4390  __ Cmp(w20, Operand(w25, ASR, 2));
4391  __ Mrs(x4, NZCV);
4392
4393  __ Cmp(x20, Operand(x26, ASR, 3));
4394  __ Mrs(x5, NZCV);
4395
4396  __ Cmp(w27, Operand(w22, ROR, 28));
4397  __ Mrs(x6, NZCV);
4398
4399  __ Cmp(x20, Operand(x21, ROR, 31));
4400  __ Mrs(x7, NZCV);
4401  END();
4402
4403  RUN();
4404
4405  CHECK_EQUAL_32(ZCFlag, w0);
4406  CHECK_EQUAL_32(ZCFlag, w1);
4407  CHECK_EQUAL_32(ZCFlag, w2);
4408  CHECK_EQUAL_32(ZCFlag, w3);
4409  CHECK_EQUAL_32(ZCFlag, w4);
4410  CHECK_EQUAL_32(ZCFlag, w5);
4411  CHECK_EQUAL_32(ZCFlag, w6);
4412  CHECK_EQUAL_32(ZCFlag, w7);
4413
4414  TEARDOWN();
4415}
4416
4417
4418TEST(cmp_extend) {
4419  INIT_V8();
4420  SETUP();
4421
4422  START();
4423  __ Mov(w20, 0x2);
4424  __ Mov(w21, 0x1);
4425  __ Mov(x22, 0xffffffffffffffffUL);
4426  __ Mov(x23, 0xff);
4427  __ Mov(x24, 0xfffffffffffffffeUL);
4428  __ Mov(x25, 0xffff);
4429  __ Mov(x26, 0xffffffff);
4430
4431  __ Cmp(w20, Operand(w21, LSL, 1));
4432  __ Mrs(x0, NZCV);
4433
4434  __ Cmp(x22, Operand(x23, SXTB, 0));
4435  __ Mrs(x1, NZCV);
4436
4437  __ Cmp(x24, Operand(x23, SXTB, 1));
4438  __ Mrs(x2, NZCV);
4439
4440  __ Cmp(x24, Operand(x23, UXTB, 1));
4441  __ Mrs(x3, NZCV);
4442
4443  __ Cmp(w22, Operand(w25, UXTH));
4444  __ Mrs(x4, NZCV);
4445
4446  __ Cmp(x22, Operand(x25, SXTH));
4447  __ Mrs(x5, NZCV);
4448
4449  __ Cmp(x22, Operand(x26, UXTW));
4450  __ Mrs(x6, NZCV);
4451
4452  __ Cmp(x24, Operand(x26, SXTW, 1));
4453  __ Mrs(x7, NZCV);
4454  END();
4455
4456  RUN();
4457
4458  CHECK_EQUAL_32(ZCFlag, w0);
4459  CHECK_EQUAL_32(ZCFlag, w1);
4460  CHECK_EQUAL_32(ZCFlag, w2);
4461  CHECK_EQUAL_32(NCFlag, w3);
4462  CHECK_EQUAL_32(NCFlag, w4);
4463  CHECK_EQUAL_32(ZCFlag, w5);
4464  CHECK_EQUAL_32(NCFlag, w6);
4465  CHECK_EQUAL_32(ZCFlag, w7);
4466
4467  TEARDOWN();
4468}
4469
4470
4471TEST(ccmp) {
4472  INIT_V8();
4473  SETUP();
4474
4475  START();
4476  __ Mov(w16, 0);
4477  __ Mov(w17, 1);
4478  __ Cmp(w16, w16);
4479  __ Ccmp(w16, w17, NCFlag, eq);
4480  __ Mrs(x0, NZCV);
4481
4482  __ Cmp(w16, w16);
4483  __ Ccmp(w16, w17, NCFlag, ne);
4484  __ Mrs(x1, NZCV);
4485
4486  __ Cmp(x16, x16);
4487  __ Ccmn(x16, 2, NZCVFlag, eq);
4488  __ Mrs(x2, NZCV);
4489
4490  __ Cmp(x16, x16);
4491  __ Ccmn(x16, 2, NZCVFlag, ne);
4492  __ Mrs(x3, NZCV);
4493
4494  __ ccmp(x16, x16, NZCVFlag, al);
4495  __ Mrs(x4, NZCV);
4496
4497  __ ccmp(x16, x16, NZCVFlag, nv);
4498  __ Mrs(x5, NZCV);
4499
4500  END();
4501
4502  RUN();
4503
4504  CHECK_EQUAL_32(NFlag, w0);
4505  CHECK_EQUAL_32(NCFlag, w1);
4506  CHECK_EQUAL_32(NoFlag, w2);
4507  CHECK_EQUAL_32(NZCVFlag, w3);
4508  CHECK_EQUAL_32(ZCFlag, w4);
4509  CHECK_EQUAL_32(ZCFlag, w5);
4510
4511  TEARDOWN();
4512}
4513
4514
4515TEST(ccmp_wide_imm) {
4516  INIT_V8();
4517  SETUP();
4518
4519  START();
4520  __ Mov(w20, 0);
4521
4522  __ Cmp(w20, Operand(w20));
4523  __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
4524  __ Mrs(x0, NZCV);
4525
4526  __ Cmp(w20, Operand(w20));
4527  __ Ccmp(x20, Operand(0xffffffffffffffffUL), NZCVFlag, eq);
4528  __ Mrs(x1, NZCV);
4529  END();
4530
4531  RUN();
4532
4533  CHECK_EQUAL_32(NFlag, w0);
4534  CHECK_EQUAL_32(NoFlag, w1);
4535
4536  TEARDOWN();
4537}
4538
4539
4540TEST(ccmp_shift_extend) {
4541  INIT_V8();
4542  SETUP();
4543
4544  START();
4545  __ Mov(w20, 0x2);
4546  __ Mov(w21, 0x1);
4547  __ Mov(x22, 0xffffffffffffffffUL);
4548  __ Mov(x23, 0xff);
4549  __ Mov(x24, 0xfffffffffffffffeUL);
4550
4551  __ Cmp(w20, Operand(w20));
4552  __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
4553  __ Mrs(x0, NZCV);
4554
4555  __ Cmp(w20, Operand(w20));
4556  __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
4557  __ Mrs(x1, NZCV);
4558
4559  __ Cmp(w20, Operand(w20));
4560  __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
4561  __ Mrs(x2, NZCV);
4562
4563  __ Cmp(w20, Operand(w20));
4564  __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
4565  __ Mrs(x3, NZCV);
4566
4567  __ Cmp(w20, Operand(w20));
4568  __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
4569  __ Mrs(x4, NZCV);
4570  END();
4571
4572  RUN();
4573
4574  CHECK_EQUAL_32(ZCFlag, w0);
4575  CHECK_EQUAL_32(ZCFlag, w1);
4576  CHECK_EQUAL_32(ZCFlag, w2);
4577  CHECK_EQUAL_32(NCFlag, w3);
4578  CHECK_EQUAL_32(NZCVFlag, w4);
4579
4580  TEARDOWN();
4581}
4582
4583
4584TEST(csel) {
4585  INIT_V8();
4586  SETUP();
4587
4588  START();
4589  __ Mov(x16, 0);
4590  __ Mov(x24, 0x0000000f0000000fUL);
4591  __ Mov(x25, 0x0000001f0000001fUL);
4592  __ Mov(x26, 0);
4593  __ Mov(x27, 0);
4594
4595  __ Cmp(w16, 0);
4596  __ Csel(w0, w24, w25, eq);
4597  __ Csel(w1, w24, w25, ne);
4598  __ Csinc(w2, w24, w25, mi);
4599  __ Csinc(w3, w24, w25, pl);
4600
4601  __ csel(w13, w24, w25, al);
4602  __ csel(x14, x24, x25, nv);
4603
4604  __ Cmp(x16, 1);
4605  __ Csinv(x4, x24, x25, gt);
4606  __ Csinv(x5, x24, x25, le);
4607  __ Csneg(x6, x24, x25, hs);
4608  __ Csneg(x7, x24, x25, lo);
4609
4610  __ Cset(w8, ne);
4611  __ Csetm(w9, ne);
4612  __ Cinc(x10, x25, ne);
4613  __ Cinv(x11, x24, ne);
4614  __ Cneg(x12, x24, ne);
4615
4616  __ csel(w15, w24, w25, al);
4617  __ csel(x18, x24, x25, nv);
4618
4619  __ CzeroX(x24, ne);
4620  __ CzeroX(x25, eq);
4621
4622  __ CmovX(x26, x25, ne);
4623  __ CmovX(x27, x25, eq);
4624  END();
4625
4626  RUN();
4627
4628  CHECK_EQUAL_64(0x0000000f, x0);
4629  CHECK_EQUAL_64(0x0000001f, x1);
4630  CHECK_EQUAL_64(0x00000020, x2);
4631  CHECK_EQUAL_64(0x0000000f, x3);
4632  CHECK_EQUAL_64(0xffffffe0ffffffe0UL, x4);
4633  CHECK_EQUAL_64(0x0000000f0000000fUL, x5);
4634  CHECK_EQUAL_64(0xffffffe0ffffffe1UL, x6);
4635  CHECK_EQUAL_64(0x0000000f0000000fUL, x7);
4636  CHECK_EQUAL_64(0x00000001, x8);
4637  CHECK_EQUAL_64(0xffffffff, x9);
4638  CHECK_EQUAL_64(0x0000001f00000020UL, x10);
4639  CHECK_EQUAL_64(0xfffffff0fffffff0UL, x11);
4640  CHECK_EQUAL_64(0xfffffff0fffffff1UL, x12);
4641  CHECK_EQUAL_64(0x0000000f, x13);
4642  CHECK_EQUAL_64(0x0000000f0000000fUL, x14);
4643  CHECK_EQUAL_64(0x0000000f, x15);
4644  CHECK_EQUAL_64(0x0000000f0000000fUL, x18);
4645  CHECK_EQUAL_64(0, x24);
4646  CHECK_EQUAL_64(0x0000001f0000001fUL, x25);
4647  CHECK_EQUAL_64(0x0000001f0000001fUL, x26);
4648  CHECK_EQUAL_64(0, x27);
4649
4650  TEARDOWN();
4651}
4652
4653
4654TEST(csel_imm) {
4655  INIT_V8();
4656  SETUP();
4657
4658  START();
4659  __ Mov(x18, 0);
4660  __ Mov(x19, 0x80000000);
4661  __ Mov(x20, 0x8000000000000000UL);
4662
4663  __ Cmp(x18, Operand(0));
4664  __ Csel(w0, w19, -2, ne);
4665  __ Csel(w1, w19, -1, ne);
4666  __ Csel(w2, w19, 0, ne);
4667  __ Csel(w3, w19, 1, ne);
4668  __ Csel(w4, w19, 2, ne);
4669  __ Csel(w5, w19, Operand(w19, ASR, 31), ne);
4670  __ Csel(w6, w19, Operand(w19, ROR, 1), ne);
4671  __ Csel(w7, w19, 3, eq);
4672
4673  __ Csel(x8, x20, -2, ne);
4674  __ Csel(x9, x20, -1, ne);
4675  __ Csel(x10, x20, 0, ne);
4676  __ Csel(x11, x20, 1, ne);
4677  __ Csel(x12, x20, 2, ne);
4678  __ Csel(x13, x20, Operand(x20, ASR, 63), ne);
4679  __ Csel(x14, x20, Operand(x20, ROR, 1), ne);
4680  __ Csel(x15, x20, 3, eq);
4681
4682  END();
4683
4684  RUN();
4685
4686  CHECK_EQUAL_32(-2, w0);
4687  CHECK_EQUAL_32(-1, w1);
4688  CHECK_EQUAL_32(0, w2);
4689  CHECK_EQUAL_32(1, w3);
4690  CHECK_EQUAL_32(2, w4);
4691  CHECK_EQUAL_32(-1, w5);
4692  CHECK_EQUAL_32(0x40000000, w6);
4693  CHECK_EQUAL_32(0x80000000, w7);
4694
4695  CHECK_EQUAL_64(-2, x8);
4696  CHECK_EQUAL_64(-1, x9);
4697  CHECK_EQUAL_64(0, x10);
4698  CHECK_EQUAL_64(1, x11);
4699  CHECK_EQUAL_64(2, x12);
4700  CHECK_EQUAL_64(-1, x13);
4701  CHECK_EQUAL_64(0x4000000000000000UL, x14);
4702  CHECK_EQUAL_64(0x8000000000000000UL, x15);
4703
4704  TEARDOWN();
4705}
4706
4707
4708TEST(lslv) {
4709  INIT_V8();
4710  SETUP();
4711
4712  uint64_t value = 0x0123456789abcdefUL;
4713  int shift[] = {1, 3, 5, 9, 17, 33};
4714
4715  START();
4716  __ Mov(x0, value);
4717  __ Mov(w1, shift[0]);
4718  __ Mov(w2, shift[1]);
4719  __ Mov(w3, shift[2]);
4720  __ Mov(w4, shift[3]);
4721  __ Mov(w5, shift[4]);
4722  __ Mov(w6, shift[5]);
4723
4724  __ lslv(x0, x0, xzr);
4725
4726  __ Lsl(x16, x0, x1);
4727  __ Lsl(x17, x0, x2);
4728  __ Lsl(x18, x0, x3);
4729  __ Lsl(x19, x0, x4);
4730  __ Lsl(x20, x0, x5);
4731  __ Lsl(x21, x0, x6);
4732
4733  __ Lsl(w22, w0, w1);
4734  __ Lsl(w23, w0, w2);
4735  __ Lsl(w24, w0, w3);
4736  __ Lsl(w25, w0, w4);
4737  __ Lsl(w26, w0, w5);
4738  __ Lsl(w27, w0, w6);
4739  END();
4740
4741  RUN();
4742
4743  CHECK_EQUAL_64(value, x0);
4744  CHECK_EQUAL_64(value << (shift[0] & 63), x16);
4745  CHECK_EQUAL_64(value << (shift[1] & 63), x17);
4746  CHECK_EQUAL_64(value << (shift[2] & 63), x18);
4747  CHECK_EQUAL_64(value << (shift[3] & 63), x19);
4748  CHECK_EQUAL_64(value << (shift[4] & 63), x20);
4749  CHECK_EQUAL_64(value << (shift[5] & 63), x21);
4750  CHECK_EQUAL_32(value << (shift[0] & 31), w22);
4751  CHECK_EQUAL_32(value << (shift[1] & 31), w23);
4752  CHECK_EQUAL_32(value << (shift[2] & 31), w24);
4753  CHECK_EQUAL_32(value << (shift[3] & 31), w25);
4754  CHECK_EQUAL_32(value << (shift[4] & 31), w26);
4755  CHECK_EQUAL_32(value << (shift[5] & 31), w27);
4756
4757  TEARDOWN();
4758}
4759
4760
4761TEST(lsrv) {
4762  INIT_V8();
4763  SETUP();
4764
4765  uint64_t value = 0x0123456789abcdefUL;
4766  int shift[] = {1, 3, 5, 9, 17, 33};
4767
4768  START();
4769  __ Mov(x0, value);
4770  __ Mov(w1, shift[0]);
4771  __ Mov(w2, shift[1]);
4772  __ Mov(w3, shift[2]);
4773  __ Mov(w4, shift[3]);
4774  __ Mov(w5, shift[4]);
4775  __ Mov(w6, shift[5]);
4776
4777  __ lsrv(x0, x0, xzr);
4778
4779  __ Lsr(x16, x0, x1);
4780  __ Lsr(x17, x0, x2);
4781  __ Lsr(x18, x0, x3);
4782  __ Lsr(x19, x0, x4);
4783  __ Lsr(x20, x0, x5);
4784  __ Lsr(x21, x0, x6);
4785
4786  __ Lsr(w22, w0, w1);
4787  __ Lsr(w23, w0, w2);
4788  __ Lsr(w24, w0, w3);
4789  __ Lsr(w25, w0, w4);
4790  __ Lsr(w26, w0, w5);
4791  __ Lsr(w27, w0, w6);
4792  END();
4793
4794  RUN();
4795
4796  CHECK_EQUAL_64(value, x0);
4797  CHECK_EQUAL_64(value >> (shift[0] & 63), x16);
4798  CHECK_EQUAL_64(value >> (shift[1] & 63), x17);
4799  CHECK_EQUAL_64(value >> (shift[2] & 63), x18);
4800  CHECK_EQUAL_64(value >> (shift[3] & 63), x19);
4801  CHECK_EQUAL_64(value >> (shift[4] & 63), x20);
4802  CHECK_EQUAL_64(value >> (shift[5] & 63), x21);
4803
4804  value &= 0xffffffffUL;
4805  CHECK_EQUAL_32(value >> (shift[0] & 31), w22);
4806  CHECK_EQUAL_32(value >> (shift[1] & 31), w23);
4807  CHECK_EQUAL_32(value >> (shift[2] & 31), w24);
4808  CHECK_EQUAL_32(value >> (shift[3] & 31), w25);
4809  CHECK_EQUAL_32(value >> (shift[4] & 31), w26);
4810  CHECK_EQUAL_32(value >> (shift[5] & 31), w27);
4811
4812  TEARDOWN();
4813}
4814
4815
4816TEST(asrv) {
4817  INIT_V8();
4818  SETUP();
4819
4820  int64_t value = 0xfedcba98fedcba98UL;
4821  int shift[] = {1, 3, 5, 9, 17, 33};
4822
4823  START();
4824  __ Mov(x0, value);
4825  __ Mov(w1, shift[0]);
4826  __ Mov(w2, shift[1]);
4827  __ Mov(w3, shift[2]);
4828  __ Mov(w4, shift[3]);
4829  __ Mov(w5, shift[4]);
4830  __ Mov(w6, shift[5]);
4831
4832  __ asrv(x0, x0, xzr);
4833
4834  __ Asr(x16, x0, x1);
4835  __ Asr(x17, x0, x2);
4836  __ Asr(x18, x0, x3);
4837  __ Asr(x19, x0, x4);
4838  __ Asr(x20, x0, x5);
4839  __ Asr(x21, x0, x6);
4840
4841  __ Asr(w22, w0, w1);
4842  __ Asr(w23, w0, w2);
4843  __ Asr(w24, w0, w3);
4844  __ Asr(w25, w0, w4);
4845  __ Asr(w26, w0, w5);
4846  __ Asr(w27, w0, w6);
4847  END();
4848
4849  RUN();
4850
4851  CHECK_EQUAL_64(value, x0);
4852  CHECK_EQUAL_64(value >> (shift[0] & 63), x16);
4853  CHECK_EQUAL_64(value >> (shift[1] & 63), x17);
4854  CHECK_EQUAL_64(value >> (shift[2] & 63), x18);
4855  CHECK_EQUAL_64(value >> (shift[3] & 63), x19);
4856  CHECK_EQUAL_64(value >> (shift[4] & 63), x20);
4857  CHECK_EQUAL_64(value >> (shift[5] & 63), x21);
4858
4859  int32_t value32 = static_cast<int32_t>(value & 0xffffffffUL);
4860  CHECK_EQUAL_32(value32 >> (shift[0] & 31), w22);
4861  CHECK_EQUAL_32(value32 >> (shift[1] & 31), w23);
4862  CHECK_EQUAL_32(value32 >> (shift[2] & 31), w24);
4863  CHECK_EQUAL_32(value32 >> (shift[3] & 31), w25);
4864  CHECK_EQUAL_32(value32 >> (shift[4] & 31), w26);
4865  CHECK_EQUAL_32(value32 >> (shift[5] & 31), w27);
4866
4867  TEARDOWN();
4868}
4869
4870
4871TEST(rorv) {
4872  INIT_V8();
4873  SETUP();
4874
4875  uint64_t value = 0x0123456789abcdefUL;
4876  int shift[] = {4, 8, 12, 16, 24, 36};
4877
4878  START();
4879  __ Mov(x0, value);
4880  __ Mov(w1, shift[0]);
4881  __ Mov(w2, shift[1]);
4882  __ Mov(w3, shift[2]);
4883  __ Mov(w4, shift[3]);
4884  __ Mov(w5, shift[4]);
4885  __ Mov(w6, shift[5]);
4886
4887  __ rorv(x0, x0, xzr);
4888
4889  __ Ror(x16, x0, x1);
4890  __ Ror(x17, x0, x2);
4891  __ Ror(x18, x0, x3);
4892  __ Ror(x19, x0, x4);
4893  __ Ror(x20, x0, x5);
4894  __ Ror(x21, x0, x6);
4895
4896  __ Ror(w22, w0, w1);
4897  __ Ror(w23, w0, w2);
4898  __ Ror(w24, w0, w3);
4899  __ Ror(w25, w0, w4);
4900  __ Ror(w26, w0, w5);
4901  __ Ror(w27, w0, w6);
4902  END();
4903
4904  RUN();
4905
4906  CHECK_EQUAL_64(value, x0);
4907  CHECK_EQUAL_64(0xf0123456789abcdeUL, x16);
4908  CHECK_EQUAL_64(0xef0123456789abcdUL, x17);
4909  CHECK_EQUAL_64(0xdef0123456789abcUL, x18);
4910  CHECK_EQUAL_64(0xcdef0123456789abUL, x19);
4911  CHECK_EQUAL_64(0xabcdef0123456789UL, x20);
4912  CHECK_EQUAL_64(0x789abcdef0123456UL, x21);
4913  CHECK_EQUAL_32(0xf89abcde, w22);
4914  CHECK_EQUAL_32(0xef89abcd, w23);
4915  CHECK_EQUAL_32(0xdef89abc, w24);
4916  CHECK_EQUAL_32(0xcdef89ab, w25);
4917  CHECK_EQUAL_32(0xabcdef89, w26);
4918  CHECK_EQUAL_32(0xf89abcde, w27);
4919
4920  TEARDOWN();
4921}
4922
4923
4924TEST(bfm) {
4925  INIT_V8();
4926  SETUP();
4927
4928  START();
4929  __ Mov(x1, 0x0123456789abcdefL);
4930
4931  __ Mov(x10, 0x8888888888888888L);
4932  __ Mov(x11, 0x8888888888888888L);
4933  __ Mov(x12, 0x8888888888888888L);
4934  __ Mov(x13, 0x8888888888888888L);
4935  __ Mov(w20, 0x88888888);
4936  __ Mov(w21, 0x88888888);
4937
4938  __ bfm(x10, x1, 16, 31);
4939  __ bfm(x11, x1, 32, 15);
4940
4941  __ bfm(w20, w1, 16, 23);
4942  __ bfm(w21, w1, 24, 15);
4943
4944  // Aliases.
4945  __ Bfi(x12, x1, 16, 8);
4946  __ Bfxil(x13, x1, 16, 8);
4947  END();
4948
4949  RUN();
4950
4951
4952  CHECK_EQUAL_64(0x88888888888889abL, x10);
4953  CHECK_EQUAL_64(0x8888cdef88888888L, x11);
4954
4955  CHECK_EQUAL_32(0x888888ab, w20);
4956  CHECK_EQUAL_32(0x88cdef88, w21);
4957
4958  CHECK_EQUAL_64(0x8888888888ef8888L, x12);
4959  CHECK_EQUAL_64(0x88888888888888abL, x13);
4960
4961  TEARDOWN();
4962}
4963
4964
4965TEST(sbfm) {
4966  INIT_V8();
4967  SETUP();
4968
4969  START();
4970  __ Mov(x1, 0x0123456789abcdefL);
4971  __ Mov(x2, 0xfedcba9876543210L);
4972
4973  __ sbfm(x10, x1, 16, 31);
4974  __ sbfm(x11, x1, 32, 15);
4975  __ sbfm(x12, x1, 32, 47);
4976  __ sbfm(x13, x1, 48, 35);
4977
4978  __ sbfm(w14, w1, 16, 23);
4979  __ sbfm(w15, w1, 24, 15);
4980  __ sbfm(w16, w2, 16, 23);
4981  __ sbfm(w17, w2, 24, 15);
4982
4983  // Aliases.
4984  __ Asr(x18, x1, 32);
4985  __ Asr(x19, x2, 32);
4986  __ Sbfiz(x20, x1, 8, 16);
4987  __ Sbfiz(x21, x2, 8, 16);
4988  __ Sbfx(x22, x1, 8, 16);
4989  __ Sbfx(x23, x2, 8, 16);
4990  __ Sxtb(x24, w1);
4991  __ Sxtb(x25, x2);
4992  __ Sxth(x26, w1);
4993  __ Sxth(x27, x2);
4994  __ Sxtw(x28, w1);
4995  __ Sxtw(x29, x2);
4996  END();
4997
4998  RUN();
4999
5000
5001  CHECK_EQUAL_64(0xffffffffffff89abL, x10);
5002  CHECK_EQUAL_64(0xffffcdef00000000L, x11);
5003  CHECK_EQUAL_64(0x4567L, x12);
5004  CHECK_EQUAL_64(0x789abcdef0000L, x13);
5005
5006  CHECK_EQUAL_32(0xffffffab, w14);
5007  CHECK_EQUAL_32(0xffcdef00, w15);
5008  CHECK_EQUAL_32(0x54, w16);
5009  CHECK_EQUAL_32(0x00321000, w17);
5010
5011  CHECK_EQUAL_64(0x01234567L, x18);
5012  CHECK_EQUAL_64(0xfffffffffedcba98L, x19);
5013  CHECK_EQUAL_64(0xffffffffffcdef00L, x20);
5014  CHECK_EQUAL_64(0x321000L, x21);
5015  CHECK_EQUAL_64(0xffffffffffffabcdL, x22);
5016  CHECK_EQUAL_64(0x5432L, x23);
5017  CHECK_EQUAL_64(0xffffffffffffffefL, x24);
5018  CHECK_EQUAL_64(0x10, x25);
5019  CHECK_EQUAL_64(0xffffffffffffcdefL, x26);
5020  CHECK_EQUAL_64(0x3210, x27);
5021  CHECK_EQUAL_64(0xffffffff89abcdefL, x28);
5022  CHECK_EQUAL_64(0x76543210, x29);
5023
5024  TEARDOWN();
5025}
5026
5027
5028TEST(ubfm) {
5029  INIT_V8();
5030  SETUP();
5031
5032  START();
5033  __ Mov(x1, 0x0123456789abcdefL);
5034  __ Mov(x2, 0xfedcba9876543210L);
5035
5036  __ Mov(x10, 0x8888888888888888L);
5037  __ Mov(x11, 0x8888888888888888L);
5038
5039  __ ubfm(x10, x1, 16, 31);
5040  __ ubfm(x11, x1, 32, 15);
5041  __ ubfm(x12, x1, 32, 47);
5042  __ ubfm(x13, x1, 48, 35);
5043
5044  __ ubfm(w25, w1, 16, 23);
5045  __ ubfm(w26, w1, 24, 15);
5046  __ ubfm(w27, w2, 16, 23);
5047  __ ubfm(w28, w2, 24, 15);
5048
5049  // Aliases
5050  __ Lsl(x15, x1, 63);
5051  __ Lsl(x16, x1, 0);
5052  __ Lsr(x17, x1, 32);
5053  __ Ubfiz(x18, x1, 8, 16);
5054  __ Ubfx(x19, x1, 8, 16);
5055  __ Uxtb(x20, x1);
5056  __ Uxth(x21, x1);
5057  __ Uxtw(x22, x1);
5058  END();
5059
5060  RUN();
5061
5062  CHECK_EQUAL_64(0x00000000000089abL, x10);
5063  CHECK_EQUAL_64(0x0000cdef00000000L, x11);
5064  CHECK_EQUAL_64(0x4567L, x12);
5065  CHECK_EQUAL_64(0x789abcdef0000L, x13);
5066
5067  CHECK_EQUAL_32(0x000000ab, w25);
5068  CHECK_EQUAL_32(0x00cdef00, w26);
5069  CHECK_EQUAL_32(0x54, w27);
5070  CHECK_EQUAL_32(0x00321000, w28);
5071
5072  CHECK_EQUAL_64(0x8000000000000000L, x15);
5073  CHECK_EQUAL_64(0x0123456789abcdefL, x16);
5074  CHECK_EQUAL_64(0x01234567L, x17);
5075  CHECK_EQUAL_64(0xcdef00L, x18);
5076  CHECK_EQUAL_64(0xabcdL, x19);
5077  CHECK_EQUAL_64(0xefL, x20);
5078  CHECK_EQUAL_64(0xcdefL, x21);
5079  CHECK_EQUAL_64(0x89abcdefL, x22);
5080
5081  TEARDOWN();
5082}
5083
5084
5085TEST(extr) {
5086  INIT_V8();
5087  SETUP();
5088
5089  START();
5090  __ Mov(x1, 0x0123456789abcdefL);
5091  __ Mov(x2, 0xfedcba9876543210L);
5092
5093  __ Extr(w10, w1, w2, 0);
5094  __ Extr(x11, x1, x2, 0);
5095  __ Extr(w12, w1, w2, 1);
5096  __ Extr(x13, x2, x1, 2);
5097
5098  __ Ror(w20, w1, 0);
5099  __ Ror(x21, x1, 0);
5100  __ Ror(w22, w2, 17);
5101  __ Ror(w23, w1, 31);
5102  __ Ror(x24, x2, 1);
5103  __ Ror(x25, x1, 63);
5104  END();
5105
5106  RUN();
5107
5108  CHECK_EQUAL_64(0x76543210, x10);
5109  CHECK_EQUAL_64(0xfedcba9876543210L, x11);
5110  CHECK_EQUAL_64(0xbb2a1908, x12);
5111  CHECK_EQUAL_64(0x0048d159e26af37bUL, x13);
5112  CHECK_EQUAL_64(0x89abcdef, x20);
5113  CHECK_EQUAL_64(0x0123456789abcdefL, x21);
5114  CHECK_EQUAL_64(0x19083b2a, x22);
5115  CHECK_EQUAL_64(0x13579bdf, x23);
5116  CHECK_EQUAL_64(0x7f6e5d4c3b2a1908UL, x24);
5117  CHECK_EQUAL_64(0x02468acf13579bdeUL, x25);
5118
5119  TEARDOWN();
5120}
5121
5122
5123TEST(fmov_imm) {
5124  INIT_V8();
5125  SETUP();
5126
5127  START();
5128  __ Fmov(s11, 1.0);
5129  __ Fmov(d22, -13.0);
5130  __ Fmov(s1, 255.0);
5131  __ Fmov(d2, 12.34567);
5132  __ Fmov(s3, 0.0);
5133  __ Fmov(d4, 0.0);
5134  __ Fmov(s5, kFP32PositiveInfinity);
5135  __ Fmov(d6, kFP64NegativeInfinity);
5136  END();
5137
5138  RUN();
5139
5140  CHECK_EQUAL_FP32(1.0, s11);
5141  CHECK_EQUAL_FP64(-13.0, d22);
5142  CHECK_EQUAL_FP32(255.0, s1);
5143  CHECK_EQUAL_FP64(12.34567, d2);
5144  CHECK_EQUAL_FP32(0.0, s3);
5145  CHECK_EQUAL_FP64(0.0, d4);
5146  CHECK_EQUAL_FP32(kFP32PositiveInfinity, s5);
5147  CHECK_EQUAL_FP64(kFP64NegativeInfinity, d6);
5148
5149  TEARDOWN();
5150}
5151
5152
5153TEST(fmov_reg) {
5154  INIT_V8();
5155  SETUP();
5156
5157  START();
5158  __ Fmov(s20, 1.0);
5159  __ Fmov(w10, s20);
5160  __ Fmov(s30, w10);
5161  __ Fmov(s5, s20);
5162  __ Fmov(d1, -13.0);
5163  __ Fmov(x1, d1);
5164  __ Fmov(d2, x1);
5165  __ Fmov(d4, d1);
5166  __ Fmov(d6, rawbits_to_double(0x0123456789abcdefL));
5167  __ Fmov(s6, s6);
5168  END();
5169
5170  RUN();
5171
5172  CHECK_EQUAL_32(float_to_rawbits(1.0), w10);
5173  CHECK_EQUAL_FP32(1.0, s30);
5174  CHECK_EQUAL_FP32(1.0, s5);
5175  CHECK_EQUAL_64(double_to_rawbits(-13.0), x1);
5176  CHECK_EQUAL_FP64(-13.0, d2);
5177  CHECK_EQUAL_FP64(-13.0, d4);
5178  CHECK_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
5179
5180  TEARDOWN();
5181}
5182
5183
5184TEST(fadd) {
5185  INIT_V8();
5186  SETUP();
5187
5188  START();
5189  __ Fmov(s14, -0.0f);
5190  __ Fmov(s15, kFP32PositiveInfinity);
5191  __ Fmov(s16, kFP32NegativeInfinity);
5192  __ Fmov(s17, 3.25f);
5193  __ Fmov(s18, 1.0f);
5194  __ Fmov(s19, 0.0f);
5195
5196  __ Fmov(d26, -0.0);
5197  __ Fmov(d27, kFP64PositiveInfinity);
5198  __ Fmov(d28, kFP64NegativeInfinity);
5199  __ Fmov(d29, 0.0);
5200  __ Fmov(d30, -2.0);
5201  __ Fmov(d31, 2.25);
5202
5203  __ Fadd(s0, s17, s18);
5204  __ Fadd(s1, s18, s19);
5205  __ Fadd(s2, s14, s18);
5206  __ Fadd(s3, s15, s18);
5207  __ Fadd(s4, s16, s18);
5208  __ Fadd(s5, s15, s16);
5209  __ Fadd(s6, s16, s15);
5210
5211  __ Fadd(d7, d30, d31);
5212  __ Fadd(d8, d29, d31);
5213  __ Fadd(d9, d26, d31);
5214  __ Fadd(d10, d27, d31);
5215  __ Fadd(d11, d28, d31);
5216  __ Fadd(d12, d27, d28);
5217  __ Fadd(d13, d28, d27);
5218  END();
5219
5220  RUN();
5221
5222  CHECK_EQUAL_FP32(4.25, s0);
5223  CHECK_EQUAL_FP32(1.0, s1);
5224  CHECK_EQUAL_FP32(1.0, s2);
5225  CHECK_EQUAL_FP32(kFP32PositiveInfinity, s3);
5226  CHECK_EQUAL_FP32(kFP32NegativeInfinity, s4);
5227  CHECK_EQUAL_FP32(kFP32DefaultNaN, s5);
5228  CHECK_EQUAL_FP32(kFP32DefaultNaN, s6);
5229  CHECK_EQUAL_FP64(0.25, d7);
5230  CHECK_EQUAL_FP64(2.25, d8);
5231  CHECK_EQUAL_FP64(2.25, d9);
5232  CHECK_EQUAL_FP64(kFP64PositiveInfinity, d10);
5233  CHECK_EQUAL_FP64(kFP64NegativeInfinity, d11);
5234  CHECK_EQUAL_FP64(kFP64DefaultNaN, d12);
5235  CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
5236
5237  TEARDOWN();
5238}
5239
5240
5241TEST(fsub) {
5242  INIT_V8();
5243  SETUP();
5244
5245  START();
5246  __ Fmov(s14, -0.0f);
5247  __ Fmov(s15, kFP32PositiveInfinity);
5248  __ Fmov(s16, kFP32NegativeInfinity);
5249  __ Fmov(s17, 3.25f);
5250  __ Fmov(s18, 1.0f);
5251  __ Fmov(s19, 0.0f);
5252
5253  __ Fmov(d26, -0.0);
5254  __ Fmov(d27, kFP64PositiveInfinity);
5255  __ Fmov(d28, kFP64NegativeInfinity);
5256  __ Fmov(d29, 0.0);
5257  __ Fmov(d30, -2.0);
5258  __ Fmov(d31, 2.25);
5259
5260  __ Fsub(s0, s17, s18);
5261  __ Fsub(s1, s18, s19);
5262  __ Fsub(s2, s14, s18);
5263  __ Fsub(s3, s18, s15);
5264  __ Fsub(s4, s18, s16);
5265  __ Fsub(s5, s15, s15);
5266  __ Fsub(s6, s16, s16);
5267
5268  __ Fsub(d7, d30, d31);
5269  __ Fsub(d8, d29, d31);
5270  __ Fsub(d9, d26, d31);
5271  __ Fsub(d10, d31, d27);
5272  __ Fsub(d11, d31, d28);
5273  __ Fsub(d12, d27, d27);
5274  __ Fsub(d13, d28, d28);
5275  END();
5276
5277  RUN();
5278
5279  CHECK_EQUAL_FP32(2.25, s0);
5280  CHECK_EQUAL_FP32(1.0, s1);
5281  CHECK_EQUAL_FP32(-1.0, s2);
5282  CHECK_EQUAL_FP32(kFP32NegativeInfinity, s3);
5283  CHECK_EQUAL_FP32(kFP32PositiveInfinity, s4);
5284  CHECK_EQUAL_FP32(kFP32DefaultNaN, s5);
5285  CHECK_EQUAL_FP32(kFP32DefaultNaN, s6);
5286  CHECK_EQUAL_FP64(-4.25, d7);
5287  CHECK_EQUAL_FP64(-2.25, d8);
5288  CHECK_EQUAL_FP64(-2.25, d9);
5289  CHECK_EQUAL_FP64(kFP64NegativeInfinity, d10);
5290  CHECK_EQUAL_FP64(kFP64PositiveInfinity, d11);
5291  CHECK_EQUAL_FP64(kFP64DefaultNaN, d12);
5292  CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
5293
5294  TEARDOWN();
5295}
5296
5297
5298TEST(fmul) {
5299  INIT_V8();
5300  SETUP();
5301
5302  START();
5303  __ Fmov(s14, -0.0f);
5304  __ Fmov(s15, kFP32PositiveInfinity);
5305  __ Fmov(s16, kFP32NegativeInfinity);
5306  __ Fmov(s17, 3.25f);
5307  __ Fmov(s18, 2.0f);
5308  __ Fmov(s19, 0.0f);
5309  __ Fmov(s20, -2.0f);
5310
5311  __ Fmov(d26, -0.0);
5312  __ Fmov(d27, kFP64PositiveInfinity);
5313  __ Fmov(d28, kFP64NegativeInfinity);
5314  __ Fmov(d29, 0.0);
5315  __ Fmov(d30, -2.0);
5316  __ Fmov(d31, 2.25);
5317
5318  __ Fmul(s0, s17, s18);
5319  __ Fmul(s1, s18, s19);
5320  __ Fmul(s2, s14, s14);
5321  __ Fmul(s3, s15, s20);
5322  __ Fmul(s4, s16, s20);
5323  __ Fmul(s5, s15, s19);
5324  __ Fmul(s6, s19, s16);
5325
5326  __ Fmul(d7, d30, d31);
5327  __ Fmul(d8, d29, d31);
5328  __ Fmul(d9, d26, d26);
5329  __ Fmul(d10, d27, d30);
5330  __ Fmul(d11, d28, d30);
5331  __ Fmul(d12, d27, d29);
5332  __ Fmul(d13, d29, d28);
5333  END();
5334
5335  RUN();
5336
5337  CHECK_EQUAL_FP32(6.5, s0);
5338  CHECK_EQUAL_FP32(0.0, s1);
5339  CHECK_EQUAL_FP32(0.0, s2);
5340  CHECK_EQUAL_FP32(kFP32NegativeInfinity, s3);
5341  CHECK_EQUAL_FP32(kFP32PositiveInfinity, s4);
5342  CHECK_EQUAL_FP32(kFP32DefaultNaN, s5);
5343  CHECK_EQUAL_FP32(kFP32DefaultNaN, s6);
5344  CHECK_EQUAL_FP64(-4.5, d7);
5345  CHECK_EQUAL_FP64(0.0, d8);
5346  CHECK_EQUAL_FP64(0.0, d9);
5347  CHECK_EQUAL_FP64(kFP64NegativeInfinity, d10);
5348  CHECK_EQUAL_FP64(kFP64PositiveInfinity, d11);
5349  CHECK_EQUAL_FP64(kFP64DefaultNaN, d12);
5350  CHECK_EQUAL_FP64(kFP64DefaultNaN, d13);
5351
5352  TEARDOWN();
5353}
5354
5355
5356static void FmaddFmsubHelper(double n, double m, double a,
5357                             double fmadd, double fmsub,
5358                             double fnmadd, double fnmsub) {
5359  SETUP();
5360  START();
5361
5362  __ Fmov(d0, n);
5363  __ Fmov(d1, m);
5364  __ Fmov(d2, a);
5365  __ Fmadd(d28, d0, d1, d2);
5366  __ Fmsub(d29, d0, d1, d2);
5367  __ Fnmadd(d30, d0, d1, d2);
5368  __ Fnmsub(d31, d0, d1, d2);
5369
5370  END();
5371  RUN();
5372
5373  CHECK_EQUAL_FP64(fmadd, d28);
5374  CHECK_EQUAL_FP64(fmsub, d29);
5375  CHECK_EQUAL_FP64(fnmadd, d30);
5376  CHECK_EQUAL_FP64(fnmsub, d31);
5377
5378  TEARDOWN();
5379}
5380
5381
5382TEST(fmadd_fmsub_double) {
5383  INIT_V8();
5384
5385  // It's hard to check the result of fused operations because the only way to
5386  // calculate the result is using fma, which is what the simulator uses anyway.
5387  // TODO(jbramley): Add tests to check behaviour against a hardware trace.
5388
5389  // Basic operation.
5390  FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0);
5391  FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0);
5392
5393  // Check the sign of exact zeroes.
5394  //               n     m     a     fmadd  fmsub  fnmadd fnmsub
5395  FmaddFmsubHelper(-0.0, +0.0, -0.0, -0.0,  +0.0,  +0.0,  +0.0);
5396  FmaddFmsubHelper(+0.0, +0.0, -0.0, +0.0,  -0.0,  +0.0,  +0.0);
5397  FmaddFmsubHelper(+0.0, +0.0, +0.0, +0.0,  +0.0,  -0.0,  +0.0);
5398  FmaddFmsubHelper(-0.0, +0.0, +0.0, +0.0,  +0.0,  +0.0,  -0.0);
5399  FmaddFmsubHelper(+0.0, -0.0, -0.0, -0.0,  +0.0,  +0.0,  +0.0);
5400  FmaddFmsubHelper(-0.0, -0.0, -0.0, +0.0,  -0.0,  +0.0,  +0.0);
5401  FmaddFmsubHelper(-0.0, -0.0, +0.0, +0.0,  +0.0,  -0.0,  +0.0);
5402  FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0,  +0.0,  +0.0,  -0.0);
5403
5404  // Check NaN generation.
5405  FmaddFmsubHelper(kFP64PositiveInfinity, 0.0, 42.0,
5406                   kFP64DefaultNaN, kFP64DefaultNaN,
5407                   kFP64DefaultNaN, kFP64DefaultNaN);
5408  FmaddFmsubHelper(0.0, kFP64PositiveInfinity, 42.0,
5409                   kFP64DefaultNaN, kFP64DefaultNaN,
5410                   kFP64DefaultNaN, kFP64DefaultNaN);
5411  FmaddFmsubHelper(kFP64PositiveInfinity, 1.0, kFP64PositiveInfinity,
5412                   kFP64PositiveInfinity,   //  inf + ( inf * 1) = inf
5413                   kFP64DefaultNaN,         //  inf + (-inf * 1) = NaN
5414                   kFP64NegativeInfinity,   // -inf + (-inf * 1) = -inf
5415                   kFP64DefaultNaN);        // -inf + ( inf * 1) = NaN
5416  FmaddFmsubHelper(kFP64NegativeInfinity, 1.0, kFP64PositiveInfinity,
5417                   kFP64DefaultNaN,         //  inf + (-inf * 1) = NaN
5418                   kFP64PositiveInfinity,   //  inf + ( inf * 1) = inf
5419                   kFP64DefaultNaN,         // -inf + ( inf * 1) = NaN
5420                   kFP64NegativeInfinity);  // -inf + (-inf * 1) = -inf
5421}
5422
5423
5424static void FmaddFmsubHelper(float n, float m, float a,
5425                             float fmadd, float fmsub,
5426                             float fnmadd, float fnmsub) {
5427  SETUP();
5428  START();
5429
5430  __ Fmov(s0, n);
5431  __ Fmov(s1, m);
5432  __ Fmov(s2, a);
5433  __ Fmadd(s28, s0, s1, s2);
5434  __ Fmsub(s29, s0, s1, s2);
5435  __ Fnmadd(s30, s0, s1, s2);
5436  __ Fnmsub(s31, s0, s1, s2);
5437
5438  END();
5439  RUN();
5440
5441  CHECK_EQUAL_FP32(fmadd, s28);
5442  CHECK_EQUAL_FP32(fmsub, s29);
5443  CHECK_EQUAL_FP32(fnmadd, s30);
5444  CHECK_EQUAL_FP32(fnmsub, s31);
5445
5446  TEARDOWN();
5447}
5448
5449
5450TEST(fmadd_fmsub_float) {
5451  INIT_V8();
5452  // It's hard to check the result of fused operations because the only way to
5453  // calculate the result is using fma, which is what the simulator uses anyway.
5454  // TODO(jbramley): Add tests to check behaviour against a hardware trace.
5455
5456  // Basic operation.
5457  FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f);
5458  FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f);
5459
5460  // Check the sign of exact zeroes.
5461  //               n      m      a      fmadd  fmsub  fnmadd fnmsub
5462  FmaddFmsubHelper(-0.0f, +0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
5463  FmaddFmsubHelper(+0.0f, +0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
5464  FmaddFmsubHelper(+0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
5465  FmaddFmsubHelper(-0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
5466  FmaddFmsubHelper(+0.0f, -0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
5467  FmaddFmsubHelper(-0.0f, -0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
5468  FmaddFmsubHelper(-0.0f, -0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
5469  FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
5470
5471  // Check NaN generation.
5472  FmaddFmsubHelper(kFP32PositiveInfinity, 0.0f, 42.0f,
5473                   kFP32DefaultNaN, kFP32DefaultNaN,
5474                   kFP32DefaultNaN, kFP32DefaultNaN);
5475  FmaddFmsubHelper(0.0f, kFP32PositiveInfinity, 42.0f,
5476                   kFP32DefaultNaN, kFP32DefaultNaN,
5477                   kFP32DefaultNaN, kFP32DefaultNaN);
5478  FmaddFmsubHelper(kFP32PositiveInfinity, 1.0f, kFP32PositiveInfinity,
5479                   kFP32PositiveInfinity,   //  inf + ( inf * 1) = inf
5480                   kFP32DefaultNaN,         //  inf + (-inf * 1) = NaN
5481                   kFP32NegativeInfinity,   // -inf + (-inf * 1) = -inf
5482                   kFP32DefaultNaN);        // -inf + ( inf * 1) = NaN
5483  FmaddFmsubHelper(kFP32NegativeInfinity, 1.0f, kFP32PositiveInfinity,
5484                   kFP32DefaultNaN,         //  inf + (-inf * 1) = NaN
5485                   kFP32PositiveInfinity,   //  inf + ( inf * 1) = inf
5486                   kFP32DefaultNaN,         // -inf + ( inf * 1) = NaN
5487                   kFP32NegativeInfinity);  // -inf + (-inf * 1) = -inf
5488}
5489
5490
5491TEST(fmadd_fmsub_double_nans) {
5492  INIT_V8();
5493  // Make sure that NaN propagation works correctly.
5494  double s1 = rawbits_to_double(0x7ff5555511111111);
5495  double s2 = rawbits_to_double(0x7ff5555522222222);
5496  double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
5497  double q1 = rawbits_to_double(0x7ffaaaaa11111111);
5498  double q2 = rawbits_to_double(0x7ffaaaaa22222222);
5499  double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
5500  DCHECK(IsSignallingNaN(s1));
5501  DCHECK(IsSignallingNaN(s2));
5502  DCHECK(IsSignallingNaN(