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