1 // Copyright 2016, 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 29 #ifdef VIXL_INCLUDE_TARGET_AARCH32 30 #include "aarch32/macro-assembler-aarch32.h" 31 #endif 32 33 #ifdef VIXL_INCLUDE_TARGET_AARCH64 34 #include "aarch64/macro-assembler-aarch64.h" 35 #endif 36 37 #define TEST(name) TEST_(SCOPES_##name) 38 39 #ifdef VIXL_INCLUDE_TARGET_A32 40 #define TEST_A32(name) TEST(name) 41 #else 42 // Do not add this test to the harness. 43 #define TEST_A32(name) void Test##name() 44 #endif 45 46 #define __ masm. 47 48 namespace vixl { 49 50 // This file contains tests for code generation scopes. 51 52 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(CodeBufferCheckScope_basic_32)53 TEST(CodeBufferCheckScope_basic_32) { 54 aarch32::MacroAssembler masm; 55 56 { 57 CodeBufferCheckScope scope(&masm, aarch32::kA32InstructionSizeInBytes); 58 __ Mov(aarch32::r0, 0); 59 } 60 61 masm.FinalizeCode(); 62 } 63 #endif // VIXL_INCLUDE_TARGET_AARCH32 64 65 66 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(CodeBufferCheckScope_basic_64)67 TEST(CodeBufferCheckScope_basic_64) { 68 aarch64::MacroAssembler masm; 69 70 { 71 CodeBufferCheckScope scope(&masm, aarch64::kInstructionSize); 72 __ Mov(aarch64::x0, 0); 73 } 74 75 masm.FinalizeCode(); 76 } 77 #endif // VIXL_INCLUDE_TARGET_AARCH64 78 79 80 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(CodeBufferCheckScope_assembler_use_32)81 TEST(CodeBufferCheckScope_assembler_use_32) { 82 aarch32::MacroAssembler masm; 83 84 { 85 CodeBufferCheckScope scope(&masm, 2 * aarch32::kA32InstructionSizeInBytes); 86 __ Mov(aarch32::r0, 0); 87 __ mov(aarch32::r1, 1); 88 } 89 90 masm.FinalizeCode(); 91 } 92 #endif // VIXL_INCLUDE_TARGET_AARCH32 93 94 95 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(CodeBufferCheckScope_assembler_use_64)96 TEST(CodeBufferCheckScope_assembler_use_64) { 97 aarch64::MacroAssembler masm; 98 99 { 100 CodeBufferCheckScope scope(&masm, 2 * aarch64::kInstructionSize); 101 __ Mov(aarch64::x0, 0); 102 __ movz(aarch64::x1, 1); 103 } 104 105 masm.FinalizeCode(); 106 } 107 #endif // VIXL_INCLUDE_TARGET_AARCH64 108 109 110 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(CodeBufferCheckScope_Open_32)111 TEST(CodeBufferCheckScope_Open_32) { 112 aarch32::MacroAssembler masm; 113 114 { 115 CodeBufferCheckScope scope; 116 __ Mov(aarch32::r0, 0); 117 scope.Open(&masm, aarch32::kA32InstructionSizeInBytes); 118 __ Mov(aarch32::r1, 1); 119 } 120 121 masm.FinalizeCode(); 122 } 123 #endif // VIXL_INCLUDE_TARGET_AARCH32 124 125 126 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(CodeBufferCheckScope_Open_64)127 TEST(CodeBufferCheckScope_Open_64) { 128 aarch64::MacroAssembler masm; 129 130 { 131 CodeBufferCheckScope scope; 132 __ Mov(aarch64::x0, 0); 133 scope.Open(&masm, aarch64::kInstructionSize); 134 __ Mov(aarch64::x1, 1); 135 } 136 137 masm.FinalizeCode(); 138 } 139 #endif // VIXL_INCLUDE_TARGET_AARCH64 140 141 142 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(CodeBufferCheckScope_Close_32)143 TEST(CodeBufferCheckScope_Close_32) { 144 aarch32::MacroAssembler masm; 145 146 { 147 CodeBufferCheckScope scope(&masm, aarch32::kA32InstructionSizeInBytes); 148 __ Mov(aarch32::r0, 0); 149 scope.Close(); 150 __ Mov(aarch32::r1, 1); 151 } 152 153 masm.FinalizeCode(); 154 } 155 #endif // VIXL_INCLUDE_TARGET_AARCH32 156 157 158 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(CodeBufferCheckScope_Close_64)159 TEST(CodeBufferCheckScope_Close_64) { 160 aarch64::MacroAssembler masm; 161 162 { 163 CodeBufferCheckScope scope(&masm, aarch64::kInstructionSize); 164 __ Mov(aarch64::x0, 0); 165 scope.Close(); 166 __ Mov(aarch64::x1, 1); 167 } 168 169 masm.FinalizeCode(); 170 } 171 #endif // VIXL_INCLUDE_TARGET_AARCH64 172 173 174 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(CodeBufferCheckScope_Open_Close_32)175 TEST(CodeBufferCheckScope_Open_Close_32) { 176 aarch32::MacroAssembler masm; 177 178 { 179 CodeBufferCheckScope scope; 180 __ Mov(aarch32::r0, 0); 181 scope.Open(&masm, aarch32::kA32InstructionSizeInBytes); 182 __ Mov(aarch32::r1, 1); 183 scope.Close(); 184 __ Mov(aarch32::r2, 2); 185 } 186 187 masm.FinalizeCode(); 188 } 189 #endif // VIXL_INCLUDE_TARGET_AARCH32 190 191 192 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(CodeBufferCheckScope_Open_Close_64)193 TEST(CodeBufferCheckScope_Open_Close_64) { 194 aarch64::MacroAssembler masm; 195 196 { 197 CodeBufferCheckScope scope; 198 __ Mov(aarch64::x0, 0); 199 scope.Open(&masm, aarch64::kInstructionSize); 200 __ Mov(aarch64::x1, 1); 201 scope.Close(); 202 __ Mov(aarch64::x2, 2); 203 } 204 205 masm.FinalizeCode(); 206 } 207 #endif // VIXL_INCLUDE_TARGET_AARCH64 208 209 210 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(EmissionCheckScope_basic_32)211 TEST(EmissionCheckScope_basic_32) { 212 aarch32::MacroAssembler masm; 213 214 { 215 EmissionCheckScope scope(&masm, aarch32::kA32InstructionSizeInBytes); 216 __ Mov(aarch32::r0, 0); 217 } 218 219 masm.FinalizeCode(); 220 } 221 #endif // VIXL_INCLUDE_TARGET_AARCH32 222 223 224 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(EmissionCheckScope_basic_64)225 TEST(EmissionCheckScope_basic_64) { 226 aarch64::MacroAssembler masm; 227 228 { 229 EmissionCheckScope scope(&masm, aarch64::kInstructionSize); 230 __ Mov(aarch64::x0, 0); 231 } 232 233 masm.FinalizeCode(); 234 } 235 #endif // VIXL_INCLUDE_TARGET_AARCH64 236 237 238 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(EmissionCheckScope_Open_32)239 TEST(EmissionCheckScope_Open_32) { 240 aarch32::MacroAssembler masm; 241 242 { 243 EmissionCheckScope scope; 244 __ Mov(aarch32::r0, 0); 245 scope.Open(&masm, aarch32::kA32InstructionSizeInBytes); 246 __ Mov(aarch32::r1, 1); 247 } 248 249 masm.FinalizeCode(); 250 } 251 #endif // VIXL_INCLUDE_TARGET_AARCH32 252 253 254 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(EmissionCheckScope_Open_64)255 TEST(EmissionCheckScope_Open_64) { 256 aarch64::MacroAssembler masm; 257 258 { 259 EmissionCheckScope scope; 260 __ Mov(aarch64::x0, 0); 261 scope.Open(&masm, aarch64::kInstructionSize); 262 __ Mov(aarch64::x1, 1); 263 } 264 265 masm.FinalizeCode(); 266 } 267 #endif // VIXL_INCLUDE_TARGET_AARCH64 268 269 270 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(EmissionCheckScope_Close_32)271 TEST(EmissionCheckScope_Close_32) { 272 aarch32::MacroAssembler masm; 273 274 { 275 EmissionCheckScope scope(&masm, aarch32::kA32InstructionSizeInBytes); 276 __ Mov(aarch32::r0, 0); 277 scope.Close(); 278 __ Mov(aarch32::r1, 1); 279 } 280 281 masm.FinalizeCode(); 282 } 283 #endif // VIXL_INCLUDE_TARGET_AARCH32 284 285 286 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(EmissionCheckScope_Close_64)287 TEST(EmissionCheckScope_Close_64) { 288 aarch64::MacroAssembler masm; 289 290 { 291 EmissionCheckScope scope(&masm, aarch64::kInstructionSize); 292 __ Mov(aarch64::x0, 0); 293 scope.Close(); 294 __ Mov(aarch64::x1, 1); 295 } 296 297 masm.FinalizeCode(); 298 } 299 #endif // VIXL_INCLUDE_TARGET_AARCH64 300 301 302 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST(EmissionCheckScope_Open_Close_32)303 TEST(EmissionCheckScope_Open_Close_32) { 304 aarch32::MacroAssembler masm; 305 306 { 307 EmissionCheckScope scope; 308 __ Mov(aarch32::r0, 0); 309 scope.Open(&masm, aarch32::kA32InstructionSizeInBytes); 310 __ Mov(aarch32::r1, 1); 311 scope.Close(); 312 __ Mov(aarch32::r2, 2); 313 } 314 315 masm.FinalizeCode(); 316 } 317 #endif // VIXL_INCLUDE_TARGET_AARCH32 318 319 320 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(EmissionCheckScope_Open_Close_64)321 TEST(EmissionCheckScope_Open_Close_64) { 322 aarch64::MacroAssembler masm; 323 324 { 325 EmissionCheckScope scope; 326 __ Mov(aarch64::x0, 0); 327 scope.Open(&masm, aarch64::kInstructionSize); 328 __ Mov(aarch64::x1, 1); 329 scope.Close(); 330 __ Mov(aarch64::x2, 2); 331 } 332 333 masm.FinalizeCode(); 334 } 335 #endif // VIXL_INCLUDE_TARGET_AARCH64 336 337 338 #ifdef VIXL_INCLUDE_TARGET_AARCH32 339 340 #define ASSERT_LITERAL_POOL_SIZE_32(expected) \ 341 VIXL_CHECK((expected) == masm.GetLiteralPoolSize()) 342 TEST_A32(EmissionCheckScope_emit_pool_32)343 TEST_A32(EmissionCheckScope_emit_pool_32) { 344 aarch32::MacroAssembler masm; 345 346 // Make sure the pool is empty; 347 masm.EmitLiteralPool(aarch32::MacroAssembler::kBranchRequired); 348 ASSERT_LITERAL_POOL_SIZE_32(0); 349 350 __ Ldrd(aarch32::r0, aarch32::r1, 0x1234567890abcdef); 351 ASSERT_LITERAL_POOL_SIZE_32(8); 352 353 const int kLdrdRange = 255; 354 const int kLessThanLdrdRange = 100; 355 356 { 357 // Check that opening the scope with a reserved space well below the limit 358 // at which can generate the literal pool does not force the emission of 359 // the pool. 360 EmissionCheckScope scope(&masm, 361 kLessThanLdrdRange, 362 EmissionCheckScope::kMaximumSize); 363 ASSERT_LITERAL_POOL_SIZE_32(8); 364 } 365 366 { 367 // Check that the scope forces emission of the pool if necessary. 368 EmissionCheckScope scope(&masm, 369 kLdrdRange + 1, 370 EmissionCheckScope::kMaximumSize); 371 ASSERT_LITERAL_POOL_SIZE_32(0); 372 } 373 374 masm.FinalizeCode(); 375 } 376 #endif // VIXL_INCLUDE_TARGET_AARCH32 377 378 379 #ifdef VIXL_INCLUDE_TARGET_AARCH64 380 381 #define ASSERT_LITERAL_POOL_SIZE_64(expected) \ 382 VIXL_CHECK((expected + aarch64::kInstructionSize) == \ 383 masm.GetLiteralPoolSize()) 384 TEST(EmissionCheckScope_emit_pool_64)385 TEST(EmissionCheckScope_emit_pool_64) { 386 aarch64::MacroAssembler masm; 387 388 // Make sure the pool is empty; 389 masm.EmitLiteralPool(aarch64::LiteralPool::kBranchRequired); 390 ASSERT_LITERAL_POOL_SIZE_64(0); 391 392 __ Ldr(aarch64::x0, 0x1234567890abcdef); 393 ASSERT_LITERAL_POOL_SIZE_64(8); 394 395 { 396 // Check that opening the scope with a reserved space well below the limit 397 // at which can generate the literal pool does not force the emission of 398 // the pool. 399 EmissionCheckScope scope(&masm, 400 10 * aarch64::kInstructionSize, 401 EmissionCheckScope::kMaximumSize); 402 ASSERT_LITERAL_POOL_SIZE_64(8); 403 } 404 405 { 406 // Check that the scope forces emission of the pool if necessary. 407 EmissionCheckScope scope(&masm, 408 aarch64::kMaxLoadLiteralRange + 1, 409 EmissionCheckScope::kMaximumSize); 410 ASSERT_LITERAL_POOL_SIZE_64(0); 411 } 412 413 masm.FinalizeCode(); 414 } 415 #endif // VIXL_INCLUDE_TARGET_AARCH64 416 417 418 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST_A32(EmissionCheckScope_emit_pool_on_Open_32)419 TEST_A32(EmissionCheckScope_emit_pool_on_Open_32) { 420 aarch32::MacroAssembler masm; 421 422 // Make sure the pool is empty; 423 masm.EmitLiteralPool(aarch32::MacroAssembler::kBranchRequired); 424 ASSERT_LITERAL_POOL_SIZE_32(0); 425 426 __ Ldrd(aarch32::r0, aarch32::r1, 0x1234567890abcdef); 427 ASSERT_LITERAL_POOL_SIZE_32(8); 428 429 const int kLdrdRange = 255; 430 const int kLessThanLdrdRange = 100; 431 432 { 433 // Check that opening the scope with a reserved space well below the limit 434 // at which can generate the literal pool does not force the emission of 435 // the pool. 436 EmissionCheckScope scope(&masm, 437 kLessThanLdrdRange, 438 EmissionCheckScope::kMaximumSize); 439 ASSERT_LITERAL_POOL_SIZE_32(8); 440 } 441 442 { 443 // Check that the scope forces emission of the pool if necessary. 444 EmissionCheckScope scope(&masm, 445 kLdrdRange + 1, 446 EmissionCheckScope::kMaximumSize); 447 ASSERT_LITERAL_POOL_SIZE_32(0); 448 } 449 450 masm.FinalizeCode(); 451 } 452 #endif // VIXL_INCLUDE_TARGET_AARCH32 453 454 455 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(EmissionCheckScope_emit_pool_on_Open_64)456 TEST(EmissionCheckScope_emit_pool_on_Open_64) { 457 aarch64::MacroAssembler masm; 458 459 // Make sure the pool is empty; 460 masm.EmitLiteralPool(aarch64::LiteralPool::kBranchRequired); 461 ASSERT_LITERAL_POOL_SIZE_64(0); 462 463 __ Ldr(aarch64::x0, 0x1234567890abcdef); 464 ASSERT_LITERAL_POOL_SIZE_64(8); 465 466 { 467 // Check that opening the scope with a reserved space well below the limit 468 // at which can generate the literal pool does not force the emission of 469 // the pool. 470 EmissionCheckScope scope; 471 scope.Open(&masm, 472 10 * aarch64::kInstructionSize, 473 EmissionCheckScope::kMaximumSize); 474 ASSERT_LITERAL_POOL_SIZE_64(8); 475 } 476 477 { 478 // Check that the scope forces emission of the pool if necessary. 479 EmissionCheckScope scope; 480 scope.Open(&masm, 481 aarch64::kMaxLoadLiteralRange + 1, 482 EmissionCheckScope::kMaximumSize); 483 ASSERT_LITERAL_POOL_SIZE_64(0); 484 } 485 486 masm.FinalizeCode(); 487 } 488 #endif // VIXL_INCLUDE_TARGET_AARCH64 489 490 491 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST_A32(ExactAssemblyScope_basic_32)492 TEST_A32(ExactAssemblyScope_basic_32) { 493 aarch32::MacroAssembler masm; 494 495 { 496 ExactAssemblyScope scope(&masm, aarch32::kA32InstructionSizeInBytes); 497 __ nop(); 498 } 499 500 masm.FinalizeCode(); 501 } 502 #endif // VIXL_INCLUDE_TARGET_AARCH32 503 504 505 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(ExactAssemblyScope_basic_64)506 TEST(ExactAssemblyScope_basic_64) { 507 aarch64::MacroAssembler masm; 508 509 { 510 ExactAssemblyScope scope(&masm, aarch64::kInstructionSize); 511 __ nop(); 512 } 513 514 masm.FinalizeCode(); 515 } 516 #endif // VIXL_INCLUDE_TARGET_AARCH64 517 518 519 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST_A32(ExactAssemblyScope_Open_32)520 TEST_A32(ExactAssemblyScope_Open_32) { 521 aarch32::MacroAssembler masm; 522 523 { 524 ExactAssemblyScope scope; 525 __ Mov(aarch32::r0, 0); 526 scope.Open(&masm, aarch32::kA32InstructionSizeInBytes); 527 __ mov(aarch32::r1, 1); 528 } 529 530 masm.FinalizeCode(); 531 } 532 #endif // VIXL_INCLUDE_TARGET_AARCH32 533 534 535 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(ExactAssemblyScope_Open_64)536 TEST(ExactAssemblyScope_Open_64) { 537 aarch64::MacroAssembler masm; 538 539 { 540 ExactAssemblyScope scope; 541 __ Mov(aarch64::x0, 0); 542 scope.Open(&masm, aarch64::kInstructionSize); 543 __ movz(aarch64::x1, 1); 544 } 545 546 masm.FinalizeCode(); 547 } 548 #endif // VIXL_INCLUDE_TARGET_AARCH64 549 550 551 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST_A32(ExactAssemblyScope_Close_32)552 TEST_A32(ExactAssemblyScope_Close_32) { 553 aarch32::MacroAssembler masm; 554 555 { 556 ExactAssemblyScope scope(&masm, aarch32::kA32InstructionSizeInBytes); 557 __ mov(aarch32::r0, 0); 558 scope.Close(); 559 __ Mov(aarch32::r1, 1); 560 } 561 562 masm.FinalizeCode(); 563 } 564 #endif // VIXL_INCLUDE_TARGET_AARCH32 565 566 567 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(ExactAssemblyScope_Close_64)568 TEST(ExactAssemblyScope_Close_64) { 569 aarch64::MacroAssembler masm; 570 571 { 572 ExactAssemblyScope scope(&masm, aarch64::kInstructionSize); 573 __ movz(aarch64::x0, 0); 574 scope.Close(); 575 __ Mov(aarch64::x1, 1); 576 } 577 578 masm.FinalizeCode(); 579 } 580 #endif // VIXL_INCLUDE_TARGET_AARCH64 581 582 583 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST_A32(ExactAssemblyScope_Open_Close_32)584 TEST_A32(ExactAssemblyScope_Open_Close_32) { 585 aarch32::MacroAssembler masm; 586 587 { 588 ExactAssemblyScope scope; 589 __ Mov(aarch32::r0, 0); 590 scope.Open(&masm, aarch32::kA32InstructionSizeInBytes); 591 __ mov(aarch32::r1, 1); 592 scope.Close(); 593 __ Mov(aarch32::r2, 2); 594 } 595 596 masm.FinalizeCode(); 597 } 598 #endif // VIXL_INCLUDE_TARGET_AARCH32 599 600 601 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(ExactAssemblyScope_Open_Close_64)602 TEST(ExactAssemblyScope_Open_Close_64) { 603 aarch64::MacroAssembler masm; 604 605 { 606 ExactAssemblyScope scope; 607 __ Mov(aarch64::x0, 0); 608 scope.Open(&masm, aarch64::kInstructionSize); 609 __ movz(aarch64::x1, 1); 610 scope.Close(); 611 __ Mov(aarch64::x2, 2); 612 } 613 614 masm.FinalizeCode(); 615 } 616 #endif // VIXL_INCLUDE_TARGET_AARCH64 617 618 619 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST_A32(ExactAssemblyScope_32)620 TEST_A32(ExactAssemblyScope_32) { 621 aarch32::MacroAssembler masm; 622 623 // By default macro instructions are allowed. 624 VIXL_CHECK(!masm.ArePoolsBlocked()); 625 VIXL_ASSERT(!masm.AllowAssembler()); 626 VIXL_ASSERT(masm.AllowMacroInstructions()); 627 { 628 ExactAssemblyScope scope1(&masm, 2 * aarch32::kA32InstructionSizeInBytes); 629 VIXL_CHECK(masm.ArePoolsBlocked()); 630 VIXL_ASSERT(masm.AllowAssembler()); 631 VIXL_ASSERT(!masm.AllowMacroInstructions()); 632 __ nop(); 633 { 634 ExactAssemblyScope scope2(&masm, 1 * aarch32::kA32InstructionSizeInBytes); 635 VIXL_CHECK(masm.ArePoolsBlocked()); 636 VIXL_ASSERT(masm.AllowAssembler()); 637 VIXL_ASSERT(!masm.AllowMacroInstructions()); 638 __ nop(); 639 } 640 VIXL_CHECK(masm.ArePoolsBlocked()); 641 VIXL_ASSERT(masm.AllowAssembler()); 642 VIXL_ASSERT(!masm.AllowMacroInstructions()); 643 } 644 VIXL_CHECK(!masm.ArePoolsBlocked()); 645 VIXL_ASSERT(!masm.AllowAssembler()); 646 VIXL_ASSERT(masm.AllowMacroInstructions()); 647 648 { 649 ExactAssemblyScope scope(&masm, 2 * aarch32::kA32InstructionSizeInBytes); 650 __ add(aarch32::r0, aarch32::r0, aarch32::r0); 651 __ sub(aarch32::r0, aarch32::r0, aarch32::r0); 652 } 653 654 masm.FinalizeCode(); 655 } 656 #endif // VIXL_INCLUDE_TARGET_AARCH32 657 658 659 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(ExactAssemblyScope_64)660 TEST(ExactAssemblyScope_64) { 661 aarch64::MacroAssembler masm; 662 663 // By default macro instructions are allowed. 664 VIXL_CHECK(!masm.ArePoolsBlocked()); 665 VIXL_ASSERT(!masm.AllowAssembler()); 666 VIXL_ASSERT(masm.AllowMacroInstructions()); 667 { 668 ExactAssemblyScope scope1(&masm, 2 * aarch64::kInstructionSize); 669 VIXL_CHECK(masm.ArePoolsBlocked()); 670 VIXL_ASSERT(masm.AllowAssembler()); 671 VIXL_ASSERT(!masm.AllowMacroInstructions()); 672 __ nop(); 673 { 674 ExactAssemblyScope scope2(&masm, 1 * aarch64::kInstructionSize); 675 VIXL_CHECK(masm.ArePoolsBlocked()); 676 VIXL_ASSERT(masm.AllowAssembler()); 677 VIXL_ASSERT(!masm.AllowMacroInstructions()); 678 __ nop(); 679 } 680 VIXL_CHECK(masm.ArePoolsBlocked()); 681 VIXL_ASSERT(masm.AllowAssembler()); 682 VIXL_ASSERT(!masm.AllowMacroInstructions()); 683 } 684 VIXL_CHECK(!masm.ArePoolsBlocked()); 685 VIXL_ASSERT(!masm.AllowAssembler()); 686 VIXL_ASSERT(masm.AllowMacroInstructions()); 687 688 { 689 ExactAssemblyScope scope(&masm, 2 * aarch64::kInstructionSize); 690 __ add(aarch64::x0, aarch64::x0, aarch64::x0); 691 __ sub(aarch64::x0, aarch64::x0, aarch64::x0); 692 } 693 694 masm.FinalizeCode(); 695 } 696 #endif // VIXL_INCLUDE_TARGET_AARCH64 697 698 699 #ifdef VIXL_INCLUDE_TARGET_AARCH32 TEST_A32(ExactAssemblyScope_scope_with_pools_32)700 TEST_A32(ExactAssemblyScope_scope_with_pools_32) { 701 aarch32::MacroAssembler masm; 702 703 ASSERT_LITERAL_POOL_SIZE_32(0); 704 705 __ Ldrd(aarch32::r0, aarch32::r1, 0x1234567890abcdef); 706 707 ASSERT_LITERAL_POOL_SIZE_32(8); 708 709 const int32_t kLdrdRange = 255; 710 const int32_t n_nops = (kLdrdRange / aarch32::kA32InstructionSizeInBytes) + 1; 711 { 712 // The literal pool should be generated when opening this scope, as 713 // otherwise the `Ldrd` will run out of range when we generate the `nop` 714 // instructions below. 715 ExactAssemblyScope scope(&masm, 716 n_nops * aarch32::kA32InstructionSizeInBytes); 717 718 // Although it must be, we do not check that the literal pool size is zero 719 // here, because we want this regression test to fail while or after we 720 // generate the nops. 721 722 for (int32_t i = 0; i < n_nops; ++i) { 723 __ nop(); 724 } 725 } 726 727 ASSERT_LITERAL_POOL_SIZE_32(0); 728 729 masm.FinalizeCode(); 730 } 731 #endif // VIXL_INCLUDE_TARGET_AARCH32 732 733 734 #ifdef VIXL_INCLUDE_TARGET_AARCH64 TEST(ExactAssemblyScope_scope_with_pools_64)735 TEST(ExactAssemblyScope_scope_with_pools_64) { 736 aarch64::MacroAssembler masm; 737 738 ASSERT_LITERAL_POOL_SIZE_64(0); 739 740 __ Ldr(aarch64::x10, 0x1234567890abcdef); 741 742 ASSERT_LITERAL_POOL_SIZE_64(8); 743 744 const int64_t n_nops = 745 aarch64::kMaxLoadLiteralRange / aarch64::kInstructionSize; 746 { 747 // The literal pool should be generated when opening this scope, as 748 // otherwise the `Ldr` will run out of range when we generate the `nop` 749 // instructions below. 750 ExactAssemblyScope scope(&masm, n_nops * aarch64::kInstructionSize); 751 752 // Although it must be, we do not check that the literal pool size is zero 753 // here, because we want this regression test to fail while or after we 754 // generate the nops. 755 756 for (int64_t i = 0; i < n_nops; ++i) { 757 __ nop(); 758 } 759 } 760 761 ASSERT_LITERAL_POOL_SIZE_64(0); 762 763 masm.FinalizeCode(); 764 } 765 #endif // VIXL_INCLUDE_TARGET_AARCH64 766 767 768 } // namespace vixl 769