asmjit_test_compiler_a64.cpp (18245B)
1 // This file is part of AsmJit project <https://asmjit.com> 2 // 3 // See <asmjit/core.h> or LICENSE.md for license and copyright information 4 // SPDX-License-Identifier: Zlib 5 6 #include <asmjit/core.h> 7 #if !defined(ASMJIT_NO_COMPILER) && !defined(ASMJIT_NO_AARCH64) 8 9 #include <asmjit/a64.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 14 #include "asmjit_test_compiler.h" 15 16 using namespace asmjit; 17 18 // a64::Compiler - A64TestCase 19 // =========================== 20 21 class A64TestCase : public TestCase { 22 public: 23 A64TestCase(const char* name = nullptr) 24 : TestCase(name, Arch::kAArch64) {} 25 26 void compile(BaseCompiler& cc) override { 27 compile(static_cast<a64::Compiler&>(cc)); 28 } 29 30 virtual void compile(a64::Compiler& cc) = 0; 31 }; 32 33 // a64::Compiler - A64Test_GpArgs 34 // ============================== 35 36 class A64Test_GpArgs : public A64TestCase { 37 public: 38 uint32_t _arg_count; 39 bool _preserve_fp; 40 41 A64Test_GpArgs(uint32_t arg_count, bool preserve_fp) 42 : _arg_count(arg_count), 43 _preserve_fp(preserve_fp) { 44 _name.assign_format("GpArgs {NumArgs=%u PreserveFP=%c}", arg_count, preserve_fp ? 'Y' : 'N'); 45 } 46 47 static void add(TestApp& app) { 48 for (uint32_t i = 0; i <= 16; i++) { 49 app.add(new A64Test_GpArgs(i, true)); 50 app.add(new A64Test_GpArgs(i, false)); 51 } 52 } 53 54 void compile(a64::Compiler& cc) override { 55 uint32_t arg_count = _arg_count; 56 FuncSignature signature; 57 58 signature.set_ret_t<int>(); 59 for (uint32_t i = 0; i < arg_count; i++) { 60 signature.add_arg_t<int>(); 61 } 62 63 FuncNode* func_node = cc.add_func(signature); 64 if (_preserve_fp) 65 func_node->frame().set_preserved_fp(); 66 67 a64::Gp sum; 68 69 if (arg_count) { 70 for (uint32_t i = 0; i < arg_count; i++) { 71 a64::Gp i_reg = cc.new_gp32("i%u", i); 72 func_node->set_arg(i, i_reg); 73 74 if (i == 0) 75 sum = i_reg; 76 else 77 cc.add(sum, sum, i_reg); 78 } 79 } 80 else { 81 sum = cc.new_gp32("i"); 82 cc.mov(sum, 0); 83 } 84 85 cc.ret(sum); 86 cc.end_func(); 87 } 88 89 bool run(void* _func, String& result, String& expect) override { 90 using U = unsigned int; 91 92 using Func0 = U (*)(); 93 using Func1 = U (*)(U); 94 using Func2 = U (*)(U, U); 95 using Func3 = U (*)(U, U, U); 96 using Func4 = U (*)(U, U, U, U); 97 using Func5 = U (*)(U, U, U, U, U); 98 using Func6 = U (*)(U, U, U, U, U, U); 99 using Func7 = U (*)(U, U, U, U, U, U, U); 100 using Func8 = U (*)(U, U, U, U, U, U, U, U); 101 using Func9 = U (*)(U, U, U, U, U, U, U, U, U); 102 using Func10 = U (*)(U, U, U, U, U, U, U, U, U, U); 103 using Func11 = U (*)(U, U, U, U, U, U, U, U, U, U, U); 104 using Func12 = U (*)(U, U, U, U, U, U, U, U, U, U, U, U); 105 using Func13 = U (*)(U, U, U, U, U, U, U, U, U, U, U, U, U); 106 using Func14 = U (*)(U, U, U, U, U, U, U, U, U, U, U, U, U, U); 107 using Func15 = U (*)(U, U, U, U, U, U, U, U, U, U, U, U, U, U, U); 108 using Func16 = U (*)(U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U); 109 110 unsigned int result_ret = 0; 111 unsigned int expect_ret = 0; 112 113 switch (_arg_count) { 114 case 0: 115 result_ret = ptr_as_func<Func0>(_func)(); 116 expect_ret = 0; 117 break; 118 case 1: 119 result_ret = ptr_as_func<Func1>(_func)(1); 120 expect_ret = 1; 121 break; 122 case 2: 123 result_ret = ptr_as_func<Func2>(_func)(1, 2); 124 expect_ret = 1 + 2; 125 break; 126 case 3: 127 result_ret = ptr_as_func<Func3>(_func)(1, 2, 3); 128 expect_ret = 1 + 2 + 3; 129 break; 130 case 4: 131 result_ret = ptr_as_func<Func4>(_func)(1, 2, 3, 4); 132 expect_ret = 1 + 2 + 3 + 4; 133 break; 134 case 5: 135 result_ret = ptr_as_func<Func5>(_func)(1, 2, 3, 4, 5); 136 expect_ret = 1 + 2 + 3 + 4 + 5; 137 break; 138 case 6: 139 result_ret = ptr_as_func<Func6>(_func)(1, 2, 3, 4, 5, 6); 140 expect_ret = 1 + 2 + 3 + 4 + 5 + 6; 141 break; 142 case 7: 143 result_ret = ptr_as_func<Func7>(_func)(1, 2, 3, 4, 5, 6, 7); 144 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7; 145 break; 146 case 8: 147 result_ret = ptr_as_func<Func8>(_func)(1, 2, 3, 4, 5, 6, 7, 8); 148 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8; 149 break; 150 case 9: 151 result_ret = ptr_as_func<Func9>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9); 152 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9; 153 break; 154 case 10: 155 result_ret = ptr_as_func<Func10>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 156 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10; 157 break; 158 case 11: 159 result_ret = ptr_as_func<Func11>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); 160 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11; 161 break; 162 case 12: 163 result_ret = ptr_as_func<Func12>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); 164 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12; 165 break; 166 case 13: 167 result_ret = ptr_as_func<Func13>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); 168 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13; 169 break; 170 case 14: 171 result_ret = ptr_as_func<Func14>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); 172 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14; 173 break; 174 case 15: 175 result_ret = ptr_as_func<Func15>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); 176 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15; 177 break; 178 case 16: 179 result_ret = ptr_as_func<Func16>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); 180 expect_ret = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16; 181 break; 182 } 183 184 result.assign_format("ret={%u, %u}", result_ret >> 28, result_ret & 0x0FFFFFFFu); 185 expect.assign_format("ret={%u, %u}", expect_ret >> 28, expect_ret & 0x0FFFFFFFu); 186 187 return result == expect; 188 } 189 }; 190 191 // a64::Compiler - A64Test_Simd1 192 // ============================= 193 194 class A64Test_Simd1 : public A64TestCase { 195 public: 196 A64Test_Simd1() 197 : A64TestCase("Simd1") {} 198 199 static void add(TestApp& app) { 200 app.add(new A64Test_Simd1()); 201 } 202 203 void compile(a64::Compiler& cc) override { 204 FuncNode* func_node = cc.add_func(FuncSignature::build<void, void*, const void*, const void*>()); 205 206 a64::Gp dst = cc.new_gp_ptr("dst"); 207 a64::Gp src1 = cc.new_gp_ptr("src1"); 208 a64::Gp src2 = cc.new_gp_ptr("src2"); 209 210 func_node->set_arg(0, dst); 211 func_node->set_arg(1, src1); 212 func_node->set_arg(2, src2); 213 214 a64::Vec v1 = cc.new_vec_q("vec1"); 215 a64::Vec v2 = cc.new_vec_q("vec2"); 216 a64::Vec v3 = cc.new_vec_q("vec3"); 217 218 cc.ldr(v2, a64::ptr(src1)); 219 cc.ldr(v3, a64::ptr(src2)); 220 cc.add(v1.b16(), v2.b16(), v3.b16()); 221 cc.str(v1, a64::ptr(dst)); 222 223 cc.end_func(); 224 } 225 226 bool run(void* _func, String& result, String& expect) override { 227 using Func = void (*)(void*, const void*, const void*); 228 229 uint32_t dst[4]; 230 uint32_t a_src[4] = { 0 , 1 , 2 , 255 }; 231 uint32_t b_src[4] = { 99, 17, 33, 1 }; 232 233 // NOTE: It's a byte-add, so uint8_t(255+1) == 0. 234 uint32_t ref[4] = { 99, 18, 35, 0 }; 235 236 ptr_as_func<Func>(_func)(dst, a_src, b_src); 237 238 result.assign_format("ret={%u, %u, %u, %u}", dst[0], dst[1], dst[2], dst[3]); 239 expect.assign_format("ret={%u, %u, %u, %u}", ref[0], ref[1], ref[2], ref[3]); 240 241 return result == expect; 242 } 243 }; 244 245 // a64::Compiler - A64Test_ManyRegs 246 // ================================ 247 248 class A64Test_ManyRegs : public A64TestCase { 249 public: 250 uint32_t _reg_count; 251 252 A64Test_ManyRegs(uint32_t n) 253 : A64TestCase(), 254 _reg_count(n) { 255 _name.assign_format("GpRegs {NumRegs=%u}", n); 256 } 257 258 static void add(TestApp& app) { 259 for (uint32_t i = 2; i < 64; i++) 260 app.add(new A64Test_ManyRegs(i)); 261 } 262 263 void compile(a64::Compiler& cc) override { 264 cc.add_func(FuncSignature::build<int>()); 265 266 a64::Gp* regs = static_cast<a64::Gp*>(malloc(_reg_count * sizeof(a64::Gp))); 267 268 for (uint32_t i = 0; i < _reg_count; i++) { 269 regs[i] = cc.new_gp32("reg%u", i); 270 cc.mov(regs[i], i + 1); 271 } 272 273 a64::Gp sum = cc.new_gp32("sum"); 274 cc.mov(sum, 0); 275 276 for (uint32_t i = 0; i < _reg_count; i++) { 277 cc.add(sum, sum, regs[i]); 278 } 279 280 cc.ret(sum); 281 cc.end_func(); 282 283 free(regs); 284 } 285 286 bool run(void* _func, String& result, String& expect) override { 287 using Func = int (*)(void); 288 Func func = ptr_as_func<Func>(_func); 289 290 result.assign_format("ret={%d}", func()); 291 expect.assign_format("ret={%d}", calc_sum()); 292 293 return result == expect; 294 } 295 296 uint32_t calc_sum() const { 297 return (_reg_count | 1) * ((_reg_count + 1) / 2); 298 } 299 }; 300 301 // a64::Compiler - A64Test_Adr 302 // =========================== 303 304 class A64Test_Adr : public A64TestCase { 305 public: 306 A64Test_Adr() 307 : A64TestCase("Adr") {} 308 309 static void add(TestApp& app) { 310 app.add(new A64Test_Adr()); 311 } 312 313 void compile(a64::Compiler& cc) override { 314 cc.add_func(FuncSignature::build<int>()); 315 316 a64::Gp addr = cc.new_gp_ptr("addr"); 317 a64::Gp val = cc.new_gp_ptr("val"); 318 319 Label L_Table = cc.new_label(); 320 321 cc.adr(addr, L_Table); 322 cc.ldrsw(val, a64::ptr(addr, 8)); 323 cc.ret(val); 324 cc.end_func(); 325 326 cc.bind(L_Table); 327 cc.embed_int32(1); 328 cc.embed_int32(2); 329 cc.embed_int32(3); 330 cc.embed_int32(4); 331 cc.embed_int32(5); 332 } 333 334 bool run(void* _func, String& result, String& expect) override { 335 using Func = int (*)(void); 336 Func func = ptr_as_func<Func>(_func); 337 338 result.assign_format("ret={%d}", func()); 339 expect.assign_format("ret={%d}", 3); 340 341 return result == expect; 342 } 343 }; 344 345 // a64::Compiler - A64Test_Branch1 346 // =============================== 347 348 class A64Test_Branch1 : public A64TestCase { 349 public: 350 A64Test_Branch1() 351 : A64TestCase("Branch1") {} 352 353 static void add(TestApp& app) { 354 app.add(new A64Test_Branch1()); 355 } 356 357 void compile(a64::Compiler& cc) override { 358 FuncNode* func_node = cc.add_func(FuncSignature::build<void, void*, size_t>()); 359 360 a64::Gp p = cc.new_gp_ptr("p"); 361 a64::Gp count = cc.new_gp_ptr("count"); 362 a64::Gp i = cc.new_gp_ptr("i"); 363 Label L = cc.new_label(); 364 365 func_node->set_arg(0, p); 366 func_node->set_arg(1, count); 367 368 cc.mov(i, 0); 369 370 cc.bind(L); 371 cc.strb(i.w(), a64::ptr(p, i)); 372 cc.add(i, i, 1); 373 cc.cmp(i, count); 374 cc.b_ne(L); 375 376 cc.end_func(); 377 } 378 379 bool run(void* _func, String& result, String& expect) override { 380 using Func = void (*)(void* p, size_t n); 381 Func func = ptr_as_func<Func>(_func); 382 383 uint8_t array[16]; 384 func(array, 16); 385 386 expect.assign("ret={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}"); 387 388 result.assign("ret={"); 389 for (size_t i = 0; i < 16; i++) { 390 if (i) 391 result.append(", "); 392 result.append_format("%d", int(array[i])); 393 } 394 result.append("}"); 395 396 return result == expect; 397 } 398 }; 399 400 // a64::Compiler - A64Test_Invoke1 401 // =============================== 402 403 class A64Test_Invoke1 : public A64TestCase { 404 public: 405 A64Test_Invoke1() 406 : A64TestCase("Invoke1") {} 407 408 static void add(TestApp& app) { 409 app.add(new A64Test_Invoke1()); 410 } 411 412 void compile(a64::Compiler& cc) override { 413 FuncNode* func_node = cc.add_func(FuncSignature::build<uint32_t, uint32_t, uint32_t>()); 414 415 a64::Gp x = cc.new_gp32("x"); 416 a64::Gp y = cc.new_gp32("y"); 417 a64::Gp r = cc.new_gp32("r"); 418 a64::Gp fn = cc.new_gp_ptr("fn"); 419 420 func_node->set_arg(0, x); 421 func_node->set_arg(1, y); 422 423 cc.mov(fn, (uint64_t)called_fn); 424 425 InvokeNode* invoke_node; 426 cc.invoke(Out(invoke_node), fn, FuncSignature::build<uint32_t, uint32_t, uint32_t>()); 427 invoke_node->set_arg(0, x); 428 invoke_node->set_arg(1, y); 429 invoke_node->set_ret(0, r); 430 431 cc.ret(r); 432 cc.end_func(); 433 } 434 435 bool run(void* _func, String& result, String& expect) override { 436 using Func = uint32_t (*)(uint32_t, uint32_t); 437 Func func = ptr_as_func<Func>(_func); 438 439 uint32_t x = 49; 440 uint32_t y = 7; 441 442 result.assign_format("ret={%u}", func(x, y)); 443 expect.assign_format("ret={%u}", x - y); 444 445 return result == expect; 446 } 447 448 static uint32_t called_fn(uint32_t x, uint32_t y) { 449 return x - y; 450 } 451 }; 452 453 // a64::Compiler - A64Test_Invoke2 454 // =============================== 455 456 class A64Test_Invoke2 : public A64TestCase { 457 public: 458 A64Test_Invoke2() 459 : A64TestCase("Invoke2") {} 460 461 static void add(TestApp& app) { 462 app.add(new A64Test_Invoke2()); 463 } 464 465 void compile(a64::Compiler& cc) override { 466 FuncNode* func_node = cc.add_func(FuncSignature::build<double, double, double>()); 467 468 a64::Vec x = cc.new_vec_d("x"); 469 a64::Vec y = cc.new_vec_d("y"); 470 a64::Vec r = cc.new_vec_d("r"); 471 a64::Gp fn = cc.new_gp_ptr("fn"); 472 473 func_node->set_arg(0, x); 474 func_node->set_arg(1, y); 475 cc.mov(fn, (uint64_t)called_fn); 476 477 InvokeNode* invoke_node; 478 cc.invoke(Out(invoke_node), fn, FuncSignature::build<double, double, double>()); 479 invoke_node->set_arg(0, x); 480 invoke_node->set_arg(1, y); 481 invoke_node->set_ret(0, r); 482 483 cc.ret(r); 484 cc.end_func(); 485 } 486 487 bool run(void* _func, String& result, String& expect) override { 488 using Func = double (*)(double, double); 489 Func func = ptr_as_func<Func>(_func); 490 491 double x = 49; 492 double y = 7; 493 494 result.assign_format("ret={%f}", func(x, y)); 495 expect.assign_format("ret={%f}", called_fn(x, y)); 496 497 return result == expect; 498 } 499 500 static double called_fn(double x, double y) { 501 return x - y; 502 } 503 }; 504 505 // a64::Compiler - A64Test_Invoke3 506 // =============================== 507 508 class A64Test_Invoke3 : public A64TestCase { 509 public: 510 A64Test_Invoke3() 511 : A64TestCase("Invoke3") {} 512 513 static void add(TestApp& app) { 514 app.add(new A64Test_Invoke3()); 515 } 516 517 void compile(a64::Compiler& cc) override { 518 FuncNode* func_node = cc.add_func(FuncSignature::build<double, double, double>()); 519 520 a64::Vec x = cc.new_vec_d("x"); 521 a64::Vec y = cc.new_vec_d("y"); 522 a64::Vec r = cc.new_vec_d("r"); 523 a64::Gp fn = cc.new_gp_ptr("fn"); 524 525 func_node->set_arg(0, x); 526 func_node->set_arg(1, y); 527 cc.mov(fn, (uint64_t)called_fn); 528 529 InvokeNode* invoke_node; 530 cc.invoke(Out(invoke_node), fn, FuncSignature::build<double, double, double>()); 531 invoke_node->set_arg(0, y); 532 invoke_node->set_arg(1, x); 533 invoke_node->set_ret(0, r); 534 535 cc.ret(r); 536 cc.end_func(); 537 } 538 539 bool run(void* _func, String& result, String& expect) override { 540 using Func = double (*)(double, double); 541 Func func = ptr_as_func<Func>(_func); 542 543 double x = 49; 544 double y = 7; 545 546 result.assign_format("ret={%f}", func(x, y)); 547 expect.assign_format("ret={%f}", called_fn(y, x)); 548 549 return result == expect; 550 } 551 552 static double called_fn(double x, double y) { 553 return x - y; 554 } 555 }; 556 557 // a64::Compiler - A64Test_JumpTable 558 // ================================= 559 560 class A64Test_JumpTable : public A64TestCase { 561 public: 562 bool _annotated; 563 564 A64Test_JumpTable(bool annotated) 565 : A64TestCase("A64Test_JumpTable"), 566 _annotated(annotated) { 567 _name.assign_format("JumpTable {%s}", annotated ? "Annotated" : "Unknown Target"); 568 } 569 570 enum Operator { 571 kOperatorAdd = 0, 572 kOperatorSub = 1, 573 kOperatorMul = 2, 574 kOperatorDiv = 3 575 }; 576 577 static void add(TestApp& app) { 578 app.add(new A64Test_JumpTable(false)); 579 app.add(new A64Test_JumpTable(true)); 580 } 581 582 void compile(a64::Compiler& cc) override { 583 FuncNode* func_node = cc.add_func(FuncSignature::build<float, float, float, uint32_t>()); 584 585 a64::Vec a = cc.new_vec_s("a"); 586 a64::Vec b = cc.new_vec_s("b"); 587 a64::Gp op = cc.new_gp32("op"); 588 589 a64::Gp target = cc.new_gp_ptr("target"); 590 a64::Gp offset = cc.new_gp_ptr("offset"); 591 592 Label L_End = cc.new_label(); 593 594 Label L_Table = cc.new_label(); 595 Label L_Add = cc.new_label(); 596 Label L_Sub = cc.new_label(); 597 Label L_Mul = cc.new_label(); 598 Label L_Div = cc.new_label(); 599 600 func_node->set_arg(0, a); 601 func_node->set_arg(1, b); 602 func_node->set_arg(2, op); 603 604 cc.adr(target, L_Table); 605 cc.ldrsw(offset, a64::ptr(target, op, a64::sxtw(2))); 606 cc.add(target, target, offset); 607 608 // JumpAnnotation allows to annotate all possible jump targets of 609 // instructions where it cannot be deduced from operands. 610 if (_annotated) { 611 JumpAnnotation* annotation = cc.new_jump_annotation(); 612 annotation->add_label(L_Add); 613 annotation->add_label(L_Sub); 614 annotation->add_label(L_Mul); 615 annotation->add_label(L_Div); 616 cc.br(target, annotation); 617 } 618 else { 619 cc.br(target); 620 } 621 622 cc.bind(L_Add); 623 cc.fadd(a, a, b); 624 cc.b(L_End); 625 626 cc.bind(L_Sub); 627 cc.fsub(a, a, b); 628 cc.b(L_End); 629 630 cc.bind(L_Mul); 631 cc.fmul(a, a, b); 632 cc.b(L_End); 633 634 cc.bind(L_Div); 635 cc.fdiv(a, a, b); 636 637 cc.bind(L_End); 638 cc.ret(a); 639 cc.end_func(); 640 641 cc.bind(L_Table); 642 cc.embed_label_delta(L_Add, L_Table, 4); 643 cc.embed_label_delta(L_Sub, L_Table, 4); 644 cc.embed_label_delta(L_Mul, L_Table, 4); 645 cc.embed_label_delta(L_Div, L_Table, 4); 646 } 647 648 bool run(void* _func, String& result, String& expect) override { 649 using Func = float (*)(float, float, uint32_t); 650 Func func = ptr_as_func<Func>(_func); 651 652 float dst[4]; 653 float ref[4]; 654 655 dst[0] = func(33.0f, 14.0f, kOperatorAdd); 656 dst[1] = func(33.0f, 14.0f, kOperatorSub); 657 dst[2] = func(10.0f, 6.0f, kOperatorMul); 658 dst[3] = func(80.0f, 8.0f, kOperatorDiv); 659 660 ref[0] = 47.0f; 661 ref[1] = 19.0f; 662 ref[2] = 60.0f; 663 ref[3] = 10.0f; 664 665 result.assign_format("ret={%f, %f, %f, %f}", double(dst[0]), double(dst[1]), double(dst[2]), double(dst[3])); 666 expect.assign_format("ret={%f, %f, %f, %f}", double(ref[0]), double(ref[1]), double(ref[2]), double(ref[3])); 667 668 return result == expect; 669 } 670 }; 671 672 // a64::Compiler - Export 673 // ====================== 674 675 void compiler_add_a64_tests(TestApp& app) { 676 app.add_t<A64Test_GpArgs>(); 677 app.add_t<A64Test_ManyRegs>(); 678 app.add_t<A64Test_Simd1>(); 679 app.add_t<A64Test_Adr>(); 680 app.add_t<A64Test_Branch1>(); 681 app.add_t<A64Test_Invoke1>(); 682 app.add_t<A64Test_Invoke2>(); 683 app.add_t<A64Test_Invoke3>(); 684 app.add_t<A64Test_JumpTable>(); 685 } 686 687 #endif // !ASMJIT_NO_COMPILER && !ASMJIT_NO_AARCH64