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