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