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