xref: /aosp_15_r20/external/vixl/test/aarch64/examples/test-examples.cc (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
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   masm.Blr(test_function_reg);                                           \
181   masm.Trace(LOG_ALL, TRACE_DISABLE);                                    \
182   regs.Dump(&masm);                                                      \
183   masm.Mov(lr, reinterpret_cast<uint64_t>(Simulator::kEndOfSimAddress)); \
184   masm.Ret();                                                            \
185   masm.FinalizeCode()
186 
187 
188 #define FACTORIAL_DOTEST(N)                                           \
189   do {                                                                \
190     simulator.ResetState();                                           \
191     simulator.WriteXRegister(0, N);                                   \
192     TEST_FUNCTION(factorial);                                         \
193     VIXL_CHECK(static_cast<uint64_t>(regs.xreg(0)) == FactorialC(N)); \
194   } while (0)
195 
TEST(factorial)196 TEST(factorial) {
197   START();
198 
199   Label factorial;
200   masm.Bind(&factorial);
201   GenerateFactorial(&masm);
202   masm.FinalizeCode();
203 
204   FACTORIAL_DOTEST(0);
205   FACTORIAL_DOTEST(1);
206   FACTORIAL_DOTEST(5);
207   FACTORIAL_DOTEST(10);
208   FACTORIAL_DOTEST(20);
209   FACTORIAL_DOTEST(25);
210 }
211 
212 
213 #define FACTORIAL_REC_DOTEST(N)                                       \
214   do {                                                                \
215     simulator.ResetState();                                           \
216     simulator.WriteXRegister(0, N);                                   \
217     TEST_FUNCTION(factorial_rec);                                     \
218     VIXL_CHECK(static_cast<uint64_t>(regs.xreg(0)) == FactorialC(N)); \
219   } while (0)
220 
TEST(factorial_rec)221 TEST(factorial_rec) {
222   START();
223 
224   Label factorial_rec;
225   masm.Bind(&factorial_rec);
226   GenerateFactorialRec(&masm);
227   masm.FinalizeCode();
228 
229   FACTORIAL_REC_DOTEST(0);
230   FACTORIAL_REC_DOTEST(1);
231   FACTORIAL_REC_DOTEST(5);
232   FACTORIAL_REC_DOTEST(10);
233   FACTORIAL_REC_DOTEST(20);
234   FACTORIAL_REC_DOTEST(25);
235 }
236 
TEST(neon_matrix_multiply)237 TEST(neon_matrix_multiply) {
238   START();
239 
240   Label neon_matrix_multiply;
241   masm.Bind(&neon_matrix_multiply);
242   GenerateNEONMatrixMultiply(&masm);
243   masm.FinalizeCode();
244 
245   {
246     const int kRowSize = 4;
247     const int kColSize = 4;
248     const int kLength = kRowSize * kColSize;
249 
250     float mat1[kLength], mat2[kLength], expected[kLength], output[kLength];
251 
252     // Fill the two input matrices with some 32 bit floating point values.
253 
254     mat1[0] = 1.0f;
255     mat1[4] = 2.0f;
256     mat1[8] = 3.0f;
257     mat1[12] = 4.0f;
258     mat1[1] = 52.03f;
259     mat1[5] = 12.24f;
260     mat1[9] = 53.56f;
261     mat1[13] = 22.22f;
262     mat1[2] = 4.43f;
263     mat1[6] = 5.00f;
264     mat1[10] = 7.00f;
265     mat1[14] = 3.11f;
266     mat1[3] = 43.47f;
267     mat1[7] = 10.97f;
268     mat1[11] = 37.78f;
269     mat1[15] = 90.91f;
270 
271     mat2[0] = 1.0f;
272     mat2[4] = 11.24f;
273     mat2[8] = 21.00f;
274     mat2[12] = 21.31f;
275     mat2[1] = 2.0f;
276     mat2[5] = 2.24f;
277     mat2[9] = 8.56f;
278     mat2[13] = 52.03f;
279     mat2[2] = 3.0f;
280     mat2[6] = 51.00f;
281     mat2[10] = 21.00f;
282     mat2[14] = 33.11f;
283     mat2[3] = 4.0f;
284     mat2[7] = 0.00f;
285     mat2[11] = 84.00f;
286     mat2[15] = 1.97f;
287 
288     MatrixMultiplyC(expected, mat1, mat2);
289 
290     simulator.ResetState();
291     simulator.WriteXRegister(0, reinterpret_cast<uintptr_t>(output));
292     simulator.WriteXRegister(1, reinterpret_cast<uintptr_t>(mat1));
293     simulator.WriteXRegister(2, reinterpret_cast<uintptr_t>(mat2));
294     TEST_FUNCTION(neon_matrix_multiply);
295 
296     // Check that the results match what is expected.
297     for (int i = 0; i < kLength; i++) {
298       VIXL_CHECK(output[i] == expected[i]);
299     }
300   }
301 }
302 
TEST(add2_vectors)303 TEST(add2_vectors) {
304   START();
305 
306   // Create and initialize the assembler and the simulator.
307   Label add2_vectors;
308   masm.Bind(&add2_vectors);
309   GenerateAdd2Vectors(&masm);
310   masm.FinalizeCode();
311 
312   // Initialize input data for the example function.
313   uint8_t A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 200};
314   uint8_t B[] =
315       {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 50};
316   uint8_t D[ARRAY_SIZE(A)];
317   uintptr_t A_addr = reinterpret_cast<uintptr_t>(A);
318   uintptr_t B_addr = reinterpret_cast<uintptr_t>(B);
319 
320   // Check whether number of elements in vectors match.
321   VIXL_STATIC_ASSERT(ARRAY_SIZE(A) == ARRAY_SIZE(B));
322   VIXL_STATIC_ASSERT(ARRAY_SIZE(A) == ARRAY_SIZE(D));
323 
324   // Compute vector sum for comparison later.
325   for (unsigned i = 0; i < ARRAY_SIZE(A); i++) {
326     D[i] = A[i] + B[i];
327   }
328 
329   // Set up simulator and run example function.
330   simulator.ResetState();
331   simulator.WriteXRegister(0, A_addr);
332   simulator.WriteXRegister(1, B_addr);
333   simulator.WriteXRegister(2, ARRAY_SIZE(A));
334   TEST_FUNCTION(add2_vectors);
335 
336   // Compare vectors to ensure sums are equal.
337   for (unsigned i = 0; i < ARRAY_SIZE(A); i++) {
338     VIXL_CHECK(A[i] == D[i]);
339   }
340 }
341 
342 #define ADD3_DOUBLE_DOTEST(A, B, C)                   \
343   do {                                                \
344     simulator.ResetState();                           \
345     simulator.WriteDRegister(0, A);                   \
346     simulator.WriteDRegister(1, B);                   \
347     simulator.WriteDRegister(2, C);                   \
348     TEST_FUNCTION(add3_double);                       \
349     VIXL_CHECK(regs.dreg(0) == Add3DoubleC(A, B, C)); \
350   } while (0)
351 
TEST(add3_double)352 TEST(add3_double) {
353   START();
354 
355   Label add3_double;
356   masm.Bind(&add3_double);
357   GenerateAdd3Double(&masm);
358   masm.FinalizeCode();
359 
360   ADD3_DOUBLE_DOTEST(0.0, 0.0, 0.0);
361   ADD3_DOUBLE_DOTEST(457.698, 14.36, 2.00025);
362   ADD3_DOUBLE_DOTEST(-45.55, -98.9, -0.354);
363   ADD3_DOUBLE_DOTEST(.55, .9, .12);
364 }
365 
366 
367 #define ADD4_DOUBLE_DOTEST(A, B, C, D)                   \
368   do {                                                   \
369     simulator.ResetState();                              \
370     simulator.WriteXRegister(0, A);                      \
371     simulator.WriteDRegister(0, B);                      \
372     simulator.WriteXRegister(1, C);                      \
373     simulator.WriteDRegister(1, D);                      \
374     TEST_FUNCTION(add4_double);                          \
375     VIXL_CHECK(regs.dreg(0) == Add4DoubleC(A, B, C, D)); \
376   } while (0)
377 
TEST(add4_double)378 TEST(add4_double) {
379   START();
380 
381   Label add4_double;
382   masm.Bind(&add4_double);
383   GenerateAdd4Double(&masm);
384   masm.FinalizeCode();
385 
386   ADD4_DOUBLE_DOTEST(0, 0, 0, 0);
387   ADD4_DOUBLE_DOTEST(4, 3.287, 6, 13.48);
388   ADD4_DOUBLE_DOTEST(56, 665.368, 0, -4932.4697);
389   ADD4_DOUBLE_DOTEST(56, 0, 546, 0);
390   ADD4_DOUBLE_DOTEST(0, 0.658, 0, 0.00000011540026);
391 }
392 
393 
394 #define SUM_ARRAY_DOTEST(Array)                                      \
395   do {                                                               \
396     simulator.ResetState();                                          \
397     uintptr_t addr = reinterpret_cast<uintptr_t>(Array);             \
398     simulator.WriteXRegister(0, addr);                               \
399     simulator.WriteXRegister(1, ARRAY_SIZE(Array));                  \
400     TEST_FUNCTION(sum_array);                                        \
401     VIXL_CHECK(regs.xreg(0) == SumArrayC(Array, ARRAY_SIZE(Array))); \
402   } while (0)
403 
TEST(sum_array)404 TEST(sum_array) {
405   START();
406 
407   Label sum_array;
408   masm.Bind(&sum_array);
409   GenerateSumArray(&masm);
410   masm.FinalizeCode();
411 
412   uint8_t data1[] = {4, 9, 13, 3, 2, 6, 5};
413   SUM_ARRAY_DOTEST(data1);
414 
415   uint8_t data2[] = {42};
416   SUM_ARRAY_DOTEST(data2);
417 
418   uint8_t data3[1000];
419   for (unsigned int i = 0; i < ARRAY_SIZE(data3); ++i) data3[i] = 255;
420   SUM_ARRAY_DOTEST(data3);
421 }
422 
423 
424 #define ABS_DOTEST(X)                   \
425   do {                                  \
426     simulator.ResetState();             \
427     simulator.WriteXRegister(0, X);     \
428     TEST_FUNCTION(func_abs);            \
429     VIXL_CHECK(regs.xreg(0) == abs(X)); \
430   } while (0)
431 
TEST(abs)432 TEST(abs) {
433   START();
434 
435   Label func_abs;
436   masm.Bind(&func_abs);
437   GenerateAbs(&masm);
438   masm.FinalizeCode();
439 
440   ABS_DOTEST(-42);
441   ABS_DOTEST(0);
442   ABS_DOTEST(545);
443   ABS_DOTEST(-428751489);
444 }
445 
446 
TEST(crc32)447 TEST(crc32) {
448   START();
449 
450   Label crc32;
451   masm.Bind(&crc32);
452   GenerateCrc32(&masm);
453   masm.FinalizeCode();
454 
455   const char* msg = "Hello World!";
456   uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
457   size_t msg_size = strlen(msg);
458   int64_t chksum = INT64_C(0xe3d6e35c);
459   simulator.WriteXRegister(0, msg_addr);
460   simulator.WriteXRegister(1, msg_size);
461   TEST_FUNCTION(crc32);
462   VIXL_CHECK(regs.xreg(0) == chksum);
463 }
464 
465 
TEST(swap4)466 TEST(swap4) {
467   START();
468 
469   Label swap4;
470   masm.Bind(&swap4);
471   GenerateSwap4(&masm);
472   masm.FinalizeCode();
473 
474   int64_t a = 15;
475   int64_t b = 26;
476   int64_t c = 46;
477   int64_t d = 79;
478 
479   simulator.WriteXRegister(0, a);
480   simulator.WriteXRegister(1, b);
481   simulator.WriteXRegister(2, c);
482   simulator.WriteXRegister(3, d);
483   TEST_FUNCTION(swap4);
484   VIXL_CHECK(regs.xreg(0) == d);
485   VIXL_CHECK(regs.xreg(1) == c);
486   VIXL_CHECK(regs.xreg(2) == b);
487   VIXL_CHECK(regs.xreg(3) == a);
488 }
489 
490 
TEST(swap_int32)491 TEST(swap_int32) {
492   START();
493 
494   Label swap_int32;
495   masm.Bind(&swap_int32);
496   GenerateSwapInt32(&masm);
497   masm.FinalizeCode();
498 
499   int32_t x = 168;
500   int32_t y = 246;
501   simulator.WriteWRegister(0, x);
502   simulator.WriteWRegister(1, y);
503   TEST_FUNCTION(swap_int32);
504   VIXL_CHECK(regs.wreg(0) == y);
505   VIXL_CHECK(regs.wreg(1) == x);
506 }
507 
508 
509 #define CHECKBOUNDS_DOTEST(Value, Low, High)                         \
510   do {                                                               \
511     simulator.ResetState();                                          \
512     simulator.WriteXRegister(0, Value);                              \
513     simulator.WriteXRegister(1, Low);                                \
514     simulator.WriteXRegister(2, High);                               \
515     TEST_FUNCTION(check_bounds);                                     \
516     VIXL_CHECK(regs.xreg(0) == ((Low <= Value) && (Value <= High))); \
517   } while (0)
518 
TEST(check_bounds)519 TEST(check_bounds) {
520   START();
521 
522   Label check_bounds;
523   masm.Bind(&check_bounds);
524   GenerateCheckBounds(&masm);
525   masm.FinalizeCode();
526 
527   CHECKBOUNDS_DOTEST(0, 100, 200);
528   CHECKBOUNDS_DOTEST(58, 100, 200);
529   CHECKBOUNDS_DOTEST(99, 100, 200);
530   CHECKBOUNDS_DOTEST(100, 100, 200);
531   CHECKBOUNDS_DOTEST(101, 100, 200);
532   CHECKBOUNDS_DOTEST(150, 100, 200);
533   CHECKBOUNDS_DOTEST(199, 100, 200);
534   CHECKBOUNDS_DOTEST(200, 100, 200);
535   CHECKBOUNDS_DOTEST(201, 100, 200);
536 }
537 
538 
539 #define GETTING_STARTED_DOTEST(Value)                         \
540   do {                                                        \
541     simulator.ResetState();                                   \
542     simulator.WriteXRegister(0, Value);                       \
543     TEST_FUNCTION(demo_function);                             \
544     VIXL_CHECK(regs.xreg(0) == (Value & 0x1122334455667788)); \
545   } while (0)
546 
TEST(getting_started)547 TEST(getting_started) {
548   START();
549 
550   Label demo_function;
551   masm.Bind(&demo_function);
552   GenerateDemoFunction(&masm);
553   masm.FinalizeCode();
554 
555   GETTING_STARTED_DOTEST(0x8899aabbccddeeff);
556   GETTING_STARTED_DOTEST(0x1122334455667788);
557   GETTING_STARTED_DOTEST(0x0000000000000000);
558   GETTING_STARTED_DOTEST(0xffffffffffffffff);
559   GETTING_STARTED_DOTEST(0x5a5a5a5a5a5a5a5a);
560 }
561 
562 
TEST(non_const_visitor)563 TEST(non_const_visitor) {
564   MacroAssembler masm;
565 
566   Label code_start, code_end;
567   masm.Bind(&code_start);
568   GenerateNonConstVisitorTestCode(&masm);
569   masm.Bind(&code_end);
570   masm.FinalizeCode();
571   Instruction* instr_start = masm.GetLabelAddress<Instruction*>(&code_start);
572   Instruction* instr_end = masm.GetLabelAddress<Instruction*>(&code_end);
573 
574   int64_t res_orig = RunNonConstVisitorTestGeneratedCode(instr_start);
575 
576   ModifyNonConstVisitorTestGeneratedCode(instr_start, instr_end);
577 
578   int64_t res_mod = RunNonConstVisitorTestGeneratedCode(instr_start);
579   VIXL_CHECK(res_orig == -res_mod);
580 }
581 
582 
TEST(literal_example)583 TEST(literal_example) {
584   VIXL_ASSERT(LiteralExample(1, 2) == 3);
585   VIXL_ASSERT(LiteralExample(INT64_C(0x100000000), 0x1) ==
586               INT64_C(0x100000001));
587 }
588 
589 
590 #ifdef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
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) * 4)
595 
596 #define RUNTIME_CALLS_DOTEST(A, B)                            \
597   do {                                                        \
598     simulator.ResetState();                                   \
599     simulator.WriteWRegister(0, A);                           \
600     simulator.WriteWRegister(1, B);                           \
601     TEST_FUNCTION(start);                                     \
602     VIXL_CHECK(regs.wreg(0) == RUNTIME_CALLS_EXPECTED(A, B)); \
603   } while (0)
604 
TEST(runtime_calls)605 TEST(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_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
619 
TEST(sve_strlen)620 TEST(sve_strlen) {
621   START();
622 
623   CPUFeatures cpu_features(CPUFeatures::kSVE);
624   masm.SetCPUFeatures(cpu_features);
625 
626   Label sve_strlen;
627   masm.Bind(&sve_strlen);
628   GenerateSVEStrlen(&masm);
629   masm.FinalizeCode();
630 
631   if (CanRun(cpu_features)) {
632     const char* inputs[] =
633         {"Exactly 15 chrs",
634          "Exactly 16 chars",
635          "Exactly 17 chars.",
636 
637          "This string is very long and will require multiple iterations, even "
638          "with the maximum VL (256 bytes). This string is very long and will "
639          "require multiple iterations, even with the maximum VL (256 bytes). "
640          "This string is very long and will require multiple iterations, even "
641          "with the maximum VL (256 bytes)."};
642 
643     for (size_t i = 0; i < ArrayLength(inputs); i++) {
644       simulator.ResetState();
645       simulator.WriteXRegister(0, reinterpret_cast<uintptr_t>(inputs[i]));
646       TEST_FUNCTION(sve_strlen);
647       VIXL_CHECK(static_cast<size_t>(regs.xreg(0)) == strlen(inputs[i]));
648     }
649   }
650 }
651 
652 #endif  // VIXL_INCLUDE_SIMULATOR_AARCH64
653