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