1// Copyright 2015, VIXL authors
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7//   * Redistributions of source code must retain the above copyright notice,
8//     this list of conditions and the following disclaimer.
9//   * Redistributions in binary form must reproduce the above copyright notice,
10//     this list of conditions and the following disclaimer in the documentation
11//     and/or other materials provided with the distribution.
12//   * Neither the name of ARM Limited nor the names of its contributors may be
13//     used to endorse or promote products derived from this software without
14//     specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#include "../test-runner.h"
28#include "../test-utils-aarch64.h"
29#include "custom-disassembler.h"
30#include "examples.h"
31#include "non-const-visitor.h"
32
33#include "aarch64/macro-assembler-aarch64.h"
34#include "aarch64/debugger-aarch64.h"
35#include "aarch64/simulator-aarch64.h"
36#define TEST(name) TEST_(EXAMPLE_##name)
37
38using namespace vixl;
39using namespace vixl::aarch64;
40
41
42TEST(custom_disassembler) { TestCustomDisassembler(); }
43
44
45// The tests below only work with the simulator.
46#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
47
48#define __ masm->
49
50uint64_t FactorialC(uint64_t n) {
51  uint64_t result = 1;
52
53  while (n != 0) {
54    result *= n;
55    n--;
56  }
57
58  return result;
59}
60
61// Multiply two column-major 4x4 matrices of 32 bit floating point values.
62// Return a column-major 4x4 matrix of 32 bit floating point values in 'C'.
63void MatrixMultiplyC(float C[16], float A[16], float B[16]) {
64  C[0] = A[0] * B[0] + A[4] * B[1] + A[8] * B[2] + A[12] * B[3];
65  C[1] = A[1] * B[0] + A[5] * B[1] + A[9] * B[2] + A[13] * B[3];
66  C[2] = A[2] * B[0] + A[6] * B[1] + A[10] * B[2] + A[14] * B[3];
67  C[3] = A[3] * B[0] + A[7] * B[1] + A[11] * B[2] + A[15] * B[3];
68
69  C[4] = A[0] * B[4] + A[4] * B[5] + A[8] * B[6] + A[12] * B[7];
70  C[5] = A[1] * B[4] + A[5] * B[5] + A[9] * B[6] + A[13] * B[7];
71  C[6] = A[2] * B[4] + A[6] * B[5] + A[10] * B[6] + A[14] * B[7];
72  C[7] = A[3] * B[4] + A[7] * B[5] + A[11] * B[6] + A[15] * B[7];
73
74  C[8] = A[0] * B[8] + A[4] * B[9] + A[8] * B[10] + A[12] * B[11];
75  C[9] = A[1] * B[8] + A[5] * B[9] + A[9] * B[10] + A[13] * B[11];
76  C[10] = A[2] * B[8] + A[6] * B[9] + A[10] * B[10] + A[14] * B[11];
77  C[11] = A[3] * B[8] + A[7] * B[9] + A[11] * B[10] + A[15] * B[11];
78
79  C[12] = A[0] * B[12] + A[4] * B[13] + A[8] * B[14] + A[12] * B[15];
80  C[13] = A[1] * B[12] + A[5] * B[13] + A[9] * B[14] + A[13] * B[15];
81  C[14] = A[2] * B[12] + A[6] * B[13] + A[10] * B[14] + A[14] * B[15];
82  C[15] = A[3] * B[12] + A[7] * B[13] + A[11] * B[14] + A[15] * B[15];
83}
84
85double Add3DoubleC(double x, double y, double z) { return x + y + z; }
86
87double Add4DoubleC(uint64_t a, double b, uint64_t c, double d) {
88  return static_cast<double>(a) + b + static_cast<double>(c) + d;
89}
90
91uint32_t SumArrayC(uint8_t* array, uint32_t size) {
92  uint32_t result = 0;
93
94  for (uint32_t i = 0; i < size; ++i) {
95    result += array[i];
96  }
97
98  return result;
99}
100
101
102void GenerateTestWrapper(MacroAssembler* masm, RegisterDump* regs) {
103  __ Push(xzr, lr);
104  __ Blr(x15);
105  regs->Dump(masm);
106  __ Pop(lr, xzr);
107  __ Ret();
108}
109
110
111#define TEST_FUNCTION(Func)                                              \
112  do {                                                                   \
113    int64_t saved_xregs[13];                                             \
114    saved_xregs[0] = simulator.ReadXRegister(19);                        \
115    saved_xregs[1] = simulator.ReadXRegister(20);                        \
116    saved_xregs[2] = simulator.ReadXRegister(21);                        \
117    saved_xregs[3] = simulator.ReadXRegister(22);                        \
118    saved_xregs[4] = simulator.ReadXRegister(23);                        \
119    saved_xregs[5] = simulator.ReadXRegister(24);                        \
120    saved_xregs[6] = simulator.ReadXRegister(25);                        \
121    saved_xregs[7] = simulator.ReadXRegister(26);                        \
122    saved_xregs[8] = simulator.ReadXRegister(27);                        \
123    saved_xregs[9] = simulator.ReadXRegister(28);                        \
124    saved_xregs[10] = simulator.ReadXRegister(29);                       \
125    saved_xregs[11] = simulator.ReadXRegister(30);                       \
126    saved_xregs[12] = simulator.ReadXRegister(31);                       \
127                                                                         \
128    uint64_t saved_dregs[8];                                             \
129    saved_dregs[0] = simulator.ReadDRegisterBits(8);                     \
130    saved_dregs[1] = simulator.ReadDRegisterBits(9);                     \
131    saved_dregs[2] = simulator.ReadDRegisterBits(10);                    \
132    saved_dregs[3] = simulator.ReadDRegisterBits(11);                    \
133    saved_dregs[4] = simulator.ReadDRegisterBits(12);                    \
134    saved_dregs[5] = simulator.ReadDRegisterBits(13);                    \
135    saved_dregs[6] = simulator.ReadDRegisterBits(14);                    \
136    saved_dregs[7] = simulator.ReadDRegisterBits(15);                    \
137                                                                         \
138    simulator.WriteXRegister(15, masm.GetLabelAddress<uint64_t>(&Func)); \
139    simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&test));        \
140                                                                         \
141    VIXL_CHECK(saved_xregs[0] == simulator.ReadXRegister(19));           \
142    VIXL_CHECK(saved_xregs[1] == simulator.ReadXRegister(20));           \
143    VIXL_CHECK(saved_xregs[2] == simulator.ReadXRegister(21));           \
144    VIXL_CHECK(saved_xregs[3] == simulator.ReadXRegister(22));           \
145    VIXL_CHECK(saved_xregs[4] == simulator.ReadXRegister(23));           \
146    VIXL_CHECK(saved_xregs[5] == simulator.ReadXRegister(24));           \
147    VIXL_CHECK(saved_xregs[6] == simulator.ReadXRegister(25));           \
148    VIXL_CHECK(saved_xregs[7] == simulator.ReadXRegister(26));           \
149    VIXL_CHECK(saved_xregs[8] == simulator.ReadXRegister(27));           \
150    VIXL_CHECK(saved_xregs[9] == simulator.ReadXRegister(28));           \
151    VIXL_CHECK(saved_xregs[10] == simulator.ReadXRegister(29));          \
152    VIXL_CHECK(saved_xregs[11] == simulator.ReadXRegister(30));          \
153    VIXL_CHECK(saved_xregs[12] == simulator.ReadXRegister(31));          \
154                                                                         \
155    VIXL_CHECK(saved_dregs[0] == simulator.ReadDRegisterBits(8));        \
156    VIXL_CHECK(saved_dregs[1] == simulator.ReadDRegisterBits(9));        \
157    VIXL_CHECK(saved_dregs[2] == simulator.ReadDRegisterBits(10));       \
158    VIXL_CHECK(saved_dregs[3] == simulator.ReadDRegisterBits(11));       \
159    VIXL_CHECK(saved_dregs[4] == simulator.ReadDRegisterBits(12));       \
160    VIXL_CHECK(saved_dregs[5] == simulator.ReadDRegisterBits(13));       \
161    VIXL_CHECK(saved_dregs[6] == simulator.ReadDRegisterBits(14));       \
162    VIXL_CHECK(saved_dregs[7] == simulator.ReadDRegisterBits(15));       \
163                                                                         \
164  } while (0)
165
166#define START()                                       \
167  MacroAssembler masm;                                \
168  Decoder decoder;                                    \
169  Debugger simulator(&decoder);                       \
170  simulator.SetColouredTrace(Test::coloured_trace()); \
171  PrintDisassembler* pdis = NULL;                     \
172  Instrument* inst = NULL;                            \
173  if (Test::trace_sim()) {                            \
174    pdis = new PrintDisassembler(stdout);             \
175    decoder.PrependVisitor(pdis);                     \
176  }                                                   \
177  if (Test::instruction_stats()) {                    \
178    inst = new Instrument("vixl_stats.csv", 10);      \
179    inst->Enable();                                   \
180    decoder.AppendVisitor(inst);                      \
181  }                                                   \
182  RegisterDump regs;                                  \
183                                                      \
184  Label test;                                         \
185  masm.Bind(&test);                                   \
186  GenerateTestWrapper(&masm, &regs);                  \
187  masm.FinalizeCode()
188
189
190#define FACTORIAL_DOTEST(N)                                           \
191  do {                                                                \
192    simulator.ResetState();                                           \
193    simulator.WriteXRegister(0, N);                                   \
194    TEST_FUNCTION(factorial);                                         \
195    VIXL_CHECK(static_cast<uint64_t>(regs.xreg(0)) == FactorialC(N)); \
196  } while (0)
197
198TEST(factorial) {
199  START();
200
201  Label factorial;
202  masm.Bind(&factorial);
203  GenerateFactorial(&masm);
204  masm.FinalizeCode();
205
206  FACTORIAL_DOTEST(0);
207  FACTORIAL_DOTEST(1);
208  FACTORIAL_DOTEST(5);
209  FACTORIAL_DOTEST(10);
210  FACTORIAL_DOTEST(20);
211  FACTORIAL_DOTEST(25);
212}
213
214
215#define FACTORIAL_REC_DOTEST(N)                                       \
216  do {                                                                \
217    simulator.ResetState();                                           \
218    simulator.WriteXRegister(0, N);                                   \
219    TEST_FUNCTION(factorial_rec);                                     \
220    VIXL_CHECK(static_cast<uint64_t>(regs.xreg(0)) == FactorialC(N)); \
221  } while (0)
222
223TEST(factorial_rec) {
224  START();
225
226  Label factorial_rec;
227  masm.Bind(&factorial_rec);
228  GenerateFactorialRec(&masm);
229  masm.FinalizeCode();
230
231  FACTORIAL_REC_DOTEST(0);
232  FACTORIAL_REC_DOTEST(1);
233  FACTORIAL_REC_DOTEST(5);
234  FACTORIAL_REC_DOTEST(10);
235  FACTORIAL_REC_DOTEST(20);
236  FACTORIAL_REC_DOTEST(25);
237}
238
239TEST(neon_matrix_multiply) {
240  START();
241
242  Label neon_matrix_multiply;
243  masm.Bind(&neon_matrix_multiply);
244  GenerateNEONMatrixMultiply(&masm);
245  masm.FinalizeCode();
246
247  {
248    const int kRowSize = 4;
249    const int kColSize = 4;
250    const int kLength = kRowSize * kColSize;
251
252    float mat1[kLength], mat2[kLength], expected[kLength], output[kLength];
253
254    // Fill the two input matrices with some 32 bit floating point values.
255
256    mat1[0] = 1.0f;
257    mat1[4] = 2.0f;
258    mat1[8] = 3.0f;
259    mat1[12] = 4.0f;
260    mat1[1] = 52.03f;
261    mat1[5] = 12.24f;
262    mat1[9] = 53.56f;
263    mat1[13] = 22.22f;
264    mat1[2] = 4.43f;
265    mat1[6] = 5.00f;
266    mat1[10] = 7.00f;
267    mat1[14] = 3.11f;
268    mat1[3] = 43.47f;
269    mat1[7] = 10.97f;
270    mat1[11] = 37.78f;
271    mat1[15] = 90.91f;
272
273    mat2[0] = 1.0f;
274    mat2[4] = 11.24f;
275    mat2[8] = 21.00f;
276    mat2[12] = 21.31f;
277    mat2[1] = 2.0f;
278    mat2[5] = 2.24f;
279    mat2[9] = 8.56f;
280    mat2[13] = 52.03f;
281    mat2[2] = 3.0f;
282    mat2[6] = 51.00f;
283    mat2[10] = 21.00f;
284    mat2[14] = 33.11f;
285    mat2[3] = 4.0f;
286    mat2[7] = 0.00f;
287    mat2[11] = 84.00f;
288    mat2[15] = 1.97f;
289
290    MatrixMultiplyC(expected, mat1, mat2);
291
292    simulator.ResetState();
293    simulator.WriteXRegister(0, reinterpret_cast<uintptr_t>(output));
294    simulator.WriteXRegister(1, reinterpret_cast<uintptr_t>(mat1));
295    simulator.WriteXRegister(2, reinterpret_cast<uintptr_t>(mat2));
296    TEST_FUNCTION(neon_matrix_multiply);
297
298    // Check that the results match what is expected.
299    for (int i = 0; i < kLength; i++) {
300      VIXL_CHECK(output[i] == expected[i]);
301    }
302  }
303}
304
305TEST(add2_vectors) {
306  START();
307
308  // Create and initialize the assembler and the simulator.
309  Label add2_vectors;
310  masm.Bind(&add2_vectors);
311  GenerateAdd2Vectors(&masm);
312  masm.FinalizeCode();
313
314  // Initialize input data for the example function.
315  uint8_t A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 200};
316  uint8_t B[] =
317      {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 50};
318  uint8_t D[ARRAY_SIZE(A)];
319  uintptr_t A_addr = reinterpret_cast<uintptr_t>(A);
320  uintptr_t B_addr = reinterpret_cast<uintptr_t>(B);
321
322  // Check whether number of elements in vectors match.
323  VIXL_STATIC_ASSERT(ARRAY_SIZE(A) == ARRAY_SIZE(B));
324  VIXL_STATIC_ASSERT(ARRAY_SIZE(A) == ARRAY_SIZE(D));
325
326  // Compute vector sum for comparison later.
327  for (unsigned i = 0; i < ARRAY_SIZE(A); i++) {
328    D[i] = A[i] + B[i];
329  }
330
331  // Set up simulator and run example function.
332  simulator.ResetState();
333  simulator.WriteXRegister(0, A_addr);
334  simulator.WriteXRegister(1, B_addr);
335  simulator.WriteXRegister(2, ARRAY_SIZE(A));
336  TEST_FUNCTION(add2_vectors);
337
338  // Compare vectors to ensure sums are equal.
339  for (unsigned i = 0; i < ARRAY_SIZE(A); i++) {
340    VIXL_CHECK(A[i] == D[i]);
341  }
342}
343
344#define ADD3_DOUBLE_DOTEST(A, B, C)                   \
345  do {                                                \
346    simulator.ResetState();                           \
347    simulator.WriteDRegister(0, A);                   \
348    simulator.WriteDRegister(1, B);                   \
349    simulator.WriteDRegister(2, C);                   \
350    TEST_FUNCTION(add3_double);                       \
351    VIXL_CHECK(regs.dreg(0) == Add3DoubleC(A, B, C)); \
352  } while (0)
353
354TEST(add3_double) {
355  START();
356
357  Label add3_double;
358  masm.Bind(&add3_double);
359  GenerateAdd3Double(&masm);
360  masm.FinalizeCode();
361
362  ADD3_DOUBLE_DOTEST(0.0, 0.0, 0.0);
363  ADD3_DOUBLE_DOTEST(457.698, 14.36, 2.00025);
364  ADD3_DOUBLE_DOTEST(-45.55, -98.9, -0.354);
365  ADD3_DOUBLE_DOTEST(.55, .9, .12);
366}
367
368
369#define ADD4_DOUBLE_DOTEST(A, B, C, D)                   \
370  do {                                                   \
371    simulator.ResetState();                              \
372    simulator.WriteXRegister(0, A);                      \
373    simulator.WriteDRegister(0, B);                      \
374    simulator.WriteXRegister(1, C);                      \
375    simulator.WriteDRegister(1, D);                      \
376    TEST_FUNCTION(add4_double);                          \
377    VIXL_CHECK(regs.dreg(0) == Add4DoubleC(A, B, C, D)); \
378  } while (0)
379
380TEST(add4_double) {
381  START();
382
383  Label add4_double;
384  masm.Bind(&add4_double);
385  GenerateAdd4Double(&masm);
386  masm.FinalizeCode();
387
388  ADD4_DOUBLE_DOTEST(0, 0, 0, 0);
389  ADD4_DOUBLE_DOTEST(4, 3.287, 6, 13.48);
390  ADD4_DOUBLE_DOTEST(56, 665.368, 0, -4932.4697);
391  ADD4_DOUBLE_DOTEST(56, 0, 546, 0);
392  ADD4_DOUBLE_DOTEST(0, 0.658, 0, 0.00000011540026);
393}
394
395
396#define SUM_ARRAY_DOTEST(Array)                                      \
397  do {                                                               \
398    simulator.ResetState();                                          \
399    uintptr_t addr = reinterpret_cast<uintptr_t>(Array);             \
400    simulator.WriteXRegister(0, addr);                               \
401    simulator.WriteXRegister(1, ARRAY_SIZE(Array));                  \
402    TEST_FUNCTION(sum_array);                                        \
403    VIXL_CHECK(regs.xreg(0) == SumArrayC(Array, ARRAY_SIZE(Array))); \
404  } while (0)
405
406TEST(sum_array) {
407  START();
408
409  Label sum_array;
410  masm.Bind(&sum_array);
411  GenerateSumArray(&masm);
412  masm.FinalizeCode();
413
414  uint8_t data1[] = {4, 9, 13, 3, 2, 6, 5};
415  SUM_ARRAY_DOTEST(data1);
416
417  uint8_t data2[] = {42};
418  SUM_ARRAY_DOTEST(data2);
419
420  uint8_t data3[1000];
421  for (unsigned int i = 0; i < ARRAY_SIZE(data3); ++i) data3[i] = 255;
422  SUM_ARRAY_DOTEST(data3);
423}
424
425
426#define ABS_DOTEST(X)                   \
427  do {                                  \
428    simulator.ResetState();             \
429    simulator.WriteXRegister(0, X);     \
430    TEST_FUNCTION(func_abs);            \
431    VIXL_CHECK(regs.xreg(0) == abs(X)); \
432  } while (0)
433
434TEST(abs) {
435  START();
436
437  Label func_abs;
438  masm.Bind(&func_abs);
439  GenerateAbs(&masm);
440  masm.FinalizeCode();
441
442  ABS_DOTEST(-42);
443  ABS_DOTEST(0);
444  ABS_DOTEST(545);
445  ABS_DOTEST(-428751489);
446}
447
448
449TEST(crc32) {
450  START();
451
452  Label crc32;
453  masm.Bind(&crc32);
454  GenerateCrc32(&masm);
455  masm.FinalizeCode();
456
457  const char* msg = "Hello World!";
458  uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
459  size_t msg_size = strlen(msg);
460  int64_t chksum = INT64_C(0xe3d6e35c);
461  simulator.WriteXRegister(0, msg_addr);
462  simulator.WriteXRegister(1, msg_size);
463  TEST_FUNCTION(crc32);
464  VIXL_CHECK(regs.xreg(0) == chksum);
465}
466
467
468TEST(swap4) {
469  START();
470
471  Label swap4;
472  masm.Bind(&swap4);
473  GenerateSwap4(&masm);
474  masm.FinalizeCode();
475
476  int64_t a = 15;
477  int64_t b = 26;
478  int64_t c = 46;
479  int64_t d = 79;
480
481  simulator.WriteXRegister(0, a);
482  simulator.WriteXRegister(1, b);
483  simulator.WriteXRegister(2, c);
484  simulator.WriteXRegister(3, d);
485  TEST_FUNCTION(swap4);
486  VIXL_CHECK(regs.xreg(0) == d);
487  VIXL_CHECK(regs.xreg(1) == c);
488  VIXL_CHECK(regs.xreg(2) == b);
489  VIXL_CHECK(regs.xreg(3) == a);
490}
491
492
493TEST(swap_int32) {
494  START();
495
496  Label swap_int32;
497  masm.Bind(&swap_int32);
498  GenerateSwapInt32(&masm);
499  masm.FinalizeCode();
500
501  int32_t x = 168;
502  int32_t y = 246;
503  simulator.WriteWRegister(0, x);
504  simulator.WriteWRegister(1, y);
505  TEST_FUNCTION(swap_int32);
506  VIXL_CHECK(regs.wreg(0) == y);
507  VIXL_CHECK(regs.wreg(1) == x);
508}
509
510
511#define CHECKBOUNDS_DOTEST(Value, Low, High)                         \
512  do {                                                               \
513    simulator.ResetState();                                          \
514    simulator.WriteXRegister(0, Value);                              \
515    simulator.WriteXRegister(1, Low);                                \
516    simulator.WriteXRegister(2, High);                               \
517    TEST_FUNCTION(check_bounds);                                     \
518    VIXL_CHECK(regs.xreg(0) == ((Low <= Value) && (Value <= High))); \
519  } while (0)
520
521TEST(check_bounds) {
522  START();
523
524  Label check_bounds;
525  masm.Bind(&check_bounds);
526  GenerateCheckBounds(&masm);
527  masm.FinalizeCode();
528
529  CHECKBOUNDS_DOTEST(0, 100, 200);
530  CHECKBOUNDS_DOTEST(58, 100, 200);
531  CHECKBOUNDS_DOTEST(99, 100, 200);
532  CHECKBOUNDS_DOTEST(100, 100, 200);
533  CHECKBOUNDS_DOTEST(101, 100, 200);
534  CHECKBOUNDS_DOTEST(150, 100, 200);
535  CHECKBOUNDS_DOTEST(199, 100, 200);
536  CHECKBOUNDS_DOTEST(200, 100, 200);
537  CHECKBOUNDS_DOTEST(201, 100, 200);
538}
539
540
541#define GETTING_STARTED_DOTEST(Value)                         \
542  do {                                                        \
543    simulator.ResetState();                                   \
544    simulator.WriteXRegister(0, Value);                       \
545    TEST_FUNCTION(demo_function);                             \
546    VIXL_CHECK(regs.xreg(0) == (Value & 0x1122334455667788)); \
547  } while (0)
548
549TEST(getting_started) {
550  START();
551
552  Label demo_function;
553  masm.Bind(&demo_function);
554  GenerateDemoFunction(&masm);
555  masm.FinalizeCode();
556
557  GETTING_STARTED_DOTEST(0x8899aabbccddeeff);
558  GETTING_STARTED_DOTEST(0x1122334455667788);
559  GETTING_STARTED_DOTEST(0x0000000000000000);
560  GETTING_STARTED_DOTEST(0xffffffffffffffff);
561  GETTING_STARTED_DOTEST(0x5a5a5a5a5a5a5a5a);
562}
563
564
565TEST(non_const_visitor) {
566  MacroAssembler masm;
567
568  Label code_start, code_end;
569  masm.Bind(&code_start);
570  GenerateNonConstVisitorTestCode(&masm);
571  masm.Bind(&code_end);
572  masm.FinalizeCode();
573  Instruction* instr_start = masm.GetLabelAddress<Instruction*>(&code_start);
574  Instruction* instr_end = masm.GetLabelAddress<Instruction*>(&code_end);
575
576  int64_t res_orig = RunNonConstVisitorTestGeneratedCode(instr_start);
577
578  ModifyNonConstVisitorTestGeneratedCode(instr_start, instr_end);
579
580  int64_t res_mod = RunNonConstVisitorTestGeneratedCode(instr_start);
581  VIXL_CHECK(res_orig == -res_mod);
582}
583
584
585TEST(literal_example) {
586  VIXL_ASSERT(LiteralExample(1, 2) == 3);
587  VIXL_ASSERT(LiteralExample(INT64_C(0x100000000), 0x1) ==
588              INT64_C(0x100000001));
589}
590
591
592// This is an approximation of the result that works for the ranges tested
593// below.
594#define RUNTIME_CALLS_EXPECTED(A, B) ((A + B) << 2)
595
596#define RUNTIME_CALLS_DOTEST(A, B, R)                                  \
597  do {                                                                 \
598    simulator.ResetState();                                            \
599    simulator.WriteWRegister(0, A);                                    \
600    simulator.WriteWRegister(1, B);                                    \
601    TEST_FUNCTION(start);                                              \
602    VIXL_CHECK(regs.wreg<int32_t>(0) == RUNTIME_CALLS_EXPECTED(A, B)); \
603  } while (0)
604
605TEST(runtime_calls) {
606  START();
607
608  Label start;
609  masm.Bind(&start);
610  GenerateRuntimeCallExamples(&masm);
611  masm.FinalizeCode();
612
613  RUNTIME_CALLS_DOTEST(0, 0);
614  RUNTIME_CALLS_DOTEST(1, -2);
615  RUNTIME_CALLS_DOTEST(123, 456);
616}
617
618#endif  // VIXL_INCLUDE_SIMULATOR_AARCH64
619