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 <sstream> 28 #include <string> 29 #include <list> 30 31 #include "test-runner.h" 32 #include "test-utils.h" 33 34 #include "aarch32/macro-assembler-aarch32.h" 35 #include "aarch32/disasm-aarch32.h" 36 37 #ifdef VIXL_NEGATIVE_TESTING 38 #include <stdexcept> 39 #endif 40 41 namespace vixl { 42 namespace aarch32 { 43 44 #define __ masm. 45 #define TEST(name) TEST_(AARCH32_DISASM_##name) 46 47 #ifdef VIXL_INCLUDE_TARGET_T32 48 #define TEST_T32(name) TEST_(AARCH32_DISASM_##name) 49 #else 50 #define TEST_T32(name) void Test##name() 51 #endif 52 53 #ifdef VIXL_INCLUDE_TARGET_A32 54 #define TEST_A32(name) TEST_(AARCH32_DISASM_##name) 55 #else 56 #define TEST_A32(name) void Test##name() 57 #endif 58 59 #define BUF_SIZE (4096) 60 61 #define SETUP() MacroAssembler masm(BUF_SIZE); 62 63 #define CLEANUP() 64 65 #ifdef VIXL_NEGATIVE_TESTING 66 #define START_COMPARE() \ 67 { \ 68 try { \ 69 int32_t start = masm.GetCursorOffset(); 70 71 #define END_COMPARE_CHECK_SIZE(EXP, SIZE) \ 72 int32_t end = masm.GetCursorOffset(); \ 73 masm.FinalizeCode(); \ 74 std::ostringstream ss; \ 75 TestDisassembler disassembler(ss, 0); \ 76 if (masm.IsUsingT32()) { \ 77 disassembler.DisassembleT32(*masm.GetBuffer(), start, end); \ 78 } else { \ 79 disassembler.DisassembleA32(*masm.GetBuffer(), start, end); \ 80 } \ 81 masm.GetBuffer()->Reset(); \ 82 if (Test::disassemble()) { \ 83 printf("----\n"); \ 84 printf("%s", ss.str().c_str()); \ 85 } \ 86 if (std::string(EXP) != ss.str()) { \ 87 printf("\n%s:%d:%s\nFound:\n%sExpected:\n%s", \ 88 __FILE__, \ 89 __LINE__, \ 90 masm.IsUsingT32() ? "T32" : "A32", \ 91 ss.str().c_str(), \ 92 EXP); \ 93 abort(); \ 94 } \ 95 if ((SIZE) != -1 && ((end - start) != (SIZE))) { \ 96 printf("\nExpected %d bits, found %d bits\n", \ 97 8 * (SIZE), \ 98 8 * (end - start)); \ 99 abort(); \ 100 } \ 101 } \ 102 catch (std::runtime_error e) { \ 103 const char* msg = e.what(); \ 104 printf("\n%s:%d:%s\nFound:\n%sExpected:\n%s", \ 105 __FILE__, \ 106 __LINE__, \ 107 masm.IsUsingT32() ? "T32" : "A32", \ 108 msg, \ 109 EXP); \ 110 abort(); \ 111 } \ 112 } 113 #else 114 #define START_COMPARE() \ 115 { \ 116 int32_t start = masm.GetCursorOffset(); 117 118 #define END_COMPARE_CHECK_SIZE(EXP, SIZE) \ 119 int32_t end = masm.GetCursorOffset(); \ 120 masm.FinalizeCode(); \ 121 std::ostringstream ss; \ 122 TestDisassembler disassembler(ss, 0); \ 123 if (masm.IsUsingT32()) { \ 124 disassembler.DisassembleT32(*masm.GetBuffer(), start, end); \ 125 } else { \ 126 disassembler.DisassembleA32(*masm.GetBuffer(), start, end); \ 127 } \ 128 masm.GetBuffer()->Reset(); \ 129 if (Test::disassemble()) { \ 130 printf("----\n"); \ 131 printf("%s", ss.str().c_str()); \ 132 } \ 133 if (std::string(EXP) != ss.str()) { \ 134 printf("\n%s:%d:%s\nFound:\n%sExpected:\n%s", \ 135 __FILE__, \ 136 __LINE__, \ 137 masm.IsUsingT32() ? "T32" : "A32", \ 138 ss.str().c_str(), \ 139 EXP); \ 140 abort(); \ 141 } \ 142 if ((SIZE) != -1 && ((end - start) != (SIZE))) { \ 143 printf("\nExpected %d bits, found %d bits\n", \ 144 8 * (SIZE), \ 145 8 * (end - start)); \ 146 abort(); \ 147 } \ 148 } 149 #endif 150 151 #define END_COMPARE(EXP) END_COMPARE_CHECK_SIZE(EXP, -1) 152 153 #ifdef VIXL_INCLUDE_TARGET_A32 154 #define COMPARE_A32(ASM, EXP) \ 155 masm.UseA32(); \ 156 START_COMPARE() \ 157 masm.ASM; \ 158 END_COMPARE(EXP) 159 #else 160 #define COMPARE_A32(ASM, EXP) 161 #endif 162 163 #ifdef VIXL_INCLUDE_TARGET_T32 164 #define COMPARE_T32(ASM, EXP) \ 165 masm.UseT32(); \ 166 START_COMPARE() \ 167 masm.ASM; \ 168 END_COMPARE(EXP) 169 #else 170 #define COMPARE_T32(ASM, EXP) 171 #endif 172 173 #ifdef VIXL_INCLUDE_TARGET_T32 174 #define COMPARE_T32_CHECK_SIZE(ASM, EXP, SIZE) \ 175 masm.UseT32(); \ 176 START_COMPARE() \ 177 masm.ASM; \ 178 END_COMPARE_CHECK_SIZE(EXP, SIZE) 179 #else 180 #define COMPARE_T32_CHECK_SIZE(ASM, EXP, SIZE) 181 #endif 182 183 #define COMPARE_BOTH(ASM, EXP) \ 184 COMPARE_A32(ASM, EXP) \ 185 COMPARE_T32(ASM, EXP) 186 187 #ifdef VIXL_NEGATIVE_TESTING 188 #define NEGATIVE_TEST(ASM, EXP, TEMPORARILY_ACCEPTED) \ 189 { \ 190 try { \ 191 int32_t start = masm.GetCursorOffset(); \ 192 ASM int32_t end = masm.GetCursorOffset(); \ 193 masm.FinalizeCode(); \ 194 if (!TEMPORARILY_ACCEPTED) { \ 195 std::ostringstream ss; \ 196 PrintDisassembler disassembler(ss, 0); \ 197 if (masm.IsUsingT32()) { \ 198 disassembler.DisassembleT32Buffer(masm.GetBuffer() \ 199 ->GetOffsetAddress<uint16_t*>( \ 200 start), \ 201 end); \ 202 } else { \ 203 disassembler.DisassembleA32Buffer(masm.GetBuffer() \ 204 ->GetOffsetAddress<uint32_t*>( \ 205 start), \ 206 end); \ 207 } \ 208 printf("\n%s:%d:%s\nNo exception raised.\n", \ 209 __FILE__, \ 210 __LINE__, \ 211 masm.IsUsingT32() ? "T32" : "A32"); \ 212 printf("Found:\n%sExpected:\n%s", ss.str().c_str(), EXP); \ 213 abort(); \ 214 } \ 215 } catch (std::runtime_error e) { \ 216 const char* msg = e.what(); \ 217 size_t exp_len = strlen(EXP); \ 218 if (TEMPORARILY_ACCEPTED) { \ 219 printf( \ 220 "\nNegative MacroAssembler test that was temporarily " \ 221 "assembling a deprecated or unpredictable instruction is now " \ 222 "correctly raising an exception. Please update the " \ 223 "test to reflect this.\n"); \ 224 printf("at: %s:%d:%s\n", \ 225 __FILE__, \ 226 __LINE__, \ 227 masm.IsUsingT32() ? "T32" : "A32"); \ 228 abort(); \ 229 } else if (std::strncmp(EXP, msg, exp_len) != 0) { \ 230 printf("\n%s:%d:%s\nFound:\n%sExpected:\n%s...", \ 231 __FILE__, \ 232 __LINE__, \ 233 masm.IsUsingT32() ? "T32" : "A32", \ 234 msg, \ 235 EXP); \ 236 abort(); \ 237 } \ 238 } \ 239 } 240 241 #ifdef VIXL_INCLUDE_TARGET_A32 242 #define MUST_FAIL_TEST_A32(ASM, EXP) \ 243 masm.UseA32(); \ 244 NEGATIVE_TEST({ masm.ASM; }, EXP, false) \ 245 masm.GetBuffer()->Reset(); 246 #else 247 #define MUST_FAIL_TEST_A32(ASM, EXP) 248 #endif 249 250 #ifdef VIXL_INCLUDE_TARGET_T32 251 #define MUST_FAIL_TEST_T32(ASM, EXP) \ 252 masm.UseT32(); \ 253 NEGATIVE_TEST({ masm.ASM; }, EXP, false) \ 254 masm.GetBuffer()->Reset(); 255 #else 256 #define MUST_FAIL_TEST_T32(ASM, EXP) 257 #endif 258 259 #define MUST_FAIL_TEST_BOTH(ASM, EXP) \ 260 MUST_FAIL_TEST_A32(ASM, EXP) \ 261 MUST_FAIL_TEST_T32(ASM, EXP) 262 263 #ifdef VIXL_INCLUDE_TARGET_A32 264 #define MUST_FAIL_TEST_A32_BLOCK(ASM, EXP) \ 265 masm.UseA32(); \ 266 NEGATIVE_TEST(ASM, EXP, false) \ 267 masm.GetBuffer()->Reset(); 268 #else 269 #define MUST_FAIL_TEST_A32_BLOCK(ASM, EXP) 270 #endif 271 272 #ifdef VIXL_INCLUDE_TARGET_T32 273 #define MUST_FAIL_TEST_T32_BLOCK(ASM, EXP) \ 274 masm.UseT32(); \ 275 NEGATIVE_TEST(ASM, EXP, false) \ 276 masm.GetBuffer()->Reset(); 277 #else 278 #define MUST_FAIL_TEST_T32_BLOCK(ASM, EXP) 279 #endif 280 281 #define MUST_FAIL_TEST_BOTH_BLOCK(ASM, EXP) \ 282 MUST_FAIL_TEST_A32_BLOCK(ASM, EXP) \ 283 MUST_FAIL_TEST_T32_BLOCK(ASM, EXP) 284 #else 285 // Skip negative tests. 286 #define MUST_FAIL_TEST_A32(ASM, EXP) \ 287 printf( \ 288 "Skipping negative tests. To enable them, build with " \ 289 "'negative_testing=on'.\n"); 290 #define MUST_FAIL_TEST_T32(ASM, EXP) \ 291 printf( \ 292 "Skipping negative tests. To enable them, build with " \ 293 "'negative_testing=on'.\n"); 294 #define MUST_FAIL_TEST_BOTH(ASM, EXP) \ 295 printf( \ 296 "Skipping negative tests. To enable them, build with " \ 297 "'negative_testing=on'.\n"); 298 #define MUST_FAIL_TEST_A32_BLOCK(ASM, EXP) \ 299 printf( \ 300 "Skipping negative tests. To enable them, build with " \ 301 "'negative_testing=on'.\n"); 302 #define MUST_FAIL_TEST_T32_BLOCK(ASM, EXP) \ 303 printf( \ 304 "Skipping negative tests. To enable them, build with " \ 305 "'negative_testing=on'.\n"); 306 #define MUST_FAIL_TEST_BOTH_BLOCK(ASM, EXP) \ 307 printf( \ 308 "Skipping negative tests. To enable them, build with " \ 309 "'negative_testing=on'.\n"); 310 #endif 311 312 #ifdef VIXL_NEGATIVE_TESTING 313 #ifdef VIXL_INCLUDE_TARGET_A32 314 #define SHOULD_FAIL_TEST_A32(ASM) \ 315 masm.UseA32(); \ 316 NEGATIVE_TEST({ masm.ASM; }, "", true) \ 317 masm.GetBuffer()->Reset(); 318 #else 319 #define SHOULD_FAIL_TEST_A32(ASM) 320 #endif 321 322 #ifdef VIXL_INCLUDE_TARGET_T32 323 #define SHOULD_FAIL_TEST_T32(ASM) \ 324 masm.UseT32(); \ 325 NEGATIVE_TEST({ masm.ASM; }, "", true) \ 326 masm.GetBuffer()->Reset(); 327 #else 328 #define SHOULD_FAIL_TEST_T32(ASM) 329 #endif 330 331 #define SHOULD_FAIL_TEST_BOTH(ASM) \ 332 SHOULD_FAIL_TEST_A32(ASM) \ 333 SHOULD_FAIL_TEST_T32(ASM) 334 #else 335 #define SHOULD_FAIL_TEST_A32(ASM) \ 336 printf( \ 337 "Skipping negative tests. To enable them, build with " \ 338 "'negative_testing=on'.\n"); 339 #define SHOULD_FAIL_TEST_T32(ASM) \ 340 printf( \ 341 "Skipping negative tests. To enable them, build with " \ 342 "'negative_testing=on'.\n"); 343 #define SHOULD_FAIL_TEST_BOTH(ASM) \ 344 printf( \ 345 "Skipping negative tests. To enable them, build with " \ 346 "'negative_testing=on'.\n"); 347 #endif 348 349 class TestDisassembler : public PrintDisassembler { 350 public: 351 TestDisassembler(std::ostream& os, uint32_t pc) // NOLINT(runtime/references) 352 : PrintDisassembler(os, pc) {} 353 354 virtual void PrintCodeAddress(uint32_t code_address) VIXL_OVERRIDE { 355 USE(code_address); 356 } 357 358 virtual void PrintOpcode16(uint32_t opcode) VIXL_OVERRIDE { USE(opcode); } 359 360 virtual void PrintOpcode32(uint32_t opcode) VIXL_OVERRIDE { USE(opcode); } 361 362 void DisassembleA32(const CodeBuffer& buffer, 363 ptrdiff_t start, 364 ptrdiff_t end) { 365 DisassembleA32Buffer(buffer.GetOffsetAddress<const uint32_t*>(start), 366 end - start); 367 } 368 369 void DisassembleT32(const CodeBuffer& buffer, 370 ptrdiff_t start, 371 ptrdiff_t end) { 372 DisassembleT32Buffer(buffer.GetOffsetAddress<const uint16_t*>(start), 373 end - start); 374 } 375 }; 376 377 378 TEST_T32(t32_disassembler_limit1) { 379 SETUP(); 380 381 masm.UseT32(); 382 START_COMPARE() 383 masm.Add(r9, r10, r11); 384 masm.GetBuffer()->Emit16(kLowestT32_32Opcode >> 16); 385 END_COMPARE( 386 "add r9, r10, r11\n" 387 "?\n"); 388 389 CLEANUP(); 390 } 391 392 393 TEST_T32(t32_disassembler_limit2) { 394 SETUP(); 395 396 masm.UseT32(); 397 START_COMPARE() 398 masm.Add(r9, r10, r11); 399 masm.Add(r0, r0, r1); 400 END_COMPARE( 401 "add r9, r10, r11\n" 402 "add r0, r1\n"); 403 404 CLEANUP(); 405 } 406 407 408 TEST(macro_assembler_orn) { 409 SETUP(); 410 411 // - Identities. 412 413 COMPARE_BOTH(Orn(r0, r1, 0), "mvn r0, #0\n"); 414 COMPARE_BOTH(Orn(r0, r0, 0xffffffff), ""); 415 416 // - Immediate form. This form does not need macro-assembler support 417 // for T32. 418 419 // Use r0 as the temporary register. 420 COMPARE_A32(Orn(r0, r1, 1), 421 "mvn r0, #1\n" 422 "orr r0, r1, r0\n"); 423 // Use ip as the temporary register. 424 COMPARE_A32(Orns(r0, r0, 1), 425 "mvn ip, #1\n" 426 "orrs r0, ip\n"); 427 428 // - Too large immediate form. 429 COMPARE_BOTH(Orn(r0, r1, 0x00ffffff), "orr r0, r1, #0xff000000\n"); 430 COMPARE_BOTH(Orn(r0, r1, 0xff00ffff), "orr r0, r1, #0xff0000\n"); 431 COMPARE_BOTH(Orns(r0, r1, 0x00ffffff), "orrs r0, r1, #0xff000000\n"); 432 433 COMPARE_A32(Orns(r0, r1, 0xabcd2345), 434 "mov ip, #9029\n" 435 "movt ip, #43981\n" 436 "mvn r0, ip\n" 437 "orrs r0, r1, r0\n"); 438 COMPARE_T32(Orn(r0, r1, 0xabcd2345), 439 "mov r0, #9029\n" 440 "movt r0, #43981\n" 441 "orn r0, r1, r0\n"); 442 443 // - Plain register form. This form does not need macro-assembler 444 // support for T32. 445 446 // Use r0 as the temporary register. 447 COMPARE_A32(Orn(r0, r1, r2), 448 "mvn r0, r2\n" 449 "orr r0, r1, r0\n"); 450 // Use ip as the temporary register. 451 COMPARE_A32(Orn(r0, r0, r1), 452 "mvn ip, r1\n" 453 "orr r0, ip\n"); 454 // Use r0 as the temporary register. 455 COMPARE_A32(Orn(r0, r1, r0), 456 "mvn r0, r0\n" 457 "orr r0, r1, r0\n"); 458 // Use ip as the temporary register. 459 COMPARE_A32(Orn(r0, r0, r0), 460 "mvn ip, r0\n" 461 "orr r0, ip\n"); 462 463 // - Shifted register form. This form does not need macro-assembler 464 // support for T32. 465 466 // Use r0 as the temporary register. 467 COMPARE_A32(Orn(r0, r1, Operand(r2, LSL, 1)), 468 "mvn r0, r2, lsl #1\n" 469 "orr r0, r1, r0\n"); 470 // Use ip as the temporary register. 471 COMPARE_A32(Orns(r0, r0, Operand(r2, LSR, 2)), 472 "mvn ip, r2, lsr #2\n" 473 "orrs r0, ip\n"); 474 475 // - Register shifted register form. 476 477 // Use r0 as the temporary register. 478 COMPARE_A32(Orn(r0, r1, Operand(r2, LSL, r3)), 479 "mvn r0, r2, lsl r3\n" 480 "orr r0, r1, r0\n"); 481 COMPARE_T32(Orn(r0, r1, Operand(r2, LSL, r3)), 482 "lsl r0, r2, r3\n" 483 "orn r0, r1, r0\n"); 484 // Use ip as the temporary register. 485 COMPARE_A32(Orns(r0, r0, Operand(r2, LSR, r3)), 486 "mvn ip, r2, lsr r3\n" 487 "orrs r0, ip\n"); 488 COMPARE_T32(Orns(r0, r0, Operand(r2, LSR, r3)), 489 "lsr ip, r2, r3\n" 490 "orns r0, ip\n"); 491 // Use ip as the temporary register. 492 COMPARE_A32(Orn(r0, r0, Operand(r0, ASR, r3)), 493 "mvn ip, r0, asr r3\n" 494 "orr r0, ip\n"); 495 COMPARE_T32(Orn(r0, r0, Operand(r0, ASR, r3)), 496 "asr ip, r0, r3\n" 497 "orn r0, ip\n"); 498 CLEANUP(); 499 } 500 501 502 TEST(macro_assembler_t32_rsc) { 503 SETUP(); 504 505 // - Immediate form. We can always re-use `rn`. 506 507 // No need for temporay registers. 508 COMPARE_T32(Rsc(r0, r1, 1), 509 "mvn r0, r1\n" 510 "adc r0, #1\n"); 511 // No need for temporay registers. 512 COMPARE_T32(Rscs(r0, r0, 2), 513 "mvn r0, r0\n" 514 "adcs r0, #2\n"); 515 516 // - Too large immediate form. 517 518 // TODO: optimize this. 519 COMPARE_A32(Rsc(r0, r1, 0x00ffffff), 520 "mvn r0, #4278190080\n" 521 "rsc r0, r1, r0\n"); 522 COMPARE_T32(Rscs(r0, r1, 0x00ffffff), 523 "mvn r0, r1\n" 524 "mvn ip, #4278190080\n" 525 "adcs r0, ip\n"); 526 COMPARE_A32(Rsc(r0, r0, 0x00ffffff), 527 "mvn ip, #4278190080\n" 528 "rsc r0, ip\n"); 529 COMPARE_T32(Rscs(r0, r0, 0x00ffffff), 530 "mvn r0, r0\n" 531 "mvn ip, #4278190080\n" 532 "adcs r0, ip\n"); 533 534 COMPARE_A32(Rsc(r0, r1, 0xabcd2345), 535 "mov r0, #9029\n" 536 "movt r0, #43981\n" 537 "rsc r0, r1, r0\n"); 538 COMPARE_T32(Rscs(r0, r1, 0xabcd2345), 539 "mvn r0, r1\n" 540 "mov ip, #56506\n" 541 "movt ip, #21554\n" 542 "sbcs r0, ip\n"); 543 COMPARE_A32(Rsc(r0, r0, 0xabcd2345), 544 "mov ip, #9029\n" 545 "movt ip, #43981\n" 546 "rsc r0, ip\n"); 547 COMPARE_T32(Rscs(r0, r0, 0xabcd2345), 548 "mvn r0, r0\n" 549 "mov ip, #56506\n" 550 "movt ip, #21554\n" 551 "sbcs r0, ip\n"); 552 553 // - Plain register form. 554 555 // No need for temporary registers. 556 COMPARE_T32(Rscs(r0, r1, r2), 557 "mvn r0, r1\n" 558 "adcs r0, r2\n"); 559 // Use r0 as the temporary register. 560 COMPARE_T32(Rscs(r0, r1, r1), 561 "mvn r0, r1\n" 562 "adcs r0, r1\n"); 563 // Use ip as the temporary register. 564 COMPARE_T32(Rscs(r0, r0, r0), 565 "mvn ip, r0\n" 566 "adcs r0, ip, r0\n"); 567 568 // - Shifted register form. 569 570 // No need for temporay registers. 571 COMPARE_T32(Rsc(r0, r1, Operand(r2, LSL, 1)), 572 "mvn r0, r1\n" 573 "adc r0, r2, lsl #1\n"); 574 // Use ip as the temporary register. 575 COMPARE_T32(Rscs(r0, r1, Operand(r0, LSR, 2)), 576 "mvn ip, r1\n" 577 "adcs r0, ip, r0, lsr #2\n"); 578 // Use r0 as the temporary register. 579 COMPARE_T32(Rsc(r0, r1, Operand(r1, ASR, 3)), 580 "mvn r0, r1\n" 581 "adc r0, r1, asr #3\n"); 582 // Use ip as the temporary register. 583 COMPARE_T32(Rscs(r0, r0, Operand(r0, ROR, 4)), 584 "mvn ip, r0\n" 585 "adcs r0, ip, r0, ror #4\n"); 586 587 // - Register shifted register form. The macro-assembler handles this form in 588 // two steps. First, a shift instruction is generated from the operand. And 589 // finally the operation is reduced to its plain register form. 590 591 COMPARE_T32(Rsc(r0, r1, Operand(r2, LSL, r3)), 592 "lsl r0, r2, r3\n" 593 "mvn ip, r1\n" 594 "adc r0, ip, r0\n"); 595 // Use r0 and ip as the temporary register. 596 COMPARE_T32(Rscs(r0, r1, Operand(r1, LSR, r3)), 597 "lsr r0, r1, r3\n" 598 "mvn ip, r1\n" 599 "adcs r0, ip, r0\n"); 600 // Use ip and r0 as the temporary register. 601 COMPARE_T32(Rsc(r0, r0, Operand(r2, ASR, r3)), 602 "asr ip, r2, r3\n" 603 "mvn r0, r0\n" 604 "adc r0, ip\n"); 605 // Use ip and r0 as the temporary register. 606 COMPARE_T32(Rscs(r0, r0, Operand(r0, ROR, r3)), 607 "ror ip, r0, r3\n" 608 "mvn r0, r0\n" 609 "adcs r0, ip\n"); 610 // Use ip and r0 as the temporary register. 611 COMPARE_T32(Rsc(r0, r0, Operand(r0, LSL, r0)), 612 "lsl ip, r0, r0\n" 613 "mvn r0, r0\n" 614 "adc r0, ip\n"); 615 616 CLEANUP(); 617 } 618 619 620 TEST(macro_assembler_t32_register_shift_register) { 621 SETUP(); 622 623 COMPARE_T32(Adc(r0, r1, Operand(r2, LSL, r3)), 624 "lsl r0, r2, r3\n" 625 "adc r0, r1, r0\n"); 626 COMPARE_T32(Adcs(r0, r0, Operand(r2, LSR, r3)), 627 "lsr ip, r2, r3\n" 628 "adcs r0, ip\n"); 629 COMPARE_T32(Add(r0, r0, Operand(r0, ASR, r3)), 630 "asr ip, r0, r3\n" 631 "add r0, ip\n"); 632 COMPARE_T32(Adds(r0, r0, Operand(r0, ROR, r0)), 633 "ror ip, r0, r0\n" 634 "adds r0, ip\n"); 635 636 CLEANUP(); 637 } 638 639 640 TEST(macro_assembler_big_offset) { 641 SETUP(); 642 643 COMPARE_BOTH(Ldr(r0, MemOperand(r1, 0xfff123)), 644 "add r0, r1, #1044480\n" // #0xff000 645 "add r0, #15728640\n" // #0x00f00000 646 "ldr r0, [r0, #291]\n"); // #0x123 647 COMPARE_BOTH(Ldr(r0, MemOperand(r1, 0xff123)), 648 "add r0, r1, #1044480\n" // #0xff000 649 "ldr r0, [r0, #291]\n"); // #0x123 650 COMPARE_BOTH(Ldr(r0, MemOperand(r1, -0xff123)), 651 "sub r0, r1, #1048576\n" // #0x100000 652 "ldr r0, [r0, #3805]\n"); // #0xedd 653 654 COMPARE_A32(Ldr(r0, MemOperand(r1, 0xfff123, PreIndex)), 655 "add r1, #1044480\n" // #0xff000 656 "add r1, #15728640\n" // #0x00f00000 657 "ldr r0, [r1, #291]!\n"); // #0x123 658 COMPARE_A32(Ldr(r0, MemOperand(r1, 0xff123, PreIndex)), 659 "add r1, #1044480\n" // #0xff000 660 "ldr r0, [r1, #291]!\n"); // #0x123 661 COMPARE_A32(Ldr(r0, MemOperand(r1, -0xff123, PreIndex)), 662 "sub r1, #1048576\n" // #0x100000 663 "ldr r0, [r1, #3805]!\n"); // #0xedd 664 665 COMPARE_T32(Ldr(r0, MemOperand(r1, 0xfff12, PreIndex)), 666 "add r1, #65280\n" // #0xff00 667 "add r1, #983040\n" // #0x000f0000 668 "ldr r0, [r1, #18]!\n"); // #0x12 669 COMPARE_T32(Ldr(r0, MemOperand(r1, 0xff12, PreIndex)), 670 "add r1, #65280\n" // #0xff00 671 "ldr r0, [r1, #18]!\n"); // #0x12 672 COMPARE_T32(Ldr(r0, MemOperand(r1, -0xff12, PreIndex)), 673 "sub r1, #65536\n" // #0x10000 674 "ldr r0, [r1, #238]!\n"); // #0xee 675 676 COMPARE_A32(Ldr(r0, MemOperand(r1, 0xfff123, PostIndex)), 677 "ldr r0, [r1], #291\n" // #0x123 678 "add r1, #1044480\n" // #0xff000 679 "add r1, #15728640\n"); // #0x00f00000 680 COMPARE_A32(Ldr(r0, MemOperand(r1, 0xff123, PostIndex)), 681 "ldr r0, [r1], #291\n" // #0x123 682 "add r1, #1044480\n"); // #0xff000 683 COMPARE_A32(Ldr(r0, MemOperand(r1, -0xff123, PostIndex)), 684 "ldr r0, [r1], #3805\n" // #0xedd 685 "sub r1, #1048576\n"); // #0x100000 686 687 COMPARE_T32(Ldr(r0, MemOperand(r1, 0xfff12, PostIndex)), 688 "ldr r0, [r1], #18\n" // #0x12 689 "add r1, #65280\n" // #0xff00 690 "add r1, #983040\n"); // #0x000f0000 691 COMPARE_T32(Ldr(r0, MemOperand(r1, 0xff12, PostIndex)), 692 "ldr r0, [r1], #18\n" // #0x12 693 "add r1, #65280\n"); // #0xff00 694 COMPARE_T32(Ldr(r0, MemOperand(r1, -0xff12, PostIndex)), 695 "ldr r0, [r1], #238\n" // #0xee 696 "sub r1, #65536\n"); // #0x10000 697 698 COMPARE_A32(Ldrh(r0, MemOperand(r1, 0xfff123)), 699 "add r0, r1, #61696\n" // #0xf100 700 "add r0, #16711680\n" // #0x00ff0000 701 "ldrh r0, [r0, #35]\n"); // #0x23 702 COMPARE_T32(Ldrh(r0, MemOperand(r1, 0xfff123)), 703 "add r0, r1, #1044480\n" // #0xff000 704 "add r0, #15728640\n" // #0x00f00000 705 "ldrh r0, [r0, #291]\n"); // #0x123 706 707 COMPARE_A32(Ldrh(r0, MemOperand(r1, 0xff123)), 708 "add r0, r1, #61696\n" // #0xf100 709 "add r0, #983040\n" // #0x000f0000 710 "ldrh r0, [r0, #35]\n"); // #0x23 711 COMPARE_T32(Ldrh(r0, MemOperand(r1, 0xff123)), 712 "add r0, r1, #1044480\n" // #0xff000 713 "ldrh r0, [r0, #291]\n"); // #0x123 714 COMPARE_A32(Ldrh(r0, MemOperand(r1, -0xff123)), 715 "sub r0, r1, #61952\n" // #0xf200 716 "sub r0, #983040\n" // #0x000f0000 717 "ldrh r0, [r0, #221]\n"); // #0xdd 718 COMPARE_T32(Ldrh(r0, MemOperand(r1, -0xff123)), 719 "sub r0, r1, #1048576\n" // #0x100000 720 "ldrh r0, [r0, #3805]\n"); // #0xedd 721 722 MUST_FAIL_TEST_BOTH(Ldr(r0, MemOperand(r0, 0xfff12, PreIndex)), 723 "Ill-formed 'ldr' instruction.\n"); 724 MUST_FAIL_TEST_BOTH(Ldr(r0, MemOperand(r0, 0xfff12, PostIndex)), 725 "Ill-formed 'ldr' instruction.\n"); 726 CLEANUP(); 727 } 728 729 730 TEST(macro_assembler_load) { 731 SETUP(); 732 733 // Register base and offset that we can encode in both A1 and T1. 734 COMPARE_BOTH(Ldr(r0, MemOperand(r1, r8, Offset)), "ldr r0, [r1, r8]\n"); 735 736 // Negative register offset. Use the destination as a scratch register, 737 // regardless of the values of the base and offset register. 738 COMPARE_T32(Ldr(r0, MemOperand(r0, minus, r0, Offset)), 739 "sub r0, r0\n" 740 "ldr r0, [r0]\n"); 741 742 COMPARE_T32(Ldr(r0, MemOperand(r0, minus, r1, Offset)), 743 "sub r0, r1\n" 744 "ldr r0, [r0]\n"); 745 746 COMPARE_T32(Ldr(r0, MemOperand(r1, minus, r0, Offset)), 747 "sub r0, r1, r0\n" 748 "ldr r0, [r0]\n"); 749 750 COMPARE_T32(Ldr(r0, MemOperand(r1, minus, r2, Offset)), 751 "sub r0, r1, r2\n" 752 "ldr r0, [r0]\n"); 753 754 // Pre-index negative offset. 755 COMPARE_T32(Ldr(r0, MemOperand(r1, minus, r2, PreIndex)), 756 "sub r1, r2\n" 757 "ldr r0, [r1]\n"); 758 759 // Post-index negative offset. 760 COMPARE_T32(Ldr(r0, MemOperand(r1, minus, r2, PostIndex)), 761 "ldr r0, [r1]\n" 762 "sub r1, r2\n"); 763 764 // SP is allowed as base, offset and destination. 765 COMPARE_BOTH(Ldr(sp, MemOperand(sp, sp, Offset)), "ldr sp, [sp, sp]\n"); 766 767 // PC is allowed as destination - make sure it is not used as a temporary 768 // register. 769 COMPARE_BOTH(Ldr(pc, MemOperand(r0, r0, Offset)), "ldr pc, [r0, r0]\n"); 770 COMPARE_A32(Ldr(pc, MemOperand(r0, r0, PreIndex)), "ldr pc, [r0, r0]!\n"); 771 COMPARE_T32(Ldr(pc, MemOperand(r0, r0, PreIndex)), 772 "add r0, r0\n" 773 "ldr pc, [r0]\n"); 774 COMPARE_A32(Ldr(pc, MemOperand(r0, r0, PostIndex)), "ldr pc, [r0], r0\n"); 775 COMPARE_T32(Ldr(pc, MemOperand(r0, r0, PostIndex)), 776 "ldr pc, [r0]\n" 777 "add r0, r0\n"); 778 779 // PC is allowed as register base in the offset variant only for A32. 780 COMPARE_A32(Ldr(r0, MemOperand(pc, r0, Offset)), "ldr r0, [pc, r0]\n"); 781 MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(pc, r0, Offset)), 782 "The MacroAssembler does not convert loads and stores with" 783 " a PC base register for T32.\n"); 784 785 // PC is not allowed as register base in the pre-index and post-index 786 // variants. 787 MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(pc, r0, PreIndex)), 788 "The MacroAssembler does not convert loads and stores " 789 "with a PC base register in pre-index or post-index " 790 "mode.\n"); 791 MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(pc, r0, PostIndex)), 792 "The MacroAssembler does not convert loads and stores " 793 "with a PC base register in pre-index or post-index " 794 "mode.\n"); 795 796 // We don't convert loads with PC as the register offset. 797 MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, minus, pc, Offset)), 798 "The MacroAssembler does not convert loads and stores " 799 "with a PC offset register.\n"); 800 MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, pc, PreIndex)), 801 "The MacroAssembler does not convert loads and stores " 802 "with a PC offset register.\n"); 803 MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, pc, PostIndex)), 804 "The MacroAssembler does not convert loads and stores " 805 "with a PC offset register.\n"); 806 807 // TODO: PC should not be allowed as register offset (unpredictable). 808 SHOULD_FAIL_TEST_BOTH(Ldr(r0, MemOperand(r0, Sign(plus), pc, Offset))); 809 810 // TODO: PC should not be allowed as register base in A32 with pre-index 811 // and post-index (unpredictable). 812 SHOULD_FAIL_TEST_A32(Ldr(r0, MemOperand(pc, r0, PreIndex))); 813 SHOULD_FAIL_TEST_A32(Ldr(r0, MemOperand(pc, r0, PostIndex))); 814 815 // TODO: load with the same register used as base and as destination 816 // should fail to assemble (unpredictable). 817 SHOULD_FAIL_TEST_A32(Ldr(r0, MemOperand(r0, r1, PreIndex))); 818 SHOULD_FAIL_TEST_A32(Ldr(r0, MemOperand(r0, r1, PostIndex))); 819 MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, r1, PreIndex)), 820 "Ill-formed 'ldr' instruction.\n"); 821 MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, r1, PostIndex)), 822 "Ill-formed 'ldr' instruction.\n"); 823 824 CLEANUP(); 825 } 826 827 828 TEST(macro_assembler_store) { 829 SETUP(); 830 831 // Register base and offset that we can encode in both A1 and T1. 832 COMPARE_BOTH(Str(r0, MemOperand(r1, r8, Offset)), "str r0, [r1, r8]\n"); 833 834 // Negative register offset. 835 COMPARE_T32(Str(r0, MemOperand(r0, minus, r0, Offset)), 836 "sub ip, r0, r0\n" 837 "str r0, [ip]\n"); 838 839 COMPARE_T32(Str(r0, MemOperand(r0, minus, r1, Offset)), 840 "sub ip, r0, r1\n" 841 "str r0, [ip]\n"); 842 843 COMPARE_T32(Str(r0, MemOperand(r1, minus, r0, Offset)), 844 "sub ip, r1, r0\n" 845 "str r0, [ip]\n"); 846 847 COMPARE_T32(Str(r0, MemOperand(r1, minus, r2, Offset)), 848 "sub ip, r1, r2\n" 849 "str r0, [ip]\n"); 850 851 // Pre-index negative offset. 852 COMPARE_T32(Str(r0, MemOperand(r1, minus, r2, PreIndex)), 853 "sub r1, r2\n" 854 "str r0, [r1]\n"); 855 856 // Post-index negative offset. 857 COMPARE_T32(Str(r0, MemOperand(r1, minus, r2, PostIndex)), 858 "str r0, [r1]\n" 859 "sub r1, r2\n"); 860 861 // SP is allowed as base, offset and source. 862 COMPARE_BOTH(Str(sp, MemOperand(sp, sp, Offset)), "str sp, [sp, sp]\n"); 863 864 // TODO: PC is allowed as the value we are storing for A32, but 865 // should not be allowed for T32 (unpredictable). 866 COMPARE_A32(Str(pc, MemOperand(r0, r0, Offset)), "str pc, [r0, r0]\n"); 867 COMPARE_A32(Str(pc, MemOperand(r0, r0, PreIndex)), "str pc, [r0, r0]!\n"); 868 COMPARE_A32(Str(pc, MemOperand(r0, r0, PostIndex)), "str pc, [r0], r0\n"); 869 SHOULD_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, Offset))); 870 SHOULD_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, PreIndex))); 871 SHOULD_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, PostIndex))); 872 873 // PC is allowed as register base in the offset variant only for A32. 874 COMPARE_A32(Str(r0, MemOperand(pc, r0, Offset)), "str r0, [pc, r0]\n"); 875 MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, Offset)), 876 "The MacroAssembler does not convert loads and stores with" 877 " a PC base register for T32.\n"); 878 879 // PC is not allowed as register base in the pre-index and post-index 880 // variants. 881 MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, PreIndex)), 882 "The MacroAssembler does not convert loads and stores " 883 "with a PC base register in pre-index or post-index " 884 "mode.\n"); 885 MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, PostIndex)), 886 "The MacroAssembler does not convert loads and stores " 887 "with a PC base register in pre-index or post-index " 888 "mode.\n"); 889 890 // We don't convert loads with PC as the register offset. 891 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, minus, pc, Offset)), 892 "The MacroAssembler does not convert loads and stores " 893 "with a PC offset register.\n"); 894 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, pc, PreIndex)), 895 "The MacroAssembler does not convert loads and stores " 896 "with a PC offset register.\n"); 897 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, pc, PostIndex)), 898 "The MacroAssembler does not convert loads and stores " 899 "with a PC offset register.\n"); 900 901 // TODO: PC should not be allowed as register offset (unpredictable). 902 SHOULD_FAIL_TEST_BOTH(Str(r0, MemOperand(r0, Sign(plus), pc, Offset))); 903 904 // TODO: PC should not be allowed as register base in A32 with pre-index 905 // and post-index (unpredictable). 906 SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(pc, r0, PreIndex))); 907 SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(pc, r0, PostIndex))); 908 909 // TODO: store with the same register used as base and as source 910 // should fail to assemble (unpredictable). 911 SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(r0, r1, PreIndex))); 912 SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(r0, r1, PostIndex))); 913 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, r1, PreIndex)), 914 "Ill-formed 'str' instruction.\n"); 915 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, r1, PostIndex)), 916 "Ill-formed 'str' instruction.\n"); 917 918 CLEANUP(); 919 } 920 921 922 TEST(macro_assembler_ldrd) { 923 SETUP(); 924 925 // - Tests with no offset. 926 927 COMPARE_BOTH(Ldrd(r0, r1, MemOperand(r3)), "ldrd r0, r1, [r3]\n"); 928 // Destination registers need to start with a even numbered register on A32. 929 MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r3)), 930 "Unpredictable instruction.\n"); 931 COMPARE_T32(Ldrd(r1, r2, MemOperand(r3)), "ldrd r1, r2, [r3]\n"); 932 // Registers need to be adjacent on A32. 933 MUST_FAIL_TEST_A32(Ldrd(r0, r2, MemOperand(r1)), 934 "Ill-formed 'ldrd' instruction.\n"); 935 COMPARE_T32(Ldrd(r0, r2, MemOperand(r1)), "ldrd r0, r2, [r1]\n"); 936 937 COMPARE_BOTH(Ldrd(r0, r1, MemOperand(r2)), "ldrd r0, r1, [r2]\n"); 938 939 // - Tests with immediate offsets. 940 941 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 1020)), 942 "add r0, r2, #1020\n" 943 "ldrd r0, r1, [r0]\n"); 944 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 1020)), "ldrd r0, r1, [r2, #1020]\n"); 945 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -1020)), 946 "sub r0, r2, #1020\n" 947 "ldrd r0, r1, [r0]\n"); 948 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -1020)), 949 "ldrd r0, r1, [r2, #-1020]\n"); 950 951 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc)), 952 "add r0, r2, #43776\n" 953 "ldrd r0, r1, [r0, #204]\n"); 954 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc)), 955 "add r0, r2, #43008\n" 956 "ldrd r0, r1, [r0, #972]\n"); 957 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc)), 958 "sub r0, r2, #44032\n" 959 "ldrd r0, r1, [r0, #52]\n"); 960 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc)), 961 "sub r0, r2, #44032\n" 962 "ldrd r0, r1, [r0, #52]\n"); 963 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec)), 964 "add r0, r2, #52480\n" 965 "add r0, #11206656\n" 966 "ldrd r0, r1, [r0, #236]\n"); 967 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec)), 968 "add r0, r2, #248832\n" 969 "add r0, #11010048\n" 970 "ldrd r0, r1, [r0, #492]\n"); 971 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec)), 972 "sub r0, r2, #52736\n" 973 "sub r0, #11206656\n" 974 "ldrd r0, r1, [r0, #20]\n"); 975 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec)), 976 "sub r0, r2, #774144\n" 977 "sub r0, #10485760\n" 978 "ldrd r0, r1, [r0, #532]\n"); 979 980 COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, 0xabcc)), 981 "add r1, r0, #43776\n" 982 "ldrd r0, r1, [r1, #204]\n"); 983 COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, 0xabcc)), 984 "add r1, r0, #43008\n" 985 "ldrd r0, r1, [r1, #972]\n"); 986 COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, -0xabcc)), 987 "sub r1, r0, #44032\n" 988 "ldrd r0, r1, [r1, #52]\n"); 989 COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, -0xabcc)), 990 "sub r1, r0, #44032\n" 991 "ldrd r0, r1, [r1, #52]\n"); 992 COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, 0xabcdec)), 993 "add r1, r0, #52480\n" 994 "add r1, #11206656\n" 995 "ldrd r0, r1, [r1, #236]\n"); 996 COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, 0xabcdec)), 997 "add r1, r0, #248832\n" 998 "add r1, #11010048\n" 999 "ldrd r0, r1, [r1, #492]\n"); 1000 COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, -0xabcdec)), 1001 "sub r1, r0, #52736\n" 1002 "sub r1, #11206656\n" 1003 "ldrd r0, r1, [r1, #20]\n"); 1004 COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, -0xabcdec)), 1005 "sub r1, r0, #774144\n" 1006 "sub r1, #10485760\n" 1007 "ldrd r0, r1, [r1, #532]\n"); 1008 1009 COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, 0xabcc)), 1010 "add r0, r1, #43776\n" 1011 "ldrd r0, r1, [r0, #204]\n"); 1012 COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, 0xabcc)), 1013 "add r0, r1, #43008\n" 1014 "ldrd r0, r1, [r0, #972]\n"); 1015 COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, -0xabcc)), 1016 "sub r0, r1, #44032\n" 1017 "ldrd r0, r1, [r0, #52]\n"); 1018 COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, -0xabcc)), 1019 "sub r0, r1, #44032\n" 1020 "ldrd r0, r1, [r0, #52]\n"); 1021 COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, 0xabcdec)), 1022 "add r0, r1, #52480\n" 1023 "add r0, #11206656\n" 1024 "ldrd r0, r1, [r0, #236]\n"); 1025 COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, 0xabcdec)), 1026 "add r0, r1, #248832\n" 1027 "add r0, #11010048\n" 1028 "ldrd r0, r1, [r0, #492]\n"); 1029 COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, -0xabcdec)), 1030 "sub r0, r1, #52736\n" 1031 "sub r0, #11206656\n" 1032 "ldrd r0, r1, [r0, #20]\n"); 1033 COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, -0xabcdec)), 1034 "sub r0, r1, #774144\n" 1035 "sub r0, #10485760\n" 1036 "ldrd r0, r1, [r0, #532]\n"); 1037 1038 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)), 1039 "ldrd r0, r1, [r2], #204\n" 1040 "add r2, #43776\n"); 1041 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)), 1042 "ldrd r0, r1, [r2], #972\n" 1043 "add r2, #43008\n"); 1044 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)), 1045 "ldrd r0, r1, [r2], #52\n" 1046 "sub r2, #44032\n"); 1047 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)), 1048 "ldrd r0, r1, [r2], #52\n" 1049 "sub r2, #44032\n"); 1050 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)), 1051 "ldrd r0, r1, [r2], #236\n" 1052 "add r2, #52480\n" 1053 "add r2, #11206656\n"); 1054 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)), 1055 "ldrd r0, r1, [r2], #492\n" 1056 "add r2, #248832\n" 1057 "add r2, #11010048\n"); 1058 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)), 1059 "ldrd r0, r1, [r2], #20\n" 1060 "sub r2, #52736\n" 1061 "sub r2, #11206656\n"); 1062 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)), 1063 "ldrd r0, r1, [r2], #532\n" 1064 "sub r2, #774144\n" 1065 "sub r2, #10485760\n"); 1066 1067 // PostIndex with the same register as base and destination is invalid. 1068 MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r0, 0xabcd, PostIndex)), 1069 "Ill-formed 'ldrd' instruction.\n"); 1070 MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r1, 0xabcdef, PostIndex)), 1071 "Ill-formed 'ldrd' instruction.\n"); 1072 1073 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)), 1074 "add r2, #43776\n" 1075 "ldrd r0, r1, [r2, #204]!\n"); 1076 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)), 1077 "add r2, #43008\n" 1078 "ldrd r0, r1, [r2, #972]!\n"); 1079 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)), 1080 "sub r2, #44032\n" 1081 "ldrd r0, r1, [r2, #52]!\n"); 1082 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)), 1083 "sub r2, #44032\n" 1084 "ldrd r0, r1, [r2, #52]!\n"); 1085 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)), 1086 "add r2, #52480\n" 1087 "add r2, #11206656\n" 1088 "ldrd r0, r1, [r2, #236]!\n"); 1089 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)), 1090 "add r2, #248832\n" 1091 "add r2, #11010048\n" 1092 "ldrd r0, r1, [r2, #492]!\n"); 1093 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)), 1094 "sub r2, #52736\n" 1095 "sub r2, #11206656\n" 1096 "ldrd r0, r1, [r2, #20]!\n"); 1097 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)), 1098 "sub r2, #774144\n" 1099 "sub r2, #10485760\n" 1100 "ldrd r0, r1, [r2, #532]!\n"); 1101 1102 // - Tests with register offsets. 1103 1104 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3)), "ldrd r0, r1, [r2, r3]\n"); 1105 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3)), 1106 "add r0, r2, r3\n" 1107 "ldrd r0, r1, [r0]\n"); 1108 1109 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3)), 1110 "ldrd r0, r1, [r2, -r3]\n"); 1111 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3)), 1112 "sub r0, r2, r3\n" 1113 "ldrd r0, r1, [r0]\n"); 1114 1115 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3, PostIndex)), 1116 "ldrd r0, r1, [r2], r3\n"); 1117 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3, PostIndex)), 1118 "ldrd r0, r1, [r2]\n" 1119 "add r2, r3\n"); 1120 1121 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PostIndex)), 1122 "ldrd r0, r1, [r2], -r3\n"); 1123 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PostIndex)), 1124 "ldrd r0, r1, [r2]\n" 1125 "sub r2, r3\n"); 1126 1127 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3, PreIndex)), 1128 "ldrd r0, r1, [r2, r3]!\n"); 1129 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3, PreIndex)), 1130 "add r2, r3\n" 1131 "ldrd r0, r1, [r2]\n"); 1132 1133 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PreIndex)), 1134 "ldrd r0, r1, [r2, -r3]!\n"); 1135 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PreIndex)), 1136 "sub r2, r3\n" 1137 "ldrd r0, r1, [r2]\n"); 1138 1139 // - We do not support register shifted base register operands with LDRD. 1140 1141 MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r2, r3, LSL, 4)), 1142 "Ill-formed 'ldrd' instruction.\n"); 1143 1144 // First register is odd - rejected by the Assembler. 1145 MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0)), 1146 "Unpredictable instruction.\n"); 1147 MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0, r0, PreIndex)), 1148 "Unpredictable instruction.\n"); 1149 // First register is odd - rejected by the MacroAssembler. 1150 MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0, 0xabcd, PreIndex)), 1151 "Ill-formed 'ldrd' instruction.\n"); 1152 1153 // First register is lr - rejected by the Assembler. 1154 MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0)), 1155 "Unpredictable instruction.\n"); 1156 MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0, r0, PreIndex)), 1157 "Unpredictable instruction.\n"); 1158 // First register is lr - rejected by the MacroAssembler. 1159 MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0, 0xabcd, PreIndex)), 1160 "Ill-formed 'ldrd' instruction.\n"); 1161 1162 // Non-adjacent registers. 1163 MUST_FAIL_TEST_A32(Ldrd(r0, r2, MemOperand(r0)), 1164 "Ill-formed 'ldrd' instruction.\n"); 1165 1166 CLEANUP(); 1167 } 1168 1169 TEST(macro_assembler_strd) { 1170 SETUP(); 1171 1172 // - Tests with no offset. 1173 1174 COMPARE_BOTH(Strd(r0, r1, MemOperand(r3)), "strd r0, r1, [r3]\n"); 1175 // Destination registers need to start with a even numbered register on A32. 1176 MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r3)), 1177 "Unpredictable instruction.\n"); 1178 COMPARE_T32(Strd(r1, r2, MemOperand(r3)), "strd r1, r2, [r3]\n"); 1179 // Registers need to be adjacent on A32. 1180 MUST_FAIL_TEST_A32(Strd(r0, r2, MemOperand(r1)), 1181 "Ill-formed 'strd' instruction.\n"); 1182 COMPARE_T32(Strd(r0, r2, MemOperand(r1)), "strd r0, r2, [r1]\n"); 1183 1184 COMPARE_BOTH(Strd(r0, r1, MemOperand(r2)), "strd r0, r1, [r2]\n"); 1185 1186 // - Tests with immediate offsets. 1187 1188 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 1020)), 1189 "add ip, r2, #1020\n" 1190 "strd r0, r1, [ip]\n"); 1191 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 1020)), "strd r0, r1, [r2, #1020]\n"); 1192 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -1020)), 1193 "sub ip, r2, #1020\n" 1194 "strd r0, r1, [ip]\n"); 1195 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -1020)), 1196 "strd r0, r1, [r2, #-1020]\n"); 1197 1198 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc)), 1199 "add ip, r2, #43776\n" 1200 "strd r0, r1, [ip, #204]\n"); 1201 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc)), 1202 "add ip, r2, #43008\n" 1203 "strd r0, r1, [ip, #972]\n"); 1204 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc)), 1205 "sub ip, r2, #44032\n" 1206 "strd r0, r1, [ip, #52]\n"); 1207 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc)), 1208 "sub ip, r2, #44032\n" 1209 "strd r0, r1, [ip, #52]\n"); 1210 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec)), 1211 "add ip, r2, #52480\n" 1212 "add ip, #11206656\n" 1213 "strd r0, r1, [ip, #236]\n"); 1214 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec)), 1215 "add ip, r2, #248832\n" 1216 "add ip, #11010048\n" 1217 "strd r0, r1, [ip, #492]\n"); 1218 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec)), 1219 "sub ip, r2, #52736\n" 1220 "sub ip, #11206656\n" 1221 "strd r0, r1, [ip, #20]\n"); 1222 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec)), 1223 "sub ip, r2, #774144\n" 1224 "sub ip, #10485760\n" 1225 "strd r0, r1, [ip, #532]\n"); 1226 1227 COMPARE_A32(Strd(r0, r1, MemOperand(r0, 0xabcc)), 1228 "add ip, r0, #43776\n" 1229 "strd r0, r1, [ip, #204]\n"); 1230 COMPARE_T32(Strd(r0, r1, MemOperand(r0, 0xabcc)), 1231 "add ip, r0, #43008\n" 1232 "strd r0, r1, [ip, #972]\n"); 1233 COMPARE_A32(Strd(r0, r1, MemOperand(r0, -0xabcc)), 1234 "sub ip, r0, #44032\n" 1235 "strd r0, r1, [ip, #52]\n"); 1236 COMPARE_T32(Strd(r0, r1, MemOperand(r0, -0xabcc)), 1237 "sub ip, r0, #44032\n" 1238 "strd r0, r1, [ip, #52]\n"); 1239 COMPARE_A32(Strd(r0, r1, MemOperand(r0, 0xabcdec)), 1240 "add ip, r0, #52480\n" 1241 "add ip, #11206656\n" 1242 "strd r0, r1, [ip, #236]\n"); 1243 COMPARE_T32(Strd(r0, r1, MemOperand(r0, 0xabcdec)), 1244 "add ip, r0, #248832\n" 1245 "add ip, #11010048\n" 1246 "strd r0, r1, [ip, #492]\n"); 1247 COMPARE_A32(Strd(r0, r1, MemOperand(r0, -0xabcdec)), 1248 "sub ip, r0, #52736\n" 1249 "sub ip, #11206656\n" 1250 "strd r0, r1, [ip, #20]\n"); 1251 COMPARE_T32(Strd(r0, r1, MemOperand(r0, -0xabcdec)), 1252 "sub ip, r0, #774144\n" 1253 "sub ip, #10485760\n" 1254 "strd r0, r1, [ip, #532]\n"); 1255 1256 COMPARE_A32(Strd(r0, r1, MemOperand(r1, 0xabcc)), 1257 "add ip, r1, #43776\n" 1258 "strd r0, r1, [ip, #204]\n"); 1259 COMPARE_T32(Strd(r0, r1, MemOperand(r1, 0xabcc)), 1260 "add ip, r1, #43008\n" 1261 "strd r0, r1, [ip, #972]\n"); 1262 COMPARE_A32(Strd(r0, r1, MemOperand(r1, -0xabcc)), 1263 "sub ip, r1, #44032\n" 1264 "strd r0, r1, [ip, #52]\n"); 1265 COMPARE_T32(Strd(r0, r1, MemOperand(r1, -0xabcc)), 1266 "sub ip, r1, #44032\n" 1267 "strd r0, r1, [ip, #52]\n"); 1268 COMPARE_A32(Strd(r0, r1, MemOperand(r1, 0xabcdec)), 1269 "add ip, r1, #52480\n" 1270 "add ip, #11206656\n" 1271 "strd r0, r1, [ip, #236]\n"); 1272 COMPARE_T32(Strd(r0, r1, MemOperand(r1, 0xabcdec)), 1273 "add ip, r1, #248832\n" 1274 "add ip, #11010048\n" 1275 "strd r0, r1, [ip, #492]\n"); 1276 COMPARE_A32(Strd(r0, r1, MemOperand(r1, -0xabcdec)), 1277 "sub ip, r1, #52736\n" 1278 "sub ip, #11206656\n" 1279 "strd r0, r1, [ip, #20]\n"); 1280 COMPARE_T32(Strd(r0, r1, MemOperand(r1, -0xabcdec)), 1281 "sub ip, r1, #774144\n" 1282 "sub ip, #10485760\n" 1283 "strd r0, r1, [ip, #532]\n"); 1284 1285 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)), 1286 "strd r0, r1, [r2], #204\n" 1287 "add r2, #43776\n"); 1288 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)), 1289 "strd r0, r1, [r2], #972\n" 1290 "add r2, #43008\n"); 1291 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)), 1292 "strd r0, r1, [r2], #52\n" 1293 "sub r2, #44032\n"); 1294 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)), 1295 "strd r0, r1, [r2], #52\n" 1296 "sub r2, #44032\n"); 1297 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)), 1298 "strd r0, r1, [r2], #236\n" 1299 "add r2, #52480\n" 1300 "add r2, #11206656\n"); 1301 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)), 1302 "strd r0, r1, [r2], #492\n" 1303 "add r2, #248832\n" 1304 "add r2, #11010048\n"); 1305 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)), 1306 "strd r0, r1, [r2], #20\n" 1307 "sub r2, #52736\n" 1308 "sub r2, #11206656\n"); 1309 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)), 1310 "strd r0, r1, [r2], #532\n" 1311 "sub r2, #774144\n" 1312 "sub r2, #10485760\n"); 1313 1314 // PostIndex with the same register as base and source is invalid. 1315 MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r0, 0xabcd, PostIndex)), 1316 "Ill-formed 'strd' instruction.\n"); 1317 MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r1, 0xabcdef, PostIndex)), 1318 "Ill-formed 'strd' instruction.\n"); 1319 1320 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)), 1321 "add r2, #43776\n" 1322 "strd r0, r1, [r2, #204]!\n"); 1323 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)), 1324 "add r2, #43008\n" 1325 "strd r0, r1, [r2, #972]!\n"); 1326 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)), 1327 "sub r2, #44032\n" 1328 "strd r0, r1, [r2, #52]!\n"); 1329 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)), 1330 "sub r2, #44032\n" 1331 "strd r0, r1, [r2, #52]!\n"); 1332 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)), 1333 "add r2, #52480\n" 1334 "add r2, #11206656\n" 1335 "strd r0, r1, [r2, #236]!\n"); 1336 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)), 1337 "add r2, #248832\n" 1338 "add r2, #11010048\n" 1339 "strd r0, r1, [r2, #492]!\n"); 1340 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)), 1341 "sub r2, #52736\n" 1342 "sub r2, #11206656\n" 1343 "strd r0, r1, [r2, #20]!\n"); 1344 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)), 1345 "sub r2, #774144\n" 1346 "sub r2, #10485760\n" 1347 "strd r0, r1, [r2, #532]!\n"); 1348 1349 // - Tests with register offsets. 1350 1351 COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3)), "strd r0, r1, [r2, r3]\n"); 1352 COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3)), 1353 "add ip, r2, r3\n" 1354 "strd r0, r1, [ip]\n"); 1355 1356 COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3)), 1357 "strd r0, r1, [r2, -r3]\n"); 1358 COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3)), 1359 "sub ip, r2, r3\n" 1360 "strd r0, r1, [ip]\n"); 1361 1362 COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3, PostIndex)), 1363 "strd r0, r1, [r2], r3\n"); 1364 COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3, PostIndex)), 1365 "strd r0, r1, [r2]\n" 1366 "add r2, r3\n"); 1367 1368 COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3, PostIndex)), 1369 "strd r0, r1, [r2], -r3\n"); 1370 COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3, PostIndex)), 1371 "strd r0, r1, [r2]\n" 1372 "sub r2, r3\n"); 1373 1374 COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3, PreIndex)), 1375 "strd r0, r1, [r2, r3]!\n"); 1376 COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3, PreIndex)), 1377 "add r2, r3\n" 1378 "strd r0, r1, [r2]\n"); 1379 1380 COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3, PreIndex)), 1381 "strd r0, r1, [r2, -r3]!\n"); 1382 COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3, PreIndex)), 1383 "sub r2, r3\n" 1384 "strd r0, r1, [r2]\n"); 1385 1386 // - We do not support register shifted base register operands with LDRD. 1387 1388 MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r2, r3, LSL, 4)), 1389 "Ill-formed 'strd' instruction.\n"); 1390 1391 // First register is odd - rejected by the Assembler. 1392 MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0)), 1393 "Unpredictable instruction.\n"); 1394 MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0, r0, PreIndex)), 1395 "Unpredictable instruction.\n"); 1396 // First register is odd - rejected by the MacroAssembler. 1397 MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0, 0xabcd, PreIndex)), 1398 "Ill-formed 'strd' instruction.\n"); 1399 1400 // First register is lr - rejected by the Assembler. 1401 MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0)), 1402 "Unpredictable instruction.\n"); 1403 MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0, r0, PreIndex)), 1404 "Unpredictable instruction.\n"); 1405 // First register is lr - rejected by the MacroAssembler. 1406 MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0, 0xabcd, PreIndex)), 1407 "Ill-formed 'strd' instruction.\n"); 1408 1409 // Non-adjacent registers. 1410 MUST_FAIL_TEST_A32(Strd(r0, r2, MemOperand(r0)), 1411 "Ill-formed 'strd' instruction.\n"); 1412 1413 CLEANUP(); 1414 } 1415 1416 1417 TEST(macro_assembler_wide_immediate) { 1418 SETUP(); 1419 1420 COMPARE_BOTH(Adc(r0, r1, 0xbadbeef), 1421 "mov r0, #48879\n" 1422 "movt r0, #2989\n" 1423 "adc r0, r1, r0\n"); 1424 1425 COMPARE_BOTH(Add(r0, r0, 0xbadbeef), 1426 "mov ip, #48879\n" 1427 "movt ip, #2989\n" 1428 "add r0, ip\n"); 1429 1430 COMPARE_BOTH(Mov(r0, 0xbadbeef), 1431 "mov r0, #48879\n" 1432 "movt r0, #2989\n"); 1433 COMPARE_A32(Mov(eq, r0, 0xbadbeef), 1434 "moveq r0, #48879\n" 1435 "movteq r0, #2989\n"); 1436 COMPARE_T32(Mov(eq, r0, 0xbadbeef), 1437 "bne 0x0000000a\n" 1438 "mov r0, #48879\n" 1439 "movt r0, #2989\n"); 1440 1441 COMPARE_BOTH(Movs(r0, 0xbadbeef), 1442 "mov r0, #48879\n" 1443 "movt r0, #2989\n" 1444 "tst r0, r0\n"); 1445 COMPARE_A32(Movs(eq, r0, 0xbadbeef), 1446 "moveq r0, #48879\n" 1447 "movteq r0, #2989\n" 1448 "tsteq r0, r0\n"); 1449 COMPARE_T32(Movs(eq, r0, 0xbadbeef), 1450 "bne 0x0000000c\n" 1451 "mov r0, #48879\n" 1452 "movt r0, #2989\n" 1453 "tst r0, r0\n"); 1454 COMPARE_A32(Movs(pc, 0x1), "movs pc, #1\n"); 1455 MUST_FAIL_TEST_T32(Movs(pc, 0x1), "Unpredictable instruction.\n"); 1456 MUST_FAIL_TEST_BOTH(Movs(pc, 0xbadbeed), "Ill-formed 'movs' instruction.\n"); 1457 1458 COMPARE_BOTH(Mov(pc, 0xbadbeef), 1459 "mov ip, #48879\n" 1460 "movt ip, #2989\n" 1461 "bx ip\n"); 1462 COMPARE_A32(Mov(eq, pc, 0xbadbeef), 1463 "mov ip, #48879\n" 1464 "movt ip, #2989\n" 1465 "bxeq ip\n"); 1466 COMPARE_T32(Mov(eq, pc, 0xbadbeef), 1467 "bne 0x0000000c\n" 1468 "mov ip, #48879\n" 1469 "movt ip, #2989\n" 1470 "bx ip\n"); 1471 1472 CLEANUP(); 1473 } 1474 1475 1476 TEST(macro_assembler_And) { 1477 SETUP(); 1478 1479 // Identities. 1480 COMPARE_BOTH(And(r0, r1, 0), "mov r0, #0\n"); 1481 COMPARE_BOTH(And(r0, r0, 0xffffffff), ""); 1482 CLEANUP(); 1483 } 1484 1485 1486 TEST(macro_assembler_Bic) { 1487 SETUP(); 1488 1489 // Identities. 1490 COMPARE_BOTH(Bic(r0, r1, 0xffffffff), "mov r0, #0\n"); 1491 COMPARE_BOTH(Bic(r0, r0, 0), ""); 1492 CLEANUP(); 1493 } 1494 1495 1496 TEST(macro_assembler_Orr) { 1497 SETUP(); 1498 1499 // Identities. 1500 COMPARE_BOTH(Orr(r0, r1, 0xffffffff), "mvn r0, #0\n"); 1501 COMPARE_BOTH(Orr(r0, r0, 0), ""); 1502 CLEANUP(); 1503 } 1504 1505 1506 TEST(macro_assembler_InstructionCondSizeRROp) { 1507 SETUP(); 1508 1509 // Special case for Orr <-> Orn correspondance. 1510 1511 COMPARE_T32(Orr(r0, r1, 0x00ffffff), "orn r0, r1, #0xff000000\n"); 1512 COMPARE_T32(Orrs(r0, r1, 0x00ffffff), "orns r0, r1, #0xff000000\n"); 1513 1514 // Encodable immediates. 1515 1516 COMPARE_A32(Add(r0, r1, -1), "sub r0, r1, #1\n"); 1517 COMPARE_A32(Adds(r0, r1, -1), "subs r0, r1, #1\n"); 1518 // 0xffffffff is encodable in a T32 ADD. 1519 COMPARE_T32(Add(r0, r1, -1), "add r0, r1, #4294967295\n"); 1520 COMPARE_T32(Adds(r0, r1, -1), "adds r0, r1, #4294967295\n"); 1521 1522 COMPARE_BOTH(Add(r0, r1, -4), "sub r0, r1, #4\n"); 1523 COMPARE_BOTH(Adds(r0, r1, -4), "subs r0, r1, #4\n"); 1524 1525 COMPARE_BOTH(Adc(r0, r1, -2), "sbc r0, r1, #1\n"); 1526 COMPARE_BOTH(Adcs(r0, r1, -2), "sbcs r0, r1, #1\n"); 1527 1528 COMPARE_A32(Sub(r0, r1, -1), "add r0, r1, #1\n"); 1529 COMPARE_A32(Subs(r0, r1, -1), "adds r0, r1, #1\n"); 1530 // 0xffffffff is encodable in a T32 SUB. 1531 COMPARE_T32(Sub(r0, r1, -1), "sub r0, r1, #4294967295\n"); 1532 COMPARE_T32(Subs(r0, r1, -1), "subs r0, r1, #4294967295\n"); 1533 1534 COMPARE_BOTH(Sub(r0, r1, -4), "add r0, r1, #4\n"); 1535 COMPARE_BOTH(Subs(r0, r1, -4), "adds r0, r1, #4\n"); 1536 1537 COMPARE_BOTH(Sbc(r0, r1, -5), "adc r0, r1, #4\n"); 1538 COMPARE_BOTH(Sbcs(r0, r1, -5), "adcs r0, r1, #4\n"); 1539 1540 // Non-encodable immediates 1541 1542 COMPARE_BOTH(Adc(r0, r1, 0xabcd), 1543 "mov r0, #43981\n" 1544 "adc r0, r1, r0\n"); 1545 1546 COMPARE_BOTH(Adc(r0, r1, -0xabcd), 1547 "mov r0, #43980\n" // This represents #0xabcd - 1. 1548 "sbc r0, r1, r0\n"); 1549 1550 COMPARE_BOTH(Adc(r0, r1, 0x1234abcd), 1551 "mov r0, #43981\n" 1552 "movt r0, #4660\n" 1553 "adc r0, r1, r0\n"); 1554 1555 COMPARE_BOTH(Adc(r0, r1, -0x1234abcd), 1556 "mov r0, #43980\n" // This represents #0x1234abcd - 1. 1557 "movt r0, #4660\n" 1558 "sbc r0, r1, r0\n"); 1559 1560 // Non-encodable immediates with the same source and destination registers. 1561 1562 COMPARE_BOTH(Sbc(r0, r0, 0xabcd), 1563 "mov ip, #43981\n" 1564 "sbc r0, ip\n"); 1565 1566 COMPARE_BOTH(Sbc(r0, r0, -0xabcd), 1567 "mov ip, #43980\n" // This represents #0xabcd - 1. 1568 "adc r0, ip\n"); 1569 1570 COMPARE_BOTH(Sbc(r0, r0, 0x1234abcd), 1571 "mov ip, #43981\n" 1572 "movt ip, #4660\n" 1573 "sbc r0, ip\n"); 1574 1575 COMPARE_BOTH(Sbc(r0, r0, -0x1234abcd), 1576 "mov ip, #43980\n" // This represents #0x1234abcd - 1. 1577 "movt ip, #4660\n" 1578 "adc r0, ip\n"); 1579 1580 1581 // Test that we can pass a register shifted register operand in T32. 1582 1583 COMPARE_T32(Adc(r0, r1, Operand(r2, LSL, r3)), 1584 "lsl r0, r2, r3\n" 1585 "adc r0, r1, r0\n"); 1586 1587 COMPARE_T32(Add(r3, r2, Operand(r2, ASR, r3)), 1588 "asr r3, r2, r3\n" 1589 "add r3, r2, r3\n"); 1590 1591 COMPARE_T32(Ands(r3, r2, Operand(r2, LSR, r2)), 1592 "lsr r3, r2, r2\n" 1593 "ands r3, r2, r3\n"); 1594 1595 COMPARE_T32(Asr(r2, r2, Operand(r2, ROR, r2)), 1596 "ror ip, r2, r2\n" 1597 "asr r2, ip\n"); 1598 1599 COMPARE_T32(Asr(r2, r2, Operand(r2, ROR, r2)), 1600 "ror ip, r2, r2\n" 1601 "asr r2, ip\n"); 1602 1603 1604 CLEANUP(); 1605 } 1606 1607 1608 TEST(macro_assembler_InstructionCondRO) { 1609 SETUP(); 1610 1611 COMPARE_BOTH(Teq(r0, 0xbad), 1612 "mov ip, #2989\n" 1613 "teq r0, ip\n"); 1614 COMPARE_BOTH(Teq(r0, 0xbadbeef), 1615 "mov ip, #48879\n" 1616 "movt ip, #2989\n" 1617 "teq r0, ip\n"); 1618 MUST_FAIL_TEST_T32(Teq(r0, Operand(r1, LSL, r2)), 1619 "Ill-formed 'teq' instruction.\n"); 1620 1621 CLEANUP(); 1622 } 1623 1624 1625 TEST(macro_assembler_too_large_immediate) { 1626 SETUP(); 1627 1628 // Attempting to use a 17-bit immediate with movt. 1629 MUST_FAIL_TEST_BOTH(Movt(r0, 0x10000), "`Movt` expects a 16-bit immediate."); 1630 1631 CLEANUP(); 1632 } 1633 1634 TEST(macro_assembler_Cbz) { 1635 SETUP(); 1636 1637 #ifdef VIXL_INCLUDE_TARGET_A32 1638 // Cbz/Cbnz are not available in A32 mode. 1639 // Make sure GetArchitectureStatePCOffset() returns the correct value. 1640 __ UseA32(); 1641 Label label_64(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(), 64); 1642 MUST_FAIL_TEST_A32(Cbz(r0, &label_64), "Cbz is only available for T32.\n"); 1643 MUST_FAIL_TEST_A32(Cbnz(r0, &label_64), "Cbnz is only available for T32.\n"); 1644 #endif 1645 1646 #ifdef VIXL_INCLUDE_TARGET_T32 1647 // Make sure GetArchitectureStatePCOffset() returns the correct value. 1648 __ UseT32(); 1649 // Largest encodable offset. 1650 Label label_126(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(), 1651 126); 1652 COMPARE_T32(Cbz(r0, &label_126), "cbz r0, 0x00000082\n"); 1653 COMPARE_T32(Cbnz(r0, &label_126), "cbnz r0, 0x00000082\n"); 1654 1655 // Offset cannot be encoded. 1656 Label label_128(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(), 1657 128); 1658 COMPARE_T32(Cbz(r0, &label_128), 1659 "cbnz r0, 0x00000004\n" 1660 "b 0x00000084\n"); 1661 COMPARE_T32(Cbnz(r0, &label_128), 1662 "cbz r0, 0x00000004\n" 1663 "b 0x00000084\n"); 1664 1665 // Offset that cannot be encoded and needs 32-bit branch instruction. 1666 Label label_8192(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(), 1667 8192); 1668 COMPARE_T32(Cbz(r0, &label_8192), 1669 "cbnz r0, 0x00000006\n" 1670 "b 0x00002004\n"); 1671 COMPARE_T32(Cbnz(r0, &label_8192), 1672 "cbz r0, 0x00000006\n" 1673 "b 0x00002004\n"); 1674 1675 // Negative offset. 1676 Label label_neg(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(), -8); 1677 COMPARE_T32(Cbz(r0, &label_neg), 1678 "cbnz r0, 0x00000004\n" 1679 "b 0xfffffffc\n"); 1680 COMPARE_T32(Cbnz(r0, &label_neg), 1681 "cbz r0, 0x00000004\n" 1682 "b 0xfffffffc\n"); 1683 1684 // Large negative offset. 1685 Label label_neg128(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(), 1686 -128); 1687 COMPARE_T32(Cbz(r0, &label_neg128), 1688 "cbnz r0, 0x00000004\n" 1689 "b 0xffffff84\n"); 1690 COMPARE_T32(Cbnz(r0, &label_neg128), 1691 "cbz r0, 0x00000004\n" 1692 "b 0xffffff84\n"); 1693 #endif 1694 1695 CLEANUP(); 1696 } 1697 1698 1699 #define TEST_VMEMOP(MACRO_OP, STRING_OP, DST_REG) \ 1700 SETUP(); \ 1701 \ 1702 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 1024)), \ 1703 "add ip, r8, #1024\n" STRING_OP #DST_REG ", [ip]\n"); \ 1704 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 1371)), \ 1705 "add ip, r8, #1371\n" STRING_OP #DST_REG ", [ip]\n"); \ 1706 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 4113)), \ 1707 "add ip, r8, #17\n" \ 1708 "add ip, #4096\n" STRING_OP #DST_REG ", [ip]\n"); \ 1709 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 65808)), \ 1710 "add ip, r8, #272\n" \ 1711 "add ip, #65536\n" STRING_OP #DST_REG ", [ip]\n"); \ 1712 \ 1713 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -1024)), \ 1714 "sub ip, r8, #1024\n" STRING_OP #DST_REG ", [ip]\n"); \ 1715 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -1371)), \ 1716 "sub ip, r8, #1371\n" STRING_OP #DST_REG ", [ip]\n"); \ 1717 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -4113)), \ 1718 "sub ip, r8, #17\n" \ 1719 "sub ip, #4096\n" STRING_OP #DST_REG ", [ip]\n"); \ 1720 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -65808)), \ 1721 "sub ip, r8, #272\n" \ 1722 "sub ip, #65536\n" STRING_OP #DST_REG ", [ip]\n"); \ 1723 \ 1724 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 0, PreIndex)), \ 1725 STRING_OP #DST_REG ", [r9]\n"); \ 1726 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 137, PreIndex)), \ 1727 "add r9, #137\n" STRING_OP #DST_REG ", [r9]\n"); \ 1728 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 4110, PreIndex)), \ 1729 "add r9, #14\n" \ 1730 "add r9, #4096\n" STRING_OP #DST_REG ", [r9]\n"); \ 1731 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 65623, PreIndex)), \ 1732 "add r9, #87\n" \ 1733 "add r9, #65536\n" STRING_OP #DST_REG ", [r9]\n"); \ 1734 \ 1735 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -137, PreIndex)), \ 1736 "sub r9, #137\n" STRING_OP #DST_REG ", [r9]\n"); \ 1737 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -4110, PreIndex)), \ 1738 "sub r9, #14\n" \ 1739 "sub r9, #4096\n" STRING_OP #DST_REG ", [r9]\n"); \ 1740 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -65623, PreIndex)), \ 1741 "sub r9, #87\n" \ 1742 "sub r9, #65536\n" STRING_OP #DST_REG ", [r9]\n"); \ 1743 \ 1744 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 0, PostIndex)), \ 1745 STRING_OP #DST_REG ", [r10]\n"); \ 1746 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 137, PostIndex)), \ 1747 STRING_OP #DST_REG \ 1748 ", [r10]\n" \ 1749 "add r10, #137\n"); \ 1750 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 4110, PostIndex)), \ 1751 STRING_OP #DST_REG \ 1752 ", [r10]\n" \ 1753 "add r10, #14\n" \ 1754 "add r10, #4096\n"); \ 1755 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 65623, PostIndex)), \ 1756 STRING_OP #DST_REG \ 1757 ", [r10]\n" \ 1758 "add r10, #87\n" \ 1759 "add r10, #65536\n"); \ 1760 \ 1761 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -137, PostIndex)), \ 1762 STRING_OP #DST_REG \ 1763 ", [r10]\n" \ 1764 "sub r10, #137\n"); \ 1765 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -4110, PostIndex)), \ 1766 STRING_OP #DST_REG \ 1767 ", [r10]\n" \ 1768 "sub r10, #14\n" \ 1769 "sub r10, #4096\n"); \ 1770 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -65623, PostIndex)), \ 1771 STRING_OP #DST_REG \ 1772 ", [r10]\n" \ 1773 "sub r10, #87\n" \ 1774 "sub r10, #65536\n"); \ 1775 CLEANUP(); 1776 1777 TEST(macro_assembler_T32_Vldr_d) { TEST_VMEMOP(Vldr, "vldr ", d0); } 1778 1779 TEST(macro_assembler_T32_Vstr_d) { TEST_VMEMOP(Vstr, "vstr ", d1); } 1780 1781 TEST(macro_assembler_T32_Vldr_s) { TEST_VMEMOP(Vldr, "vldr ", s2); } 1782 1783 TEST(macro_assembler_T32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); } 1784 1785 #undef TEST_VMEMOP 1786 1787 #define TEST_VMEMOP(MACRO_OP, STRING_OP, DST_REG) \ 1788 SETUP(); \ 1789 \ 1790 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 137)), \ 1791 "add ip, r8, #137\n" STRING_OP #DST_REG ", [ip]\n"); \ 1792 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 274)), \ 1793 "add ip, r8, #18\n" \ 1794 "add ip, #256\n" STRING_OP #DST_REG ", [ip]\n"); \ 1795 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 65623)), \ 1796 "add ip, r8, #87\n" \ 1797 "add ip, #65536\n" STRING_OP #DST_REG ", [ip]\n"); \ 1798 \ 1799 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -137)), \ 1800 "sub ip, r8, #137\n" STRING_OP #DST_REG ", [ip]\n"); \ 1801 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -274)), \ 1802 "sub ip, r8, #18\n" \ 1803 "sub ip, #256\n" STRING_OP #DST_REG ", [ip]\n"); \ 1804 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -65623)), \ 1805 "sub ip, r8, #87\n" \ 1806 "sub ip, #65536\n" STRING_OP #DST_REG ", [ip]\n"); \ 1807 \ 1808 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 0, PreIndex)), \ 1809 STRING_OP #DST_REG ", [r9]\n"); \ 1810 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 137, PreIndex)), \ 1811 "add r9, #137\n" STRING_OP #DST_REG ", [r9]\n"); \ 1812 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 274, PreIndex)), \ 1813 "add r9, #18\n" \ 1814 "add r9, #256\n" STRING_OP #DST_REG ", [r9]\n"); \ 1815 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 65623, PreIndex)), \ 1816 "add r9, #87\n" \ 1817 "add r9, #65536\n" STRING_OP #DST_REG ", [r9]\n"); \ 1818 \ 1819 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -137, PreIndex)), \ 1820 "sub r9, #137\n" STRING_OP #DST_REG ", [r9]\n"); \ 1821 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -274, PreIndex)), \ 1822 "sub r9, #18\n" \ 1823 "sub r9, #256\n" STRING_OP #DST_REG ", [r9]\n"); \ 1824 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -65623, PreIndex)), \ 1825 "sub r9, #87\n" \ 1826 "sub r9, #65536\n" STRING_OP #DST_REG ", [r9]\n"); \ 1827 \ 1828 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 0, PostIndex)), \ 1829 STRING_OP #DST_REG ", [r10]\n"); \ 1830 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 137, PostIndex)), \ 1831 STRING_OP #DST_REG \ 1832 ", [r10]\n" \ 1833 "add r10, #137\n"); \ 1834 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 274, PostIndex)), \ 1835 STRING_OP #DST_REG \ 1836 ", [r10]\n" \ 1837 "add r10, #18\n" \ 1838 "add r10, #256\n"); \ 1839 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 65623, PostIndex)), \ 1840 STRING_OP #DST_REG \ 1841 ", [r10]\n" \ 1842 "add r10, #87\n" \ 1843 "add r10, #65536\n"); \ 1844 \ 1845 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -137, PostIndex)), \ 1846 STRING_OP #DST_REG \ 1847 ", [r10]\n" \ 1848 "sub r10, #137\n"); \ 1849 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -274, PostIndex)), \ 1850 STRING_OP #DST_REG \ 1851 ", [r10]\n" \ 1852 "sub r10, #18\n" \ 1853 "sub r10, #256\n"); \ 1854 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -65623, PostIndex)), \ 1855 STRING_OP #DST_REG \ 1856 ", [r10]\n" \ 1857 "sub r10, #87\n" \ 1858 "sub r10, #65536\n"); \ 1859 CLEANUP(); 1860 1861 1862 TEST(macro_assembler_A32_Vldr_d) { TEST_VMEMOP(Vldr, "vldr ", d0); } 1863 1864 TEST(macro_assembler_A32_Vstr_d) { TEST_VMEMOP(Vstr, "vstr ", d1); } 1865 1866 TEST(macro_assembler_A32_Vldr_s) { TEST_VMEMOP(Vldr, "vldr ", s2); } 1867 1868 TEST(macro_assembler_A32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); } 1869 1870 #undef TEST_VMEMOP 1871 1872 TEST(macro_assembler_Vldr_Vstr_negative) { 1873 SETUP(); 1874 1875 MUST_FAIL_TEST_BOTH(Vldr(s0, MemOperand(pc, 1, PreIndex)), 1876 "The MacroAssembler does not convert vldr or vstr" 1877 " with a PC base register.\n"); 1878 1879 MUST_FAIL_TEST_BOTH(Vldr(s0, MemOperand(pc, r0, PreIndex)), 1880 "Ill-formed 'vldr' instruction.\n"); 1881 1882 MUST_FAIL_TEST_BOTH(Vstr(s0, MemOperand(pc, 1, PreIndex)), 1883 "The MacroAssembler does not convert vldr or vstr" 1884 " with a PC base register.\n"); 1885 1886 MUST_FAIL_TEST_BOTH(Vstr(s0, MemOperand(pc, r0, PreIndex)), 1887 "Ill-formed 'vstr' instruction.\n"); 1888 1889 MUST_FAIL_TEST_BOTH(Vldr(d0, MemOperand(pc, 1, PreIndex)), 1890 "The MacroAssembler does not convert vldr or vstr" 1891 " with a PC base register.\n"); 1892 1893 MUST_FAIL_TEST_BOTH(Vldr(d0, MemOperand(pc, r0, PreIndex)), 1894 "Ill-formed 'vldr' instruction.\n"); 1895 1896 MUST_FAIL_TEST_BOTH(Vstr(d0, MemOperand(pc, 1, PreIndex)), 1897 "The MacroAssembler does not convert vldr or vstr" 1898 " with a PC base register.\n"); 1899 1900 MUST_FAIL_TEST_BOTH(Vstr(d0, MemOperand(pc, r0, PreIndex)), 1901 "Ill-formed 'vstr' instruction.\n"); 1902 CLEANUP(); 1903 } 1904 1905 #define TEST_SHIFT_T32(Inst, name, offset) \ 1906 COMPARE_T32(Inst(r0, Operand(r1, LSL, r2)), \ 1907 "lsl ip, r1, r2\n" name " r0, ip\n"); \ 1908 COMPARE_T32(Inst(r0, Operand(r1, LSR, r2)), \ 1909 "lsr ip, r1, r2\n" name " r0, ip\n"); \ 1910 COMPARE_T32(Inst(r0, Operand(r1, ASR, r2)), \ 1911 "asr ip, r1, r2\n" name " r0, ip\n"); \ 1912 COMPARE_T32(Inst(r0, Operand(r1, ROR, r2)), \ 1913 "ror ip, r1, r2\n" name " r0, ip\n"); \ 1914 COMPARE_T32(Inst(eq, r0, Operand(r1, LSL, r2)), \ 1915 "bne " #offset \ 1916 "\n" \ 1917 "lsl ip, r1, r2\n" name " r0, ip\n"); \ 1918 COMPARE_T32(Inst(le, r0, Operand(r1, LSL, r2)), \ 1919 "bgt " #offset \ 1920 "\n" \ 1921 "lsl ip, r1, r2\n" name " r0, ip\n"); 1922 1923 #define TEST_MOV_SHIFT_T32(Inst, s, offset) \ 1924 COMPARE_T32(Inst(r0, Operand(r1, LSL, r2)), "lsl" s " r0, r1, r2\n"); \ 1925 COMPARE_T32(Inst(r0, Operand(r1, LSR, r2)), "lsr" s " r0, r1, r2\n"); \ 1926 COMPARE_T32(Inst(r0, Operand(r1, ASR, r2)), "asr" s " r0, r1, r2\n"); \ 1927 COMPARE_T32(Inst(r0, Operand(r1, ROR, r2)), "ror" s " r0, r1, r2\n"); \ 1928 COMPARE_T32(Inst(eq, r0, Operand(r1, LSL, r2)), \ 1929 "bne " #offset \ 1930 "\n" \ 1931 "lsl" s " r0, r1, r2\n"); \ 1932 COMPARE_T32(Inst(le, r0, Operand(r1, LSL, r2)), \ 1933 "bgt " #offset \ 1934 "\n" \ 1935 "lsl" s " r0, r1, r2\n"); 1936 1937 #define TEST_WIDE_IMMEDIATE(Inst, name, offset) \ 1938 COMPARE_BOTH(Inst(r0, 0xbadbeef), \ 1939 "mov ip, #48879\n" \ 1940 "movt ip, #2989\n" name " r0, ip\n"); \ 1941 COMPARE_A32(Inst(eq, r0, 0xbadbeef), \ 1942 "moveq ip, #48879\n" \ 1943 "movteq ip, #2989\n" name "eq r0, ip\n"); \ 1944 COMPARE_T32(Inst(eq, r0, 0xbadbeef), \ 1945 "bne " #offset \ 1946 "\n" \ 1947 "mov ip, #48879\n" \ 1948 "movt ip, #2989\n" name " r0, ip\n"); 1949 1950 #define TEST_WIDE_IMMEDIATE_PC(Inst, name, offset) \ 1951 COMPARE_A32(Inst(pc, 0xbadbeef), \ 1952 "mov ip, #48879\n" \ 1953 "movt ip, #2989\n" name " pc, ip\n"); \ 1954 COMPARE_A32(Inst(eq, pc, 0xbadbeef), \ 1955 "moveq ip, #48879\n" \ 1956 "movteq ip, #2989\n" name "eq pc, ip\n"); \ 1957 MUST_FAIL_TEST_T32(Inst(pc, 0xbadbeef), \ 1958 "Ill-formed '" name "' instruction.\n"); \ 1959 MUST_FAIL_TEST_T32(Inst(eq, pc, 0xbadbeef), \ 1960 "Ill-formed '" name "' instruction.\n"); 1961 1962 TEST(macro_assembler_InstructionCondSizeROp) { 1963 SETUP(); 1964 1965 // T32 register shifted register. 1966 TEST_SHIFT_T32(Cmn, "cmn", 0x0000000a) 1967 TEST_SHIFT_T32(Cmp, "cmp", 0x00000008) 1968 TEST_SHIFT_T32(Mvn, "mvn", 0x0000000a) 1969 TEST_SHIFT_T32(Mvns, "mvns", 0x0000000a) 1970 TEST_SHIFT_T32(Sxtb, "sxtb", 0x0000000a) 1971 TEST_SHIFT_T32(Sxth, "sxth", 0x0000000a) 1972 TEST_SHIFT_T32(Tst, "tst", 0x0000000a) 1973 TEST_SHIFT_T32(Uxtb, "uxtb", 0x0000000a) 1974 TEST_SHIFT_T32(Uxth, "uxth", 0x0000000a) 1975 1976 TEST_MOV_SHIFT_T32(Mov, "", 0x00000006) 1977 TEST_MOV_SHIFT_T32(Movs, "s", 0x00000006) 1978 1979 MUST_FAIL_TEST_BOTH(Movs(pc, r0), "Unpredictable instruction.\n"); 1980 MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, LSL, 0x4)), 1981 "Unpredictable instruction.\n"); 1982 MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, ASR, r2)), 1983 "Unpredictable instruction.\n"); 1984 1985 // Wide immediates (Mov and Movs are tested in 1986 // "macro_assembler_wide_immediate"). 1987 TEST_WIDE_IMMEDIATE(Cmp, "cmp", 0x0000000c); 1988 TEST_WIDE_IMMEDIATE(Cmn, "cmn", 0x0000000e); 1989 TEST_WIDE_IMMEDIATE(Tst, "tst", 0x0000000e); 1990 TEST_WIDE_IMMEDIATE_PC(Cmp, "cmp", 0x0000000c); 1991 TEST_WIDE_IMMEDIATE_PC(Cmn, "cmn", 0x0000000e); 1992 TEST_WIDE_IMMEDIATE_PC(Tst, "tst", 0x0000000e); 1993 1994 // For Mvn and Mvns, we don't allow PC as a destination. 1995 TEST_WIDE_IMMEDIATE(Mvn, "mvn", 0x0000000e); 1996 TEST_WIDE_IMMEDIATE(Mvns, "mvns", 0x0000000e); 1997 MUST_FAIL_TEST_BOTH(Mvn(pc, 0xbadbeef), "Ill-formed 'mvn' instruction.\n"); 1998 MUST_FAIL_TEST_BOTH(Mvn(eq, pc, 0xbadbeef), 1999 "Ill-formed 'mvn' instruction.\n"); 2000 MUST_FAIL_TEST_BOTH(Mvns(pc, 0xbadbeef), "Ill-formed 'mvns' instruction.\n"); 2001 MUST_FAIL_TEST_BOTH(Mvns(eq, pc, 0xbadbeef), 2002 "Ill-formed 'mvns' instruction.\n"); 2003 2004 MUST_FAIL_TEST_BOTH(Sxtb(r0, 0x1), "Ill-formed 'sxtb' instruction.\n"); 2005 MUST_FAIL_TEST_BOTH(Sxth(r0, 0x1), "Ill-formed 'sxth' instruction.\n"); 2006 MUST_FAIL_TEST_BOTH(Uxtb(r0, 0x1), "Ill-formed 'uxtb' instruction.\n"); 2007 MUST_FAIL_TEST_BOTH(Uxth(r0, 0x1), "Ill-formed 'uxth' instruction.\n"); 2008 2009 CLEANUP(); 2010 } 2011 2012 #undef TEST_SHIFT_T32 2013 #undef TEST_MOV_SHIFT_T32 2014 #undef TEST_WIDE_IMMEDIATE 2015 #undef TEST_WIDE_IMMEDIATE_PC 2016 2017 TEST(macro_assembler_Msr) { 2018 SETUP(); 2019 2020 // Msr with immediate for T32. 2021 COMPARE_T32(Msr(APSR_nzcvq, 0x0), 2022 "mov ip, #0\n" 2023 "msr APSR_nzcvq, ip\n"); 2024 2025 // Wide immediate. 2026 COMPARE_BOTH(Msr(APSR_nzcvq, 0xbadbeef), 2027 "mov ip, #48879\n" 2028 "movt ip, #2989\n" 2029 "msr APSR_nzcvq, ip\n"); 2030 2031 // Other types of operands are not handled. 2032 MUST_FAIL_TEST_BOTH(Msr(APSR_nzcvq, Operand(r0, LSR, r1)), 2033 "Ill-formed 'msr' instruction.\n"); 2034 CLEANUP(); 2035 } 2036 2037 2038 TEST(macro_assembler_Vmov_imm) { 2039 SETUP(); 2040 2041 COMPARE_BOTH(Vmov(s0, 0.0f), 2042 "mov ip, #0\n" 2043 "vmov s0, ip\n"); 2044 COMPARE_BOTH(Vmov(s1, 1.0f), "vmov.f32 s1, #1\n"); 2045 COMPARE_BOTH(Vmov(s2, RawbitsToFloat(0x0000db6c)), 2046 "mov ip, #56172\n" 2047 "vmov s2, ip\n"); 2048 COMPARE_BOTH(Vmov(s3, RawbitsToFloat(0x327b23c6)), 2049 "mov ip, #9158\n" 2050 "movt ip, #12923\n" 2051 "vmov s3, ip\n"); 2052 COMPARE_BOTH(Vmov(s4, RawbitsToFloat(0xffcc7fff)), 2053 "mvn ip, #3375104\n" 2054 "vmov s4, ip\n"); 2055 COMPARE_BOTH(Vmov(s5, RawbitsToFloat(0xb72df575)), 2056 "mov ip, #62837\n" 2057 "movt ip, #46893\n" 2058 "vmov s5, ip\n"); 2059 2060 COMPARE_BOTH(Vmov(d6, 0.0), "vmov.i64 d6, #0x0000000000000000\n"); 2061 COMPARE_BOTH(Vmov(d7, 1.0), "vmov.f64 d7, #1\n"); 2062 COMPARE_BOTH(Vmov(d8, RawbitsToDouble(0x000000000000af8e)), 2063 "mov ip, #44942\n" 2064 "vdup.32 d8, ip\n" 2065 "mov ip, #0\n" 2066 "vmov.32 d8[1], ip\n"); 2067 COMPARE_BOTH(Vmov(d9, RawbitsToDouble(0x000070210000af8e)), 2068 "mov ip, #44942\n" 2069 "vdup.32 d9, ip\n" 2070 "mov ip, #28705\n" 2071 "vmov.32 d9[1], ip\n"); 2072 COMPARE_BOTH(Vmov(d10, RawbitsToDouble(0x7021000000000000)), 2073 "mov ip, #0\n" 2074 "vdup.32 d10, ip\n" 2075 "mov ip, #0\n" 2076 "movt ip, #28705\n" 2077 "vmov.32 d10[1], ip\n"); 2078 COMPARE_BOTH(Vmov(d11, RawbitsToDouble(0x7021da4b0000af8e)), 2079 "mov ip, #44942\n" 2080 "vdup.32 d11, ip\n" 2081 "mov ip, #55883\n" 2082 "movt ip, #28705\n" 2083 "vmov.32 d11[1], ip\n"); 2084 COMPARE_BOTH(Vmov(d12, RawbitsToDouble(0x0cff553204ec4a3f)), 2085 "mov ip, #19007\n" 2086 "movt ip, #1260\n" 2087 "vdup.32 d12, ip\n" 2088 "mov ip, #21810\n" 2089 "movt ip, #3327\n" 2090 "vmov.32 d12[1], ip\n"); 2091 COMPARE_BOTH(Vmov(d13, RawbitsToDouble(0xa2037ad20000f592)), 2092 "mov ip, #62866\n" 2093 "vdup.32 d13, ip\n" 2094 "mov ip, #31442\n" 2095 "movt ip, #41475\n" 2096 "vmov.32 d13[1], ip\n"); 2097 COMPARE_BOTH(Vmov(d14, RawbitsToDouble(0xe62556c325a59470)), 2098 "mov ip, #38000\n" 2099 "movt ip, #9637\n" 2100 "vdup.32 d14, ip\n" 2101 "mov ip, #22211\n" 2102 "movt ip, #58917\n" 2103 "vmov.32 d14[1], ip\n"); 2104 CLEANUP(); 2105 } 2106 2107 TEST(macro_assembler_PushRegisterList) { 2108 SETUP(); 2109 2110 // Allow the test to use all registers. 2111 UseScratchRegisterScope temps(&masm); 2112 temps.ExcludeAll(); 2113 2114 COMPARE_BOTH(Push(RegisterList(0x1111)), "push {r0,r4,r8,ip}\n"); 2115 2116 COMPARE_BOTH(Push(RegisterList(0x1fff)), 2117 "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2118 2119 COMPARE_BOTH(Push(RegisterList(0x5fff)), 2120 "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip,lr}\n"); 2121 2122 COMPARE_A32(Push(ne, RegisterList(0x1fff)), 2123 "pushne {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2124 2125 COMPARE_T32(Push(ne, RegisterList(0x1fff)), 2126 "beq 0x00000006\n" 2127 "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2128 2129 COMPARE_A32(Push(RegisterList(sp)), "stmdb sp!, {sp}\n"); 2130 2131 // TODO: Clarify behaviour of MacroAssembler vs Assembler with respect to 2132 // deprecated and unpredictable instructions. The tests reflect the 2133 // current behaviour and will need to be updated. 2134 2135 // Deprecated, but accepted: 2136 SHOULD_FAIL_TEST_A32(Push(RegisterList(pc))); 2137 // Whereas we don't accept the single-register version: 2138 MUST_FAIL_TEST_A32(Push(pc), "Unpredictable instruction.\n"); 2139 2140 // For T32, pushing the PC is allowed: 2141 COMPARE_T32(Push(pc), "push {pc}\n"); 2142 2143 // Accepted, but stores UNKNOWN value for the SP: 2144 SHOULD_FAIL_TEST_A32(Push(RegisterList(r0, sp))); 2145 2146 // The following use the T1 and A1 encodings for T32 and A32 respectively, and 2147 // hence have different preferred disassembly. 2148 COMPARE_T32(Push(RegisterList(r0)), "push {r0}\n"); 2149 COMPARE_A32(Push(RegisterList(r0)), "stmdb sp!, {r0}\n"); 2150 COMPARE_T32(Push(RegisterList(r7)), "push {r7}\n"); 2151 COMPARE_A32(Push(RegisterList(r7)), "stmdb sp!, {r7}\n"); 2152 COMPARE_T32(Push(RegisterList(lr)), "push {lr}\n"); 2153 COMPARE_A32(Push(RegisterList(lr)), "stmdb sp!, {lr}\n"); 2154 2155 // T2 and A1 encodings, with the same preferred disassembly: 2156 COMPARE_BOTH(Push(RegisterList(r8)), "stmdb sp!, {r8}\n"); 2157 2158 // Cannot push the sp and pc in T32 when using a register list. 2159 MUST_FAIL_TEST_T32(Push(RegisterList(sp)), 2160 "Ill-formed 'push' instruction.\n"); 2161 MUST_FAIL_TEST_T32(Push(RegisterList(pc)), 2162 "Ill-formed 'push' instruction.\n"); 2163 2164 CLEANUP(); 2165 } 2166 2167 TEST(macro_assembler_PopRegisterList) { 2168 SETUP(); 2169 2170 // Allow the test to use all registers. 2171 UseScratchRegisterScope temps(&masm); 2172 temps.ExcludeAll(); 2173 2174 COMPARE_BOTH(Pop(RegisterList(0x1111)), "pop {r0,r4,r8,ip}\n"); 2175 2176 COMPARE_BOTH(Pop(RegisterList(0x1fff)), 2177 "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2178 2179 COMPARE_BOTH(Pop(RegisterList(0x5fff)), 2180 "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip,lr}\n"); 2181 2182 COMPARE_A32(Pop(ne, RegisterList(0x1fff)), 2183 "popne {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2184 2185 COMPARE_T32(Pop(ne, RegisterList(0x1fff)), 2186 "beq 0x00000006\n" 2187 "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2188 2189 // TODO: Accepted, but value of SP after the instruction is UNKNOWN: 2190 SHOULD_FAIL_TEST_A32(Pop(RegisterList(sp))); 2191 2192 // Cannot pop the sp in T32 when using a register list. 2193 MUST_FAIL_TEST_T32(Pop(RegisterList(sp)), "Ill-formed 'pop' instruction.\n"); 2194 2195 // The following use the T1 and A1 encodings for T32 and A32 respectively, and 2196 // hence have different preferred disassembly. 2197 COMPARE_T32(Pop(RegisterList(pc)), "pop {pc}\n"); 2198 COMPARE_A32(Pop(RegisterList(pc)), "ldm sp!, {pc}\n"); 2199 COMPARE_T32(Pop(RegisterList(r0)), "pop {r0}\n"); 2200 COMPARE_A32(Pop(RegisterList(r0)), "ldm sp!, {r0}\n"); 2201 COMPARE_T32(Pop(RegisterList(r7)), "pop {r7}\n"); 2202 COMPARE_A32(Pop(RegisterList(r7)), "ldm sp!, {r7}\n"); 2203 2204 // T2 and A1 encodings, with the same preferred disassembly: 2205 COMPARE_BOTH(Pop(RegisterList(r8)), "ldm sp!, {r8}\n"); 2206 COMPARE_BOTH(Pop(RegisterList(lr)), "ldm sp!, {lr}\n"); 2207 2208 // TODO: Pushing both the lr and pc should not be allowed by the 2209 // MacroAssembler (deprecated for A32, for T32 they shouldn't both 2210 // be in the list). 2211 SHOULD_FAIL_TEST_BOTH(Pop(RegisterList(lr, pc))); 2212 2213 CLEANUP(); 2214 } 2215 2216 2217 TEST(macro_assembler_unpredictable) { 2218 SETUP(); 2219 2220 // ADC, ADCS (immediate). 2221 COMPARE_A32(Adc(pc, r0, 1), "adc pc, r0, #1\n"); 2222 COMPARE_A32(Adc(r0, pc, 1), "adc r0, pc, #1\n"); 2223 MUST_FAIL_TEST_T32(Adc(pc, r0, 1), "Unpredictable instruction.\n"); 2224 MUST_FAIL_TEST_T32(Adc(r0, pc, 1), "Unpredictable instruction.\n"); 2225 COMPARE_A32(Adcs(pc, r0, 1), "adcs pc, r0, #1\n"); 2226 COMPARE_A32(Adcs(r0, pc, 1), "adcs r0, pc, #1\n"); 2227 MUST_FAIL_TEST_T32(Adcs(pc, r0, 1), "Unpredictable instruction.\n"); 2228 MUST_FAIL_TEST_T32(Adcs(r0, pc, 1), "Unpredictable instruction.\n"); 2229 2230 // ADC, ADCS (register). 2231 COMPARE_A32(Adc(pc, r0, r1), "adc pc, r0, r1\n"); 2232 COMPARE_A32(Adc(r0, pc, r1), "adc r0, pc, r1\n"); 2233 COMPARE_A32(Adc(r0, r1, pc), "adc r0, r1, pc\n"); 2234 MUST_FAIL_TEST_T32(Adc(pc, r0, r1), "Unpredictable instruction.\n"); 2235 MUST_FAIL_TEST_T32(Adc(r0, pc, r1), "Unpredictable instruction.\n"); 2236 MUST_FAIL_TEST_T32(Adc(r0, r1, pc), "Unpredictable instruction.\n"); 2237 COMPARE_A32(Adcs(pc, r0, r1), "adcs pc, r0, r1\n"); 2238 COMPARE_A32(Adcs(r0, pc, r1), "adcs r0, pc, r1\n"); 2239 COMPARE_A32(Adcs(r0, r1, pc), "adcs r0, r1, pc\n"); 2240 MUST_FAIL_TEST_T32(Adcs(pc, r0, r1), "Unpredictable instruction.\n"); 2241 MUST_FAIL_TEST_T32(Adcs(r0, pc, r1), "Unpredictable instruction.\n"); 2242 MUST_FAIL_TEST_T32(Adcs(r0, r1, pc), "Unpredictable instruction.\n"); 2243 2244 // ADC, ADCS (register-shifted register). 2245 MUST_FAIL_TEST_A32(Adc(pc, r0, Operand(r1, LSL, r2)), 2246 "Unpredictable instruction.\n"); 2247 MUST_FAIL_TEST_A32(Adc(r0, pc, Operand(r1, LSL, r2)), 2248 "Unpredictable instruction.\n"); 2249 MUST_FAIL_TEST_A32(Adc(r0, r1, Operand(pc, LSL, r2)), 2250 "Unpredictable instruction.\n"); 2251 MUST_FAIL_TEST_A32(Adc(r0, r1, Operand(r2, LSL, pc)), 2252 "Unpredictable instruction.\n"); 2253 MUST_FAIL_TEST_A32(Adcs(pc, r0, Operand(r1, LSL, r2)), 2254 "Unpredictable instruction.\n"); 2255 MUST_FAIL_TEST_A32(Adcs(r0, pc, Operand(r1, LSL, r2)), 2256 "Unpredictable instruction.\n"); 2257 MUST_FAIL_TEST_A32(Adcs(r0, r1, Operand(pc, LSL, r2)), 2258 "Unpredictable instruction.\n"); 2259 MUST_FAIL_TEST_A32(Adcs(r0, r1, Operand(r2, LSL, pc)), 2260 "Unpredictable instruction.\n"); 2261 2262 // ADD (immediate, to PC). 2263 COMPARE_A32(Add(r0, pc, 1), "adr r0, 0x00000009\n"); 2264 COMPARE_T32(Add(r0, pc, 1), "adr r0, 0x00000005\n"); 2265 COMPARE_A32(Add(pc, pc, 1), "adr pc, 0x00000009\n"); 2266 MUST_FAIL_TEST_T32(Add(pc, pc, 1), "Unpredictable instruction.\n"); 2267 2268 // ADD, ADDS (immediate). 2269 COMPARE_A32(Add(pc, r0, 1), "add pc, r0, #1\n"); 2270 MUST_FAIL_TEST_T32(Add(pc, r0, 1), "Unpredictable instruction.\n"); 2271 MUST_FAIL_TEST_T32(Add(pc, r0, 0x123), "Unpredictable instruction.\n"); 2272 COMPARE_A32(Adds(pc, r0, 1), "adds pc, r0, #1\n"); 2273 COMPARE_A32(Adds(r0, pc, 1), "adds r0, pc, #1\n"); 2274 // TODO: Try to make these error messages more consistent. 2275 MUST_FAIL_TEST_T32(Adds(r0, pc, 1), "Unpredictable instruction.\n"); 2276 MUST_FAIL_TEST_T32(Adds(r0, pc, 0x123), "Ill-formed 'adds' instruction.\n"); 2277 2278 // ADD, ADDS (register). 2279 COMPARE_A32(Add(pc, r0, r1), "add pc, r0, r1\n"); 2280 COMPARE_A32(Add(r0, pc, r1), "add r0, pc, r1\n"); 2281 COMPARE_A32(Add(r0, r1, pc), "add r0, r1, pc\n"); 2282 COMPARE_T32(Add(r0, r0, pc), "add r0, pc\n"); 2283 COMPARE_T32(Add(pc, pc, r0), "add pc, r0\n"); 2284 MUST_FAIL_TEST_T32(Add(pc, pc, pc), "Unpredictable instruction.\n"); 2285 MUST_FAIL_TEST_T32(Add(pc, r0, r1), "Unpredictable instruction.\n"); 2286 MUST_FAIL_TEST_T32(Add(r0, pc, r1), "Unpredictable instruction.\n"); 2287 MUST_FAIL_TEST_T32(Add(r0, r1, pc), "Unpredictable instruction.\n"); 2288 COMPARE_A32(Adds(pc, r0, r1), "adds pc, r0, r1\n"); 2289 COMPARE_A32(Adds(r0, pc, r1), "adds r0, pc, r1\n"); 2290 COMPARE_A32(Adds(r0, r1, pc), "adds r0, r1, pc\n"); 2291 MUST_FAIL_TEST_T32(Adds(r0, pc, r1), "Unpredictable instruction.\n"); 2292 MUST_FAIL_TEST_T32(Adds(r0, r1, pc), "Unpredictable instruction.\n"); 2293 2294 // ADD, ADDS (register-shifted register) 2295 MUST_FAIL_TEST_A32(Add(pc, r0, Operand(r1, LSL, r2)), 2296 "Unpredictable instruction.\n"); 2297 MUST_FAIL_TEST_A32(Add(r0, pc, Operand(r1, LSL, r2)), 2298 "Unpredictable instruction.\n"); 2299 MUST_FAIL_TEST_A32(Add(r0, r1, Operand(pc, LSL, r2)), 2300 "Unpredictable instruction.\n"); 2301 MUST_FAIL_TEST_A32(Add(r0, r1, Operand(r2, LSL, pc)), 2302 "Unpredictable instruction.\n"); 2303 COMPARE_A32(Add(pc, sp, 1), "add pc, sp, #1\n"); 2304 MUST_FAIL_TEST_T32(Add(pc, sp, 1), "Unpredictable instruction.\n"); 2305 MUST_FAIL_TEST_A32(Adds(pc, r0, Operand(r1, LSL, r2)), 2306 "Unpredictable instruction.\n"); 2307 MUST_FAIL_TEST_A32(Adds(r0, pc, Operand(r1, LSL, r2)), 2308 "Unpredictable instruction.\n"); 2309 MUST_FAIL_TEST_A32(Adds(r0, r1, Operand(pc, LSL, r2)), 2310 "Unpredictable instruction.\n"); 2311 MUST_FAIL_TEST_A32(Adds(r0, r1, Operand(r2, LSL, pc)), 2312 "Unpredictable instruction.\n"); 2313 2314 // ADD, ADDS (SP plus immediate). 2315 COMPARE_A32(Add(pc, sp, 1), "add pc, sp, #1\n"); 2316 MUST_FAIL_TEST_T32(Add(pc, sp, 1), "Unpredictable instruction.\n"); 2317 COMPARE_A32(Adds(pc, sp, 1), "adds pc, sp, #1\n"); 2318 MUST_FAIL_TEST_T32(Adds(pc, sp, 1), "Ill-formed 'adds' instruction.\n"); 2319 2320 // ADD, ADDS (SP plus register). 2321 COMPARE_A32(Add(pc, sp, r0), "add pc, sp, r0\n"); 2322 MUST_FAIL_TEST_T32(Add(pc, sp, r0), "Unpredictable instruction.\n"); 2323 COMPARE_A32(Add(r0, sp, pc), "add r0, sp, pc\n"); 2324 MUST_FAIL_TEST_T32(Add(r0, sp, pc), "Unpredictable instruction.\n"); 2325 COMPARE_BOTH(Add(pc, sp, pc), "add pc, sp, pc\n"); 2326 COMPARE_BOTH(Add(sp, sp, pc), "add sp, pc\n"); 2327 COMPARE_A32(Adds(pc, sp, r0), "adds pc, sp, r0\n"); 2328 MUST_FAIL_TEST_T32(Adds(pc, sp, r0), "Ill-formed 'adds' instruction.\n"); 2329 COMPARE_A32(Adds(r0, sp, pc), "adds r0, sp, pc\n"); 2330 MUST_FAIL_TEST_T32(Adds(r0, sp, pc), "Unpredictable instruction.\n"); 2331 COMPARE_A32(Adds(pc, sp, pc), "adds pc, sp, pc\n"); 2332 MUST_FAIL_TEST_T32(Adds(pc, sp, pc), "Ill-formed 'adds' instruction.\n"); 2333 COMPARE_A32(Adds(sp, sp, pc), "adds sp, pc\n"); 2334 MUST_FAIL_TEST_T32(Adds(sp, sp, pc), "Unpredictable instruction.\n"); 2335 2336 // ADR. 2337 { 2338 Literal<uint32_t> literal(0x12345678); 2339 // The address is 0x4 and not 0x0 because of the branch over the literal. 2340 // TODO: Consider disallowing this instruction. 2341 COMPARE_A32(Adr(pc, &literal), "adr pc, 0x00000004\n"); 2342 MUST_FAIL_TEST_T32(Adr(pc, &literal), "Unpredictable instruction.\n"); 2343 } 2344 2345 // CLZ. 2346 MUST_FAIL_TEST_BOTH(Clz(pc, r0), "Unpredictable instruction.\n"); 2347 MUST_FAIL_TEST_BOTH(Clz(r0, pc), "Unpredictable instruction.\n"); 2348 2349 // MOV, MOVS (immediate). 2350 COMPARE_A32(Mov(pc, 1), "mov pc, #1\n"); 2351 MUST_FAIL_TEST_T32(Mov(pc, 1), "Unpredictable instruction.\n"); 2352 MUST_FAIL_TEST_T32(Mov(pc, 0xfff), "Unpredictable instruction.\n"); 2353 COMPARE_A32(Mov(pc, 0xf000), "mov pc, #61440\n"); 2354 MUST_FAIL_TEST_T32(Mov(pc, 0xf000), "Unpredictable instruction.\n"); 2355 COMPARE_A32(Movs(pc, 1), "movs pc, #1\n"); 2356 MUST_FAIL_TEST_T32(Movs(pc, 1), "Unpredictable instruction.\n"); 2357 MUST_FAIL_TEST_BOTH(Movs(pc, 0xfff), "Ill-formed 'movs' instruction.\n"); 2358 COMPARE_A32(Movs(pc, 0xf000), "movs pc, #61440\n"); 2359 MUST_FAIL_TEST_T32(Movs(pc, 0xf000), "Unpredictable instruction.\n"); 2360 2361 // MOV, MOVS (register). 2362 COMPARE_BOTH(Mov(pc, r0), "mov pc, r0\n"); 2363 COMPARE_BOTH(Mov(r0, pc), "mov r0, pc\n"); 2364 MUST_FAIL_TEST_BOTH(Movs(pc, r0), "Unpredictable instruction.\n"); 2365 COMPARE_A32(Movs(r0, pc), "movs r0, pc\n"); 2366 MUST_FAIL_TEST_T32(Movs(r0, pc), "Unpredictable instruction.\n"); 2367 2368 // MOV, MOVS (register-shifted register). 2369 MUST_FAIL_TEST_BOTH(Mov(pc, Operand(r0, ASR, r1)), 2370 "Unpredictable instruction.\n"); 2371 MUST_FAIL_TEST_BOTH(Mov(r0, Operand(pc, ASR, r1)), 2372 "Unpredictable instruction.\n"); 2373 MUST_FAIL_TEST_BOTH(Mov(r0, Operand(r1, ASR, pc)), 2374 "Unpredictable instruction.\n"); 2375 MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, ASR, r1)), 2376 "Unpredictable instruction.\n"); 2377 MUST_FAIL_TEST_BOTH(Movs(r0, Operand(pc, ASR, r1)), 2378 "Unpredictable instruction.\n"); 2379 MUST_FAIL_TEST_BOTH(Movs(r0, Operand(r1, ASR, pc)), 2380 "Unpredictable instruction.\n"); 2381 2382 CLEANUP(); 2383 } 2384 2385 2386 TEST(macro_assembler_pc_rel_A32) { 2387 SETUP(); 2388 // Simple cases alias adr. 2389 COMPARE_A32(Add(r0, pc, -8), "adr r0, 0x00000000\n"); 2390 COMPARE_A32(Add(r0, pc, 255), "adr r0, 0x00000107\n"); 2391 COMPARE_A32(Add(r0, pc, 256), "adr r0, 0x00000108\n"); 2392 COMPARE_A32(Add(r0, pc, 1024), "adr r0, 0x00000408\n"); 2393 COMPARE_A32(Add(r0, pc, -9), "adr r0, 0xffffffff\n"); 2394 COMPARE_A32(Add(r0, pc, -1024), "adr r0, 0xfffffc08\n"); 2395 COMPARE_A32(Add(r0, pc, UINT32_C(0x80000000)), "adr r0, 0x80000008\n"); 2396 COMPARE_A32(Add(r0, pc, -0x7fffffff), "adr r0, 0x80000009\n"); 2397 2398 COMPARE_A32(Sub(r0, pc, 8), "adr r0, 0x00000000\n"); 2399 COMPARE_A32(Sub(r0, pc, -255), "adr r0, 0x00000107\n"); 2400 COMPARE_A32(Sub(r0, pc, -256), "adr r0, 0x00000108\n"); 2401 COMPARE_A32(Sub(r0, pc, -1024), "adr r0, 0x00000408\n"); 2402 COMPARE_A32(Sub(r0, pc, 9), "adr r0, 0xffffffff\n"); 2403 COMPARE_A32(Sub(r0, pc, 1024), "adr r0, 0xfffffc08\n"); 2404 COMPARE_A32(Sub(r0, pc, UINT32_C(0x80000000)), "adr r0, 0x80000008\n"); 2405 COMPARE_A32(Sub(r0, pc, -0x7fffffff), "adr r0, 0x80000007\n"); 2406 2407 // Cases out of range. 2408 // Only negative offsets are supported, because the proper behaviour for 2409 // positive offsets is not clear. 2410 MUST_FAIL_TEST_A32(Add(r0, pc, 1025), "Ill-formed 'add' instruction.\n"); 2411 MUST_FAIL_TEST_A32(Add(r0, pc, 0xffff), "Ill-formed 'add' instruction.\n"); 2412 MUST_FAIL_TEST_A32(Add(r0, pc, 0x10001), "Ill-formed 'add' instruction.\n"); 2413 MUST_FAIL_TEST_A32(Add(r0, pc, 0x12345678), 2414 "Ill-formed 'add' instruction.\n"); 2415 MUST_FAIL_TEST_A32(Add(r0, pc, 0x7fffffff), 2416 "Ill-formed 'add' instruction.\n"); 2417 COMPARE_A32(Add(r0, pc, -1025), 2418 "adr r0, 0x00000007\n" 2419 "sub r0, #1024\n"); 2420 COMPARE_A32(Add(r0, pc, -0xffff), 2421 "adr r0, 0xffffff09\n" 2422 "sub r0, #65280\n"); 2423 COMPARE_A32(Add(r0, pc, -0x10001), 2424 "adr r0, 0x00000007\n" 2425 "sub r0, #65536\n"); 2426 COMPARE_A32(Add(r0, pc, -0x2345678), 2427 "adr r0, 0xfffffd90\n" 2428 "sub r0, #21504\n" 2429 "sub r0, #36962304\n"); 2430 COMPARE_A32(Add(r0, pc, -0x12345678), 2431 "adr r0, 0xfffffd90\n" 2432 "mov ip, #21504\n" 2433 "movt ip, #4660\n" 2434 "sub r0, ip\n"); 2435 2436 MUST_FAIL_TEST_A32(Sub(r0, pc, -1025), "Ill-formed 'add' instruction.\n"); 2437 MUST_FAIL_TEST_A32(Sub(r0, pc, -0xffff), "Ill-formed 'add' instruction.\n"); 2438 MUST_FAIL_TEST_A32(Sub(r0, pc, -0x10001), "Ill-formed 'add' instruction.\n"); 2439 MUST_FAIL_TEST_A32(Sub(r0, pc, -0x12345678), 2440 "Ill-formed 'add' instruction.\n"); 2441 COMPARE_A32(Sub(r0, pc, 1025), 2442 "adr r0, 0x00000007\n" 2443 "sub r0, #1024\n"); 2444 COMPARE_A32(Sub(r0, pc, 0xffff), 2445 "adr r0, 0xffffff09\n" 2446 "sub r0, #65280\n"); 2447 COMPARE_A32(Sub(r0, pc, 0x10001), 2448 "adr r0, 0x00000007\n" 2449 "sub r0, #65536\n"); 2450 COMPARE_A32(Sub(r0, pc, 0x2345678), 2451 "adr r0, 0xfffffd90\n" 2452 "sub r0, #21504\n" 2453 "sub r0, #36962304\n"); 2454 COMPARE_A32(Sub(r0, pc, 0x12345678), 2455 "adr r0, 0xfffffd90\n" 2456 "mov ip, #21504\n" 2457 "movt ip, #4660\n" 2458 "sub r0, ip\n"); 2459 COMPARE_A32(Sub(r0, pc, 0x7fffffff), 2460 "adr r0, 0xffffff09\n" 2461 "add r0, #256\n" 2462 "add r0, #2147483648\n"); 2463 2464 CLEANUP(); 2465 } 2466 2467 2468 TEST(macro_assembler_pc_rel_T32) { 2469 SETUP(); 2470 // Simple cases alias adr. 2471 COMPARE_T32(Add(r0, pc, -4), "adr r0, 0x00000000\n"); // T1 2472 COMPARE_T32(Add(r0, pc, 1020), "adr r0, 0x00000400\n"); // T1 2473 COMPARE_T32(Add(r0, pc, -5), "adr r0, 0xffffffff\n"); // T2 2474 COMPARE_T32(Add(r0, pc, -4095), "adr r0, 0xfffff005\n"); // T2 2475 COMPARE_T32(Add(r0, pc, -3), "adr r0, 0x00000001\n"); // T3 2476 COMPARE_T32(Add(r0, pc, 1021), "adr r0, 0x00000401\n"); // T3 2477 COMPARE_T32(Add(r0, pc, 1019), "adr r0, 0x000003ff\n"); // T3 2478 COMPARE_T32(Add(r0, pc, 4095), "adr r0, 0x00001003\n"); // T3 2479 2480 COMPARE_T32(Sub(r0, pc, 4), "adr r0, 0x00000000\n"); // T1 2481 COMPARE_T32(Sub(r0, pc, -1020), "adr r0, 0x00000400\n"); // T1 2482 COMPARE_T32(Sub(r0, pc, 5), "adr r0, 0xffffffff\n"); // T2 2483 COMPARE_T32(Sub(r0, pc, 4095), "adr r0, 0xfffff005\n"); // T2 2484 COMPARE_T32(Sub(r0, pc, 3), "adr r0, 0x00000001\n"); // T3 2485 COMPARE_T32(Sub(r0, pc, -1021), "adr r0, 0x00000401\n"); // T3 2486 COMPARE_T32(Sub(r0, pc, -1019), "adr r0, 0x000003ff\n"); // T3 2487 COMPARE_T32(Sub(r0, pc, -4095), "adr r0, 0x00001003\n"); // T3 2488 2489 // Cases out of range. 2490 // Only negative offsets are supported, because the proper behaviour for 2491 // positive offsets is not clear. 2492 2493 MUST_FAIL_TEST_T32(Add(r0, pc, 4096), "Unpredictable instruction.\n"); 2494 2495 // TODO: This case is incorrect; the instruction is unpredictable. The test 2496 // must be updated once the bug is fixed. 2497 COMPARE_T32(Add(r0, pc, -4096), "sub r0, pc, #4096\n"); 2498 2499 MUST_FAIL_TEST_T32(Add(r0, pc, 0xffff), "Ill-formed 'add' instruction.\n"); 2500 MUST_FAIL_TEST_T32(Add(r0, pc, 0x10002), "Ill-formed 'add' instruction.\n"); 2501 MUST_FAIL_TEST_T32(Add(r0, pc, 0x12345678), 2502 "Ill-formed 'add' instruction.\n"); 2503 MUST_FAIL_TEST_T32(Add(r0, pc, 0x7fffffff), 2504 "Ill-formed 'add' instruction.\n"); 2505 COMPARE_T32(Add(r0, pc, -0x12345678), 2506 "mov r0, pc\n" 2507 "mov ip, #22136\n" 2508 "movt ip, #4660\n" 2509 "sub r0, ip\n"); 2510 COMPARE_T32(Add(r0, pc, -0x7fffffff), 2511 "mov r0, pc\n" 2512 "add r0, #1\n" 2513 "add r0, #2147483648\n"); 2514 2515 // TODO: This test aborts in the Assembler (with unpredictable instruction 2516 // errors) before the MacroAssembler gets a chance to do something 2517 // predictable. 2518 // COMPARE_T32(Sub(r0, pc, -4096), "mov r0, pc\n" 2519 // "add r0, #4096\n"); 2520 2521 // TODO: This case is incorrect; the instruction is unpredictable. The test 2522 // must be updated once the bug is fixed. 2523 COMPARE_T32(Sub(r0, pc, 4096), "sub r0, pc, #4096\n"); 2524 2525 MUST_FAIL_TEST_T32(Sub(r0, pc, -0xffff), "Ill-formed 'add' instruction.\n"); 2526 MUST_FAIL_TEST_T32(Sub(r0, pc, -0x10002), "Ill-formed 'add' instruction.\n"); 2527 MUST_FAIL_TEST_T32(Sub(r0, pc, -0x12345678), 2528 "Ill-formed 'add' instruction.\n"); 2529 MUST_FAIL_TEST_T32(Sub(r0, pc, -0x7fffffff), 2530 "Ill-formed 'add' instruction.\n"); 2531 COMPARE_T32(Sub(r0, pc, 0x12345678), 2532 "mov r0, pc\n" 2533 "mov ip, #22136\n" 2534 "movt ip, #4660\n" 2535 "sub r0, ip\n"); 2536 COMPARE_T32(Sub(r0, pc, 0x7fffffff), 2537 "mov r0, pc\n" 2538 "add r0, #1\n" 2539 "add r0, #2147483648\n"); 2540 CLEANUP(); 2541 } 2542 2543 2544 TEST(macro_assembler_unsupported) { 2545 SETUP(); 2546 2547 MUST_FAIL_TEST_BOTH(Sxtab(r0, r1, Operand(r2, ROR, 1)), 2548 "Ill-formed 'sxtab' instruction.\n"); 2549 MUST_FAIL_TEST_BOTH(Sxtab16(r0, r1, Operand(r0, ASR, 2)), 2550 "Ill-formed 'sxtab16' instruction.\n"); 2551 MUST_FAIL_TEST_BOTH(Sxtah(r0, r1, Operand(r0, LSL, r1)), 2552 "Ill-formed 'sxtah' instruction.\n"); 2553 MUST_FAIL_TEST_BOTH(Uxtab(r0, r1, Operand(r0, LSR, r2)), 2554 "Ill-formed 'uxtab' instruction.\n"); 2555 MUST_FAIL_TEST_BOTH(Uxtab16(r0, r1, Operand(r0, ROR, 1)), 2556 "Ill-formed 'uxtab16' instruction.\n"); 2557 MUST_FAIL_TEST_BOTH(Uxtah(r0, r1, Operand(r0, ASR, 2)), 2558 "Ill-formed 'uxtah' instruction.\n"); 2559 MUST_FAIL_TEST_BOTH(Pkhbt(r0, r1, Operand(r0, LSL, r1)), 2560 "Ill-formed 'pkhbt' instruction.\n"); 2561 MUST_FAIL_TEST_BOTH(Pkhtb(r0, r1, Operand(r0, LSR, r2)), 2562 "Ill-formed 'pkhtb' instruction.\n"); 2563 2564 MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, 1, PreIndex)), 2565 "Ill-formed 'pld' instruction.\n"); 2566 MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, 1, PostIndex)), 2567 "Ill-formed 'pldw' instruction.\n"); 2568 MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, 1, PreIndex)), 2569 "Ill-formed 'pli' instruction.\n"); 2570 2571 MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, r0, PreIndex)), 2572 "Ill-formed 'pld' instruction.\n"); 2573 MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, r1, PostIndex)), 2574 "Ill-formed 'pldw' instruction.\n"); 2575 MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, r2, PreIndex)), 2576 "Ill-formed 'pli' instruction.\n"); 2577 2578 MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, r0, LSL, 1, PreIndex)), 2579 "Ill-formed 'pld' instruction.\n"); 2580 MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, r1, LSR, 2, PostIndex)), 2581 "Ill-formed 'pldw' instruction.\n"); 2582 MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, r2, ASR, 3, PreIndex)), 2583 "Ill-formed 'pli' instruction.\n"); 2584 2585 MUST_FAIL_TEST_BOTH(Lda(r0, MemOperand(r0, 1)), 2586 "Ill-formed 'lda' instruction.\n"); 2587 MUST_FAIL_TEST_BOTH(Ldab(r0, MemOperand(r0, 1)), 2588 "Ill-formed 'ldab' instruction.\n"); 2589 MUST_FAIL_TEST_BOTH(Ldaex(r0, MemOperand(r0, 1)), 2590 "Ill-formed 'ldaex' instruction.\n"); 2591 MUST_FAIL_TEST_BOTH(Ldaexb(r0, MemOperand(r0, 1)), 2592 "Ill-formed 'ldaexb' instruction.\n"); 2593 MUST_FAIL_TEST_BOTH(Ldaexh(r0, MemOperand(r0, 1)), 2594 "Ill-formed 'ldaexh' instruction.\n"); 2595 MUST_FAIL_TEST_BOTH(Ldah(r0, MemOperand(r0, 1)), 2596 "Ill-formed 'ldah' instruction.\n"); 2597 MUST_FAIL_TEST_BOTH(Ldrex(r0, MemOperand(r0, 1)), 2598 "Ill-formed 'ldrex' instruction.\n"); 2599 MUST_FAIL_TEST_BOTH(Ldrexb(r0, MemOperand(r0, 1)), 2600 "Ill-formed 'ldrexb' instruction.\n"); 2601 MUST_FAIL_TEST_BOTH(Ldrexh(r0, MemOperand(r0, 1)), 2602 "Ill-formed 'ldrexh' instruction.\n"); 2603 MUST_FAIL_TEST_BOTH(Stl(r0, MemOperand(r0, 1)), 2604 "Ill-formed 'stl' instruction.\n"); 2605 MUST_FAIL_TEST_BOTH(Stlb(r0, MemOperand(r0, 1)), 2606 "Ill-formed 'stlb' instruction.\n"); 2607 MUST_FAIL_TEST_BOTH(Stlh(r0, MemOperand(r0, 1)), 2608 "Ill-formed 'stlh' instruction.\n"); 2609 2610 MUST_FAIL_TEST_BOTH(Ldaexd(r0, r1, MemOperand(r0, 1)), 2611 "Ill-formed 'ldaexd' instruction.\n"); 2612 MUST_FAIL_TEST_BOTH(Ldrexd(r0, r1, MemOperand(r0, 1)), 2613 "Ill-formed 'ldrexd' instruction.\n"); 2614 MUST_FAIL_TEST_BOTH(Stlex(r0, r1, MemOperand(r0, 1)), 2615 "Ill-formed 'stlex' instruction.\n"); 2616 MUST_FAIL_TEST_BOTH(Stlexb(r0, r1, MemOperand(r0, 1)), 2617 "Ill-formed 'stlexb' instruction.\n"); 2618 MUST_FAIL_TEST_BOTH(Stlexh(r0, r1, MemOperand(r0, 1)), 2619 "Ill-formed 'stlexh' instruction.\n"); 2620 MUST_FAIL_TEST_BOTH(Strex(r0, r1, MemOperand(r0, 1)), 2621 "Ill-formed 'strex' instruction.\n"); 2622 MUST_FAIL_TEST_BOTH(Strexb(r0, r1, MemOperand(r0, 1)), 2623 "Ill-formed 'strexb' instruction.\n"); 2624 MUST_FAIL_TEST_BOTH(Strexh(r0, r1, MemOperand(r0, 1)), 2625 "Ill-formed 'strexh' instruction.\n"); 2626 2627 MUST_FAIL_TEST_BOTH(Stlexd(r0, r1, r2, MemOperand(r0, 1)), 2628 "Ill-formed 'stlexd' instruction.\n"); 2629 MUST_FAIL_TEST_BOTH(Strexd(r0, r1, r2, MemOperand(r0, 1)), 2630 "Ill-formed 'strexd' instruction.\n"); 2631 2632 CLEANUP(); 2633 } 2634 2635 TEST(macro_assembler_Vmov_neon_immediate) { 2636 SETUP(); 2637 2638 // Move 8, 16 and 32-bit immediates into D registers, duplicated across the 2639 // destination. 2640 COMPARE_BOTH(Vmov(I8, d0, 0xac), "vmov.i8 d0, #172\n"); 2641 2642 COMPARE_BOTH(Vmov(I16, d0, 0xa4), "vmov.i16 d0, #164\n"); 2643 COMPARE_BOTH(Vmov(I16, d0, 0x9797), "vmov.i8 d0, #151\n"); 2644 COMPARE_BOTH(Vmov(I16, d0, 0x9ef6), 2645 "mov ip, #40694\n" 2646 "vdup.16 d0, ip\n"); 2647 2648 COMPARE_BOTH(Vmov(I32, d0, 0x6d0000), "vmov.i32 d0, #7143424\n"); 2649 COMPARE_BOTH(Vmov(I32, d0, 0x15ffffff), "vmvn.i32 d0, #3925868544\n"); 2650 COMPARE_BOTH(Vmov(I32, d0, 0x74747474), "vmov.i8 d0, #116\n"); 2651 COMPARE_BOTH(Vmov(I32, d0, 0xff0000ff), "vmov.i64 d0, #0xff0000ffff0000ff\n"); 2652 COMPARE_BOTH(Vmov(I32, d0, 0x1ecb9ef6), 2653 "mov ip, #40694\n" 2654 "movt ip, #7883\n" 2655 "vdup.32 d0, ip\n"); 2656 COMPARE_BOTH(Vmov(I32, d0, 0x006d0000), "vmov.i32 d0, #7143424\n"); 2657 COMPARE_BOTH(Vmov(I32, d0, 0x00004da6), 2658 "mov ip, #19878\n" 2659 "vdup.32 d0, ip\n"); 2660 COMPARE_BOTH(Vmov(I32, d0, 0xffffff55), "vmvn.i32 d0, #170\n"); 2661 COMPARE_BOTH(Vmov(I32, d0, 0xffff55ff), "vmvn.i32 d0, #43520\n"); 2662 COMPARE_BOTH(Vmov(I32, d0, 0xff55ffff), "vmvn.i32 d0, #11141120\n"); 2663 2664 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0xa5a5a5a5a5a5a5a5)), 2665 "vmov.i8 d0, #165\n"); 2666 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x0a01248315ffffff)), 2667 "mvn ip, #3925868544\n" 2668 "vdup.32 d0, ip\n" 2669 "mov ip, #9347\n" 2670 "movt ip, #2561\n" 2671 "vmov.32 d0[1], ip\n"); 2672 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x6fe1a7a779e33af2)), 2673 "mov ip, #15090\n" 2674 "movt ip, #31203\n" 2675 "vdup.32 d0, ip\n" 2676 "mov ip, #42919\n" 2677 "movt ip, #28641\n" 2678 "vmov.32 d0[1], ip\n"); 2679 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x2efa8b440000c1da)), 2680 "mov ip, #49626\n" 2681 "vdup.32 d0, ip\n" 2682 "mov ip, #35652\n" 2683 "movt ip, #12026\n" 2684 "vmov.32 d0[1], ip\n"); 2685 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x00008bb75c3036fd)), 2686 "mov ip, #14077\n" 2687 "movt ip, #23600\n" 2688 "vdup.32 d0, ip\n" 2689 "mov ip, #35767\n" 2690 "vmov.32 d0[1], ip\n"); 2691 2692 COMPARE_BOTH(Vmov(F32, d0, 0.5), "vmov.f32 d0, #0.5\n"); 2693 COMPARE_BOTH(Vmov(F32, d0, 1.1), 2694 "mov ip, #52429\n" 2695 "movt ip, #16268\n" 2696 "vdup.32 d0, ip\n"); 2697 2698 COMPARE_T32(Vmov(I64, d0, UINT64_C(0x2fff2fff3e2869e7)), 2699 "mov ip, #27111\n" 2700 "movt ip, #15912\n" 2701 "vdup.32 d0, ip\n" 2702 "mvn ip, #3489714176\n" 2703 "vmov.32 d0[1], ip\n"); 2704 2705 COMPARE_A32(Vmov(I32, d0, 0x0ffffffa), 2706 "mvn ip, #4026531845\n" 2707 "vdup.32 d0, ip\n"); 2708 COMPARE_A32(Vmov(I64, d0, UINT64_C(0x65ffffff16a0ef46)), 2709 "mov ip, #61254\n" 2710 "movt ip, #5792\n" 2711 "vdup.32 d0, ip\n" 2712 "mvn ip, #2583691264\n" 2713 "vmov.32 d0[1], ip\n"); 2714 2715 // Move 8, 16 and 32-bit immediates into Q registers, duplicated across the 2716 // destination. 2717 COMPARE_BOTH(Vmov(I8, q0, 0xac), "vmov.i8 q0, #172\n"); 2718 2719 COMPARE_BOTH(Vmov(I16, q0, 0xa4), "vmov.i16 q0, #164\n"); 2720 COMPARE_BOTH(Vmov(I16, q0, 0x9797), "vmov.i8 q0, #151\n"); 2721 COMPARE_BOTH(Vmov(I16, q0, 0x9ef6), 2722 "mov ip, #40694\n" 2723 "vdup.16 q0, ip\n"); 2724 2725 COMPARE_BOTH(Vmov(I32, q0, 0x6d0000), "vmov.i32 q0, #7143424\n"); 2726 COMPARE_BOTH(Vmov(I32, q0, 0x15ffffff), "vmvn.i32 q0, #3925868544\n"); 2727 COMPARE_BOTH(Vmov(I32, q0, 0x74747474), "vmov.i8 q0, #116\n"); 2728 COMPARE_BOTH(Vmov(I32, q0, 0xff0000ff), "vmov.i64 q0, #0xff0000ffff0000ff\n"); 2729 COMPARE_BOTH(Vmov(I32, q0, 0x1ecb9ef6), 2730 "mov ip, #40694\n" 2731 "movt ip, #7883\n" 2732 "vdup.32 q0, ip\n"); 2733 COMPARE_BOTH(Vmov(I32, q0, 0x006d0000), "vmov.i32 q0, #7143424\n"); 2734 COMPARE_BOTH(Vmov(I32, q0, 0x00004da6), 2735 "mov ip, #19878\n" 2736 "vdup.32 q0, ip\n"); 2737 2738 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0xa5a5a5a5a5a5a5a5)), 2739 "vmov.i8 q0, #165\n"); 2740 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x0a01248315ffffff)), 2741 "mvn ip, #3925868544\n" 2742 "vdup.32 q0, ip\n" 2743 "mov ip, #9347\n" 2744 "movt ip, #2561\n" 2745 "vmov.32 d0[1], ip\n" 2746 "vmov.f64 d1, d0\n"); 2747 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x6fe1a7a779e33af2)), 2748 "mov ip, #15090\n" 2749 "movt ip, #31203\n" 2750 "vdup.32 q0, ip\n" 2751 "mov ip, #42919\n" 2752 "movt ip, #28641\n" 2753 "vmov.32 d0[1], ip\n" 2754 "vmov.f64 d1, d0\n"); 2755 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x2efa8b440000c1da)), 2756 "mov ip, #49626\n" 2757 "vdup.32 q0, ip\n" 2758 "mov ip, #35652\n" 2759 "movt ip, #12026\n" 2760 "vmov.32 d0[1], ip\n" 2761 "vmov.f64 d1, d0\n"); 2762 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x00008bb75c3036fd)), 2763 "mov ip, #14077\n" 2764 "movt ip, #23600\n" 2765 "vdup.32 q0, ip\n" 2766 "mov ip, #35767\n" 2767 "vmov.32 d0[1], ip\n" 2768 "vmov.f64 d1, d0\n"); 2769 2770 COMPARE_BOTH(Vmov(F32, q0, 0.5), "vmov.f32 q0, #0.5\n"); 2771 COMPARE_BOTH(Vmov(F32, q0, 1.1), 2772 "mov ip, #52429\n" 2773 "movt ip, #16268\n" 2774 "vdup.32 q0, ip\n"); 2775 COMPARE_BOTH(Vmov(F64, q0, 0.5), 2776 "vmov.f64 d0, #0.5\n" 2777 "vmov.f64 d1, d0\n"); 2778 COMPARE_BOTH(Vmov(F64, q0, 1.1), 2779 "mov ip, #39322\n" 2780 "movt ip, #39321\n" 2781 "vdup.32 d0, ip\n" 2782 "mov ip, #39321\n" 2783 "movt ip, #16369\n" 2784 "vmov.32 d0[1], ip\n" 2785 "vmov.f64 d1, d0\n"); 2786 2787 COMPARE_T32(Vmov(I64, q0, UINT64_C(0x2fff2fff3e2869e7)), 2788 "mov ip, #27111\n" 2789 "movt ip, #15912\n" 2790 "vdup.32 q0, ip\n" 2791 "mvn ip, #3489714176\n" 2792 "vmov.32 d0[1], ip\n" 2793 "vmov.f64 d1, d0\n"); 2794 2795 COMPARE_A32(Vmov(I32, q0, 0x0ffffffa), 2796 "mvn ip, #4026531845\n" 2797 "vdup.32 q0, ip\n"); 2798 COMPARE_A32(Vmov(I64, q0, UINT64_C(0x65ffffff16a0ef46)), 2799 "mov ip, #61254\n" 2800 "movt ip, #5792\n" 2801 "vdup.32 q0, ip\n" 2802 "mvn ip, #2583691264\n" 2803 "vmov.32 d0[1], ip\n" 2804 "vmov.f64 d1, d0\n"); 2805 CLEANUP(); 2806 } 2807 2808 TEST(macro_assembler_T32_IT) { 2809 SETUP(); 2810 2811 // ADC (register) T1 2812 COMPARE_T32(Adc(eq, r0, r0, r1), 2813 "it eq\n" 2814 "adceq r0, r1\n"); 2815 2816 COMPARE_T32(Adc(eq, r0, r1, r2), 2817 "bne 0x00000006\n" 2818 "adc r0, r1, r2\n"); 2819 2820 // ADD (immediate) T1 2821 COMPARE_T32(Add(eq, r0, r1, 0x1), 2822 "it eq\n" 2823 "addeq r0, r1, #1\n"); 2824 2825 COMPARE_T32(Add(eq, r0, r1, 0x8), 2826 "bne 0x00000006\n" 2827 "add r0, r1, #8\n"); 2828 2829 // ADD (immediate) T2 2830 COMPARE_T32(Add(eq, r0, r0, 0xff), 2831 "it eq\n" 2832 "addeq r0, #255\n"); 2833 2834 // ADD (register) T1 2835 COMPARE_T32(Add(eq, r0, r1, r7), 2836 "it eq\n" 2837 "addeq r0, r1, r7\n"); 2838 2839 // ADD (register) T2 2840 COMPARE_T32(Add(eq, r5, r5, r8), 2841 "it eq\n" 2842 "addeq r5, r8\n"); 2843 2844 // ADD (SP plus immediate) T1 2845 COMPARE_T32(Add(eq, r7, sp, 1020), 2846 "it eq\n" 2847 "addeq r7, sp, #1020\n"); 2848 2849 COMPARE_T32(Add(eq, r7, sp, 1), 2850 "bne 0x00000006\n" 2851 "add r7, sp, #1\n"); 2852 2853 COMPARE_T32(Add(eq, r7, sp, 1024), 2854 "bne 0x00000006\n" 2855 "add r7, sp, #1024\n"); 2856 2857 COMPARE_T32(Add(eq, sp, sp, 32), 2858 "bne 0x00000004\n" 2859 "add sp, #32\n"); 2860 2861 // ADD (SP plus register) T1 2862 COMPARE_T32(Add(eq, r7, sp, r7), 2863 "it eq\n" 2864 "addeq r7, sp, r7\n"); 2865 2866 // ADD (SP plus register) T2 2867 COMPARE_T32(Add(eq, sp, sp, r10), 2868 "it eq\n" 2869 "addeq sp, r10\n"); 2870 2871 COMPARE_T32(Add(eq, r5, r5, sp), 2872 "bne 0x00000006\n" 2873 "add.w r5, sp\n"); 2874 2875 // AND (register) T1 2876 COMPARE_T32(And(eq, r7, r7, r0), 2877 "it eq\n" 2878 "andeq r7, r0\n"); 2879 2880 COMPARE_T32(And(eq, r8, r8, r0), 2881 "bne 0x00000006\n" 2882 "and r8, r0\n"); 2883 2884 // ASR (immediate) T2 2885 COMPARE_T32(Asr(eq, r0, r1, 16), 2886 "it eq\n" 2887 "asreq r0, r1, #16\n"); 2888 2889 COMPARE_T32(Asr(eq, r0, r1, 32), 2890 "it eq\n" 2891 "asreq r0, r1, #32\n"); 2892 2893 COMPARE_T32(Asr(eq, r0, r1, 0), 2894 "bne 0x0000000a\n" 2895 "mov r0, #0\n" 2896 "asr r0, r1, r0\n"); 2897 2898 // ASR (register) T1 2899 COMPARE_T32(Asr(eq, r7, r7, r3), 2900 "it eq\n" 2901 "asreq r7, r3\n"); 2902 2903 COMPARE_T32(Asr(eq, r8, r8, r3), 2904 "bne 0x00000006\n" 2905 "asr r8, r3\n"); 2906 2907 // BIC (register) T1 2908 COMPARE_T32(Bic(eq, r7, r7, r6), 2909 "it eq\n" 2910 "biceq r7, r6\n"); 2911 2912 COMPARE_T32(Bic(eq, r8, r8, r6), 2913 "bne 0x00000006\n" 2914 "bic r8, r6\n"); 2915 2916 Label l; 2917 __ Bind(&l); 2918 2919 // BLX (register) T1 2920 COMPARE_T32(Blx(eq, lr), 2921 "it eq\n" 2922 "blxeq lr\n"); 2923 COMPARE_T32(Blx(eq, &l), 2924 "bne 0x00000006\n" 2925 "blx 0x00000000\n"); 2926 2927 // BX (register) T1 2928 COMPARE_T32(Bx(eq, lr), 2929 "it eq\n" 2930 "bxeq lr\n"); 2931 2932 // CMN (register) T1 2933 COMPARE_T32(Cmn(eq, r0, r1), 2934 "it eq\n" 2935 "cmneq r0, r1\n"); 2936 2937 COMPARE_T32(Cmn(eq, r0, r8), 2938 "bne 0x00000006\n" 2939 "cmn r0, r8\n"); 2940 2941 // CMP (immediate) T1 2942 COMPARE_T32(Cmp(eq, r7, 0xff), 2943 "it eq\n" 2944 "cmpeq r7, #255\n"); 2945 2946 // CMP (register) T1 2947 COMPARE_T32(Cmp(eq, r6, r7), 2948 "it eq\n" 2949 "cmpeq r6, r7\n"); 2950 2951 // CMP (register) T2 2952 COMPARE_T32(Cmp(eq, r9, r10), 2953 "it eq\n" 2954 "cmpeq r9, r10\n"); 2955 2956 COMPARE_T32(Cmp(eq, r0, 0x100), 2957 "bne 0x00000006\n" 2958 "cmp r0, #256\n"); 2959 2960 // EOR (register) T1 2961 COMPARE_T32(Eor(eq, r0, r0, r7), 2962 "it eq\n" 2963 "eoreq r0, r7\n"); 2964 2965 COMPARE_T32(Eor(eq, r0, r0, 0x1), 2966 "bne 0x00000006\n" 2967 "eor r0, #0x1\n"); 2968 2969 // LDR (immediate) T1 2970 COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 124)), 2971 "it eq\n" 2972 "ldreq r4, [r7, #124]\n"); 2973 2974 COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 1)), 2975 "bne 0x00000006\n" 2976 "ldr r4, [r7, #1]\n"); 2977 2978 COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 128)), 2979 "bne 0x00000006\n" 2980 "ldr r4, [r7, #128]\n"); 2981 2982 // LDR (immediate) T2 2983 COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1020)), 2984 "it eq\n" 2985 "ldreq r4, [sp, #1020]\n"); 2986 2987 COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1)), 2988 "bne 0x00000006\n" 2989 "ldr r4, [sp, #1]\n"); 2990 2991 COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1024)), 2992 "bne 0x00000006\n" 2993 "ldr r4, [sp, #1024]\n"); 2994 2995 // LDR (register) T1 2996 COMPARE_T32(Ldr(eq, r5, MemOperand(r6, r7)), 2997 "it eq\n" 2998 "ldreq r5, [r6, r7]\n"); 2999 3000 COMPARE_T32(Ldr(eq, r5, MemOperand(r6, r8)), 3001 "bne 0x00000006\n" 3002 "ldr r5, [r6, r8]\n"); 3003 3004 // LDRB (immediate) T1 3005 COMPARE_T32(Ldrb(eq, r6, MemOperand(r7, 31)), 3006 "it eq\n" 3007 "ldrbeq r6, [r7, #31]\n"); 3008 3009 COMPARE_T32(Ldrb(eq, r6, MemOperand(r7, 32)), 3010 "bne 0x00000006\n" 3011 "ldrb r6, [r7, #32]\n"); 3012 3013 // LDRB (register) T1 3014 COMPARE_T32(Ldrb(eq, r5, MemOperand(r6, r7)), 3015 "it eq\n" 3016 "ldrbeq r5, [r6, r7]\n"); 3017 3018 COMPARE_T32(Ldrb(eq, r6, MemOperand(r9)), 3019 "bne 0x00000006\n" 3020 "ldrb r6, [r9]\n"); 3021 3022 // LDRH (immediate) T1 3023 COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 62)), 3024 "it eq\n" 3025 "ldrheq r6, [r7, #62]\n"); 3026 3027 COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 64)), 3028 "bne 0x00000006\n" 3029 "ldrh r6, [r7, #64]\n"); 3030 3031 COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 1)), 3032 "bne 0x00000006\n" 3033 "ldrh r6, [r7, #1]\n"); 3034 3035 // LDRH (register) T1 3036 COMPARE_T32(Ldrh(eq, r5, MemOperand(r6, r7)), 3037 "it eq\n" 3038 "ldrheq r5, [r6, r7]\n"); 3039 3040 COMPARE_T32(Ldrh(eq, r6, MemOperand(r9)), 3041 "bne 0x00000006\n" 3042 "ldrh r6, [r9]\n"); 3043 3044 // LDRSB (register) T1 3045 COMPARE_T32(Ldrsb(eq, r5, MemOperand(r6, r7)), 3046 "it eq\n" 3047 "ldrsbeq r5, [r6, r7]\n"); 3048 3049 COMPARE_T32(Ldrsb(eq, r6, MemOperand(r9)), 3050 "bne 0x00000006\n" 3051 "ldrsb r6, [r9]\n"); 3052 3053 // LDRSH (register) T1 3054 COMPARE_T32(Ldrsh(eq, r5, MemOperand(r6, r7)), 3055 "it eq\n" 3056 "ldrsheq r5, [r6, r7]\n"); 3057 3058 COMPARE_T32(Ldrsh(eq, r6, MemOperand(r9)), 3059 "bne 0x00000006\n" 3060 "ldrsh r6, [r9]\n"); 3061 3062 // LSL (immediate) T2 3063 COMPARE_T32(Lsl(eq, r0, r1, 16), 3064 "it eq\n" 3065 "lsleq r0, r1, #16\n"); 3066 3067 COMPARE_T32(Lsl(eq, r0, r1, 0), 3068 "bne 0x0000000a\n" 3069 "mov r0, #0\n" 3070 "lsl r0, r1, r0\n"); 3071 3072 COMPARE_T32(Lsl(eq, r0, r1, 32), 3073 "bne 0x0000000a\n" 3074 "mov r0, #32\n" 3075 "lsl r0, r1, r0\n"); 3076 3077 // LSL (register) T1 3078 COMPARE_T32(Lsl(eq, r7, r7, r3), 3079 "it eq\n" 3080 "lsleq r7, r3\n"); 3081 3082 COMPARE_T32(Lsl(eq, r8, r8, r3), 3083 "bne 0x00000006\n" 3084 "lsl r8, r3\n"); 3085 3086 // LSR (immediate) T2 3087 COMPARE_T32(Lsr(eq, r0, r1, 16), 3088 "it eq\n" 3089 "lsreq r0, r1, #16\n"); 3090 3091 COMPARE_T32(Lsr(eq, r0, r1, 32), 3092 "it eq\n" 3093 "lsreq r0, r1, #32\n"); 3094 3095 COMPARE_T32(Lsr(eq, r0, r1, 0), 3096 "bne 0x0000000a\n" 3097 "mov r0, #0\n" 3098 "lsr r0, r1, r0\n"); 3099 3100 // LSR (register) T1 3101 COMPARE_T32(Lsr(eq, r7, r7, r3), 3102 "it eq\n" 3103 "lsreq r7, r3\n"); 3104 3105 COMPARE_T32(Lsr(eq, r8, r8, r3), 3106 "bne 0x00000006\n" 3107 "lsr r8, r3\n"); 3108 3109 // MOV (immediate) T1 3110 COMPARE_T32(Mov(eq, r7, 0xff), 3111 "it eq\n" 3112 "moveq r7, #255\n"); 3113 3114 // MOV (register) T1 3115 COMPARE_T32(Mov(eq, r9, r8), 3116 "it eq\n" 3117 "moveq r9, r8\n"); 3118 3119 // MOV (register) T2 3120 COMPARE_T32(Mov(eq, r0, Operand(r1, LSR, 16)), 3121 "it eq\n" 3122 "lsreq r0, r1, #16\n"); 3123 3124 COMPARE_T32(Mov(eq, r0, Operand(r1, ROR, 16)), 3125 "bne 0x00000006\n" 3126 "ror r0, r1, #16\n"); 3127 3128 // MOV (register-shifted register) T1 3129 COMPARE_T32(Mov(eq, r0, Operand(r0, LSR, r1)), 3130 "it eq\n" 3131 "lsreq r0, r1\n"); 3132 3133 COMPARE_T32(Mov(eq, r0, Operand(r1, LSR, r2)), 3134 "bne 0x00000006\n" 3135 "lsr r0, r1, r2\n"); 3136 3137 // MUL (T1) 3138 COMPARE_T32(Mul(eq, r0, r1, r0), 3139 "it eq\n" 3140 "muleq r0, r1, r0\n"); 3141 3142 COMPARE_T32(Mul(eq, r0, r1, r2), 3143 "bne 0x00000006\n" 3144 "mul r0, r1, r2\n"); 3145 3146 // MVN (register) T1 3147 COMPARE_T32(Mvn(eq, r4, r6), 3148 "it eq\n" 3149 "mvneq r4, r6\n"); 3150 3151 COMPARE_T32(Mvn(eq, r8, r6), 3152 "bne 0x00000006\n" 3153 "mvn r8, r6\n"); 3154 3155 // ORR (register) T1 3156 COMPARE_T32(Orr(eq, r0, r0, r1), 3157 "it eq\n" 3158 "orreq r0, r1\n"); 3159 3160 COMPARE_T32(Orr(eq, r0, r1, r2), 3161 "bne 0x00000006\n" 3162 "orr r0, r1, r2\n"); 3163 3164 // ROR (register) T1 3165 COMPARE_T32(Ror(eq, r7, r7, r3), 3166 "it eq\n" 3167 "roreq r7, r3\n"); 3168 3169 COMPARE_T32(Ror(eq, r8, r8, r3), 3170 "bne 0x00000006\n" 3171 "ror r8, r3\n"); 3172 3173 COMPARE_T32(Ror(eq, r0, r1, 16), 3174 "bne 0x00000006\n" 3175 "ror r0, r1, #16\n"); 3176 3177 // RSB (immediate) T1 3178 COMPARE_T32(Rsb(eq, r0, r1, 0), 3179 "it eq\n" 3180 "rsbeq r0, r1, #0\n"); 3181 3182 COMPARE_T32(Rsb(eq, r0, r1, 1), 3183 "bne 0x00000006\n" 3184 "rsb r0, r1, #1\n"); 3185 3186 // SBC (register) T1 3187 COMPARE_T32(Sbc(eq, r0, r0, r1), 3188 "it eq\n" 3189 "sbceq r0, r1\n"); 3190 3191 COMPARE_T32(Sbc(eq, r0, r1, r2), 3192 "bne 0x00000006\n" 3193 "sbc r0, r1, r2\n"); 3194 3195 // STR (immediate) T1 3196 COMPARE_T32(Str(eq, r4, MemOperand(r7, 124)), 3197 "it eq\n" 3198 "streq r4, [r7, #124]\n"); 3199 3200 COMPARE_T32(Str(eq, r4, MemOperand(r7, 1)), 3201 "bne 0x00000006\n" 3202 "str r4, [r7, #1]\n"); 3203 3204 COMPARE_T32(Str(eq, r4, MemOperand(r7, 128)), 3205 "bne 0x00000006\n" 3206 "str r4, [r7, #128]\n"); 3207 3208 // STR (immediate) T2 3209 COMPARE_T32(Str(eq, r4, MemOperand(sp, 1020)), 3210 "it eq\n" 3211 "streq r4, [sp, #1020]\n"); 3212 3213 COMPARE_T32(Str(eq, r4, MemOperand(sp, 1)), 3214 "bne 0x00000006\n" 3215 "str r4, [sp, #1]\n"); 3216 3217 COMPARE_T32(Str(eq, r4, MemOperand(sp, 1024)), 3218 "bne 0x00000006\n" 3219 "str r4, [sp, #1024]\n"); 3220 3221 // STR (register) T1 3222 COMPARE_T32(Str(eq, r5, MemOperand(r6, r7)), 3223 "it eq\n" 3224 "streq r5, [r6, r7]\n"); 3225 3226 COMPARE_T32(Str(eq, r5, MemOperand(r6, r8)), 3227 "bne 0x00000006\n" 3228 "str r5, [r6, r8]\n"); 3229 3230 // STRB (immediate) T1 3231 COMPARE_T32(Strb(eq, r6, MemOperand(r7, 31)), 3232 "it eq\n" 3233 "strbeq r6, [r7, #31]\n"); 3234 3235 COMPARE_T32(Strb(eq, r6, MemOperand(r7, 32)), 3236 "bne 0x00000006\n" 3237 "strb r6, [r7, #32]\n"); 3238 3239 // STRB (register) T1 3240 COMPARE_T32(Strb(eq, r5, MemOperand(r6, r7)), 3241 "it eq\n" 3242 "strbeq r5, [r6, r7]\n"); 3243 3244 COMPARE_T32(Strb(eq, r6, MemOperand(r9)), 3245 "bne 0x00000006\n" 3246 "strb r6, [r9]\n"); 3247 3248 // STRH (immediate) T1 3249 COMPARE_T32(Strh(eq, r6, MemOperand(r7, 62)), 3250 "it eq\n" 3251 "strheq r6, [r7, #62]\n"); 3252 3253 COMPARE_T32(Strh(eq, r6, MemOperand(r7, 64)), 3254 "bne 0x00000006\n" 3255 "strh r6, [r7, #64]\n"); 3256 3257 COMPARE_T32(Strh(eq, r6, MemOperand(r7, 1)), 3258 "bne 0x00000006\n" 3259 "strh r6, [r7, #1]\n"); 3260 3261 // STRH (register) T1 3262 COMPARE_T32(Strh(eq, r5, MemOperand(r6, r7)), 3263 "it eq\n" 3264 "strheq r5, [r6, r7]\n"); 3265 3266 COMPARE_T32(Strh(eq, r6, MemOperand(r9)), 3267 "bne 0x00000006\n" 3268 "strh r6, [r9]\n"); 3269 3270 // SUB (immediate) T1 3271 COMPARE_T32(Sub(eq, r0, r1, 0x1), 3272 "it eq\n" 3273 "subeq r0, r1, #1\n"); 3274 3275 COMPARE_T32(Sub(eq, r0, r1, 0x8), 3276 "bne 0x00000006\n" 3277 "sub r0, r1, #8\n"); 3278 3279 // SUB (immediate) T2 3280 COMPARE_T32(Sub(eq, r0, r0, 0xff), 3281 "it eq\n" 3282 "subeq r0, #255\n"); 3283 3284 // SUB (register) T1 3285 COMPARE_T32(Sub(eq, r0, r1, r7), 3286 "it eq\n" 3287 "subeq r0, r1, r7\n"); 3288 3289 COMPARE_T32(Sub(eq, r5, r5, r8), 3290 "bne 0x00000006\n" 3291 "sub r5, r8\n"); 3292 3293 COMPARE_T32(Sub(eq, r7, sp, 1), 3294 "bne 0x00000006\n" 3295 "sub r7, sp, #1\n"); 3296 3297 COMPARE_T32(Sub(eq, pc, pc, 0), 3298 "bne 0x00000006\n" 3299 "sub pc, #0\n"); 3300 3301 // TST (register) T1 3302 COMPARE_T32(Tst(eq, r0, r1), 3303 "it eq\n" 3304 "tsteq r0, r1\n"); 3305 3306 COMPARE_T32(Tst(eq, r8, r9), 3307 "bne 0x00000006\n" 3308 "tst r8, r9\n"); 3309 3310 CLEANUP(); 3311 } 3312 3313 3314 TEST(unbound_label) { 3315 SETUP(); 3316 3317 #ifdef VIXL_DEBUG 3318 MUST_FAIL_TEST_BOTH_BLOCK({ 3319 Label label; 3320 masm.B(&label); 3321 }, "Label used but not bound.\n") 3322 3323 MUST_FAIL_TEST_BOTH_BLOCK({ 3324 Label label; 3325 masm.B(eq, &label); 3326 }, "Label used but not bound.\n") 3327 3328 MUST_FAIL_TEST_T32_BLOCK({ 3329 Label label; 3330 masm.Cbz(r0, &label); 3331 }, "Label used but not bound.\n") 3332 3333 MUST_FAIL_TEST_T32_BLOCK({ 3334 Label label; 3335 masm.Cbnz(r1, &label); 3336 }, "Label used but not bound.\n") 3337 #endif 3338 3339 CLEANUP(); 3340 } 3341 3342 3343 TEST(macro_assembler_AddressComputationHelper) { 3344 SETUP(); 3345 3346 // Simple cases: the address fits in the mask. 3347 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0xfff, 0xfff)), 3348 "ldr r0, [r1, #4095]\n"); 3349 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 1, 0xfff)), 3350 "ldr r0, [r1, #1]\n"); 3351 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0, 0xfff)), 3352 "ldr r0, [r1]\n"); 3353 3354 // Similar, but the base register must be preserved. (This has no effect for 3355 // encodable cases.) 3356 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r2, r1, 0xfff, 0xfff)), 3357 "ldr r0, [r1, #4095]\n"); 3358 3359 // Cases where the extra offset has to be aligned. 3360 COMPARE_A32(Vldr(d0, masm.MemOperandComputationHelper(r1, r1, 0x3fc, 0x3fc)), 3361 "vldr d0, [r1, #1020]\n"); 3362 3363 // Out-of-range offsets. 3364 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0x1000, 0xfff)), 3365 "add r1, #4096\n" 3366 "ldr r0, [r1]\n"); 3367 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r2, r1, 0x1000, 0xfff)), 3368 "add r2, r1, #4096\n" 3369 "ldr r0, [r2]\n"); 3370 COMPARE_A32(Ldr(r0, 3371 masm.MemOperandComputationHelper(r2, r1, 0xffffffff, 0xfff)), 3372 "sub r2, r1, #1\n" 3373 "ldr r0, [r2]\n"); 3374 3375 // TODO: Improve the code generation for these cases. 3376 3377 COMPARE_A32(Ldr(r0, 3378 masm.MemOperandComputationHelper(r2, r1, 0x12345678, 0xfff)), 3379 "mov r2, #20480\n" 3380 "movt r2, #4660\n" 3381 "add r2, r1, r2\n" 3382 "ldr r0, [r2, #1656]\n"); 3383 COMPARE_A32(Ldr(r0, 3384 masm.MemOperandComputationHelper(r2, r1, 0x7fffffff, 0xfff)), 3385 "sub r2, r1, #1\n" 3386 "sub r2, #2147483648\n" 3387 "ldr r0, [r2]\n"); 3388 COMPARE_A32(Ldr(r0, 3389 masm.MemOperandComputationHelper(r2, r1, 0xffcba000, 0xfff)), 3390 "sub r2, r1, #286720\n" 3391 "sub r2, #3145728\n" 3392 "ldr r0, [r2]\n"); 3393 3394 CLEANUP(); 3395 } 3396 3397 3398 TEST(barriers) { 3399 SETUP(); 3400 3401 // DMB 3402 COMPARE_BOTH(Dmb(SY), "dmb sy\n"); 3403 COMPARE_BOTH(Dmb(ST), "dmb st\n"); 3404 COMPARE_BOTH(Dmb(ISH), "dmb ish\n"); 3405 COMPARE_BOTH(Dmb(ISHST), "dmb ishst\n"); 3406 COMPARE_BOTH(Dmb(NSH), "dmb nsh\n"); 3407 COMPARE_BOTH(Dmb(NSHST), "dmb nshst\n"); 3408 COMPARE_BOTH(Dmb(OSH), "dmb osh\n"); 3409 COMPARE_BOTH(Dmb(OSHST), "dmb oshst\n"); 3410 3411 // DSB 3412 COMPARE_BOTH(Dsb(SY), "dsb sy\n"); 3413 COMPARE_BOTH(Dsb(ST), "dsb st\n"); 3414 COMPARE_BOTH(Dsb(ISH), "dsb ish\n"); 3415 COMPARE_BOTH(Dsb(ISHST), "dsb ishst\n"); 3416 COMPARE_BOTH(Dsb(NSH), "dsb nsh\n"); 3417 COMPARE_BOTH(Dsb(NSHST), "dsb nshst\n"); 3418 COMPARE_BOTH(Dsb(OSH), "dsb osh\n"); 3419 COMPARE_BOTH(Dsb(OSHST), "dsb oshst\n"); 3420 3421 // ISB 3422 COMPARE_BOTH(Isb(SY), "isb sy\n"); 3423 3424 CLEANUP(); 3425 } 3426 3427 3428 TEST(preloads) { 3429 // Smoke test for various pld/pli forms. 3430 SETUP(); 3431 3432 // PLD immediate 3433 COMPARE_BOTH(Pld(MemOperand(r0, 0)), "pld [r0]\n"); 3434 COMPARE_BOTH(Pld(MemOperand(r1, 123)), "pld [r1, #123]\n"); 3435 COMPARE_BOTH(Pld(MemOperand(r4, -123)), "pld [r4, #-123]\n"); 3436 3437 COMPARE_A32(Pld(MemOperand(r7, -4095)), "pld [r7, #-4095]\n"); 3438 3439 // PLDW immediate 3440 COMPARE_BOTH(Pldw(MemOperand(r0, 0)), "pldw [r0]\n"); 3441 COMPARE_BOTH(Pldw(MemOperand(r1, 123)), "pldw [r1, #123]\n"); 3442 COMPARE_BOTH(Pldw(MemOperand(r4, -123)), "pldw [r4, #-123]\n"); 3443 3444 COMPARE_A32(Pldw(MemOperand(r7, -4095)), "pldw [r7, #-4095]\n"); 3445 3446 // PLD register 3447 COMPARE_BOTH(Pld(MemOperand(r0, r1)), "pld [r0, r1]\n"); 3448 COMPARE_BOTH(Pld(MemOperand(r0, r1, LSL, 1)), "pld [r0, r1, lsl #1]\n"); 3449 3450 COMPARE_A32(Pld(MemOperand(r0, r1, LSL, 20)), "pld [r0, r1, lsl #20]\n"); 3451 3452 // PLDW register 3453 COMPARE_BOTH(Pldw(MemOperand(r0, r1)), "pldw [r0, r1]\n"); 3454 COMPARE_BOTH(Pldw(MemOperand(r0, r1, LSL, 1)), "pldw [r0, r1, lsl #1]\n"); 3455 3456 COMPARE_A32(Pldw(MemOperand(r0, r1, LSL, 20)), "pldw [r0, r1, lsl #20]\n"); 3457 3458 // PLD literal 3459 Label pld_label; 3460 COMPARE_A32(Pld(&pld_label);, "pld [pc, #-0]\n"); 3461 COMPARE_T32(Pld(&pld_label);, "pld [pc, #-0]\n"); 3462 __ Bind(&pld_label); 3463 3464 // PLI immediate 3465 COMPARE_BOTH(Pli(MemOperand(r0, 0)), "pli [r0]\n"); 3466 COMPARE_BOTH(Pli(MemOperand(r1, 123)), "pli [r1, #123]\n"); 3467 COMPARE_BOTH(Pli(MemOperand(r4, -123)), "pli [r4, #-123]\n"); 3468 3469 COMPARE_A32(Pli(MemOperand(r7, -4095)), "pli [r7, #-4095]\n"); 3470 3471 // PLI register 3472 COMPARE_BOTH(Pli(MemOperand(r0, r1)), "pli [r0, r1]\n"); 3473 COMPARE_BOTH(Pli(MemOperand(r0, r1, LSL, 1)), "pli [r0, r1, lsl #1]\n"); 3474 3475 COMPARE_A32(Pli(MemOperand(r0, r1, LSL, 20)), "pli [r0, r1, lsl #20]\n"); 3476 3477 // PLI literal 3478 Label pli_label; 3479 COMPARE_A32(Pli(&pli_label);, "pli [pc, #-0]\n"); 3480 COMPARE_T32(Pli(&pli_label);, "pli [pc, #-0]\n"); 3481 __ Bind(&pli_label); 3482 3483 CLEANUP(); 3484 } 3485 3486 3487 TEST(vmrs_vmsr) { 3488 SETUP(); 3489 3490 COMPARE_BOTH(Vmsr(FPSCR, r0), "vmsr FPSCR, r0\n"); 3491 3492 COMPARE_BOTH(Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR), 3493 "vmrs r1, FPSCR\n"); 3494 3495 COMPARE_BOTH(Vmrs(RegisterOrAPSR_nzcv(pc.GetCode()), FPSCR), 3496 "vmrs APSR_nzcv, FPSCR\n"); 3497 3498 CLEANUP(); 3499 } 3500 3501 3502 TEST(ldm_stm) { 3503 SETUP(); 3504 3505 // ldm/stm 3506 COMPARE_BOTH(Ldm(r0, NO_WRITE_BACK, RegisterList(r1)), "ldm r0, {r1}\n"); 3507 3508 COMPARE_BOTH(Ldm(r1, NO_WRITE_BACK, RegisterList(r2, r5, r9, r10)), 3509 "ldm r1, {r2,r5,r9,r10}\n"); 3510 3511 COMPARE_BOTH(Ldm(r0, WRITE_BACK, RegisterList(r1, r2)), "ldm r0!, {r1,r2}\n"); 3512 3513 COMPARE_BOTH(Stm(r1, NO_WRITE_BACK, RegisterList(r2, r5, r9, r10)), 3514 "stm r1, {r2,r5,r9,r10}\n"); 3515 3516 COMPARE_BOTH(Stm(r0, WRITE_BACK, RegisterList(r1, r2)), "stm r0!, {r1,r2}\n"); 3517 3518 // ldmda/stmda 3519 COMPARE_A32(Ldmda(r11, WRITE_BACK, RegisterList(r0, r1)), 3520 "ldmda r11!, {r0,r1}\n"); 3521 3522 COMPARE_A32(Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3523 "ldmda r11, {r2,r3}\n"); 3524 3525 COMPARE_A32(Stmda(r11, WRITE_BACK, RegisterList(r0, r1)), 3526 "stmda r11!, {r0,r1}\n"); 3527 3528 COMPARE_A32(Stmda(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3529 "stmda r11, {r2,r3}\n"); 3530 3531 // ldmib/stmib 3532 COMPARE_A32(Ldmib(r11, WRITE_BACK, RegisterList(r0, r1)), 3533 "ldmib r11!, {r0,r1}\n"); 3534 3535 COMPARE_A32(Ldmib(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3536 "ldmib r11, {r2,r3}\n"); 3537 3538 COMPARE_A32(Stmib(r11, WRITE_BACK, RegisterList(r0, r1)), 3539 "stmib r11!, {r0,r1}\n"); 3540 3541 COMPARE_A32(Stmib(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3542 "stmib r11, {r2,r3}\n"); 3543 3544 // ldmdb/stmdb 3545 COMPARE_BOTH(Ldmdb(r11, WRITE_BACK, RegisterList(r0, r1)), 3546 "ldmdb r11!, {r0,r1}\n"); 3547 3548 COMPARE_BOTH(Ldmdb(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3549 "ldmdb r11, {r2,r3}\n"); 3550 3551 COMPARE_BOTH(Stmdb(r11, WRITE_BACK, RegisterList(r0, r1)), 3552 "stmdb r11!, {r0,r1}\n"); 3553 3554 COMPARE_BOTH(Stmdb(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3555 "stmdb r11, {r2,r3}\n"); 3556 3557 CLEANUP(); 3558 } 3559 3560 3561 #define CHECK_T32_16(ASM, EXP) COMPARE_T32_CHECK_SIZE(ASM, EXP, 2) 3562 // For instructions inside an IT block, we need to account for the IT 3563 // instruction as well (another 16 bits). 3564 #define CHECK_T32_16_IT_BLOCK(ASM, EXP) COMPARE_T32_CHECK_SIZE(ASM, EXP, 4) 3565 3566 TEST(macro_assembler_T32_16bit) { 3567 SETUP(); 3568 3569 // Allow the test to use all registers. 3570 UseScratchRegisterScope temps(&masm); 3571 temps.ExcludeAll(); 3572 3573 CHECK_T32_16(Adc(DontCare, r7, r7, r6), "adcs r7, r6\n"); 3574 3575 CHECK_T32_16_IT_BLOCK(Adc(DontCare, eq, r7, r7, r6), 3576 "it eq\n" 3577 "adceq r7, r6\n"); 3578 3579 CHECK_T32_16(Add(DontCare, r6, r7, 7), "adds r6, r7, #7\n"); 3580 3581 CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r6, r7, 7), 3582 "it lt\n" 3583 "addlt r6, r7, #7\n"); 3584 3585 CHECK_T32_16(Add(DontCare, r5, r5, 255), "adds r5, #255\n"); 3586 3587 CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r5, r5, 255), 3588 "it lt\n" 3589 "addlt r5, #255\n"); 3590 3591 // Make sure we select the non flag-setting version here, since 3592 // this can have two potential encodings. 3593 CHECK_T32_16(Add(DontCare, r1, r1, r2), "add r1, r2\n"); 3594 3595 CHECK_T32_16(Add(DontCare, r1, r2, r7), "adds r1, r2, r7\n"); 3596 3597 CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r1, r2, r7), 3598 "it lt\n" 3599 "addlt r1, r2, r7\n"); 3600 3601 CHECK_T32_16(Add(DontCare, r4, r4, r12), "add r4, ip\n"); 3602 3603 CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, r4, r4, r12), 3604 "it eq\n" 3605 "addeq r4, ip\n"); 3606 3607 CHECK_T32_16(Add(DontCare, r0, sp, 1020), "add r0, sp, #1020\n"); 3608 3609 CHECK_T32_16_IT_BLOCK(Add(DontCare, ge, r0, sp, 1020), 3610 "it ge\n" 3611 "addge r0, sp, #1020\n"); 3612 3613 // The equivalent inside an IT block is deprecated. 3614 CHECK_T32_16(Add(DontCare, sp, sp, 508), "add sp, #508\n"); 3615 3616 CHECK_T32_16(Add(DontCare, r7, sp, r7), "add r7, sp, r7\n"); 3617 3618 CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, r7, sp, r7), 3619 "it eq\n" 3620 "addeq r7, sp, r7\n"); 3621 3622 CHECK_T32_16(Add(DontCare, sp, sp, r10), "add sp, r10\n"); 3623 3624 CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, sp, sp, r10), 3625 "it eq\n" 3626 "addeq sp, r10\n"); 3627 3628 CHECK_T32_16(And(DontCare, r7, r7, r6), "ands r7, r6\n"); 3629 3630 CHECK_T32_16_IT_BLOCK(And(DontCare, eq, r7, r7, r6), 3631 "it eq\n" 3632 "andeq r7, r6\n"); 3633 3634 CHECK_T32_16(Asr(DontCare, r0, r1, 32), "asrs r0, r1, #32\n"); 3635 3636 CHECK_T32_16_IT_BLOCK(Asr(DontCare, eq, r0, r1, 32), 3637 "it eq\n" 3638 "asreq r0, r1, #32\n"); 3639 3640 CHECK_T32_16(Asr(DontCare, r0, r0, r1), "asrs r0, r1\n"); 3641 3642 CHECK_T32_16_IT_BLOCK(Asr(DontCare, eq, r0, r0, r1), 3643 "it eq\n" 3644 "asreq r0, r1\n"); 3645 3646 CHECK_T32_16(Bic(DontCare, r7, r7, r6), "bics r7, r6\n"); 3647 3648 CHECK_T32_16_IT_BLOCK(Bic(DontCare, eq, r7, r7, r6), 3649 "it eq\n" 3650 "biceq r7, r6\n"); 3651 3652 CHECK_T32_16(Eor(DontCare, r7, r7, r6), "eors r7, r6\n"); 3653 3654 CHECK_T32_16_IT_BLOCK(Eor(DontCare, eq, r7, r7, r6), 3655 "it eq\n" 3656 "eoreq r7, r6\n"); 3657 3658 CHECK_T32_16(Lsl(DontCare, r0, r1, 31), "lsls r0, r1, #31\n"); 3659 3660 CHECK_T32_16_IT_BLOCK(Lsl(DontCare, eq, r0, r1, 31), 3661 "it eq\n" 3662 "lsleq r0, r1, #31\n"); 3663 3664 CHECK_T32_16(Lsl(DontCare, r0, r0, r1), "lsls r0, r1\n"); 3665 3666 CHECK_T32_16_IT_BLOCK(Lsl(DontCare, eq, r0, r0, r1), 3667 "it eq\n" 3668 "lsleq r0, r1\n"); 3669 3670 CHECK_T32_16(Lsr(DontCare, r0, r1, 32), "lsrs r0, r1, #32\n"); 3671 3672 CHECK_T32_16_IT_BLOCK(Lsr(DontCare, eq, r0, r1, 32), 3673 "it eq\n" 3674 "lsreq r0, r1, #32\n"); 3675 3676 CHECK_T32_16(Lsr(DontCare, r0, r0, r1), "lsrs r0, r1\n"); 3677 3678 CHECK_T32_16_IT_BLOCK(Lsr(DontCare, eq, r0, r0, r1), 3679 "it eq\n" 3680 "lsreq r0, r1\n"); 3681 3682 CHECK_T32_16(Mov(DontCare, r7, 255), "movs r7, #255\n"); 3683 3684 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, 255), 3685 "it eq\n" 3686 "moveq r7, #255\n"); 3687 3688 CHECK_T32_16(Mov(DontCare, r9, r8), "mov r9, r8\n"); 3689 3690 // Check that we don't try to pick the MOVS register-shifted register variant. 3691 CHECK_T32_16(Mov(DontCare, r5, r6), "mov r5, r6\n"); 3692 3693 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r9, r8), 3694 "it eq\n" 3695 "moveq r9, r8\n"); 3696 3697 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, ASR, 1)), "asrs r5, r6, #1\n"); 3698 3699 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, ASR, 32)), "asrs r5, r6, #32\n"); 3700 3701 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSR, 1)), "lsrs r5, r6, #1\n"); 3702 3703 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSR, 32)), "lsrs r5, r6, #32\n"); 3704 3705 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSL, 1)), "lsls r5, r6, #1\n"); 3706 3707 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSL, 31)), "lsls r5, r6, #31\n"); 3708 3709 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, ASR, 1)), 3710 "it eq\n" 3711 "asreq r5, r6, #1\n"); 3712 3713 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, ASR, 32)), 3714 "it eq\n" 3715 "asreq r5, r6, #32\n"); 3716 3717 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSR, 1)), 3718 "it eq\n" 3719 "lsreq r5, r6, #1\n"); 3720 3721 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSR, 32)), 3722 "it eq\n" 3723 "lsreq r5, r6, #32\n"); 3724 3725 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSL, 1)), 3726 "it eq\n" 3727 "lsleq r5, r6, #1\n"); 3728 3729 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSL, 31)), 3730 "it eq\n" 3731 "lsleq r5, r6, #31\n"); 3732 3733 CHECK_T32_16(Mov(DontCare, r7, Operand(r7, ASR, r6)), "asrs r7, r6\n"); 3734 3735 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, ASR, r6)), 3736 "it eq\n" 3737 "asreq r7, r6\n"); 3738 3739 CHECK_T32_16(Mov(DontCare, r7, Operand(r7, LSR, r6)), "lsrs r7, r6\n"); 3740 3741 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, LSR, r6)), 3742 "it eq\n" 3743 "lsreq r7, r6\n"); 3744 3745 CHECK_T32_16(Mov(DontCare, r7, Operand(r7, LSL, r6)), "lsls r7, r6\n"); 3746 3747 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, LSL, r6)), 3748 "it eq\n" 3749 "lsleq r7, r6\n"); 3750 3751 CHECK_T32_16(Mov(DontCare, r7, Operand(r7, ROR, r6)), "rors r7, r6\n"); 3752 3753 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, ROR, r6)), 3754 "it eq\n" 3755 "roreq r7, r6\n"); 3756 3757 CHECK_T32_16(Mul(DontCare, r0, r1, r0), "muls r0, r1, r0\n"); 3758 3759 CHECK_T32_16_IT_BLOCK(Mul(DontCare, eq, r0, r1, r0), 3760 "it eq\n" 3761 "muleq r0, r1, r0\n"); 3762 3763 CHECK_T32_16(Mvn(DontCare, r6, r7), "mvns r6, r7\n"); 3764 3765 CHECK_T32_16_IT_BLOCK(Mvn(DontCare, eq, r6, r7), 3766 "it eq\n" 3767 "mvneq r6, r7\n"); 3768 3769 CHECK_T32_16(Orr(DontCare, r7, r7, r6), "orrs r7, r6\n"); 3770 3771 CHECK_T32_16_IT_BLOCK(Orr(DontCare, eq, r7, r7, r6), 3772 "it eq\n" 3773 "orreq r7, r6\n"); 3774 3775 CHECK_T32_16(Ror(DontCare, r0, r0, r1), "rors r0, r1\n"); 3776 3777 CHECK_T32_16_IT_BLOCK(Ror(DontCare, eq, r0, r0, r1), 3778 "it eq\n" 3779 "roreq r0, r1\n"); 3780 3781 CHECK_T32_16(Rsb(DontCare, r7, r6, 0), "rsbs r7, r6, #0\n"); 3782 3783 CHECK_T32_16_IT_BLOCK(Rsb(DontCare, eq, r7, r6, 0), 3784 "it eq\n" 3785 "rsbeq r7, r6, #0\n"); 3786 3787 CHECK_T32_16(Sbc(DontCare, r7, r7, r6), "sbcs r7, r6\n"); 3788 3789 CHECK_T32_16_IT_BLOCK(Sbc(DontCare, eq, r7, r7, r6), 3790 "it eq\n" 3791 "sbceq r7, r6\n"); 3792 3793 CHECK_T32_16(Sub(DontCare, r6, r7, 7), "subs r6, r7, #7\n"); 3794 3795 CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r6, r7, 7), 3796 "it lt\n" 3797 "sublt r6, r7, #7\n"); 3798 3799 CHECK_T32_16(Sub(DontCare, r5, r5, 255), "subs r5, #255\n"); 3800 3801 CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r5, r5, 255), 3802 "it lt\n" 3803 "sublt r5, #255\n"); 3804 3805 CHECK_T32_16(Sub(DontCare, r1, r2, r7), "subs r1, r2, r7\n"); 3806 3807 CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r1, r2, r7), 3808 "it lt\n" 3809 "sublt r1, r2, r7\n"); 3810 3811 // The equivalent inside an IT block is deprecated. 3812 CHECK_T32_16(Sub(DontCare, sp, sp, 508), "sub sp, #508\n"); 3813 3814 // Generate SUBS for ADD. 3815 CHECK_T32_16(Add(DontCare, r0, r1, -1), "subs r0, r1, #1\n"); 3816 3817 CHECK_T32_16(Add(DontCare, r0, r1, -7), "subs r0, r1, #7\n"); 3818 3819 CHECK_T32_16(Add(DontCare, r6, r6, -1), "subs r6, #1\n"); 3820 3821 CHECK_T32_16(Add(DontCare, r6, r6, -255), "subs r6, #255\n"); 3822 3823 // Generate ADDS for SUB. 3824 CHECK_T32_16(Sub(DontCare, r0, r1, -1), "adds r0, r1, #1\n"); 3825 3826 CHECK_T32_16(Sub(DontCare, r0, r1, -7), "adds r0, r1, #7\n"); 3827 3828 CHECK_T32_16(Sub(DontCare, r6, r6, -1), "adds r6, #1\n"); 3829 3830 CHECK_T32_16(Sub(DontCare, r6, r6, -255), "adds r6, #255\n"); 3831 3832 // Check that we don't change the opcode for INT_MIN. 3833 COMPARE_T32(Add(DontCare, r6, r6, 0x80000000), "add r6, #2147483648\n"); 3834 3835 COMPARE_T32(Sub(DontCare, r6, r6, 0x80000000), "sub r6, #2147483648\n"); 3836 3837 CLEANUP(); 3838 } 3839 #undef CHECK_T32_16 3840 #undef CHECK_T32_16_IT_BLOCK 3841 3842 TEST(nop_code) { 3843 SETUP(); 3844 3845 COMPARE_BOTH(Nop(), "nop\n"); 3846 3847 COMPARE_BOTH(And(r0, r0, r0), ""); 3848 COMPARE_BOTH(And(DontCare, r0, r0, r0), ""); 3849 3850 COMPARE_BOTH(Mov(r0, r0), ""); 3851 COMPARE_BOTH(Mov(DontCare, r0, r0), ""); 3852 3853 COMPARE_BOTH(Orr(r0, r0, r0), ""); 3854 COMPARE_BOTH(Orr(DontCare, r0, r0, r0), ""); 3855 3856 CLEANUP(); 3857 } 3858 3859 3860 TEST(big_add_sub) { 3861 SETUP(); 3862 3863 COMPARE_A32(Add(r0, r1, 0x4321), 3864 "add r0, r1, #33\n" 3865 "add r0, #17152\n"); 3866 COMPARE_T32(Add(r0, r1, 0x4321), 3867 "add r0, r1, #801\n" 3868 "add r0, #16384\n"); 3869 COMPARE_BOTH(Add(r0, r1, 0x432100), 3870 "add r0, r1, #8448\n" 3871 "add r0, #4390912\n"); 3872 COMPARE_BOTH(Add(r0, r1, 0x43000210), 3873 "add r0, r1, #528\n" 3874 "add r0, #1124073472\n"); 3875 COMPARE_BOTH(Add(r0, r1, 0x30c00210), 3876 "add r0, r1, #528\n" 3877 "add r0, #817889280\n"); 3878 COMPARE_BOTH(Add(r0, r1, 0x43000021), 3879 "add r0, r1, #33\n" 3880 "add r0, #1124073472\n"); 3881 COMPARE_T32(Add(r0, r1, 0x54321), 3882 "add r0, r1, #801\n" 3883 "add r0, #344064\n"); 3884 COMPARE_T32(Add(r0, r1, 0x54000321), 3885 "add r0, r1, #801\n" 3886 "add r0, #1409286144\n"); 3887 3888 COMPARE_A32(Sub(r0, r1, 0x4321), 3889 "sub r0, r1, #33\n" 3890 "sub r0, #17152\n"); 3891 COMPARE_T32(Sub(r0, r1, 0x4321), 3892 "sub r0, r1, #801\n" 3893 "sub r0, #16384\n"); 3894 COMPARE_BOTH(Sub(r0, r1, 0x432100), 3895 "sub r0, r1, #8448\n" 3896 "sub r0, #4390912\n"); 3897 COMPARE_BOTH(Sub(r0, r1, 0x43000210), 3898 "sub r0, r1, #528\n" 3899 "sub r0, #1124073472\n"); 3900 COMPARE_BOTH(Sub(r0, r1, 0x30c00210), 3901 "sub r0, r1, #528\n" 3902 "sub r0, #817889280\n"); 3903 COMPARE_BOTH(Sub(r0, r1, 0x43000021), 3904 "sub r0, r1, #33\n" 3905 "sub r0, #1124073472\n"); 3906 COMPARE_T32(Sub(r0, r1, 0x54321), 3907 "sub r0, r1, #801\n" 3908 "sub r0, #344064\n"); 3909 COMPARE_T32(Sub(r0, r1, 0x54000321), 3910 "sub r0, r1, #801\n" 3911 "sub r0, #1409286144\n"); 3912 3913 CLEANUP(); 3914 } 3915 3916 } // namespace aarch32 3917 } // namespace vixl 3918