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 <list> 28#include <sstream> 29#include <string> 30 31#include "test-runner.h" 32#include "test-utils.h" 33 34#include "aarch32/disasm-aarch32.h" 35#include "aarch32/macro-assembler-aarch32.h" 36 37#ifdef VIXL_NEGATIVE_TESTING 38#include <stdexcept> 39#endif 40 41namespace vixl { 42namespace 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 349class 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 378TEST_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 393TEST_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 408TEST(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 502TEST(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 620TEST(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 640TEST(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 730TEST(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 MUST_FAIL_TEST_BOTH(Ldr(r0, MemOperand(r0, Sign(plus), pc, Offset)), 808 "Unpredictable instruction.\n"); 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 828TEST(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 COMPARE_A32(Str(pc, MemOperand(r0, r0, Offset)), "str pc, [r0, r0]\n"); 865 COMPARE_A32(Str(pc, MemOperand(r0, r0, PreIndex)), "str pc, [r0, r0]!\n"); 866 COMPARE_A32(Str(pc, MemOperand(r0, r0, PostIndex)), "str pc, [r0], r0\n"); 867 MUST_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, Offset)), 868 "Unpredictable instruction.\n"); 869 MUST_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, PreIndex)), 870 "Unpredictable instruction.\n"); 871 MUST_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, PostIndex)), 872 "Unpredictable instruction.\n"); 873 874 // PC is allowed as register base in the offset variant only for A32. 875 COMPARE_A32(Str(r0, MemOperand(pc, r0, Offset)), "str r0, [pc, r0]\n"); 876 MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, Offset)), 877 "The MacroAssembler does not convert loads and stores with" 878 " a PC base register for T32.\n"); 879 880 // PC is not allowed as register base in the pre-index and post-index 881 // variants. 882 MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, PreIndex)), 883 "The MacroAssembler does not convert loads and stores " 884 "with a PC base register in pre-index or post-index " 885 "mode.\n"); 886 MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, PostIndex)), 887 "The MacroAssembler does not convert loads and stores " 888 "with a PC base register in pre-index or post-index " 889 "mode.\n"); 890 891 // We don't convert loads with PC as the register offset. 892 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, minus, pc, Offset)), 893 "The MacroAssembler does not convert loads and stores " 894 "with a PC offset register.\n"); 895 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, pc, PreIndex)), 896 "The MacroAssembler does not convert loads and stores " 897 "with a PC offset register.\n"); 898 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, pc, PostIndex)), 899 "The MacroAssembler does not convert loads and stores " 900 "with a PC offset register.\n"); 901 902 MUST_FAIL_TEST_BOTH(Str(r0, MemOperand(r0, Sign(plus), pc, Offset)), 903 "Unpredictable instruction.\n"); 904 905 // TODO: PC should not be allowed as register base in A32 with pre-index 906 // and post-index (unpredictable). 907 SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(pc, r0, PreIndex))); 908 SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(pc, r0, PostIndex))); 909 910 // TODO: store with the same register used as base and as source 911 // should fail to assemble (unpredictable). 912 SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(r0, r1, PreIndex))); 913 SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(r0, r1, PostIndex))); 914 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, r1, PreIndex)), 915 "Ill-formed 'str' instruction.\n"); 916 MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, r1, PostIndex)), 917 "Ill-formed 'str' instruction.\n"); 918 919 CLEANUP(); 920} 921 922 923TEST(macro_assembler_ldrd) { 924 SETUP(); 925 926 // - Tests with no offset. 927 928 COMPARE_BOTH(Ldrd(r0, r1, MemOperand(r3)), "ldrd r0, r1, [r3]\n"); 929 // Destination registers need to start with a even numbered register on A32. 930 MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r3)), 931 "Unpredictable instruction.\n"); 932 COMPARE_T32(Ldrd(r1, r2, MemOperand(r3)), "ldrd r1, r2, [r3]\n"); 933 // Registers need to be adjacent on A32. 934 MUST_FAIL_TEST_A32(Ldrd(r0, r2, MemOperand(r1)), 935 "Ill-formed 'ldrd' instruction.\n"); 936 COMPARE_T32(Ldrd(r0, r2, MemOperand(r1)), "ldrd r0, r2, [r1]\n"); 937 938 COMPARE_BOTH(Ldrd(r0, r1, MemOperand(r2)), "ldrd r0, r1, [r2]\n"); 939 940 // - Tests with immediate offsets. 941 942 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 1020)), 943 "add r0, r2, #1020\n" 944 "ldrd r0, r1, [r0]\n"); 945 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 1020)), "ldrd r0, r1, [r2, #1020]\n"); 946 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -1020)), 947 "sub r0, r2, #1020\n" 948 "ldrd r0, r1, [r0]\n"); 949 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -1020)), 950 "ldrd r0, r1, [r2, #-1020]\n"); 951 952 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc)), 953 "add r0, r2, #43776\n" 954 "ldrd r0, r1, [r0, #204]\n"); 955 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc)), 956 "add r0, r2, #43008\n" 957 "ldrd r0, r1, [r0, #972]\n"); 958 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc)), 959 "sub r0, r2, #44032\n" 960 "ldrd r0, r1, [r0, #52]\n"); 961 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc)), 962 "sub r0, r2, #44032\n" 963 "ldrd r0, r1, [r0, #52]\n"); 964 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec)), 965 "add r0, r2, #52480\n" 966 "add r0, #11206656\n" 967 "ldrd r0, r1, [r0, #236]\n"); 968 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec)), 969 "add r0, r2, #248832\n" 970 "add r0, #11010048\n" 971 "ldrd r0, r1, [r0, #492]\n"); 972 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec)), 973 "sub r0, r2, #52736\n" 974 "sub r0, #11206656\n" 975 "ldrd r0, r1, [r0, #20]\n"); 976 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec)), 977 "sub r0, r2, #774144\n" 978 "sub r0, #10485760\n" 979 "ldrd r0, r1, [r0, #532]\n"); 980 981 COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, 0xabcc)), 982 "add r1, r0, #43776\n" 983 "ldrd r0, r1, [r1, #204]\n"); 984 COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, 0xabcc)), 985 "add r1, r0, #43008\n" 986 "ldrd r0, r1, [r1, #972]\n"); 987 COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, -0xabcc)), 988 "sub r1, r0, #44032\n" 989 "ldrd r0, r1, [r1, #52]\n"); 990 COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, -0xabcc)), 991 "sub r1, r0, #44032\n" 992 "ldrd r0, r1, [r1, #52]\n"); 993 COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, 0xabcdec)), 994 "add r1, r0, #52480\n" 995 "add r1, #11206656\n" 996 "ldrd r0, r1, [r1, #236]\n"); 997 COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, 0xabcdec)), 998 "add r1, r0, #248832\n" 999 "add r1, #11010048\n" 1000 "ldrd r0, r1, [r1, #492]\n"); 1001 COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, -0xabcdec)), 1002 "sub r1, r0, #52736\n" 1003 "sub r1, #11206656\n" 1004 "ldrd r0, r1, [r1, #20]\n"); 1005 COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, -0xabcdec)), 1006 "sub r1, r0, #774144\n" 1007 "sub r1, #10485760\n" 1008 "ldrd r0, r1, [r1, #532]\n"); 1009 1010 COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, 0xabcc)), 1011 "add r0, r1, #43776\n" 1012 "ldrd r0, r1, [r0, #204]\n"); 1013 COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, 0xabcc)), 1014 "add r0, r1, #43008\n" 1015 "ldrd r0, r1, [r0, #972]\n"); 1016 COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, -0xabcc)), 1017 "sub r0, r1, #44032\n" 1018 "ldrd r0, r1, [r0, #52]\n"); 1019 COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, -0xabcc)), 1020 "sub r0, r1, #44032\n" 1021 "ldrd r0, r1, [r0, #52]\n"); 1022 COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, 0xabcdec)), 1023 "add r0, r1, #52480\n" 1024 "add r0, #11206656\n" 1025 "ldrd r0, r1, [r0, #236]\n"); 1026 COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, 0xabcdec)), 1027 "add r0, r1, #248832\n" 1028 "add r0, #11010048\n" 1029 "ldrd r0, r1, [r0, #492]\n"); 1030 COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, -0xabcdec)), 1031 "sub r0, r1, #52736\n" 1032 "sub r0, #11206656\n" 1033 "ldrd r0, r1, [r0, #20]\n"); 1034 COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, -0xabcdec)), 1035 "sub r0, r1, #774144\n" 1036 "sub r0, #10485760\n" 1037 "ldrd r0, r1, [r0, #532]\n"); 1038 1039 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)), 1040 "ldrd r0, r1, [r2], #204\n" 1041 "add r2, #43776\n"); 1042 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)), 1043 "ldrd r0, r1, [r2], #972\n" 1044 "add r2, #43008\n"); 1045 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)), 1046 "ldrd r0, r1, [r2], #52\n" 1047 "sub r2, #44032\n"); 1048 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)), 1049 "ldrd r0, r1, [r2], #52\n" 1050 "sub r2, #44032\n"); 1051 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)), 1052 "ldrd r0, r1, [r2], #236\n" 1053 "add r2, #52480\n" 1054 "add r2, #11206656\n"); 1055 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)), 1056 "ldrd r0, r1, [r2], #492\n" 1057 "add r2, #248832\n" 1058 "add r2, #11010048\n"); 1059 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)), 1060 "ldrd r0, r1, [r2], #20\n" 1061 "sub r2, #52736\n" 1062 "sub r2, #11206656\n"); 1063 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)), 1064 "ldrd r0, r1, [r2], #532\n" 1065 "sub r2, #774144\n" 1066 "sub r2, #10485760\n"); 1067 1068 // PostIndex with the same register as base and destination is invalid. 1069 MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r0, 0xabcd, PostIndex)), 1070 "Ill-formed 'ldrd' instruction.\n"); 1071 MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r1, 0xabcdef, PostIndex)), 1072 "Ill-formed 'ldrd' instruction.\n"); 1073 1074 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)), 1075 "add r2, #43776\n" 1076 "ldrd r0, r1, [r2, #204]!\n"); 1077 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)), 1078 "add r2, #43008\n" 1079 "ldrd r0, r1, [r2, #972]!\n"); 1080 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)), 1081 "sub r2, #44032\n" 1082 "ldrd r0, r1, [r2, #52]!\n"); 1083 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)), 1084 "sub r2, #44032\n" 1085 "ldrd r0, r1, [r2, #52]!\n"); 1086 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)), 1087 "add r2, #52480\n" 1088 "add r2, #11206656\n" 1089 "ldrd r0, r1, [r2, #236]!\n"); 1090 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)), 1091 "add r2, #248832\n" 1092 "add r2, #11010048\n" 1093 "ldrd r0, r1, [r2, #492]!\n"); 1094 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)), 1095 "sub r2, #52736\n" 1096 "sub r2, #11206656\n" 1097 "ldrd r0, r1, [r2, #20]!\n"); 1098 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)), 1099 "sub r2, #774144\n" 1100 "sub r2, #10485760\n" 1101 "ldrd r0, r1, [r2, #532]!\n"); 1102 1103 // - Tests with register offsets. 1104 1105 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3)), "ldrd r0, r1, [r2, r3]\n"); 1106 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3)), 1107 "add r0, r2, r3\n" 1108 "ldrd r0, r1, [r0]\n"); 1109 1110 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3)), 1111 "ldrd r0, r1, [r2, -r3]\n"); 1112 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3)), 1113 "sub r0, r2, r3\n" 1114 "ldrd r0, r1, [r0]\n"); 1115 1116 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3, PostIndex)), 1117 "ldrd r0, r1, [r2], r3\n"); 1118 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3, PostIndex)), 1119 "ldrd r0, r1, [r2]\n" 1120 "add r2, r3\n"); 1121 1122 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PostIndex)), 1123 "ldrd r0, r1, [r2], -r3\n"); 1124 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PostIndex)), 1125 "ldrd r0, r1, [r2]\n" 1126 "sub r2, r3\n"); 1127 1128 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3, PreIndex)), 1129 "ldrd r0, r1, [r2, r3]!\n"); 1130 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3, PreIndex)), 1131 "add r2, r3\n" 1132 "ldrd r0, r1, [r2]\n"); 1133 1134 COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PreIndex)), 1135 "ldrd r0, r1, [r2, -r3]!\n"); 1136 COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PreIndex)), 1137 "sub r2, r3\n" 1138 "ldrd r0, r1, [r2]\n"); 1139 1140 // - We do not support register shifted base register operands with LDRD. 1141 1142 MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r2, r3, LSL, 4)), 1143 "Ill-formed 'ldrd' instruction.\n"); 1144 1145 // First register is odd - rejected by the Assembler. 1146 MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0)), 1147 "Unpredictable instruction.\n"); 1148 MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0, r0, PreIndex)), 1149 "Unpredictable instruction.\n"); 1150 // First register is odd - rejected by the MacroAssembler. 1151 MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0, 0xabcd, PreIndex)), 1152 "Ill-formed 'ldrd' instruction.\n"); 1153 1154 // First register is lr - rejected by the Assembler. 1155 MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0)), 1156 "Unpredictable instruction.\n"); 1157 MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0, r0, PreIndex)), 1158 "Unpredictable instruction.\n"); 1159 // First register is lr - rejected by the MacroAssembler. 1160 MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0, 0xabcd, PreIndex)), 1161 "Ill-formed 'ldrd' instruction.\n"); 1162 1163 // Non-adjacent registers. 1164 MUST_FAIL_TEST_A32(Ldrd(r0, r2, MemOperand(r0)), 1165 "Ill-formed 'ldrd' instruction.\n"); 1166 1167 CLEANUP(); 1168} 1169 1170TEST(macro_assembler_strd) { 1171 SETUP(); 1172 1173 // - Tests with no offset. 1174 1175 COMPARE_BOTH(Strd(r0, r1, MemOperand(r3)), "strd r0, r1, [r3]\n"); 1176 // Destination registers need to start with a even numbered register on A32. 1177 MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r3)), 1178 "Unpredictable instruction.\n"); 1179 COMPARE_T32(Strd(r1, r2, MemOperand(r3)), "strd r1, r2, [r3]\n"); 1180 // Registers need to be adjacent on A32. 1181 MUST_FAIL_TEST_A32(Strd(r0, r2, MemOperand(r1)), 1182 "Ill-formed 'strd' instruction.\n"); 1183 COMPARE_T32(Strd(r0, r2, MemOperand(r1)), "strd r0, r2, [r1]\n"); 1184 1185 COMPARE_BOTH(Strd(r0, r1, MemOperand(r2)), "strd r0, r1, [r2]\n"); 1186 1187 // - Tests with immediate offsets. 1188 1189 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 1020)), 1190 "add ip, r2, #1020\n" 1191 "strd r0, r1, [ip]\n"); 1192 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 1020)), "strd r0, r1, [r2, #1020]\n"); 1193 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -1020)), 1194 "sub ip, r2, #1020\n" 1195 "strd r0, r1, [ip]\n"); 1196 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -1020)), 1197 "strd r0, r1, [r2, #-1020]\n"); 1198 1199 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc)), 1200 "add ip, r2, #43776\n" 1201 "strd r0, r1, [ip, #204]\n"); 1202 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc)), 1203 "add ip, r2, #43008\n" 1204 "strd r0, r1, [ip, #972]\n"); 1205 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc)), 1206 "sub ip, r2, #44032\n" 1207 "strd r0, r1, [ip, #52]\n"); 1208 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc)), 1209 "sub ip, r2, #44032\n" 1210 "strd r0, r1, [ip, #52]\n"); 1211 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec)), 1212 "add ip, r2, #52480\n" 1213 "add ip, #11206656\n" 1214 "strd r0, r1, [ip, #236]\n"); 1215 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec)), 1216 "add ip, r2, #248832\n" 1217 "add ip, #11010048\n" 1218 "strd r0, r1, [ip, #492]\n"); 1219 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec)), 1220 "sub ip, r2, #52736\n" 1221 "sub ip, #11206656\n" 1222 "strd r0, r1, [ip, #20]\n"); 1223 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec)), 1224 "sub ip, r2, #774144\n" 1225 "sub ip, #10485760\n" 1226 "strd r0, r1, [ip, #532]\n"); 1227 1228 COMPARE_A32(Strd(r0, r1, MemOperand(r0, 0xabcc)), 1229 "add ip, r0, #43776\n" 1230 "strd r0, r1, [ip, #204]\n"); 1231 COMPARE_T32(Strd(r0, r1, MemOperand(r0, 0xabcc)), 1232 "add ip, r0, #43008\n" 1233 "strd r0, r1, [ip, #972]\n"); 1234 COMPARE_A32(Strd(r0, r1, MemOperand(r0, -0xabcc)), 1235 "sub ip, r0, #44032\n" 1236 "strd r0, r1, [ip, #52]\n"); 1237 COMPARE_T32(Strd(r0, r1, MemOperand(r0, -0xabcc)), 1238 "sub ip, r0, #44032\n" 1239 "strd r0, r1, [ip, #52]\n"); 1240 COMPARE_A32(Strd(r0, r1, MemOperand(r0, 0xabcdec)), 1241 "add ip, r0, #52480\n" 1242 "add ip, #11206656\n" 1243 "strd r0, r1, [ip, #236]\n"); 1244 COMPARE_T32(Strd(r0, r1, MemOperand(r0, 0xabcdec)), 1245 "add ip, r0, #248832\n" 1246 "add ip, #11010048\n" 1247 "strd r0, r1, [ip, #492]\n"); 1248 COMPARE_A32(Strd(r0, r1, MemOperand(r0, -0xabcdec)), 1249 "sub ip, r0, #52736\n" 1250 "sub ip, #11206656\n" 1251 "strd r0, r1, [ip, #20]\n"); 1252 COMPARE_T32(Strd(r0, r1, MemOperand(r0, -0xabcdec)), 1253 "sub ip, r0, #774144\n" 1254 "sub ip, #10485760\n" 1255 "strd r0, r1, [ip, #532]\n"); 1256 1257 COMPARE_A32(Strd(r0, r1, MemOperand(r1, 0xabcc)), 1258 "add ip, r1, #43776\n" 1259 "strd r0, r1, [ip, #204]\n"); 1260 COMPARE_T32(Strd(r0, r1, MemOperand(r1, 0xabcc)), 1261 "add ip, r1, #43008\n" 1262 "strd r0, r1, [ip, #972]\n"); 1263 COMPARE_A32(Strd(r0, r1, MemOperand(r1, -0xabcc)), 1264 "sub ip, r1, #44032\n" 1265 "strd r0, r1, [ip, #52]\n"); 1266 COMPARE_T32(Strd(r0, r1, MemOperand(r1, -0xabcc)), 1267 "sub ip, r1, #44032\n" 1268 "strd r0, r1, [ip, #52]\n"); 1269 COMPARE_A32(Strd(r0, r1, MemOperand(r1, 0xabcdec)), 1270 "add ip, r1, #52480\n" 1271 "add ip, #11206656\n" 1272 "strd r0, r1, [ip, #236]\n"); 1273 COMPARE_T32(Strd(r0, r1, MemOperand(r1, 0xabcdec)), 1274 "add ip, r1, #248832\n" 1275 "add ip, #11010048\n" 1276 "strd r0, r1, [ip, #492]\n"); 1277 COMPARE_A32(Strd(r0, r1, MemOperand(r1, -0xabcdec)), 1278 "sub ip, r1, #52736\n" 1279 "sub ip, #11206656\n" 1280 "strd r0, r1, [ip, #20]\n"); 1281 COMPARE_T32(Strd(r0, r1, MemOperand(r1, -0xabcdec)), 1282 "sub ip, r1, #774144\n" 1283 "sub ip, #10485760\n" 1284 "strd r0, r1, [ip, #532]\n"); 1285 1286 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)), 1287 "strd r0, r1, [r2], #204\n" 1288 "add r2, #43776\n"); 1289 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)), 1290 "strd r0, r1, [r2], #972\n" 1291 "add r2, #43008\n"); 1292 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)), 1293 "strd r0, r1, [r2], #52\n" 1294 "sub r2, #44032\n"); 1295 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)), 1296 "strd r0, r1, [r2], #52\n" 1297 "sub r2, #44032\n"); 1298 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)), 1299 "strd r0, r1, [r2], #236\n" 1300 "add r2, #52480\n" 1301 "add r2, #11206656\n"); 1302 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)), 1303 "strd r0, r1, [r2], #492\n" 1304 "add r2, #248832\n" 1305 "add r2, #11010048\n"); 1306 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)), 1307 "strd r0, r1, [r2], #20\n" 1308 "sub r2, #52736\n" 1309 "sub r2, #11206656\n"); 1310 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)), 1311 "strd r0, r1, [r2], #532\n" 1312 "sub r2, #774144\n" 1313 "sub r2, #10485760\n"); 1314 1315 // PostIndex with the same register as base and source is invalid. 1316 MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r0, 0xabcd, PostIndex)), 1317 "Ill-formed 'strd' instruction.\n"); 1318 MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r1, 0xabcdef, PostIndex)), 1319 "Ill-formed 'strd' instruction.\n"); 1320 1321 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)), 1322 "add r2, #43776\n" 1323 "strd r0, r1, [r2, #204]!\n"); 1324 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)), 1325 "add r2, #43008\n" 1326 "strd r0, r1, [r2, #972]!\n"); 1327 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)), 1328 "sub r2, #44032\n" 1329 "strd r0, r1, [r2, #52]!\n"); 1330 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)), 1331 "sub r2, #44032\n" 1332 "strd r0, r1, [r2, #52]!\n"); 1333 COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)), 1334 "add r2, #52480\n" 1335 "add r2, #11206656\n" 1336 "strd r0, r1, [r2, #236]!\n"); 1337 COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)), 1338 "add r2, #248832\n" 1339 "add r2, #11010048\n" 1340 "strd r0, r1, [r2, #492]!\n"); 1341 COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)), 1342 "sub r2, #52736\n" 1343 "sub r2, #11206656\n" 1344 "strd r0, r1, [r2, #20]!\n"); 1345 COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)), 1346 "sub r2, #774144\n" 1347 "sub r2, #10485760\n" 1348 "strd r0, r1, [r2, #532]!\n"); 1349 1350 // - Tests with register offsets. 1351 1352 COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3)), "strd r0, r1, [r2, r3]\n"); 1353 COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3)), 1354 "add ip, r2, r3\n" 1355 "strd r0, r1, [ip]\n"); 1356 1357 COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3)), 1358 "strd r0, r1, [r2, -r3]\n"); 1359 COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3)), 1360 "sub ip, r2, r3\n" 1361 "strd r0, r1, [ip]\n"); 1362 1363 COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3, PostIndex)), 1364 "strd r0, r1, [r2], r3\n"); 1365 COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3, PostIndex)), 1366 "strd r0, r1, [r2]\n" 1367 "add r2, r3\n"); 1368 1369 COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3, PostIndex)), 1370 "strd r0, r1, [r2], -r3\n"); 1371 COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3, PostIndex)), 1372 "strd r0, r1, [r2]\n" 1373 "sub r2, r3\n"); 1374 1375 COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3, PreIndex)), 1376 "strd r0, r1, [r2, r3]!\n"); 1377 COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3, PreIndex)), 1378 "add r2, r3\n" 1379 "strd r0, r1, [r2]\n"); 1380 1381 COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3, PreIndex)), 1382 "strd r0, r1, [r2, -r3]!\n"); 1383 COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3, PreIndex)), 1384 "sub r2, r3\n" 1385 "strd r0, r1, [r2]\n"); 1386 1387 // - We do not support register shifted base register operands with LDRD. 1388 1389 MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r2, r3, LSL, 4)), 1390 "Ill-formed 'strd' instruction.\n"); 1391 1392 // First register is odd - rejected by the Assembler. 1393 MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0)), 1394 "Unpredictable instruction.\n"); 1395 MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0, r0, PreIndex)), 1396 "Unpredictable instruction.\n"); 1397 // First register is odd - rejected by the MacroAssembler. 1398 MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0, 0xabcd, PreIndex)), 1399 "Ill-formed 'strd' instruction.\n"); 1400 1401 // First register is lr - rejected by the Assembler. 1402 MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0)), 1403 "Unpredictable instruction.\n"); 1404 MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0, r0, PreIndex)), 1405 "Unpredictable instruction.\n"); 1406 // First register is lr - rejected by the MacroAssembler. 1407 MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0, 0xabcd, PreIndex)), 1408 "Ill-formed 'strd' instruction.\n"); 1409 1410 // Non-adjacent registers. 1411 MUST_FAIL_TEST_A32(Strd(r0, r2, MemOperand(r0)), 1412 "Ill-formed 'strd' instruction.\n"); 1413 1414 CLEANUP(); 1415} 1416 1417 1418TEST(macro_assembler_wide_immediate) { 1419 SETUP(); 1420 1421 COMPARE_BOTH(Adc(r0, r1, 0xbadbeef), 1422 "mov r0, #48879\n" 1423 "movt r0, #2989\n" 1424 "adc r0, r1, r0\n"); 1425 1426 COMPARE_BOTH(Add(r0, r0, 0xbadbeef), 1427 "mov ip, #48879\n" 1428 "movt ip, #2989\n" 1429 "add r0, ip\n"); 1430 1431 COMPARE_BOTH(Mov(r0, 0xbadbeef), 1432 "mov r0, #48879\n" 1433 "movt r0, #2989\n"); 1434 COMPARE_A32(Mov(eq, r0, 0xbadbeef), 1435 "moveq r0, #48879\n" 1436 "movteq r0, #2989\n"); 1437 COMPARE_T32(Mov(eq, r0, 0xbadbeef), 1438 "bne 0x0000000a\n" 1439 "mov r0, #48879\n" 1440 "movt r0, #2989\n"); 1441 1442 COMPARE_BOTH(Movs(r0, 0xbadbeef), 1443 "mov r0, #48879\n" 1444 "movt r0, #2989\n" 1445 "tst r0, r0\n"); 1446 COMPARE_A32(Movs(eq, r0, 0xbadbeef), 1447 "moveq r0, #48879\n" 1448 "movteq r0, #2989\n" 1449 "tsteq r0, r0\n"); 1450 COMPARE_T32(Movs(eq, r0, 0xbadbeef), 1451 "bne 0x0000000c\n" 1452 "mov r0, #48879\n" 1453 "movt r0, #2989\n" 1454 "tst r0, r0\n"); 1455 COMPARE_A32(Movs(pc, 0x1), "movs pc, #1\n"); 1456 MUST_FAIL_TEST_T32(Movs(pc, 0x1), "Unpredictable instruction.\n"); 1457 MUST_FAIL_TEST_BOTH(Movs(pc, 0xbadbeed), "Ill-formed 'movs' instruction.\n"); 1458 1459 COMPARE_BOTH(Mov(pc, 0xbadbeef), 1460 "mov ip, #48879\n" 1461 "movt ip, #2989\n" 1462 "bx ip\n"); 1463 COMPARE_A32(Mov(eq, pc, 0xbadbeef), 1464 "mov ip, #48879\n" 1465 "movt ip, #2989\n" 1466 "bxeq ip\n"); 1467 COMPARE_T32(Mov(eq, pc, 0xbadbeef), 1468 "bne 0x0000000c\n" 1469 "mov ip, #48879\n" 1470 "movt ip, #2989\n" 1471 "bx ip\n"); 1472 1473 CLEANUP(); 1474} 1475 1476 1477TEST(macro_assembler_And) { 1478 SETUP(); 1479 1480 // Identities. 1481 COMPARE_BOTH(And(r0, r1, 0), "mov r0, #0\n"); 1482 COMPARE_BOTH(And(r0, r0, 0xffffffff), ""); 1483 CLEANUP(); 1484} 1485 1486 1487TEST(macro_assembler_Bic) { 1488 SETUP(); 1489 1490 // Identities. 1491 COMPARE_BOTH(Bic(r0, r1, 0xffffffff), "mov r0, #0\n"); 1492 COMPARE_BOTH(Bic(r0, r0, 0), ""); 1493 CLEANUP(); 1494} 1495 1496 1497TEST(macro_assembler_Orr) { 1498 SETUP(); 1499 1500 // Identities. 1501 COMPARE_BOTH(Orr(r0, r1, 0xffffffff), "mvn r0, #0\n"); 1502 COMPARE_BOTH(Orr(r0, r0, 0), ""); 1503 CLEANUP(); 1504} 1505 1506 1507TEST(macro_assembler_InstructionCondSizeRROp) { 1508 SETUP(); 1509 1510 // Special case for Orr <-> Orn correspondance. 1511 1512 COMPARE_T32(Orr(r0, r1, 0x00ffffff), "orn r0, r1, #0xff000000\n"); 1513 COMPARE_T32(Orrs(r0, r1, 0x00ffffff), "orns r0, r1, #0xff000000\n"); 1514 1515 // Encodable immediates. 1516 1517 COMPARE_A32(Add(r0, r1, -1), "sub r0, r1, #1\n"); 1518 COMPARE_A32(Adds(r0, r1, -1), "subs r0, r1, #1\n"); 1519 // 0xffffffff is encodable in a T32 ADD. 1520 COMPARE_T32(Add(r0, r1, -1), "add r0, r1, #4294967295\n"); 1521 COMPARE_T32(Adds(r0, r1, -1), "adds r0, r1, #4294967295\n"); 1522 1523 COMPARE_BOTH(Add(r0, r1, -4), "sub r0, r1, #4\n"); 1524 COMPARE_BOTH(Adds(r0, r1, -4), "subs r0, r1, #4\n"); 1525 1526 COMPARE_BOTH(Adc(r0, r1, -2), "sbc r0, r1, #1\n"); 1527 COMPARE_BOTH(Adcs(r0, r1, -2), "sbcs r0, r1, #1\n"); 1528 1529 COMPARE_A32(Sub(r0, r1, -1), "add r0, r1, #1\n"); 1530 COMPARE_A32(Subs(r0, r1, -1), "adds r0, r1, #1\n"); 1531 // 0xffffffff is encodable in a T32 SUB. 1532 COMPARE_T32(Sub(r0, r1, -1), "sub r0, r1, #4294967295\n"); 1533 COMPARE_T32(Subs(r0, r1, -1), "subs r0, r1, #4294967295\n"); 1534 1535 COMPARE_BOTH(Sub(r0, r1, -4), "add r0, r1, #4\n"); 1536 COMPARE_BOTH(Subs(r0, r1, -4), "adds r0, r1, #4\n"); 1537 1538 COMPARE_BOTH(Sbc(r0, r1, -5), "adc r0, r1, #4\n"); 1539 COMPARE_BOTH(Sbcs(r0, r1, -5), "adcs r0, r1, #4\n"); 1540 1541 // Non-encodable immediates 1542 1543 COMPARE_BOTH(Adc(r0, r1, 0xabcd), 1544 "mov r0, #43981\n" 1545 "adc r0, r1, r0\n"); 1546 1547 COMPARE_BOTH(Adc(r0, r1, -0xabcd), 1548 "mov r0, #43980\n" // This represents #0xabcd - 1. 1549 "sbc r0, r1, r0\n"); 1550 1551 COMPARE_BOTH(Adc(r0, r1, 0x1234abcd), 1552 "mov r0, #43981\n" 1553 "movt r0, #4660\n" 1554 "adc r0, r1, r0\n"); 1555 1556 COMPARE_BOTH(Adc(r0, r1, -0x1234abcd), 1557 "mov r0, #43980\n" // This represents #0x1234abcd - 1. 1558 "movt r0, #4660\n" 1559 "sbc r0, r1, r0\n"); 1560 1561 // Non-encodable immediates with the same source and destination registers. 1562 1563 COMPARE_BOTH(Sbc(r0, r0, 0xabcd), 1564 "mov ip, #43981\n" 1565 "sbc r0, ip\n"); 1566 1567 COMPARE_BOTH(Sbc(r0, r0, -0xabcd), 1568 "mov ip, #43980\n" // This represents #0xabcd - 1. 1569 "adc r0, ip\n"); 1570 1571 COMPARE_BOTH(Sbc(r0, r0, 0x1234abcd), 1572 "mov ip, #43981\n" 1573 "movt ip, #4660\n" 1574 "sbc r0, ip\n"); 1575 1576 COMPARE_BOTH(Sbc(r0, r0, -0x1234abcd), 1577 "mov ip, #43980\n" // This represents #0x1234abcd - 1. 1578 "movt ip, #4660\n" 1579 "adc r0, ip\n"); 1580 1581 1582 // Test that we can pass a register shifted register operand in T32. 1583 1584 COMPARE_T32(Adc(r0, r1, Operand(r2, LSL, r3)), 1585 "lsl r0, r2, r3\n" 1586 "adc r0, r1, r0\n"); 1587 1588 COMPARE_T32(Add(r3, r2, Operand(r2, ASR, r3)), 1589 "asr r3, r2, r3\n" 1590 "add r3, r2, r3\n"); 1591 1592 COMPARE_T32(Ands(r3, r2, Operand(r2, LSR, r2)), 1593 "lsr r3, r2, r2\n" 1594 "ands r3, r2, r3\n"); 1595 1596 COMPARE_T32(Asr(r2, r2, Operand(r2, ROR, r2)), 1597 "ror ip, r2, r2\n" 1598 "asr r2, ip\n"); 1599 1600 COMPARE_T32(Asr(r2, r2, Operand(r2, ROR, r2)), 1601 "ror ip, r2, r2\n" 1602 "asr r2, ip\n"); 1603 1604 1605 CLEANUP(); 1606} 1607 1608 1609TEST(macro_assembler_InstructionCondRO) { 1610 SETUP(); 1611 1612 COMPARE_BOTH(Teq(r0, 0xbad), 1613 "mov ip, #2989\n" 1614 "teq r0, ip\n"); 1615 COMPARE_BOTH(Teq(r0, 0xbadbeef), 1616 "mov ip, #48879\n" 1617 "movt ip, #2989\n" 1618 "teq r0, ip\n"); 1619 MUST_FAIL_TEST_T32(Teq(r0, Operand(r1, LSL, r2)), 1620 "Ill-formed 'teq' instruction.\n"); 1621 1622 CLEANUP(); 1623} 1624 1625 1626TEST(macro_assembler_too_large_immediate) { 1627 SETUP(); 1628 1629 // Attempting to use a 17-bit immediate with movt. 1630 MUST_FAIL_TEST_BOTH(Movt(r0, 0x10000), "`Movt` expects a 16-bit immediate."); 1631 1632 CLEANUP(); 1633} 1634 1635 1636TEST(macro_assembler_Cbz) { 1637 SETUP(); 1638 1639#ifdef VIXL_INCLUDE_TARGET_A32 1640 // Cbz/Cbnz are not available in A32 mode. 1641 // Make sure GetArchitectureStatePCOffset() returns the correct value. 1642 __ UseA32(); 1643 Label label_64(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() + 64); 1644 MUST_FAIL_TEST_A32(Cbz(r0, &label_64), "Cbz is only available for T32.\n"); 1645 MUST_FAIL_TEST_A32(Cbnz(r0, &label_64), "Cbnz is only available for T32.\n"); 1646#endif 1647 1648#ifdef VIXL_INCLUDE_TARGET_T32 1649 // Make sure GetArchitectureStatePCOffset() returns the correct value. 1650 __ UseT32(); 1651 // Largest encodable offset. 1652 Label label_126(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() + 1653 126); 1654 COMPARE_T32(Cbz(r0, &label_126), "cbz r0, 0x00000082\n"); 1655 COMPARE_T32(Cbnz(r0, &label_126), "cbnz r0, 0x00000082\n"); 1656 1657 // Offset cannot be encoded. 1658 Label label_128(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() + 1659 128); 1660 COMPARE_T32(Cbz(r0, &label_128), 1661 "cbnz r0, 0x00000004\n" 1662 "b 0x00000084\n"); 1663 COMPARE_T32(Cbnz(r0, &label_128), 1664 "cbz r0, 0x00000004\n" 1665 "b 0x00000084\n"); 1666 1667 // Offset that cannot be encoded and needs 32-bit branch instruction. 1668 Label label_8192(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() + 1669 8192); 1670 COMPARE_T32(Cbz(r0, &label_8192), 1671 "cbnz r0, 0x00000006\n" 1672 "b 0x00002004\n"); 1673 COMPARE_T32(Cbnz(r0, &label_8192), 1674 "cbz r0, 0x00000006\n" 1675 "b 0x00002004\n"); 1676 1677 // Negative offset. 1678 Label label_neg(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() + 1679 -8); 1680 COMPARE_T32(Cbz(r0, &label_neg), 1681 "cbnz r0, 0x00000004\n" 1682 "b 0xfffffffc\n"); 1683 COMPARE_T32(Cbnz(r0, &label_neg), 1684 "cbz r0, 0x00000004\n" 1685 "b 0xfffffffc\n"); 1686 1687 // Large negative offset. 1688 Label label_neg128(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() + 1689 -128); 1690 COMPARE_T32(Cbz(r0, &label_neg128), 1691 "cbnz r0, 0x00000004\n" 1692 "b 0xffffff84\n"); 1693 COMPARE_T32(Cbnz(r0, &label_neg128), 1694 "cbz r0, 0x00000004\n" 1695 "b 0xffffff84\n"); 1696#endif 1697 1698 CLEANUP(); 1699} 1700 1701 1702#ifdef VIXL_NEGATIVE_TESTING 1703TEST(assembler_crc_negative) { 1704 SETUP(); 1705 1706 ExactAssemblyScope scope(&masm, 2, CodeBufferCheckScope::kMaximumSize); 1707 1708 masm.it(eq); 1709 1710 MUST_FAIL_TEST_T32(crc32b(eq, r0, r1, r2), "Unpredictable instruction.\n"); 1711 MUST_FAIL_TEST_T32(crc32cb(eq, r0, r1, r2), "Unpredictable instruction.\n"); 1712 MUST_FAIL_TEST_T32(crc32ch(eq, r0, r1, r2), "Unpredictable instruction.\n"); 1713 MUST_FAIL_TEST_T32(crc32cw(eq, r0, r1, r2), "Unpredictable instruction.\n"); 1714 MUST_FAIL_TEST_T32(crc32h(eq, r0, r1, r2), "Unpredictable instruction.\n"); 1715 MUST_FAIL_TEST_T32(crc32w(eq, r0, r1, r2), "Unpredictable instruction.\n"); 1716 1717 CLEANUP(); 1718} 1719#endif 1720 1721 1722#ifdef VIXL_NEGATIVE_TESTING 1723TEST(assembler_hvc_negative) { 1724 SETUP(); 1725 1726 ExactAssemblyScope scope(&masm, 2, CodeBufferCheckScope::kMaximumSize); 1727 1728 masm.it(eq); 1729 1730 MUST_FAIL_TEST_T32(hvc(eq, 0), "Unpredictable instruction.\n"); 1731 1732 CLEANUP(); 1733} 1734#endif 1735 1736 1737TEST(macro_assembler_vld) { 1738 SETUP(); 1739 1740 COMPARE_BOTH(Vld1(Untyped8, 1741 NeonRegisterList(d0, kMultipleLanes), 1742 AlignedMemOperand(r1, kNoAlignment)), 1743 "vld1.8 {d0}, [r1]\n"); 1744 COMPARE_BOTH(Vld1(Untyped8, 1745 NeonRegisterList(d0, kMultipleLanes), 1746 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1747 "vld1.8 {d0}, [r1]!\n"); 1748 COMPARE_BOTH(Vld1(Untyped8, 1749 NeonRegisterList(d0, kMultipleLanes), 1750 AlignedMemOperand(r8, kNoAlignment, r2, PostIndex)), 1751 "vld1.8 {d0}, [r8], r2\n"); 1752 COMPARE_BOTH(Vld1(Untyped8, 1753 NeonRegisterList(d0, kAllLanes), 1754 AlignedMemOperand(r1, kNoAlignment)), 1755 "vld1.8 {d0[]}, [r1]\n"); 1756 COMPARE_BOTH(Vld1(Untyped8, 1757 NeonRegisterList(d0, kAllLanes), 1758 AlignedMemOperand(r9, kNoAlignment, PostIndex)), 1759 "vld1.8 {d0[]}, [r9]!\n"); 1760 COMPARE_BOTH(Vld1(Untyped8, 1761 NeonRegisterList(d0, kAllLanes), 1762 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1763 "vld1.8 {d0[]}, [r1], r2\n"); 1764 COMPARE_BOTH(Vld1(Untyped8, 1765 NeonRegisterList(d0, 0), 1766 AlignedMemOperand(r10, kNoAlignment)), 1767 "vld1.8 {d0[0]}, [r10]\n"); 1768 COMPARE_BOTH(Vld1(Untyped8, 1769 NeonRegisterList(d0, 1), 1770 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1771 "vld1.8 {d0[1]}, [r1]!\n"); 1772 COMPARE_BOTH(Vld1(Untyped8, 1773 NeonRegisterList(d0, 2), 1774 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1775 "vld1.8 {d0[2]}, [r1], r2\n"); 1776 1777 COMPARE_BOTH(Vld2(Untyped8, 1778 NeonRegisterList(d0, d1, kSingle, kMultipleLanes), 1779 AlignedMemOperand(r1, kNoAlignment)), 1780 "vld2.8 {d0,d1}, [r1]\n"); 1781 COMPARE_BOTH(Vld2(Untyped8, 1782 NeonRegisterList(d0, d1, kSingle, kMultipleLanes), 1783 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1784 "vld2.8 {d0,d1}, [r1]!\n"); 1785 COMPARE_BOTH(Vld2(Untyped8, 1786 NeonRegisterList(d0, d1, kSingle, kMultipleLanes), 1787 AlignedMemOperand(r1, kNoAlignment, r8, PostIndex)), 1788 "vld2.8 {d0,d1}, [r1], r8\n"); 1789 COMPARE_BOTH(Vld2(Untyped8, 1790 NeonRegisterList(d0, d1, kSingle, kAllLanes), 1791 AlignedMemOperand(r1, kNoAlignment)), 1792 "vld2.8 {d0[],d1[]}, [r1]\n"); 1793 COMPARE_BOTH(Vld2(Untyped8, 1794 NeonRegisterList(d0, d1, kSingle, kAllLanes), 1795 AlignedMemOperand(r9, kNoAlignment, PostIndex)), 1796 "vld2.8 {d0[],d1[]}, [r9]!\n"); 1797 COMPARE_BOTH(Vld2(Untyped8, 1798 NeonRegisterList(d0, d1, kSingle, kAllLanes), 1799 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1800 "vld2.8 {d0[],d1[]}, [r1], r2\n"); 1801 COMPARE_BOTH(Vld2(Untyped8, 1802 NeonRegisterList(d0, d1, kSingle, 0), 1803 AlignedMemOperand(r10, kNoAlignment)), 1804 "vld2.8 {d0[0],d1[0]}, [r10]\n"); 1805 COMPARE_BOTH(Vld2(Untyped8, 1806 NeonRegisterList(d0, d1, kSingle, 1), 1807 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1808 "vld2.8 {d0[1],d1[1]}, [r1]!\n"); 1809 COMPARE_BOTH(Vld2(Untyped8, 1810 NeonRegisterList(d0, d1, kSingle, 2), 1811 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1812 "vld2.8 {d0[2],d1[2]}, [r1], r2\n"); 1813 1814 COMPARE_BOTH(Vld3(Untyped8, 1815 NeonRegisterList(d0, d2, kSingle, kMultipleLanes), 1816 AlignedMemOperand(r1, kNoAlignment)), 1817 "vld3.8 {d0,d1,d2}, [r1]\n"); 1818 COMPARE_BOTH(Vld3(Untyped8, 1819 NeonRegisterList(d0, d2, kSingle, kMultipleLanes), 1820 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1821 "vld3.8 {d0,d1,d2}, [r1]!\n"); 1822 COMPARE_BOTH(Vld3(Untyped8, 1823 NeonRegisterList(d0, d2, kSingle, kMultipleLanes), 1824 AlignedMemOperand(r11, kNoAlignment, r2, PostIndex)), 1825 "vld3.8 {d0,d1,d2}, [r11], r2\n"); 1826 COMPARE_BOTH(Vld3(Untyped8, 1827 NeonRegisterList(d0, d2, kSingle, kAllLanes), 1828 MemOperand(r1)), 1829 "vld3.8 {d0[],d1[],d2[]}, [r1]\n"); 1830 COMPARE_BOTH(Vld3(Untyped8, 1831 NeonRegisterList(d0, d2, kSingle, kAllLanes), 1832 MemOperand(r11, PostIndex)), 1833 "vld3.8 {d0[],d1[],d2[]}, [r11]!\n"); 1834 COMPARE_BOTH(Vld3(Untyped8, 1835 NeonRegisterList(d0, d2, kSingle, kAllLanes), 1836 MemOperand(r1, r2, PostIndex)), 1837 "vld3.8 {d0[],d1[],d2[]}, [r1], r2\n"); 1838 COMPARE_BOTH(Vld3(Untyped8, 1839 NeonRegisterList(d0, d2, kSingle, 0), 1840 MemOperand(sp)), 1841 "vld3.8 {d0[0],d1[0],d2[0]}, [sp]\n"); 1842 COMPARE_BOTH(Vld3(Untyped8, 1843 NeonRegisterList(d0, d2, kSingle, 1), 1844 MemOperand(r1, PostIndex)), 1845 "vld3.8 {d0[1],d1[1],d2[1]}, [r1]!\n"); 1846 COMPARE_BOTH(Vld3(Untyped8, 1847 NeonRegisterList(d0, d2, kSingle, 2), 1848 MemOperand(r1, r2, PostIndex)), 1849 "vld3.8 {d0[2],d1[2],d2[2]}, [r1], r2\n"); 1850 1851 COMPARE_BOTH(Vld4(Untyped8, 1852 NeonRegisterList(d0, d6, kDouble, kMultipleLanes), 1853 AlignedMemOperand(r1, kNoAlignment)), 1854 "vld4.8 {d0,d2,d4,d6}, [r1]\n"); 1855 COMPARE_BOTH(Vld4(Untyped8, 1856 NeonRegisterList(d0, d3, kSingle, kMultipleLanes), 1857 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1858 "vld4.8 {d0,d1,d2,d3}, [r1]!\n"); 1859 COMPARE_BOTH(Vld4(Untyped8, 1860 NeonRegisterList(d0, d3, kSingle, kMultipleLanes), 1861 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1862 "vld4.8 {d0,d1,d2,d3}, [r1], r2\n"); 1863 COMPARE_BOTH(Vld4(Untyped8, 1864 NeonRegisterList(d0, d3, kSingle, kAllLanes), 1865 AlignedMemOperand(r1, kNoAlignment)), 1866 "vld4.8 {d0[],d1[],d2[],d3[]}, [r1]\n"); 1867 COMPARE_BOTH(Vld4(Untyped8, 1868 NeonRegisterList(d0, d6, kDouble, kAllLanes), 1869 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1870 "vld4.8 {d0[],d2[],d4[],d6[]}, [r1]!\n"); 1871 COMPARE_BOTH(Vld4(Untyped8, 1872 NeonRegisterList(d0, d3, kSingle, kAllLanes), 1873 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1874 "vld4.8 {d0[],d1[],d2[],d3[]}, [r1], r2\n"); 1875 COMPARE_BOTH(Vld4(Untyped16, 1876 NeonRegisterList(d0, d6, kDouble, 3), 1877 AlignedMemOperand(r1, kNoAlignment)), 1878 "vld4.16 {d0[3],d2[3],d4[3],d6[3]}, [r1]\n"); 1879 COMPARE_BOTH(Vld4(Untyped8, 1880 NeonRegisterList(d0, d3, kSingle, 6), 1881 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1882 "vld4.8 {d0[6],d1[6],d2[6],d3[6]}, [r1]!\n"); 1883 COMPARE_BOTH(Vld4(Untyped8, 1884 NeonRegisterList(d0, d3, kSingle, 7), 1885 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1886 "vld4.8 {d0[7],d1[7],d2[7],d3[7]}, [r1], r2\n"); 1887 1888 CLEANUP(); 1889} 1890 1891 1892TEST(macro_assembler_vst) { 1893 SETUP(); 1894 1895 COMPARE_BOTH(Vst1(Untyped8, 1896 NeonRegisterList(d0, kMultipleLanes), 1897 AlignedMemOperand(r1, kNoAlignment)), 1898 "vst1.8 {d0}, [r1]\n"); 1899 COMPARE_BOTH(Vst1(Untyped8, 1900 NeonRegisterList(d0, kMultipleLanes), 1901 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1902 "vst1.8 {d0}, [r1]!\n"); 1903 COMPARE_BOTH(Vst1(Untyped8, 1904 NeonRegisterList(d0, kMultipleLanes), 1905 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1906 "vst1.8 {d0}, [r1], r2\n"); 1907 COMPARE_BOTH(Vst1(Untyped8, 1908 NeonRegisterList(d0, 0), 1909 AlignedMemOperand(r1, kNoAlignment)), 1910 "vst1.8 {d0[0]}, [r1]\n"); 1911 COMPARE_BOTH(Vst1(Untyped8, 1912 NeonRegisterList(d0, 1), 1913 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1914 "vst1.8 {d0[1]}, [r1]!\n"); 1915 COMPARE_BOTH(Vst1(Untyped8, 1916 NeonRegisterList(d0, 2), 1917 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1918 "vst1.8 {d0[2]}, [r1], r2\n"); 1919 1920 COMPARE_BOTH(Vst2(Untyped8, 1921 NeonRegisterList(d0, d1, kSingle, kMultipleLanes), 1922 AlignedMemOperand(r1, kNoAlignment)), 1923 "vst2.8 {d0,d1}, [r1]\n"); 1924 COMPARE_BOTH(Vst2(Untyped8, 1925 NeonRegisterList(d0, d1, kSingle, kMultipleLanes), 1926 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1927 "vst2.8 {d0,d1}, [r1]!\n"); 1928 COMPARE_BOTH(Vst2(Untyped8, 1929 NeonRegisterList(d0, d1, kSingle, kMultipleLanes), 1930 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1931 "vst2.8 {d0,d1}, [r1], r2\n"); 1932 COMPARE_BOTH(Vst2(Untyped8, 1933 NeonRegisterList(d0, d1, kSingle, 3), 1934 AlignedMemOperand(r1, kNoAlignment)), 1935 "vst2.8 {d0[3],d1[3]}, [r1]\n"); 1936 COMPARE_BOTH(Vst2(Untyped8, 1937 NeonRegisterList(d0, d1, kSingle, 4), 1938 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1939 "vst2.8 {d0[4],d1[4]}, [r1]!\n"); 1940 COMPARE_BOTH(Vst2(Untyped8, 1941 NeonRegisterList(d0, d1, kSingle, 5), 1942 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1943 "vst2.8 {d0[5],d1[5]}, [r1], r2\n"); 1944 1945 COMPARE_BOTH(Vst3(Untyped8, 1946 NeonRegisterList(d0, d2, kSingle, kMultipleLanes), 1947 AlignedMemOperand(r1, kNoAlignment)), 1948 "vst3.8 {d0,d1,d2}, [r1]\n"); 1949 COMPARE_BOTH(Vst3(Untyped8, 1950 NeonRegisterList(d0, d2, kSingle, kMultipleLanes), 1951 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1952 "vst3.8 {d0,d1,d2}, [r1]!\n"); 1953 COMPARE_BOTH(Vst3(Untyped8, 1954 NeonRegisterList(d0, d2, kSingle, kMultipleLanes), 1955 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1956 "vst3.8 {d0,d1,d2}, [r1], r2\n"); 1957 COMPARE_BOTH(Vst3(Untyped8, 1958 NeonRegisterList(d0, d2, kSingle, 0), 1959 MemOperand(r1)), 1960 "vst3.8 {d0[0],d1[0],d2[0]}, [r1]\n"); 1961 COMPARE_BOTH(Vst3(Untyped8, 1962 NeonRegisterList(d0, d2, kSingle, 6), 1963 MemOperand(r1, PostIndex)), 1964 "vst3.8 {d0[6],d1[6],d2[6]}, [r1]!\n"); 1965 COMPARE_BOTH(Vst3(Untyped8, 1966 NeonRegisterList(d0, d2, kSingle, 7), 1967 MemOperand(r1, r2, PostIndex)), 1968 "vst3.8 {d0[7],d1[7],d2[7]}, [r1], r2\n"); 1969 1970 COMPARE_BOTH(Vst4(Untyped8, 1971 NeonRegisterList(d10, d13, kSingle, kMultipleLanes), 1972 AlignedMemOperand(r1, kNoAlignment)), 1973 "vst4.8 {d10,d11,d12,d13}, [r1]\n"); 1974 COMPARE_BOTH(Vst4(Untyped8, 1975 NeonRegisterList(d10, d13, kSingle, kMultipleLanes), 1976 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1977 "vst4.8 {d10,d11,d12,d13}, [r1]!\n"); 1978 COMPARE_BOTH(Vst4(Untyped8, 1979 NeonRegisterList(d0, d3, kSingle, kMultipleLanes), 1980 AlignedMemOperand(r8, kNoAlignment, r9, PostIndex)), 1981 "vst4.8 {d0,d1,d2,d3}, [r8], r9\n"); 1982 COMPARE_BOTH(Vst4(Untyped8, 1983 NeonRegisterList(d0, d3, kSingle, 0), 1984 AlignedMemOperand(r1, kNoAlignment)), 1985 "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [r1]\n"); 1986 COMPARE_BOTH(Vst4(Untyped8, 1987 NeonRegisterList(d0, d3, kSingle, 0), 1988 AlignedMemOperand(r1, kNoAlignment, PostIndex)), 1989 "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [r1]!\n"); 1990 COMPARE_BOTH(Vst4(Untyped8, 1991 NeonRegisterList(d0, d3, kSingle, 0), 1992 AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)), 1993 "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [r1], r2\n"); 1994 1995 CLEANUP(); 1996} 1997 1998 1999TEST(assembler_vldm_vstm_negative) { 2000 SETUP(); 2001 2002 ExactAssemblyScope scope(&masm, 0, CodeBufferCheckScope::kMaximumSize); 2003 2004 MUST_FAIL_TEST_BOTH(fldmdbx(pc, WRITE_BACK, DRegisterList(d0)), 2005 "Unpredictable instruction.\n"); 2006 MUST_FAIL_TEST_BOTH(fldmiax(pc, WRITE_BACK, DRegisterList(d0)), 2007 "Unpredictable instruction.\n"); 2008 MUST_FAIL_TEST_T32(fldmiax(pc, NO_WRITE_BACK, DRegisterList(d0)), 2009 "Unpredictable instruction.\n"); 2010 2011 MUST_FAIL_TEST_BOTH(fstmdbx(pc, WRITE_BACK, DRegisterList(d0)), 2012 "Unpredictable instruction.\n"); 2013 MUST_FAIL_TEST_BOTH(fstmiax(pc, WRITE_BACK, DRegisterList(d0)), 2014 "Unpredictable instruction.\n"); 2015 MUST_FAIL_TEST_T32(fstmiax(pc, NO_WRITE_BACK, DRegisterList(d0)), 2016 "Unpredictable instruction.\n"); 2017 2018 MUST_FAIL_TEST_BOTH(vldmdb(pc, WRITE_BACK, SRegisterList(s0)), 2019 "Unpredictable instruction.\n"); 2020 MUST_FAIL_TEST_BOTH(vldm(pc, WRITE_BACK, SRegisterList(s0)), 2021 "Unpredictable instruction.\n"); 2022 MUST_FAIL_TEST_T32(vldm(pc, NO_WRITE_BACK, SRegisterList(s0)), 2023 "Unpredictable instruction.\n"); 2024 MUST_FAIL_TEST_BOTH(vldmia(pc, WRITE_BACK, SRegisterList(s0)), 2025 "Unpredictable instruction.\n"); 2026 MUST_FAIL_TEST_T32(vldmia(pc, NO_WRITE_BACK, SRegisterList(s0)), 2027 "Unpredictable instruction.\n"); 2028 2029 MUST_FAIL_TEST_BOTH(vldmdb(pc, WRITE_BACK, DRegisterList(d0)), 2030 "Unpredictable instruction.\n"); 2031 MUST_FAIL_TEST_BOTH(vldm(pc, WRITE_BACK, DRegisterList(d0)), 2032 "Unpredictable instruction.\n"); 2033 MUST_FAIL_TEST_T32(vldm(pc, NO_WRITE_BACK, DRegisterList(d0)), 2034 "Unpredictable instruction.\n"); 2035 MUST_FAIL_TEST_BOTH(vldmia(pc, WRITE_BACK, DRegisterList(d0)), 2036 "Unpredictable instruction.\n"); 2037 MUST_FAIL_TEST_T32(vldmia(pc, NO_WRITE_BACK, DRegisterList(d0)), 2038 "Unpredictable instruction.\n"); 2039 2040 MUST_FAIL_TEST_BOTH(vstmdb(pc, WRITE_BACK, SRegisterList(s0)), 2041 "Unpredictable instruction.\n"); 2042 MUST_FAIL_TEST_BOTH(vstm(pc, WRITE_BACK, SRegisterList(s0)), 2043 "Unpredictable instruction.\n"); 2044 MUST_FAIL_TEST_T32(vstm(pc, NO_WRITE_BACK, SRegisterList(s0)), 2045 "Unpredictable instruction.\n"); 2046 MUST_FAIL_TEST_BOTH(vstmia(pc, WRITE_BACK, SRegisterList(s0)), 2047 "Unpredictable instruction.\n"); 2048 MUST_FAIL_TEST_T32(vstmia(pc, NO_WRITE_BACK, SRegisterList(s0)), 2049 "Unpredictable instruction.\n"); 2050 2051 MUST_FAIL_TEST_BOTH(vstmdb(pc, WRITE_BACK, DRegisterList(d0)), 2052 "Unpredictable instruction.\n"); 2053 MUST_FAIL_TEST_BOTH(vstm(pc, WRITE_BACK, DRegisterList(d0)), 2054 "Unpredictable instruction.\n"); 2055 MUST_FAIL_TEST_T32(vstm(pc, NO_WRITE_BACK, DRegisterList(d0)), 2056 "Unpredictable instruction.\n"); 2057 MUST_FAIL_TEST_BOTH(vstmia(pc, WRITE_BACK, DRegisterList(d0)), 2058 "Unpredictable instruction.\n"); 2059 MUST_FAIL_TEST_T32(vstmia(pc, NO_WRITE_BACK, DRegisterList(d0)), 2060 "Unpredictable instruction.\n"); 2061 2062 CLEANUP(); 2063} 2064 2065 2066#define TEST_VMEMOP(MACRO_OP, STRING_OP, DST_REG) \ 2067 SETUP(); \ 2068 \ 2069 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 1024)), \ 2070 "add ip, r8, #1024\n" STRING_OP #DST_REG ", [ip]\n"); \ 2071 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 1371)), \ 2072 "add ip, r8, #1371\n" STRING_OP #DST_REG ", [ip]\n"); \ 2073 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 4113)), \ 2074 "add ip, r8, #17\n" \ 2075 "add ip, #4096\n" STRING_OP #DST_REG ", [ip]\n"); \ 2076 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 65808)), \ 2077 "add ip, r8, #272\n" \ 2078 "add ip, #65536\n" STRING_OP #DST_REG ", [ip]\n"); \ 2079 \ 2080 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -1024)), \ 2081 "sub ip, r8, #1024\n" STRING_OP #DST_REG ", [ip]\n"); \ 2082 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -1371)), \ 2083 "sub ip, r8, #1371\n" STRING_OP #DST_REG ", [ip]\n"); \ 2084 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -4113)), \ 2085 "sub ip, r8, #17\n" \ 2086 "sub ip, #4096\n" STRING_OP #DST_REG ", [ip]\n"); \ 2087 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -65808)), \ 2088 "sub ip, r8, #272\n" \ 2089 "sub ip, #65536\n" STRING_OP #DST_REG ", [ip]\n"); \ 2090 \ 2091 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 0, PreIndex)), \ 2092 STRING_OP #DST_REG ", [r9]\n"); \ 2093 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 137, PreIndex)), \ 2094 "add r9, #137\n" STRING_OP #DST_REG ", [r9]\n"); \ 2095 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 4110, PreIndex)), \ 2096 "add r9, #14\n" \ 2097 "add r9, #4096\n" STRING_OP #DST_REG ", [r9]\n"); \ 2098 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 65623, PreIndex)), \ 2099 "add r9, #87\n" \ 2100 "add r9, #65536\n" STRING_OP #DST_REG ", [r9]\n"); \ 2101 \ 2102 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -137, PreIndex)), \ 2103 "sub r9, #137\n" STRING_OP #DST_REG ", [r9]\n"); \ 2104 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -4110, PreIndex)), \ 2105 "sub r9, #14\n" \ 2106 "sub r9, #4096\n" STRING_OP #DST_REG ", [r9]\n"); \ 2107 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -65623, PreIndex)), \ 2108 "sub r9, #87\n" \ 2109 "sub r9, #65536\n" STRING_OP #DST_REG ", [r9]\n"); \ 2110 \ 2111 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 0, PostIndex)), \ 2112 STRING_OP #DST_REG ", [r10]\n"); \ 2113 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 137, PostIndex)), \ 2114 STRING_OP #DST_REG \ 2115 ", [r10]\n" \ 2116 "add r10, #137\n"); \ 2117 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 4110, PostIndex)), \ 2118 STRING_OP #DST_REG \ 2119 ", [r10]\n" \ 2120 "add r10, #14\n" \ 2121 "add r10, #4096\n"); \ 2122 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 65623, PostIndex)), \ 2123 STRING_OP #DST_REG \ 2124 ", [r10]\n" \ 2125 "add r10, #87\n" \ 2126 "add r10, #65536\n"); \ 2127 \ 2128 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -137, PostIndex)), \ 2129 STRING_OP #DST_REG \ 2130 ", [r10]\n" \ 2131 "sub r10, #137\n"); \ 2132 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -4110, PostIndex)), \ 2133 STRING_OP #DST_REG \ 2134 ", [r10]\n" \ 2135 "sub r10, #14\n" \ 2136 "sub r10, #4096\n"); \ 2137 COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -65623, PostIndex)), \ 2138 STRING_OP #DST_REG \ 2139 ", [r10]\n" \ 2140 "sub r10, #87\n" \ 2141 "sub r10, #65536\n"); \ 2142 CLEANUP(); 2143 2144TEST(macro_assembler_T32_Vldr_d) { TEST_VMEMOP(Vldr, "vldr ", d0); } 2145 2146TEST(macro_assembler_T32_Vstr_d) { TEST_VMEMOP(Vstr, "vstr ", d1); } 2147 2148TEST(macro_assembler_T32_Vldr_s) { TEST_VMEMOP(Vldr, "vldr ", s2); } 2149 2150TEST(macro_assembler_T32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); } 2151 2152#undef TEST_VMEMOP 2153 2154#define TEST_VMEMOP(MACRO_OP, STRING_OP, DST_REG) \ 2155 SETUP(); \ 2156 \ 2157 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 137)), \ 2158 "add ip, r8, #137\n" STRING_OP #DST_REG ", [ip]\n"); \ 2159 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 274)), \ 2160 "add ip, r8, #18\n" \ 2161 "add ip, #256\n" STRING_OP #DST_REG ", [ip]\n"); \ 2162 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 65623)), \ 2163 "add ip, r8, #87\n" \ 2164 "add ip, #65536\n" STRING_OP #DST_REG ", [ip]\n"); \ 2165 \ 2166 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -137)), \ 2167 "sub ip, r8, #137\n" STRING_OP #DST_REG ", [ip]\n"); \ 2168 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -274)), \ 2169 "sub ip, r8, #18\n" \ 2170 "sub ip, #256\n" STRING_OP #DST_REG ", [ip]\n"); \ 2171 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -65623)), \ 2172 "sub ip, r8, #87\n" \ 2173 "sub ip, #65536\n" STRING_OP #DST_REG ", [ip]\n"); \ 2174 \ 2175 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 0, PreIndex)), \ 2176 STRING_OP #DST_REG ", [r9]\n"); \ 2177 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 137, PreIndex)), \ 2178 "add r9, #137\n" STRING_OP #DST_REG ", [r9]\n"); \ 2179 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 274, PreIndex)), \ 2180 "add r9, #18\n" \ 2181 "add r9, #256\n" STRING_OP #DST_REG ", [r9]\n"); \ 2182 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 65623, PreIndex)), \ 2183 "add r9, #87\n" \ 2184 "add r9, #65536\n" STRING_OP #DST_REG ", [r9]\n"); \ 2185 \ 2186 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -137, PreIndex)), \ 2187 "sub r9, #137\n" STRING_OP #DST_REG ", [r9]\n"); \ 2188 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -274, PreIndex)), \ 2189 "sub r9, #18\n" \ 2190 "sub r9, #256\n" STRING_OP #DST_REG ", [r9]\n"); \ 2191 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -65623, PreIndex)), \ 2192 "sub r9, #87\n" \ 2193 "sub r9, #65536\n" STRING_OP #DST_REG ", [r9]\n"); \ 2194 \ 2195 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 0, PostIndex)), \ 2196 STRING_OP #DST_REG ", [r10]\n"); \ 2197 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 137, PostIndex)), \ 2198 STRING_OP #DST_REG \ 2199 ", [r10]\n" \ 2200 "add r10, #137\n"); \ 2201 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 274, PostIndex)), \ 2202 STRING_OP #DST_REG \ 2203 ", [r10]\n" \ 2204 "add r10, #18\n" \ 2205 "add r10, #256\n"); \ 2206 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 65623, PostIndex)), \ 2207 STRING_OP #DST_REG \ 2208 ", [r10]\n" \ 2209 "add r10, #87\n" \ 2210 "add r10, #65536\n"); \ 2211 \ 2212 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -137, PostIndex)), \ 2213 STRING_OP #DST_REG \ 2214 ", [r10]\n" \ 2215 "sub r10, #137\n"); \ 2216 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -274, PostIndex)), \ 2217 STRING_OP #DST_REG \ 2218 ", [r10]\n" \ 2219 "sub r10, #18\n" \ 2220 "sub r10, #256\n"); \ 2221 COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -65623, PostIndex)), \ 2222 STRING_OP #DST_REG \ 2223 ", [r10]\n" \ 2224 "sub r10, #87\n" \ 2225 "sub r10, #65536\n"); \ 2226 CLEANUP(); 2227 2228 2229TEST(macro_assembler_A32_Vldr_d) { TEST_VMEMOP(Vldr, "vldr ", d0); } 2230 2231TEST(macro_assembler_A32_Vstr_d) { TEST_VMEMOP(Vstr, "vstr ", d1); } 2232 2233TEST(macro_assembler_A32_Vldr_s) { TEST_VMEMOP(Vldr, "vldr ", s2); } 2234 2235TEST(macro_assembler_A32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); } 2236 2237#undef TEST_VMEMOP 2238 2239TEST(assembler_vstr_negative) { 2240 SETUP(); 2241 2242 ExactAssemblyScope scope(&masm, 8, CodeBufferCheckScope::kMaximumSize); 2243 2244 MUST_FAIL_TEST_T32(vstr(s0, MemOperand(pc, 0)), 2245 "Unpredictable instruction.\n"); 2246 2247 MUST_FAIL_TEST_T32(vstr(d0, MemOperand(pc, 0)), 2248 "Unpredictable instruction.\n"); 2249 2250 CLEANUP(); 2251} 2252 2253TEST(macro_assembler_Vldr_Vstr_negative) { 2254 SETUP(); 2255 2256 MUST_FAIL_TEST_BOTH(Vldr(s0, MemOperand(pc, 1, PreIndex)), 2257 "The MacroAssembler does not convert vldr or vstr" 2258 " with a PC base register.\n"); 2259 2260 MUST_FAIL_TEST_BOTH(Vldr(s0, MemOperand(pc, r0, PreIndex)), 2261 "Ill-formed 'vldr' instruction.\n"); 2262 2263 MUST_FAIL_TEST_BOTH(Vstr(s0, MemOperand(pc, 1, PreIndex)), 2264 "The MacroAssembler does not convert vldr or vstr" 2265 " with a PC base register.\n"); 2266 2267 MUST_FAIL_TEST_BOTH(Vstr(s0, MemOperand(pc, r0, PreIndex)), 2268 "Ill-formed 'vstr' instruction.\n"); 2269 2270 MUST_FAIL_TEST_BOTH(Vldr(d0, MemOperand(pc, 1, PreIndex)), 2271 "The MacroAssembler does not convert vldr or vstr" 2272 " with a PC base register.\n"); 2273 2274 MUST_FAIL_TEST_BOTH(Vldr(d0, MemOperand(pc, r0, PreIndex)), 2275 "Ill-formed 'vldr' instruction.\n"); 2276 2277 MUST_FAIL_TEST_BOTH(Vstr(d0, MemOperand(pc, 1, PreIndex)), 2278 "The MacroAssembler does not convert vldr or vstr" 2279 " with a PC base register.\n"); 2280 2281 MUST_FAIL_TEST_BOTH(Vstr(d0, MemOperand(pc, r0, PreIndex)), 2282 "Ill-formed 'vstr' instruction.\n"); 2283 CLEANUP(); 2284} 2285 2286#define TEST_SHIFT_T32(Inst, name, offset) \ 2287 COMPARE_T32(Inst(r0, Operand(r1, LSL, r2)), \ 2288 "lsl ip, r1, r2\n" name " r0, ip\n"); \ 2289 COMPARE_T32(Inst(r0, Operand(r1, LSR, r2)), \ 2290 "lsr ip, r1, r2\n" name " r0, ip\n"); \ 2291 COMPARE_T32(Inst(r0, Operand(r1, ASR, r2)), \ 2292 "asr ip, r1, r2\n" name " r0, ip\n"); \ 2293 COMPARE_T32(Inst(r0, Operand(r1, ROR, r2)), \ 2294 "ror ip, r1, r2\n" name " r0, ip\n"); \ 2295 COMPARE_T32(Inst(eq, r0, Operand(r1, LSL, r2)), \ 2296 "bne " #offset \ 2297 "\n" \ 2298 "lsl ip, r1, r2\n" name " r0, ip\n"); \ 2299 COMPARE_T32(Inst(le, r0, Operand(r1, LSL, r2)), \ 2300 "bgt " #offset \ 2301 "\n" \ 2302 "lsl ip, r1, r2\n" name " r0, ip\n"); 2303 2304#define TEST_MOV_SHIFT_T32(Inst, s, offset) \ 2305 COMPARE_T32(Inst(r0, Operand(r1, LSL, r2)), "lsl" s " r0, r1, r2\n"); \ 2306 COMPARE_T32(Inst(r0, Operand(r1, LSR, r2)), "lsr" s " r0, r1, r2\n"); \ 2307 COMPARE_T32(Inst(r0, Operand(r1, ASR, r2)), "asr" s " r0, r1, r2\n"); \ 2308 COMPARE_T32(Inst(r0, Operand(r1, ROR, r2)), "ror" s " r0, r1, r2\n"); \ 2309 COMPARE_T32(Inst(eq, r0, Operand(r1, LSL, r2)), \ 2310 "bne " #offset \ 2311 "\n" \ 2312 "lsl" s " r0, r1, r2\n"); \ 2313 COMPARE_T32(Inst(le, r0, Operand(r1, LSL, r2)), \ 2314 "bgt " #offset \ 2315 "\n" \ 2316 "lsl" s " r0, r1, r2\n"); 2317 2318#define TEST_WIDE_IMMEDIATE(Inst, name, offset) \ 2319 COMPARE_BOTH(Inst(r0, 0xbadbeef), \ 2320 "mov ip, #48879\n" \ 2321 "movt ip, #2989\n" name " r0, ip\n"); \ 2322 COMPARE_A32(Inst(eq, r0, 0xbadbeef), \ 2323 "moveq ip, #48879\n" \ 2324 "movteq ip, #2989\n" name "eq r0, ip\n"); \ 2325 COMPARE_T32(Inst(eq, r0, 0xbadbeef), \ 2326 "bne " #offset \ 2327 "\n" \ 2328 "mov ip, #48879\n" \ 2329 "movt ip, #2989\n" name " r0, ip\n"); 2330 2331#define TEST_WIDE_IMMEDIATE_PC(Inst, name, offset) \ 2332 COMPARE_A32(Inst(pc, 0xbadbeef), \ 2333 "mov ip, #48879\n" \ 2334 "movt ip, #2989\n" name " pc, ip\n"); \ 2335 COMPARE_A32(Inst(eq, pc, 0xbadbeef), \ 2336 "moveq ip, #48879\n" \ 2337 "movteq ip, #2989\n" name "eq pc, ip\n"); \ 2338 MUST_FAIL_TEST_T32(Inst(pc, 0xbadbeef), \ 2339 "Ill-formed '" name "' instruction.\n"); \ 2340 MUST_FAIL_TEST_T32(Inst(eq, pc, 0xbadbeef), \ 2341 "Ill-formed '" name "' instruction.\n"); 2342 2343TEST(macro_assembler_InstructionCondSizeROp) { 2344 SETUP(); 2345 2346 // T32 register shifted register. 2347 TEST_SHIFT_T32(Cmn, "cmn", 0x0000000a) 2348 TEST_SHIFT_T32(Cmp, "cmp", 0x00000008) 2349 TEST_SHIFT_T32(Mvn, "mvn", 0x0000000a) 2350 TEST_SHIFT_T32(Mvns, "mvns", 0x0000000a) 2351 TEST_SHIFT_T32(Sxtb, "sxtb", 0x0000000a) 2352 TEST_SHIFT_T32(Sxth, "sxth", 0x0000000a) 2353 TEST_SHIFT_T32(Tst, "tst", 0x0000000a) 2354 TEST_SHIFT_T32(Uxtb, "uxtb", 0x0000000a) 2355 TEST_SHIFT_T32(Uxth, "uxth", 0x0000000a) 2356 2357 TEST_MOV_SHIFT_T32(Mov, "", 0x00000006) 2358 TEST_MOV_SHIFT_T32(Movs, "s", 0x00000006) 2359 2360 MUST_FAIL_TEST_BOTH(Movs(pc, r0), "Unpredictable instruction.\n"); 2361 MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, LSL, 0x4)), 2362 "Unpredictable instruction.\n"); 2363 MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, ASR, r2)), 2364 "Unpredictable instruction.\n"); 2365 2366 // Wide immediates (Mov and Movs are tested in 2367 // "macro_assembler_wide_immediate"). 2368 TEST_WIDE_IMMEDIATE(Cmp, "cmp", 0x0000000c); 2369 TEST_WIDE_IMMEDIATE(Cmn, "cmn", 0x0000000e); 2370 TEST_WIDE_IMMEDIATE(Tst, "tst", 0x0000000e); 2371 TEST_WIDE_IMMEDIATE_PC(Cmp, "cmp", 0x0000000c); 2372 TEST_WIDE_IMMEDIATE_PC(Cmn, "cmn", 0x0000000e); 2373 TEST_WIDE_IMMEDIATE_PC(Tst, "tst", 0x0000000e); 2374 2375 // For Mvn and Mvns, we don't allow PC as a destination. 2376 TEST_WIDE_IMMEDIATE(Mvn, "mvn", 0x0000000e); 2377 TEST_WIDE_IMMEDIATE(Mvns, "mvns", 0x0000000e); 2378 MUST_FAIL_TEST_BOTH(Mvn(pc, 0xbadbeef), "Ill-formed 'mvn' instruction.\n"); 2379 MUST_FAIL_TEST_BOTH(Mvn(eq, pc, 0xbadbeef), 2380 "Ill-formed 'mvn' instruction.\n"); 2381 MUST_FAIL_TEST_BOTH(Mvns(pc, 0xbadbeef), "Ill-formed 'mvns' instruction.\n"); 2382 MUST_FAIL_TEST_BOTH(Mvns(eq, pc, 0xbadbeef), 2383 "Ill-formed 'mvns' instruction.\n"); 2384 2385 MUST_FAIL_TEST_BOTH(Sxtb(r0, 0x1), "Ill-formed 'sxtb' instruction.\n"); 2386 MUST_FAIL_TEST_BOTH(Sxth(r0, 0x1), "Ill-formed 'sxth' instruction.\n"); 2387 MUST_FAIL_TEST_BOTH(Uxtb(r0, 0x1), "Ill-formed 'uxtb' instruction.\n"); 2388 MUST_FAIL_TEST_BOTH(Uxth(r0, 0x1), "Ill-formed 'uxth' instruction.\n"); 2389 2390 CLEANUP(); 2391} 2392 2393#undef TEST_SHIFT_T32 2394#undef TEST_MOV_SHIFT_T32 2395#undef TEST_WIDE_IMMEDIATE 2396#undef TEST_WIDE_IMMEDIATE_PC 2397 2398TEST(macro_assembler_Msr) { 2399 SETUP(); 2400 2401 // Msr with immediate for T32. 2402 COMPARE_T32(Msr(APSR_nzcvq, 0x0), 2403 "mov ip, #0\n" 2404 "msr APSR_nzcvq, ip\n"); 2405 2406 // Wide immediate. 2407 COMPARE_BOTH(Msr(APSR_nzcvq, 0xbadbeef), 2408 "mov ip, #48879\n" 2409 "movt ip, #2989\n" 2410 "msr APSR_nzcvq, ip\n"); 2411 2412 // Other types of operands are not handled. 2413 MUST_FAIL_TEST_BOTH(Msr(APSR_nzcvq, Operand(r0, LSR, r1)), 2414 "Ill-formed 'msr' instruction.\n"); 2415 CLEANUP(); 2416} 2417 2418 2419TEST(macro_assembler_Vmov_imm) { 2420 SETUP(); 2421 2422 COMPARE_BOTH(Vmov(s0, 0.0f), 2423 "mov ip, #0\n" 2424 "vmov s0, ip\n"); 2425 COMPARE_BOTH(Vmov(s1, 1.0f), "vmov.f32 s1, #1\n"); 2426 COMPARE_BOTH(Vmov(s2, RawbitsToFloat(0x0000db6c)), 2427 "mov ip, #56172\n" 2428 "vmov s2, ip\n"); 2429 COMPARE_BOTH(Vmov(s3, RawbitsToFloat(0x327b23c6)), 2430 "mov ip, #9158\n" 2431 "movt ip, #12923\n" 2432 "vmov s3, ip\n"); 2433 COMPARE_BOTH(Vmov(s4, RawbitsToFloat(0xffcc7fff)), 2434 "mvn ip, #3375104\n" 2435 "vmov s4, ip\n"); 2436 COMPARE_BOTH(Vmov(s5, RawbitsToFloat(0xb72df575)), 2437 "mov ip, #62837\n" 2438 "movt ip, #46893\n" 2439 "vmov s5, ip\n"); 2440 2441 COMPARE_BOTH(Vmov(d6, 0.0), "vmov.i64 d6, #0x0000000000000000\n"); 2442 COMPARE_BOTH(Vmov(d7, 1.0), "vmov.f64 d7, #1\n"); 2443 COMPARE_BOTH(Vmov(d8, RawbitsToDouble(0x000000000000af8e)), 2444 "mov ip, #44942\n" 2445 "vdup.32 d8, ip\n" 2446 "mov ip, #0\n" 2447 "vmov.32 d8[1], ip\n"); 2448 COMPARE_BOTH(Vmov(d9, RawbitsToDouble(0x000070210000af8e)), 2449 "mov ip, #44942\n" 2450 "vdup.32 d9, ip\n" 2451 "mov ip, #28705\n" 2452 "vmov.32 d9[1], ip\n"); 2453 COMPARE_BOTH(Vmov(d10, RawbitsToDouble(0x7021000000000000)), 2454 "mov ip, #0\n" 2455 "vdup.32 d10, ip\n" 2456 "mov ip, #0\n" 2457 "movt ip, #28705\n" 2458 "vmov.32 d10[1], ip\n"); 2459 COMPARE_BOTH(Vmov(d11, RawbitsToDouble(0x7021da4b0000af8e)), 2460 "mov ip, #44942\n" 2461 "vdup.32 d11, ip\n" 2462 "mov ip, #55883\n" 2463 "movt ip, #28705\n" 2464 "vmov.32 d11[1], ip\n"); 2465 COMPARE_BOTH(Vmov(d12, RawbitsToDouble(0x0cff553204ec4a3f)), 2466 "mov ip, #19007\n" 2467 "movt ip, #1260\n" 2468 "vdup.32 d12, ip\n" 2469 "mov ip, #21810\n" 2470 "movt ip, #3327\n" 2471 "vmov.32 d12[1], ip\n"); 2472 COMPARE_BOTH(Vmov(d13, RawbitsToDouble(0xa2037ad20000f592)), 2473 "mov ip, #62866\n" 2474 "vdup.32 d13, ip\n" 2475 "mov ip, #31442\n" 2476 "movt ip, #41475\n" 2477 "vmov.32 d13[1], ip\n"); 2478 COMPARE_BOTH(Vmov(d14, RawbitsToDouble(0xe62556c325a59470)), 2479 "mov ip, #38000\n" 2480 "movt ip, #9637\n" 2481 "vdup.32 d14, ip\n" 2482 "mov ip, #22211\n" 2483 "movt ip, #58917\n" 2484 "vmov.32 d14[1], ip\n"); 2485 CLEANUP(); 2486} 2487 2488TEST(macro_assembler_PushRegisterList) { 2489 SETUP(); 2490 2491 // Allow the test to use all registers. 2492 UseScratchRegisterScope temps(&masm); 2493 temps.ExcludeAll(); 2494 2495 COMPARE_BOTH(Push(RegisterList(0x1111)), "push {r0,r4,r8,ip}\n"); 2496 2497 COMPARE_BOTH(Push(RegisterList(0x1fff)), 2498 "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2499 2500 COMPARE_BOTH(Push(RegisterList(0x5fff)), 2501 "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip,lr}\n"); 2502 2503 COMPARE_A32(Push(ne, RegisterList(0x1fff)), 2504 "pushne {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2505 2506 COMPARE_T32(Push(ne, RegisterList(0x1fff)), 2507 "beq 0x00000006\n" 2508 "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2509 2510 COMPARE_A32(Push(RegisterList(sp)), "stmdb sp!, {sp}\n"); 2511 2512 // TODO: Clarify behaviour of MacroAssembler vs Assembler with respect to 2513 // deprecated and unpredictable instructions. The tests reflect the 2514 // current behaviour and will need to be updated. 2515 2516 // Deprecated, but accepted: 2517 SHOULD_FAIL_TEST_A32(Push(RegisterList(pc))); 2518 // Whereas we don't accept the single-register version: 2519 MUST_FAIL_TEST_BOTH(Push(pc), "Unpredictable instruction.\n"); 2520 2521 // Accepted, but stores UNKNOWN value for the SP: 2522 SHOULD_FAIL_TEST_A32(Push(RegisterList(r0, sp))); 2523 2524 // The following use the T1 and A1 encodings for T32 and A32 respectively, and 2525 // hence have different preferred disassembly. 2526 COMPARE_T32(Push(RegisterList(r0)), "push {r0}\n"); 2527 COMPARE_A32(Push(RegisterList(r0)), "stmdb sp!, {r0}\n"); 2528 COMPARE_T32(Push(RegisterList(r7)), "push {r7}\n"); 2529 COMPARE_A32(Push(RegisterList(r7)), "stmdb sp!, {r7}\n"); 2530 COMPARE_T32(Push(RegisterList(lr)), "push {lr}\n"); 2531 COMPARE_A32(Push(RegisterList(lr)), "stmdb sp!, {lr}\n"); 2532 2533 // T2 and A1 encodings, with the same preferred disassembly: 2534 COMPARE_BOTH(Push(RegisterList(r8)), "stmdb sp!, {r8}\n"); 2535 2536 // Cannot push the sp and pc in T32 when using a register list. 2537 MUST_FAIL_TEST_T32(Push(RegisterList(sp)), 2538 "Ill-formed 'push' instruction.\n"); 2539 MUST_FAIL_TEST_T32(Push(RegisterList(pc)), 2540 "Ill-formed 'push' instruction.\n"); 2541 2542 CLEANUP(); 2543} 2544 2545TEST(macro_assembler_PopRegisterList) { 2546 SETUP(); 2547 2548 // Allow the test to use all registers. 2549 UseScratchRegisterScope temps(&masm); 2550 temps.ExcludeAll(); 2551 2552 COMPARE_BOTH(Pop(RegisterList(0x1111)), "pop {r0,r4,r8,ip}\n"); 2553 2554 COMPARE_BOTH(Pop(RegisterList(0x1fff)), 2555 "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2556 2557 COMPARE_BOTH(Pop(RegisterList(0x5fff)), 2558 "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip,lr}\n"); 2559 2560 COMPARE_A32(Pop(ne, RegisterList(0x1fff)), 2561 "popne {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2562 2563 COMPARE_T32(Pop(ne, RegisterList(0x1fff)), 2564 "beq 0x00000006\n" 2565 "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n"); 2566 2567 // TODO: Accepted, but value of SP after the instruction is UNKNOWN: 2568 SHOULD_FAIL_TEST_A32(Pop(RegisterList(sp))); 2569 2570 // Cannot pop the sp in T32 when using a register list. 2571 MUST_FAIL_TEST_T32(Pop(RegisterList(sp)), "Ill-formed 'pop' instruction.\n"); 2572 2573 // The following use the T1 and A1 encodings for T32 and A32 respectively, and 2574 // hence have different preferred disassembly. 2575 COMPARE_T32(Pop(RegisterList(pc)), "pop {pc}\n"); 2576 COMPARE_A32(Pop(RegisterList(pc)), "ldm sp!, {pc}\n"); 2577 COMPARE_T32(Pop(RegisterList(r0)), "pop {r0}\n"); 2578 COMPARE_A32(Pop(RegisterList(r0)), "ldm sp!, {r0}\n"); 2579 COMPARE_T32(Pop(RegisterList(r7)), "pop {r7}\n"); 2580 COMPARE_A32(Pop(RegisterList(r7)), "ldm sp!, {r7}\n"); 2581 2582 // T2 and A1 encodings, with the same preferred disassembly: 2583 COMPARE_BOTH(Pop(RegisterList(r8)), "ldm sp!, {r8}\n"); 2584 COMPARE_BOTH(Pop(RegisterList(lr)), "ldm sp!, {lr}\n"); 2585 2586 // TODO: Pushing both the lr and pc should not be allowed by the 2587 // MacroAssembler (deprecated for A32, for T32 they shouldn't both 2588 // be in the list). 2589 SHOULD_FAIL_TEST_BOTH(Pop(RegisterList(lr, pc))); 2590 2591 CLEANUP(); 2592} 2593 2594 2595TEST(macro_assembler_unpredictable) { 2596 SETUP(); 2597 2598 // ADC, ADCS (immediate). 2599 COMPARE_A32(Adc(pc, r0, 1), "adc pc, r0, #1\n"); 2600 COMPARE_A32(Adc(r0, pc, 1), "adc r0, pc, #1\n"); 2601 MUST_FAIL_TEST_T32(Adc(pc, r0, 1), "Unpredictable instruction.\n"); 2602 MUST_FAIL_TEST_T32(Adc(r0, pc, 1), "Unpredictable instruction.\n"); 2603 COMPARE_A32(Adcs(pc, r0, 1), "adcs pc, r0, #1\n"); 2604 COMPARE_A32(Adcs(r0, pc, 1), "adcs r0, pc, #1\n"); 2605 MUST_FAIL_TEST_T32(Adcs(pc, r0, 1), "Unpredictable instruction.\n"); 2606 MUST_FAIL_TEST_T32(Adcs(r0, pc, 1), "Unpredictable instruction.\n"); 2607 2608 // ADC, ADCS (register). 2609 COMPARE_A32(Adc(pc, r0, r1), "adc pc, r0, r1\n"); 2610 COMPARE_A32(Adc(r0, pc, r1), "adc r0, pc, r1\n"); 2611 COMPARE_A32(Adc(r0, r1, pc), "adc r0, r1, pc\n"); 2612 MUST_FAIL_TEST_T32(Adc(pc, r0, r1), "Unpredictable instruction.\n"); 2613 MUST_FAIL_TEST_T32(Adc(r0, pc, r1), "Unpredictable instruction.\n"); 2614 MUST_FAIL_TEST_T32(Adc(r0, r1, pc), "Unpredictable instruction.\n"); 2615 COMPARE_A32(Adcs(pc, r0, r1), "adcs pc, r0, r1\n"); 2616 COMPARE_A32(Adcs(r0, pc, r1), "adcs r0, pc, r1\n"); 2617 COMPARE_A32(Adcs(r0, r1, pc), "adcs r0, r1, pc\n"); 2618 MUST_FAIL_TEST_T32(Adcs(pc, r0, r1), "Unpredictable instruction.\n"); 2619 MUST_FAIL_TEST_T32(Adcs(r0, pc, r1), "Unpredictable instruction.\n"); 2620 MUST_FAIL_TEST_T32(Adcs(r0, r1, pc), "Unpredictable instruction.\n"); 2621 2622 // ADC, ADCS (register-shifted register). 2623 MUST_FAIL_TEST_A32(Adc(pc, r0, Operand(r1, LSL, r2)), 2624 "Unpredictable instruction.\n"); 2625 MUST_FAIL_TEST_A32(Adc(r0, pc, Operand(r1, LSL, r2)), 2626 "Unpredictable instruction.\n"); 2627 MUST_FAIL_TEST_A32(Adc(r0, r1, Operand(pc, LSL, r2)), 2628 "Unpredictable instruction.\n"); 2629 MUST_FAIL_TEST_A32(Adc(r0, r1, Operand(r2, LSL, pc)), 2630 "Unpredictable instruction.\n"); 2631 MUST_FAIL_TEST_A32(Adcs(pc, r0, Operand(r1, LSL, r2)), 2632 "Unpredictable instruction.\n"); 2633 MUST_FAIL_TEST_A32(Adcs(r0, pc, Operand(r1, LSL, r2)), 2634 "Unpredictable instruction.\n"); 2635 MUST_FAIL_TEST_A32(Adcs(r0, r1, Operand(pc, LSL, r2)), 2636 "Unpredictable instruction.\n"); 2637 MUST_FAIL_TEST_A32(Adcs(r0, r1, Operand(r2, LSL, pc)), 2638 "Unpredictable instruction.\n"); 2639 2640 // ADD (immediate, to PC). 2641 COMPARE_A32(Add(r0, pc, 1), "adr r0, 0x00000009\n"); 2642 COMPARE_T32(Add(r0, pc, 1), "adr r0, 0x00000005\n"); 2643 COMPARE_A32(Add(pc, pc, 1), "adr pc, 0x00000009\n"); 2644 MUST_FAIL_TEST_T32(Add(pc, pc, 1), "Unpredictable instruction.\n"); 2645 2646 // ADD, ADDS (immediate). 2647 COMPARE_A32(Add(pc, r0, 1), "add pc, r0, #1\n"); 2648 MUST_FAIL_TEST_T32(Add(pc, r0, 1), "Unpredictable instruction.\n"); 2649 MUST_FAIL_TEST_T32(Add(pc, r0, 0x123), "Unpredictable instruction.\n"); 2650 COMPARE_A32(Adds(pc, r0, 1), "adds pc, r0, #1\n"); 2651 COMPARE_A32(Adds(r0, pc, 1), "adds r0, pc, #1\n"); 2652 // TODO: Try to make these error messages more consistent. 2653 MUST_FAIL_TEST_T32(Adds(r0, pc, 1), "Unpredictable instruction.\n"); 2654 MUST_FAIL_TEST_T32(Adds(r0, pc, 0x123), "Ill-formed 'adds' instruction.\n"); 2655 2656 // ADD, ADDS (register). 2657 COMPARE_A32(Add(pc, r0, r1), "add pc, r0, r1\n"); 2658 COMPARE_A32(Add(r0, pc, r1), "add r0, pc, r1\n"); 2659 COMPARE_A32(Add(r0, r1, pc), "add r0, r1, pc\n"); 2660 COMPARE_T32(Add(r0, r0, pc), "add r0, pc\n"); 2661 COMPARE_T32(Add(pc, pc, r0), "add pc, r0\n"); 2662 MUST_FAIL_TEST_T32(Add(pc, pc, pc), "Unpredictable instruction.\n"); 2663 MUST_FAIL_TEST_T32(Add(pc, r0, r1), "Unpredictable instruction.\n"); 2664 MUST_FAIL_TEST_T32(Add(r0, pc, r1), "Unpredictable instruction.\n"); 2665 MUST_FAIL_TEST_T32(Add(r0, r1, pc), "Unpredictable instruction.\n"); 2666 COMPARE_A32(Adds(pc, r0, r1), "adds pc, r0, r1\n"); 2667 COMPARE_A32(Adds(r0, pc, r1), "adds r0, pc, r1\n"); 2668 COMPARE_A32(Adds(r0, r1, pc), "adds r0, r1, pc\n"); 2669 MUST_FAIL_TEST_T32(Adds(r0, pc, r1), "Unpredictable instruction.\n"); 2670 MUST_FAIL_TEST_T32(Adds(r0, r1, pc), "Unpredictable instruction.\n"); 2671 2672 // ADD, ADDS (register-shifted register) 2673 MUST_FAIL_TEST_A32(Add(pc, r0, Operand(r1, LSL, r2)), 2674 "Unpredictable instruction.\n"); 2675 MUST_FAIL_TEST_A32(Add(r0, pc, Operand(r1, LSL, r2)), 2676 "Unpredictable instruction.\n"); 2677 MUST_FAIL_TEST_A32(Add(r0, r1, Operand(pc, LSL, r2)), 2678 "Unpredictable instruction.\n"); 2679 MUST_FAIL_TEST_A32(Add(r0, r1, Operand(r2, LSL, pc)), 2680 "Unpredictable instruction.\n"); 2681 COMPARE_A32(Add(pc, sp, 1), "add pc, sp, #1\n"); 2682 MUST_FAIL_TEST_T32(Add(pc, sp, 1), "Unpredictable instruction.\n"); 2683 MUST_FAIL_TEST_A32(Adds(pc, r0, Operand(r1, LSL, r2)), 2684 "Unpredictable instruction.\n"); 2685 MUST_FAIL_TEST_A32(Adds(r0, pc, Operand(r1, LSL, r2)), 2686 "Unpredictable instruction.\n"); 2687 MUST_FAIL_TEST_A32(Adds(r0, r1, Operand(pc, LSL, r2)), 2688 "Unpredictable instruction.\n"); 2689 MUST_FAIL_TEST_A32(Adds(r0, r1, Operand(r2, LSL, pc)), 2690 "Unpredictable instruction.\n"); 2691 2692 // ADD, ADDS (SP plus immediate). 2693 COMPARE_A32(Add(pc, sp, 1), "add pc, sp, #1\n"); 2694 MUST_FAIL_TEST_T32(Add(pc, sp, 1), "Unpredictable instruction.\n"); 2695 COMPARE_A32(Adds(pc, sp, 1), "adds pc, sp, #1\n"); 2696 MUST_FAIL_TEST_T32(Adds(pc, sp, 1), "Ill-formed 'adds' instruction.\n"); 2697 2698 // ADD, ADDS (SP plus register). 2699 COMPARE_A32(Add(pc, sp, r0), "add pc, sp, r0\n"); 2700 MUST_FAIL_TEST_T32(Add(pc, sp, r0), "Unpredictable instruction.\n"); 2701 COMPARE_A32(Add(r0, sp, pc), "add r0, sp, pc\n"); 2702 MUST_FAIL_TEST_T32(Add(r0, sp, pc), "Unpredictable instruction.\n"); 2703 COMPARE_BOTH(Add(pc, sp, pc), "add pc, sp, pc\n"); 2704 COMPARE_BOTH(Add(sp, sp, pc), "add sp, pc\n"); 2705 COMPARE_A32(Adds(pc, sp, r0), "adds pc, sp, r0\n"); 2706 MUST_FAIL_TEST_T32(Adds(pc, sp, r0), "Ill-formed 'adds' instruction.\n"); 2707 COMPARE_A32(Adds(r0, sp, pc), "adds r0, sp, pc\n"); 2708 MUST_FAIL_TEST_T32(Adds(r0, sp, pc), "Unpredictable instruction.\n"); 2709 COMPARE_A32(Adds(pc, sp, pc), "adds pc, sp, pc\n"); 2710 MUST_FAIL_TEST_T32(Adds(pc, sp, pc), "Ill-formed 'adds' instruction.\n"); 2711 COMPARE_A32(Adds(sp, sp, pc), "adds sp, pc\n"); 2712 MUST_FAIL_TEST_T32(Adds(sp, sp, pc), "Unpredictable instruction.\n"); 2713 2714 // ADR. 2715 { 2716 Literal<uint32_t> literal(0x12345678); 2717 // The address is 0x4 and not 0x0 because of the branch over the literal. 2718 // TODO: Consider disallowing this instruction. 2719 COMPARE_A32(Adr(pc, &literal), "adr pc, 0x00000004\n"); 2720 MUST_FAIL_TEST_T32(Adr(pc, &literal), "Unpredictable instruction.\n"); 2721 } 2722 2723 // CLZ. 2724 MUST_FAIL_TEST_BOTH(Clz(pc, r0), "Unpredictable instruction.\n"); 2725 MUST_FAIL_TEST_BOTH(Clz(r0, pc), "Unpredictable instruction.\n"); 2726 2727 // MOV, MOVS (immediate). 2728 COMPARE_A32(Mov(pc, 1), "mov pc, #1\n"); 2729 MUST_FAIL_TEST_T32(Mov(pc, 1), "Unpredictable instruction.\n"); 2730 MUST_FAIL_TEST_T32(Mov(pc, 0xfff), "Unpredictable instruction.\n"); 2731 COMPARE_A32(Mov(pc, 0xf000), "mov pc, #61440\n"); 2732 MUST_FAIL_TEST_T32(Mov(pc, 0xf000), "Unpredictable instruction.\n"); 2733 COMPARE_A32(Movs(pc, 1), "movs pc, #1\n"); 2734 MUST_FAIL_TEST_T32(Movs(pc, 1), "Unpredictable instruction.\n"); 2735 MUST_FAIL_TEST_BOTH(Movs(pc, 0xfff), "Ill-formed 'movs' instruction.\n"); 2736 COMPARE_A32(Movs(pc, 0xf000), "movs pc, #61440\n"); 2737 MUST_FAIL_TEST_T32(Movs(pc, 0xf000), "Unpredictable instruction.\n"); 2738 2739 // MOV, MOVS (register). 2740 COMPARE_BOTH(Mov(pc, r0), "mov pc, r0\n"); 2741 COMPARE_BOTH(Mov(r0, pc), "mov r0, pc\n"); 2742 MUST_FAIL_TEST_BOTH(Movs(pc, r0), "Unpredictable instruction.\n"); 2743 COMPARE_A32(Movs(r0, pc), "movs r0, pc\n"); 2744 MUST_FAIL_TEST_T32(Movs(r0, pc), "Unpredictable instruction.\n"); 2745 2746 // MOV, MOVS (register-shifted register). 2747 MUST_FAIL_TEST_BOTH(Mov(pc, Operand(r0, ASR, r1)), 2748 "Unpredictable instruction.\n"); 2749 MUST_FAIL_TEST_BOTH(Mov(r0, Operand(pc, ASR, r1)), 2750 "Unpredictable instruction.\n"); 2751 MUST_FAIL_TEST_BOTH(Mov(r0, Operand(r1, ASR, pc)), 2752 "Unpredictable instruction.\n"); 2753 MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, ASR, r1)), 2754 "Unpredictable instruction.\n"); 2755 MUST_FAIL_TEST_BOTH(Movs(r0, Operand(pc, ASR, r1)), 2756 "Unpredictable instruction.\n"); 2757 MUST_FAIL_TEST_BOTH(Movs(r0, Operand(r1, ASR, pc)), 2758 "Unpredictable instruction.\n"); 2759 2760 CLEANUP(); 2761} 2762 2763 2764TEST(macro_assembler_pc_rel_A32) { 2765 SETUP(); 2766 // Simple cases alias adr. 2767 COMPARE_A32(Add(r0, pc, -8), "adr r0, 0x00000000\n"); 2768 COMPARE_A32(Add(r0, pc, 255), "adr r0, 0x00000107\n"); 2769 COMPARE_A32(Add(r0, pc, 256), "adr r0, 0x00000108\n"); 2770 COMPARE_A32(Add(r0, pc, 1024), "adr r0, 0x00000408\n"); 2771 COMPARE_A32(Add(r0, pc, -9), "adr r0, 0xffffffff\n"); 2772 COMPARE_A32(Add(r0, pc, -1024), "adr r0, 0xfffffc08\n"); 2773 COMPARE_A32(Add(r0, pc, UINT32_C(0x80000000)), "adr r0, 0x80000008\n"); 2774 COMPARE_A32(Add(r0, pc, -0x7fffffff), "adr r0, 0x80000009\n"); 2775 2776 COMPARE_A32(Sub(r0, pc, 8), "adr r0, 0x00000000\n"); 2777 COMPARE_A32(Sub(r0, pc, -255), "adr r0, 0x00000107\n"); 2778 COMPARE_A32(Sub(r0, pc, -256), "adr r0, 0x00000108\n"); 2779 COMPARE_A32(Sub(r0, pc, -1024), "adr r0, 0x00000408\n"); 2780 COMPARE_A32(Sub(r0, pc, 9), "adr r0, 0xffffffff\n"); 2781 COMPARE_A32(Sub(r0, pc, 1024), "adr r0, 0xfffffc08\n"); 2782 COMPARE_A32(Sub(r0, pc, UINT32_C(0x80000000)), "adr r0, 0x80000008\n"); 2783 COMPARE_A32(Sub(r0, pc, -0x7fffffff), "adr r0, 0x80000007\n"); 2784 2785 // Cases out of range. 2786 // Only negative offsets are supported, because the proper behaviour for 2787 // positive offsets is not clear. 2788 MUST_FAIL_TEST_A32(Add(r0, pc, 1025), "Ill-formed 'add' instruction.\n"); 2789 MUST_FAIL_TEST_A32(Add(r0, pc, 0xffff), "Ill-formed 'add' instruction.\n"); 2790 MUST_FAIL_TEST_A32(Add(r0, pc, 0x10001), "Ill-formed 'add' instruction.\n"); 2791 MUST_FAIL_TEST_A32(Add(r0, pc, 0x12345678), 2792 "Ill-formed 'add' instruction.\n"); 2793 MUST_FAIL_TEST_A32(Add(r0, pc, 0x7fffffff), 2794 "Ill-formed 'add' instruction.\n"); 2795 COMPARE_A32(Add(r0, pc, -1025), 2796 "adr r0, 0x00000007\n" 2797 "sub r0, #1024\n"); 2798 COMPARE_A32(Add(r0, pc, -0xffff), 2799 "adr r0, 0xffffff09\n" 2800 "sub r0, #65280\n"); 2801 COMPARE_A32(Add(r0, pc, -0x10001), 2802 "adr r0, 0x00000007\n" 2803 "sub r0, #65536\n"); 2804 COMPARE_A32(Add(r0, pc, -0x2345678), 2805 "adr r0, 0xfffffd90\n" 2806 "sub r0, #21504\n" 2807 "sub r0, #36962304\n"); 2808 COMPARE_A32(Add(r0, pc, -0x12345678), 2809 "adr r0, 0xfffffd90\n" 2810 "mov ip, #21504\n" 2811 "movt ip, #4660\n" 2812 "sub r0, ip\n"); 2813 2814 MUST_FAIL_TEST_A32(Sub(r0, pc, -1025), "Ill-formed 'add' instruction.\n"); 2815 MUST_FAIL_TEST_A32(Sub(r0, pc, -0xffff), "Ill-formed 'add' instruction.\n"); 2816 MUST_FAIL_TEST_A32(Sub(r0, pc, -0x10001), "Ill-formed 'add' instruction.\n"); 2817 MUST_FAIL_TEST_A32(Sub(r0, pc, -0x12345678), 2818 "Ill-formed 'add' instruction.\n"); 2819 COMPARE_A32(Sub(r0, pc, 1025), 2820 "adr r0, 0x00000007\n" 2821 "sub r0, #1024\n"); 2822 COMPARE_A32(Sub(r0, pc, 0xffff), 2823 "adr r0, 0xffffff09\n" 2824 "sub r0, #65280\n"); 2825 COMPARE_A32(Sub(r0, pc, 0x10001), 2826 "adr r0, 0x00000007\n" 2827 "sub r0, #65536\n"); 2828 COMPARE_A32(Sub(r0, pc, 0x2345678), 2829 "adr r0, 0xfffffd90\n" 2830 "sub r0, #21504\n" 2831 "sub r0, #36962304\n"); 2832 COMPARE_A32(Sub(r0, pc, 0x12345678), 2833 "adr r0, 0xfffffd90\n" 2834 "mov ip, #21504\n" 2835 "movt ip, #4660\n" 2836 "sub r0, ip\n"); 2837 COMPARE_A32(Sub(r0, pc, 0x7fffffff), 2838 "adr r0, 0xffffff09\n" 2839 "add r0, #256\n" 2840 "add r0, #2147483648\n"); 2841 2842 CLEANUP(); 2843} 2844 2845 2846TEST(macro_assembler_pc_rel_T32) { 2847 SETUP(); 2848 // Simple cases alias adr. 2849 COMPARE_T32(Add(r0, pc, -4), "adr r0, 0x00000000\n"); // T1 2850 COMPARE_T32(Add(r0, pc, 1020), "adr r0, 0x00000400\n"); // T1 2851 COMPARE_T32(Add(r0, pc, -5), "adr r0, 0xffffffff\n"); // T2 2852 COMPARE_T32(Add(r0, pc, -4095), "adr r0, 0xfffff005\n"); // T2 2853 COMPARE_T32(Add(r0, pc, -3), "adr r0, 0x00000001\n"); // T3 2854 COMPARE_T32(Add(r0, pc, 1021), "adr r0, 0x00000401\n"); // T3 2855 COMPARE_T32(Add(r0, pc, 1019), "adr r0, 0x000003ff\n"); // T3 2856 COMPARE_T32(Add(r0, pc, 4095), "adr r0, 0x00001003\n"); // T3 2857 2858 COMPARE_T32(Sub(r0, pc, 4), "adr r0, 0x00000000\n"); // T1 2859 COMPARE_T32(Sub(r0, pc, -1020), "adr r0, 0x00000400\n"); // T1 2860 COMPARE_T32(Sub(r0, pc, 5), "adr r0, 0xffffffff\n"); // T2 2861 COMPARE_T32(Sub(r0, pc, 4095), "adr r0, 0xfffff005\n"); // T2 2862 COMPARE_T32(Sub(r0, pc, 3), "adr r0, 0x00000001\n"); // T3 2863 COMPARE_T32(Sub(r0, pc, -1021), "adr r0, 0x00000401\n"); // T3 2864 COMPARE_T32(Sub(r0, pc, -1019), "adr r0, 0x000003ff\n"); // T3 2865 COMPARE_T32(Sub(r0, pc, -4095), "adr r0, 0x00001003\n"); // T3 2866 2867 // Cases out of range. 2868 // Only negative offsets are supported, because the proper behaviour for 2869 // positive offsets is not clear. 2870 2871 MUST_FAIL_TEST_T32(Add(r0, pc, 4096), "Unpredictable instruction.\n"); 2872 2873 MUST_FAIL_TEST_T32(Add(r0, pc, -4096), "Unpredictable instruction.\n"); 2874 2875 MUST_FAIL_TEST_T32(Add(r0, pc, 0xffff), "Ill-formed 'add' instruction.\n"); 2876 MUST_FAIL_TEST_T32(Add(r0, pc, 0x10002), "Ill-formed 'add' instruction.\n"); 2877 MUST_FAIL_TEST_T32(Add(r0, pc, 0x12345678), 2878 "Ill-formed 'add' instruction.\n"); 2879 MUST_FAIL_TEST_T32(Add(r0, pc, 0x7fffffff), 2880 "Ill-formed 'add' instruction.\n"); 2881 COMPARE_T32(Add(r0, pc, -0x12345678), 2882 "mov r0, pc\n" 2883 "mov ip, #22136\n" 2884 "movt ip, #4660\n" 2885 "sub r0, ip\n"); 2886 COMPARE_T32(Add(r0, pc, -0x7fffffff), 2887 "mov r0, pc\n" 2888 "add r0, #1\n" 2889 "add r0, #2147483648\n"); 2890 2891 // TODO: This test aborts in the Assembler (with unpredictable instruction 2892 // errors) before the MacroAssembler gets a chance to do something 2893 // predictable. 2894 // COMPARE_T32(Sub(r0, pc, -4096), "mov r0, pc\n" 2895 // "add r0, #4096\n"); 2896 2897 MUST_FAIL_TEST_T32(Sub(r0, pc, 4096), "Unpredictable instruction.\n"); 2898 2899 MUST_FAIL_TEST_T32(Sub(r0, pc, -0xffff), "Ill-formed 'add' instruction.\n"); 2900 MUST_FAIL_TEST_T32(Sub(r0, pc, -0x10002), "Ill-formed 'add' instruction.\n"); 2901 MUST_FAIL_TEST_T32(Sub(r0, pc, -0x12345678), 2902 "Ill-formed 'add' instruction.\n"); 2903 MUST_FAIL_TEST_T32(Sub(r0, pc, -0x7fffffff), 2904 "Ill-formed 'add' instruction.\n"); 2905 COMPARE_T32(Sub(r0, pc, 0x12345678), 2906 "mov r0, pc\n" 2907 "mov ip, #22136\n" 2908 "movt ip, #4660\n" 2909 "sub r0, ip\n"); 2910 COMPARE_T32(Sub(r0, pc, 0x7fffffff), 2911 "mov r0, pc\n" 2912 "add r0, #1\n" 2913 "add r0, #2147483648\n"); 2914 CLEANUP(); 2915} 2916 2917 2918TEST(macro_assembler_unsupported) { 2919 SETUP(); 2920 2921 MUST_FAIL_TEST_BOTH(Sxtab(r0, r1, Operand(r2, ROR, 1)), 2922 "Ill-formed 'sxtab' instruction.\n"); 2923 MUST_FAIL_TEST_BOTH(Sxtab16(r0, r1, Operand(r0, ASR, 2)), 2924 "Ill-formed 'sxtab16' instruction.\n"); 2925 MUST_FAIL_TEST_BOTH(Sxtah(r0, r1, Operand(r0, LSL, r1)), 2926 "Ill-formed 'sxtah' instruction.\n"); 2927 MUST_FAIL_TEST_BOTH(Uxtab(r0, r1, Operand(r0, LSR, r2)), 2928 "Ill-formed 'uxtab' instruction.\n"); 2929 MUST_FAIL_TEST_BOTH(Uxtab16(r0, r1, Operand(r0, ROR, 1)), 2930 "Ill-formed 'uxtab16' instruction.\n"); 2931 MUST_FAIL_TEST_BOTH(Uxtah(r0, r1, Operand(r0, ASR, 2)), 2932 "Ill-formed 'uxtah' instruction.\n"); 2933 MUST_FAIL_TEST_BOTH(Pkhbt(r0, r1, Operand(r0, LSL, r1)), 2934 "Ill-formed 'pkhbt' instruction.\n"); 2935 MUST_FAIL_TEST_BOTH(Pkhtb(r0, r1, Operand(r0, LSR, r2)), 2936 "Ill-formed 'pkhtb' instruction.\n"); 2937 2938 MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, 1, PreIndex)), 2939 "Ill-formed 'pld' instruction.\n"); 2940 MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, 1, PostIndex)), 2941 "Ill-formed 'pldw' instruction.\n"); 2942 MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, 1, PreIndex)), 2943 "Ill-formed 'pli' instruction.\n"); 2944 2945 MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, r0, PreIndex)), 2946 "Ill-formed 'pld' instruction.\n"); 2947 MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, r1, PostIndex)), 2948 "Ill-formed 'pldw' instruction.\n"); 2949 MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, r2, PreIndex)), 2950 "Ill-formed 'pli' instruction.\n"); 2951 2952 MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, r0, LSL, 1, PreIndex)), 2953 "Ill-formed 'pld' instruction.\n"); 2954 MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, r1, LSR, 2, PostIndex)), 2955 "Ill-formed 'pldw' instruction.\n"); 2956 MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, r2, ASR, 3, PreIndex)), 2957 "Ill-formed 'pli' instruction.\n"); 2958 2959 MUST_FAIL_TEST_BOTH(Lda(r0, MemOperand(r0, 1)), 2960 "Ill-formed 'lda' instruction.\n"); 2961 MUST_FAIL_TEST_BOTH(Ldab(r0, MemOperand(r0, 1)), 2962 "Ill-formed 'ldab' instruction.\n"); 2963 MUST_FAIL_TEST_BOTH(Ldaex(r0, MemOperand(r0, 1)), 2964 "Ill-formed 'ldaex' instruction.\n"); 2965 MUST_FAIL_TEST_BOTH(Ldaexb(r0, MemOperand(r0, 1)), 2966 "Ill-formed 'ldaexb' instruction.\n"); 2967 MUST_FAIL_TEST_BOTH(Ldaexh(r0, MemOperand(r0, 1)), 2968 "Ill-formed 'ldaexh' instruction.\n"); 2969 MUST_FAIL_TEST_BOTH(Ldah(r0, MemOperand(r0, 1)), 2970 "Ill-formed 'ldah' instruction.\n"); 2971 MUST_FAIL_TEST_BOTH(Ldrex(r0, MemOperand(r0, 1)), 2972 "Ill-formed 'ldrex' instruction.\n"); 2973 MUST_FAIL_TEST_BOTH(Ldrexb(r0, MemOperand(r0, 1)), 2974 "Ill-formed 'ldrexb' instruction.\n"); 2975 MUST_FAIL_TEST_BOTH(Ldrexh(r0, MemOperand(r0, 1)), 2976 "Ill-formed 'ldrexh' instruction.\n"); 2977 MUST_FAIL_TEST_BOTH(Stl(r0, MemOperand(r0, 1)), 2978 "Ill-formed 'stl' instruction.\n"); 2979 MUST_FAIL_TEST_BOTH(Stlb(r0, MemOperand(r0, 1)), 2980 "Ill-formed 'stlb' instruction.\n"); 2981 MUST_FAIL_TEST_BOTH(Stlh(r0, MemOperand(r0, 1)), 2982 "Ill-formed 'stlh' instruction.\n"); 2983 2984 MUST_FAIL_TEST_BOTH(Ldaexd(r0, r1, MemOperand(r0, 1)), 2985 "Ill-formed 'ldaexd' instruction.\n"); 2986 MUST_FAIL_TEST_BOTH(Ldrexd(r0, r1, MemOperand(r0, 1)), 2987 "Ill-formed 'ldrexd' instruction.\n"); 2988 MUST_FAIL_TEST_BOTH(Stlex(r0, r1, MemOperand(r0, 1)), 2989 "Ill-formed 'stlex' instruction.\n"); 2990 MUST_FAIL_TEST_BOTH(Stlexb(r0, r1, MemOperand(r0, 1)), 2991 "Ill-formed 'stlexb' instruction.\n"); 2992 MUST_FAIL_TEST_BOTH(Stlexh(r0, r1, MemOperand(r0, 1)), 2993 "Ill-formed 'stlexh' instruction.\n"); 2994 MUST_FAIL_TEST_BOTH(Strex(r0, r1, MemOperand(r0, 1)), 2995 "Ill-formed 'strex' instruction.\n"); 2996 MUST_FAIL_TEST_BOTH(Strexb(r0, r1, MemOperand(r0, 1)), 2997 "Ill-formed 'strexb' instruction.\n"); 2998 MUST_FAIL_TEST_BOTH(Strexh(r0, r1, MemOperand(r0, 1)), 2999 "Ill-formed 'strexh' instruction.\n"); 3000 3001 MUST_FAIL_TEST_BOTH(Stlexd(r0, r1, r2, MemOperand(r0, 1)), 3002 "Ill-formed 'stlexd' instruction.\n"); 3003 MUST_FAIL_TEST_BOTH(Strexd(r0, r1, r2, MemOperand(r0, 1)), 3004 "Ill-formed 'strexd' instruction.\n"); 3005 3006 CLEANUP(); 3007} 3008 3009TEST(macro_assembler_Vmov_neon_immediate) { 3010 SETUP(); 3011 3012 // Move 8, 16 and 32-bit immediates into D registers, duplicated across the 3013 // destination. 3014 COMPARE_BOTH(Vmov(I8, d0, 0xac), "vmov.i8 d0, #172\n"); 3015 3016 COMPARE_BOTH(Vmov(I16, d0, 0xa4), "vmov.i16 d0, #164\n"); 3017 COMPARE_BOTH(Vmov(I16, d0, 0x9797), "vmov.i8 d0, #151\n"); 3018 COMPARE_BOTH(Vmov(I16, d0, 0x9ef6), 3019 "mov ip, #40694\n" 3020 "vdup.16 d0, ip\n"); 3021 3022 COMPARE_BOTH(Vmov(I32, d0, 0x6d0000), "vmov.i32 d0, #7143424\n"); 3023 COMPARE_BOTH(Vmov(I32, d0, 0x15ffffff), "vmvn.i32 d0, #3925868544\n"); 3024 COMPARE_BOTH(Vmov(I32, d0, 0x74747474), "vmov.i8 d0, #116\n"); 3025 COMPARE_BOTH(Vmov(I32, d0, 0xff0000ff), "vmov.i64 d0, #0xff0000ffff0000ff\n"); 3026 COMPARE_BOTH(Vmov(I32, d0, 0x1ecb9ef6), 3027 "mov ip, #40694\n" 3028 "movt ip, #7883\n" 3029 "vdup.32 d0, ip\n"); 3030 COMPARE_BOTH(Vmov(I32, d0, 0x006d0000), "vmov.i32 d0, #7143424\n"); 3031 COMPARE_BOTH(Vmov(I32, d0, 0x00004da6), 3032 "mov ip, #19878\n" 3033 "vdup.32 d0, ip\n"); 3034 COMPARE_BOTH(Vmov(I32, d0, 0xffffff55), "vmvn.i32 d0, #170\n"); 3035 COMPARE_BOTH(Vmov(I32, d0, 0xffff55ff), "vmvn.i32 d0, #43520\n"); 3036 COMPARE_BOTH(Vmov(I32, d0, 0xff55ffff), "vmvn.i32 d0, #11141120\n"); 3037 3038 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0xa5a5a5a5a5a5a5a5)), 3039 "vmov.i8 d0, #165\n"); 3040 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x0a01248315ffffff)), 3041 "mvn ip, #3925868544\n" 3042 "vdup.32 d0, ip\n" 3043 "mov ip, #9347\n" 3044 "movt ip, #2561\n" 3045 "vmov.32 d0[1], ip\n"); 3046 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x6fe1a7a779e33af2)), 3047 "mov ip, #15090\n" 3048 "movt ip, #31203\n" 3049 "vdup.32 d0, ip\n" 3050 "mov ip, #42919\n" 3051 "movt ip, #28641\n" 3052 "vmov.32 d0[1], ip\n"); 3053 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x2efa8b440000c1da)), 3054 "mov ip, #49626\n" 3055 "vdup.32 d0, ip\n" 3056 "mov ip, #35652\n" 3057 "movt ip, #12026\n" 3058 "vmov.32 d0[1], ip\n"); 3059 COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x00008bb75c3036fd)), 3060 "mov ip, #14077\n" 3061 "movt ip, #23600\n" 3062 "vdup.32 d0, ip\n" 3063 "mov ip, #35767\n" 3064 "vmov.32 d0[1], ip\n"); 3065 3066 COMPARE_BOTH(Vmov(F32, d0, 0.5), "vmov.f32 d0, #0.5\n"); 3067 COMPARE_BOTH(Vmov(F32, d0, 1.1), 3068 "mov ip, #52429\n" 3069 "movt ip, #16268\n" 3070 "vdup.32 d0, ip\n"); 3071 3072 COMPARE_T32(Vmov(I64, d0, UINT64_C(0x2fff2fff3e2869e7)), 3073 "mov ip, #27111\n" 3074 "movt ip, #15912\n" 3075 "vdup.32 d0, ip\n" 3076 "mvn ip, #3489714176\n" 3077 "vmov.32 d0[1], ip\n"); 3078 3079 COMPARE_A32(Vmov(I32, d0, 0x0ffffffa), 3080 "mvn ip, #4026531845\n" 3081 "vdup.32 d0, ip\n"); 3082 COMPARE_A32(Vmov(I64, d0, UINT64_C(0x65ffffff16a0ef46)), 3083 "mov ip, #61254\n" 3084 "movt ip, #5792\n" 3085 "vdup.32 d0, ip\n" 3086 "mvn ip, #2583691264\n" 3087 "vmov.32 d0[1], ip\n"); 3088 3089 // Move 8, 16 and 32-bit immediates into Q registers, duplicated across the 3090 // destination. 3091 COMPARE_BOTH(Vmov(I8, q0, 0xac), "vmov.i8 q0, #172\n"); 3092 3093 COMPARE_BOTH(Vmov(I16, q0, 0xa4), "vmov.i16 q0, #164\n"); 3094 COMPARE_BOTH(Vmov(I16, q0, 0x9797), "vmov.i8 q0, #151\n"); 3095 COMPARE_BOTH(Vmov(I16, q0, 0x9ef6), 3096 "mov ip, #40694\n" 3097 "vdup.16 q0, ip\n"); 3098 3099 COMPARE_BOTH(Vmov(I32, q0, 0x6d0000), "vmov.i32 q0, #7143424\n"); 3100 COMPARE_BOTH(Vmov(I32, q0, 0x15ffffff), "vmvn.i32 q0, #3925868544\n"); 3101 COMPARE_BOTH(Vmov(I32, q0, 0x74747474), "vmov.i8 q0, #116\n"); 3102 COMPARE_BOTH(Vmov(I32, q0, 0xff0000ff), "vmov.i64 q0, #0xff0000ffff0000ff\n"); 3103 COMPARE_BOTH(Vmov(I32, q0, 0x1ecb9ef6), 3104 "mov ip, #40694\n" 3105 "movt ip, #7883\n" 3106 "vdup.32 q0, ip\n"); 3107 COMPARE_BOTH(Vmov(I32, q0, 0x006d0000), "vmov.i32 q0, #7143424\n"); 3108 COMPARE_BOTH(Vmov(I32, q0, 0x00004da6), 3109 "mov ip, #19878\n" 3110 "vdup.32 q0, ip\n"); 3111 3112 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0xa5a5a5a5a5a5a5a5)), 3113 "vmov.i8 q0, #165\n"); 3114 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x0a01248315ffffff)), 3115 "mvn ip, #3925868544\n" 3116 "vdup.32 q0, ip\n" 3117 "mov ip, #9347\n" 3118 "movt ip, #2561\n" 3119 "vmov.32 d0[1], ip\n" 3120 "vmov.f64 d1, d0\n"); 3121 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x6fe1a7a779e33af2)), 3122 "mov ip, #15090\n" 3123 "movt ip, #31203\n" 3124 "vdup.32 q0, ip\n" 3125 "mov ip, #42919\n" 3126 "movt ip, #28641\n" 3127 "vmov.32 d0[1], ip\n" 3128 "vmov.f64 d1, d0\n"); 3129 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x2efa8b440000c1da)), 3130 "mov ip, #49626\n" 3131 "vdup.32 q0, ip\n" 3132 "mov ip, #35652\n" 3133 "movt ip, #12026\n" 3134 "vmov.32 d0[1], ip\n" 3135 "vmov.f64 d1, d0\n"); 3136 COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x00008bb75c3036fd)), 3137 "mov ip, #14077\n" 3138 "movt ip, #23600\n" 3139 "vdup.32 q0, ip\n" 3140 "mov ip, #35767\n" 3141 "vmov.32 d0[1], ip\n" 3142 "vmov.f64 d1, d0\n"); 3143 3144 COMPARE_BOTH(Vmov(F32, q0, 0.5), "vmov.f32 q0, #0.5\n"); 3145 COMPARE_BOTH(Vmov(F32, q0, 1.1), 3146 "mov ip, #52429\n" 3147 "movt ip, #16268\n" 3148 "vdup.32 q0, ip\n"); 3149 COMPARE_BOTH(Vmov(F64, q0, 0.5), 3150 "vmov.f64 d0, #0.5\n" 3151 "vmov.f64 d1, d0\n"); 3152 COMPARE_BOTH(Vmov(F64, q0, 1.1), 3153 "mov ip, #39322\n" 3154 "movt ip, #39321\n" 3155 "vdup.32 d0, ip\n" 3156 "mov ip, #39321\n" 3157 "movt ip, #16369\n" 3158 "vmov.32 d0[1], ip\n" 3159 "vmov.f64 d1, d0\n"); 3160 3161 COMPARE_T32(Vmov(I64, q0, UINT64_C(0x2fff2fff3e2869e7)), 3162 "mov ip, #27111\n" 3163 "movt ip, #15912\n" 3164 "vdup.32 q0, ip\n" 3165 "mvn ip, #3489714176\n" 3166 "vmov.32 d0[1], ip\n" 3167 "vmov.f64 d1, d0\n"); 3168 3169 COMPARE_A32(Vmov(I32, q0, 0x0ffffffa), 3170 "mvn ip, #4026531845\n" 3171 "vdup.32 q0, ip\n"); 3172 COMPARE_A32(Vmov(I64, q0, UINT64_C(0x65ffffff16a0ef46)), 3173 "mov ip, #61254\n" 3174 "movt ip, #5792\n" 3175 "vdup.32 q0, ip\n" 3176 "mvn ip, #2583691264\n" 3177 "vmov.32 d0[1], ip\n" 3178 "vmov.f64 d1, d0\n"); 3179 CLEANUP(); 3180} 3181 3182TEST(macro_assembler_T32_IT) { 3183 SETUP(); 3184 3185 // ADC (register) T1 3186 COMPARE_T32(Adc(eq, r0, r0, r1), 3187 "it eq\n" 3188 "adceq r0, r1\n"); 3189 3190 COMPARE_T32(Adc(eq, r0, r1, r2), 3191 "bne 0x00000006\n" 3192 "adc r0, r1, r2\n"); 3193 3194 // ADD (immediate) T1 3195 COMPARE_T32(Add(eq, r0, r1, 0x1), 3196 "it eq\n" 3197 "addeq r0, r1, #1\n"); 3198 3199 COMPARE_T32(Add(eq, r0, r1, 0x8), 3200 "bne 0x00000006\n" 3201 "add r0, r1, #8\n"); 3202 3203 // ADD (immediate) T2 3204 COMPARE_T32(Add(eq, r0, r0, 0xff), 3205 "it eq\n" 3206 "addeq r0, #255\n"); 3207 3208 // ADD (register) T1 3209 COMPARE_T32(Add(eq, r0, r1, r7), 3210 "it eq\n" 3211 "addeq r0, r1, r7\n"); 3212 3213 // ADD (register) T2 3214 COMPARE_T32(Add(eq, r5, r5, r8), 3215 "it eq\n" 3216 "addeq r5, r8\n"); 3217 3218 // ADD (SP plus immediate) T1 3219 COMPARE_T32(Add(eq, r7, sp, 1020), 3220 "it eq\n" 3221 "addeq r7, sp, #1020\n"); 3222 3223 COMPARE_T32(Add(eq, r7, sp, 1), 3224 "bne 0x00000006\n" 3225 "add r7, sp, #1\n"); 3226 3227 COMPARE_T32(Add(eq, r7, sp, 1024), 3228 "bne 0x00000006\n" 3229 "add r7, sp, #1024\n"); 3230 3231 COMPARE_T32(Add(eq, sp, sp, 32), 3232 "bne 0x00000004\n" 3233 "add sp, #32\n"); 3234 3235 // ADD (SP plus register) T1 3236 COMPARE_T32(Add(eq, r7, sp, r7), 3237 "it eq\n" 3238 "addeq r7, sp, r7\n"); 3239 3240 // ADD (SP plus register) T2 3241 COMPARE_T32(Add(eq, sp, sp, r10), 3242 "it eq\n" 3243 "addeq sp, r10\n"); 3244 3245 COMPARE_T32(Add(eq, r5, r5, sp), 3246 "bne 0x00000006\n" 3247 "add.w r5, sp\n"); 3248 3249 // AND (register) T1 3250 COMPARE_T32(And(eq, r7, r7, r0), 3251 "it eq\n" 3252 "andeq r7, r0\n"); 3253 3254 COMPARE_T32(And(eq, r8, r8, r0), 3255 "bne 0x00000006\n" 3256 "and r8, r0\n"); 3257 3258 // ASR (immediate) T2 3259 COMPARE_T32(Asr(eq, r0, r1, 16), 3260 "it eq\n" 3261 "asreq r0, r1, #16\n"); 3262 3263 COMPARE_T32(Asr(eq, r0, r1, 32), 3264 "it eq\n" 3265 "asreq r0, r1, #32\n"); 3266 3267 COMPARE_T32(Asr(eq, r0, r1, 0), 3268 "bne 0x0000000a\n" 3269 "mov r0, #0\n" 3270 "asr r0, r1, r0\n"); 3271 3272 // ASR (register) T1 3273 COMPARE_T32(Asr(eq, r7, r7, r3), 3274 "it eq\n" 3275 "asreq r7, r3\n"); 3276 3277 COMPARE_T32(Asr(eq, r8, r8, r3), 3278 "bne 0x00000006\n" 3279 "asr r8, r3\n"); 3280 3281 // BIC (register) T1 3282 COMPARE_T32(Bic(eq, r7, r7, r6), 3283 "it eq\n" 3284 "biceq r7, r6\n"); 3285 3286 COMPARE_T32(Bic(eq, r8, r8, r6), 3287 "bne 0x00000006\n" 3288 "bic r8, r6\n"); 3289 3290 Label l; 3291 __ Bind(&l); 3292 3293 // BLX (register) T1 3294 COMPARE_T32(Blx(eq, lr), 3295 "it eq\n" 3296 "blxeq lr\n"); 3297 COMPARE_T32(Blx(eq, &l), 3298 "bne 0x00000006\n" 3299 "blx 0x00000000\n"); 3300 3301 // BX (register) T1 3302 COMPARE_T32(Bx(eq, lr), 3303 "it eq\n" 3304 "bxeq lr\n"); 3305 3306 // CMN (register) T1 3307 COMPARE_T32(Cmn(eq, r0, r1), 3308 "it eq\n" 3309 "cmneq r0, r1\n"); 3310 3311 COMPARE_T32(Cmn(eq, r0, r8), 3312 "bne 0x00000006\n" 3313 "cmn r0, r8\n"); 3314 3315 // CMP (immediate) T1 3316 COMPARE_T32(Cmp(eq, r7, 0xff), 3317 "it eq\n" 3318 "cmpeq r7, #255\n"); 3319 3320 // CMP (register) T1 3321 COMPARE_T32(Cmp(eq, r6, r7), 3322 "it eq\n" 3323 "cmpeq r6, r7\n"); 3324 3325 // CMP (register) T2 3326 COMPARE_T32(Cmp(eq, r9, r10), 3327 "it eq\n" 3328 "cmpeq r9, r10\n"); 3329 3330 COMPARE_T32(Cmp(eq, r0, 0x100), 3331 "bne 0x00000006\n" 3332 "cmp r0, #256\n"); 3333 3334 // EOR (register) T1 3335 COMPARE_T32(Eor(eq, r0, r0, r7), 3336 "it eq\n" 3337 "eoreq r0, r7\n"); 3338 3339 COMPARE_T32(Eor(eq, r0, r0, 0x1), 3340 "bne 0x00000006\n" 3341 "eor r0, #0x1\n"); 3342 3343 // LDR (immediate) T1 3344 COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 124)), 3345 "it eq\n" 3346 "ldreq r4, [r7, #124]\n"); 3347 3348 COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 1)), 3349 "bne 0x00000006\n" 3350 "ldr r4, [r7, #1]\n"); 3351 3352 COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 128)), 3353 "bne 0x00000006\n" 3354 "ldr r4, [r7, #128]\n"); 3355 3356 // LDR (immediate) T2 3357 COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1020)), 3358 "it eq\n" 3359 "ldreq r4, [sp, #1020]\n"); 3360 3361 COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1)), 3362 "bne 0x00000006\n" 3363 "ldr r4, [sp, #1]\n"); 3364 3365 COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1024)), 3366 "bne 0x00000006\n" 3367 "ldr r4, [sp, #1024]\n"); 3368 3369 // LDR (register) T1 3370 COMPARE_T32(Ldr(eq, r5, MemOperand(r6, r7)), 3371 "it eq\n" 3372 "ldreq r5, [r6, r7]\n"); 3373 3374 COMPARE_T32(Ldr(eq, r5, MemOperand(r6, r8)), 3375 "bne 0x00000006\n" 3376 "ldr r5, [r6, r8]\n"); 3377 3378 // LDRB (immediate) T1 3379 COMPARE_T32(Ldrb(eq, r6, MemOperand(r7, 31)), 3380 "it eq\n" 3381 "ldrbeq r6, [r7, #31]\n"); 3382 3383 COMPARE_T32(Ldrb(eq, r6, MemOperand(r7, 32)), 3384 "bne 0x00000006\n" 3385 "ldrb r6, [r7, #32]\n"); 3386 3387 // LDRB (register) T1 3388 COMPARE_T32(Ldrb(eq, r5, MemOperand(r6, r7)), 3389 "it eq\n" 3390 "ldrbeq r5, [r6, r7]\n"); 3391 3392 COMPARE_T32(Ldrb(eq, r6, MemOperand(r9)), 3393 "bne 0x00000006\n" 3394 "ldrb r6, [r9]\n"); 3395 3396 // LDRH (immediate) T1 3397 COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 62)), 3398 "it eq\n" 3399 "ldrheq r6, [r7, #62]\n"); 3400 3401 COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 64)), 3402 "bne 0x00000006\n" 3403 "ldrh r6, [r7, #64]\n"); 3404 3405 COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 1)), 3406 "bne 0x00000006\n" 3407 "ldrh r6, [r7, #1]\n"); 3408 3409 // LDRH (register) T1 3410 COMPARE_T32(Ldrh(eq, r5, MemOperand(r6, r7)), 3411 "it eq\n" 3412 "ldrheq r5, [r6, r7]\n"); 3413 3414 COMPARE_T32(Ldrh(eq, r6, MemOperand(r9)), 3415 "bne 0x00000006\n" 3416 "ldrh r6, [r9]\n"); 3417 3418 // LDRSB (register) T1 3419 COMPARE_T32(Ldrsb(eq, r5, MemOperand(r6, r7)), 3420 "it eq\n" 3421 "ldrsbeq r5, [r6, r7]\n"); 3422 3423 COMPARE_T32(Ldrsb(eq, r6, MemOperand(r9)), 3424 "bne 0x00000006\n" 3425 "ldrsb r6, [r9]\n"); 3426 3427 // LDRSH (register) T1 3428 COMPARE_T32(Ldrsh(eq, r5, MemOperand(r6, r7)), 3429 "it eq\n" 3430 "ldrsheq r5, [r6, r7]\n"); 3431 3432 COMPARE_T32(Ldrsh(eq, r6, MemOperand(r9)), 3433 "bne 0x00000006\n" 3434 "ldrsh r6, [r9]\n"); 3435 3436 // LSL (immediate) T2 3437 COMPARE_T32(Lsl(eq, r0, r1, 16), 3438 "it eq\n" 3439 "lsleq r0, r1, #16\n"); 3440 3441 COMPARE_T32(Lsl(eq, r0, r1, 0), 3442 "bne 0x0000000a\n" 3443 "mov r0, #0\n" 3444 "lsl r0, r1, r0\n"); 3445 3446 COMPARE_T32(Lsl(eq, r0, r1, 32), 3447 "bne 0x0000000a\n" 3448 "mov r0, #32\n" 3449 "lsl r0, r1, r0\n"); 3450 3451 // LSL (register) T1 3452 COMPARE_T32(Lsl(eq, r7, r7, r3), 3453 "it eq\n" 3454 "lsleq r7, r3\n"); 3455 3456 COMPARE_T32(Lsl(eq, r8, r8, r3), 3457 "bne 0x00000006\n" 3458 "lsl r8, r3\n"); 3459 3460 // LSR (immediate) T2 3461 COMPARE_T32(Lsr(eq, r0, r1, 16), 3462 "it eq\n" 3463 "lsreq r0, r1, #16\n"); 3464 3465 COMPARE_T32(Lsr(eq, r0, r1, 32), 3466 "it eq\n" 3467 "lsreq r0, r1, #32\n"); 3468 3469 COMPARE_T32(Lsr(eq, r0, r1, 0), 3470 "bne 0x0000000a\n" 3471 "mov r0, #0\n" 3472 "lsr r0, r1, r0\n"); 3473 3474 // LSR (register) T1 3475 COMPARE_T32(Lsr(eq, r7, r7, r3), 3476 "it eq\n" 3477 "lsreq r7, r3\n"); 3478 3479 COMPARE_T32(Lsr(eq, r8, r8, r3), 3480 "bne 0x00000006\n" 3481 "lsr r8, r3\n"); 3482 3483 // MOV (immediate) T1 3484 COMPARE_T32(Mov(eq, r7, 0xff), 3485 "it eq\n" 3486 "moveq r7, #255\n"); 3487 3488 // MOV (register) T1 3489 COMPARE_T32(Mov(eq, r9, r8), 3490 "it eq\n" 3491 "moveq r9, r8\n"); 3492 3493 // MOV (register) T2 3494 COMPARE_T32(Mov(eq, r0, Operand(r1, LSR, 16)), 3495 "it eq\n" 3496 "lsreq r0, r1, #16\n"); 3497 3498 COMPARE_T32(Mov(eq, r0, Operand(r1, ROR, 16)), 3499 "bne 0x00000006\n" 3500 "ror r0, r1, #16\n"); 3501 3502 // MOV (register-shifted register) T1 3503 COMPARE_T32(Mov(eq, r0, Operand(r0, LSR, r1)), 3504 "it eq\n" 3505 "lsreq r0, r1\n"); 3506 3507 COMPARE_T32(Mov(eq, r0, Operand(r1, LSR, r2)), 3508 "bne 0x00000006\n" 3509 "lsr r0, r1, r2\n"); 3510 3511 // MUL (T1) 3512 COMPARE_T32(Mul(eq, r0, r1, r0), 3513 "it eq\n" 3514 "muleq r0, r1, r0\n"); 3515 3516 COMPARE_T32(Mul(eq, r0, r1, r2), 3517 "bne 0x00000006\n" 3518 "mul r0, r1, r2\n"); 3519 3520 // MVN (register) T1 3521 COMPARE_T32(Mvn(eq, r4, r6), 3522 "it eq\n" 3523 "mvneq r4, r6\n"); 3524 3525 COMPARE_T32(Mvn(eq, r8, r6), 3526 "bne 0x00000006\n" 3527 "mvn r8, r6\n"); 3528 3529 // ORR (register) T1 3530 COMPARE_T32(Orr(eq, r0, r0, r1), 3531 "it eq\n" 3532 "orreq r0, r1\n"); 3533 3534 COMPARE_T32(Orr(eq, r0, r1, r2), 3535 "bne 0x00000006\n" 3536 "orr r0, r1, r2\n"); 3537 3538 // ROR (register) T1 3539 COMPARE_T32(Ror(eq, r7, r7, r3), 3540 "it eq\n" 3541 "roreq r7, r3\n"); 3542 3543 COMPARE_T32(Ror(eq, r8, r8, r3), 3544 "bne 0x00000006\n" 3545 "ror r8, r3\n"); 3546 3547 COMPARE_T32(Ror(eq, r0, r1, 16), 3548 "bne 0x00000006\n" 3549 "ror r0, r1, #16\n"); 3550 3551 // RSB (immediate) T1 3552 COMPARE_T32(Rsb(eq, r0, r1, 0), 3553 "it eq\n" 3554 "rsbeq r0, r1, #0\n"); 3555 3556 COMPARE_T32(Rsb(eq, r0, r1, 1), 3557 "bne 0x00000006\n" 3558 "rsb r0, r1, #1\n"); 3559 3560 // SBC (register) T1 3561 COMPARE_T32(Sbc(eq, r0, r0, r1), 3562 "it eq\n" 3563 "sbceq r0, r1\n"); 3564 3565 COMPARE_T32(Sbc(eq, r0, r1, r2), 3566 "bne 0x00000006\n" 3567 "sbc r0, r1, r2\n"); 3568 3569 // STR (immediate) T1 3570 COMPARE_T32(Str(eq, r4, MemOperand(r7, 124)), 3571 "it eq\n" 3572 "streq r4, [r7, #124]\n"); 3573 3574 COMPARE_T32(Str(eq, r4, MemOperand(r7, 1)), 3575 "bne 0x00000006\n" 3576 "str r4, [r7, #1]\n"); 3577 3578 COMPARE_T32(Str(eq, r4, MemOperand(r7, 128)), 3579 "bne 0x00000006\n" 3580 "str r4, [r7, #128]\n"); 3581 3582 // STR (immediate) T2 3583 COMPARE_T32(Str(eq, r4, MemOperand(sp, 1020)), 3584 "it eq\n" 3585 "streq r4, [sp, #1020]\n"); 3586 3587 COMPARE_T32(Str(eq, r4, MemOperand(sp, 1)), 3588 "bne 0x00000006\n" 3589 "str r4, [sp, #1]\n"); 3590 3591 COMPARE_T32(Str(eq, r4, MemOperand(sp, 1024)), 3592 "bne 0x00000006\n" 3593 "str r4, [sp, #1024]\n"); 3594 3595 // STR (register) T1 3596 COMPARE_T32(Str(eq, r5, MemOperand(r6, r7)), 3597 "it eq\n" 3598 "streq r5, [r6, r7]\n"); 3599 3600 COMPARE_T32(Str(eq, r5, MemOperand(r6, r8)), 3601 "bne 0x00000006\n" 3602 "str r5, [r6, r8]\n"); 3603 3604 // STRB (immediate) T1 3605 COMPARE_T32(Strb(eq, r6, MemOperand(r7, 31)), 3606 "it eq\n" 3607 "strbeq r6, [r7, #31]\n"); 3608 3609 COMPARE_T32(Strb(eq, r6, MemOperand(r7, 32)), 3610 "bne 0x00000006\n" 3611 "strb r6, [r7, #32]\n"); 3612 3613 // STRB (register) T1 3614 COMPARE_T32(Strb(eq, r5, MemOperand(r6, r7)), 3615 "it eq\n" 3616 "strbeq r5, [r6, r7]\n"); 3617 3618 COMPARE_T32(Strb(eq, r6, MemOperand(r9)), 3619 "bne 0x00000006\n" 3620 "strb r6, [r9]\n"); 3621 3622 // STRH (immediate) T1 3623 COMPARE_T32(Strh(eq, r6, MemOperand(r7, 62)), 3624 "it eq\n" 3625 "strheq r6, [r7, #62]\n"); 3626 3627 COMPARE_T32(Strh(eq, r6, MemOperand(r7, 64)), 3628 "bne 0x00000006\n" 3629 "strh r6, [r7, #64]\n"); 3630 3631 COMPARE_T32(Strh(eq, r6, MemOperand(r7, 1)), 3632 "bne 0x00000006\n" 3633 "strh r6, [r7, #1]\n"); 3634 3635 // STRH (register) T1 3636 COMPARE_T32(Strh(eq, r5, MemOperand(r6, r7)), 3637 "it eq\n" 3638 "strheq r5, [r6, r7]\n"); 3639 3640 COMPARE_T32(Strh(eq, r6, MemOperand(r9)), 3641 "bne 0x00000006\n" 3642 "strh r6, [r9]\n"); 3643 3644 // SUB (immediate) T1 3645 COMPARE_T32(Sub(eq, r0, r1, 0x1), 3646 "it eq\n" 3647 "subeq r0, r1, #1\n"); 3648 3649 COMPARE_T32(Sub(eq, r0, r1, 0x8), 3650 "bne 0x00000006\n" 3651 "sub r0, r1, #8\n"); 3652 3653 // SUB (immediate) T2 3654 COMPARE_T32(Sub(eq, r0, r0, 0xff), 3655 "it eq\n" 3656 "subeq r0, #255\n"); 3657 3658 // SUB (register) T1 3659 COMPARE_T32(Sub(eq, r0, r1, r7), 3660 "it eq\n" 3661 "subeq r0, r1, r7\n"); 3662 3663 COMPARE_T32(Sub(eq, r5, r5, r8), 3664 "bne 0x00000006\n" 3665 "sub r5, r8\n"); 3666 3667 COMPARE_T32(Sub(eq, r7, sp, 1), 3668 "bne 0x00000006\n" 3669 "sub r7, sp, #1\n"); 3670 3671 MUST_FAIL_TEST_T32(Sub(eq, pc, pc, 0), "Unpredictable instruction.\n"); 3672 3673 // TST (register) T1 3674 COMPARE_T32(Tst(eq, r0, r1), 3675 "it eq\n" 3676 "tsteq r0, r1\n"); 3677 3678 COMPARE_T32(Tst(eq, r8, r9), 3679 "bne 0x00000006\n" 3680 "tst r8, r9\n"); 3681 3682 CLEANUP(); 3683} 3684 3685 3686TEST(unbound_label) { 3687 SETUP(); 3688 3689#ifdef VIXL_DEBUG 3690 MUST_FAIL_TEST_BOTH_BLOCK( 3691 { 3692 Label label; 3693 masm.B(&label); 3694 }, 3695 "Location, label or literal used but not bound.\n") 3696 3697 MUST_FAIL_TEST_BOTH_BLOCK( 3698 { 3699 Label label; 3700 masm.B(eq, &label); 3701 }, 3702 "Location, label or literal used but not bound.\n") 3703 3704 MUST_FAIL_TEST_T32_BLOCK( 3705 { 3706 Label label; 3707 masm.Cbz(r0, &label); 3708 }, 3709 "Location, label or literal used but not bound.\n") 3710 3711 MUST_FAIL_TEST_T32_BLOCK( 3712 { 3713 Label label; 3714 masm.Cbnz(r1, &label); 3715 }, 3716 "Location, label or literal used but not bound.\n") 3717#endif 3718 3719 CLEANUP(); 3720} 3721 3722 3723TEST(macro_assembler_AddressComputationHelper) { 3724 SETUP(); 3725 3726 // Simple cases: the address fits in the mask. 3727 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0xfff, 0xfff)), 3728 "ldr r0, [r1, #4095]\n"); 3729 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 1, 0xfff)), 3730 "ldr r0, [r1, #1]\n"); 3731 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0, 0xfff)), 3732 "ldr r0, [r1]\n"); 3733 3734 // Similar, but the base register must be preserved. (This has no effect for 3735 // encodable cases.) 3736 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r2, r1, 0xfff, 0xfff)), 3737 "ldr r0, [r1, #4095]\n"); 3738 3739 // Cases where the extra offset has to be aligned. 3740 COMPARE_A32(Vldr(d0, masm.MemOperandComputationHelper(r1, r1, 0x3fc, 0x3fc)), 3741 "vldr d0, [r1, #1020]\n"); 3742 3743 // Out-of-range offsets. 3744 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0x1000, 0xfff)), 3745 "add r1, #4096\n" 3746 "ldr r0, [r1]\n"); 3747 COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r2, r1, 0x1000, 0xfff)), 3748 "add r2, r1, #4096\n" 3749 "ldr r0, [r2]\n"); 3750 COMPARE_A32(Ldr(r0, 3751 masm.MemOperandComputationHelper(r2, r1, 0xffffffff, 0xfff)), 3752 "sub r2, r1, #1\n" 3753 "ldr r0, [r2]\n"); 3754 3755 // TODO: Improve the code generation for these cases. 3756 3757 COMPARE_A32(Ldr(r0, 3758 masm.MemOperandComputationHelper(r2, r1, 0x12345678, 0xfff)), 3759 "mov r2, #20480\n" 3760 "movt r2, #4660\n" 3761 "add r2, r1, r2\n" 3762 "ldr r0, [r2, #1656]\n"); 3763 COMPARE_A32(Ldr(r0, 3764 masm.MemOperandComputationHelper(r2, r1, 0x7fffffff, 0xfff)), 3765 "sub r2, r1, #1\n" 3766 "sub r2, #2147483648\n" 3767 "ldr r0, [r2]\n"); 3768 COMPARE_A32(Ldr(r0, 3769 masm.MemOperandComputationHelper(r2, r1, 0xffcba000, 0xfff)), 3770 "sub r2, r1, #286720\n" 3771 "sub r2, #3145728\n" 3772 "ldr r0, [r2]\n"); 3773 3774 CLEANUP(); 3775} 3776 3777 3778TEST(barriers) { 3779 SETUP(); 3780 3781 // DMB 3782 COMPARE_BOTH(Dmb(SY), "dmb sy\n"); 3783 COMPARE_BOTH(Dmb(ST), "dmb st\n"); 3784 COMPARE_BOTH(Dmb(ISH), "dmb ish\n"); 3785 COMPARE_BOTH(Dmb(ISHST), "dmb ishst\n"); 3786 COMPARE_BOTH(Dmb(NSH), "dmb nsh\n"); 3787 COMPARE_BOTH(Dmb(NSHST), "dmb nshst\n"); 3788 COMPARE_BOTH(Dmb(OSH), "dmb osh\n"); 3789 COMPARE_BOTH(Dmb(OSHST), "dmb oshst\n"); 3790 3791 // DSB 3792 COMPARE_BOTH(Dsb(SY), "dsb sy\n"); 3793 COMPARE_BOTH(Dsb(ST), "dsb st\n"); 3794 COMPARE_BOTH(Dsb(ISH), "dsb ish\n"); 3795 COMPARE_BOTH(Dsb(ISHST), "dsb ishst\n"); 3796 COMPARE_BOTH(Dsb(NSH), "dsb nsh\n"); 3797 COMPARE_BOTH(Dsb(NSHST), "dsb nshst\n"); 3798 COMPARE_BOTH(Dsb(OSH), "dsb osh\n"); 3799 COMPARE_BOTH(Dsb(OSHST), "dsb oshst\n"); 3800 3801 // ISB 3802 COMPARE_BOTH(Isb(SY), "isb sy\n"); 3803 3804 CLEANUP(); 3805} 3806 3807 3808TEST(preloads) { 3809 // Smoke test for various pld/pli forms. 3810 SETUP(); 3811 3812 // PLD immediate 3813 COMPARE_BOTH(Pld(MemOperand(r0, 0)), "pld [r0]\n"); 3814 COMPARE_BOTH(Pld(MemOperand(r1, 123)), "pld [r1, #123]\n"); 3815 COMPARE_BOTH(Pld(MemOperand(r4, -123)), "pld [r4, #-123]\n"); 3816 3817 COMPARE_A32(Pld(MemOperand(r7, -4095)), "pld [r7, #-4095]\n"); 3818 3819 // PLDW immediate 3820 COMPARE_BOTH(Pldw(MemOperand(r0, 0)), "pldw [r0]\n"); 3821 COMPARE_BOTH(Pldw(MemOperand(r1, 123)), "pldw [r1, #123]\n"); 3822 COMPARE_BOTH(Pldw(MemOperand(r4, -123)), "pldw [r4, #-123]\n"); 3823 3824 COMPARE_A32(Pldw(MemOperand(r7, -4095)), "pldw [r7, #-4095]\n"); 3825 3826 // PLD register 3827 COMPARE_BOTH(Pld(MemOperand(r0, r1)), "pld [r0, r1]\n"); 3828 COMPARE_BOTH(Pld(MemOperand(r0, r1, LSL, 1)), "pld [r0, r1, lsl #1]\n"); 3829 3830 COMPARE_A32(Pld(MemOperand(r0, r1, LSL, 20)), "pld [r0, r1, lsl #20]\n"); 3831 3832 // PLDW register 3833 COMPARE_BOTH(Pldw(MemOperand(r0, r1)), "pldw [r0, r1]\n"); 3834 COMPARE_BOTH(Pldw(MemOperand(r0, r1, LSL, 1)), "pldw [r0, r1, lsl #1]\n"); 3835 3836 COMPARE_A32(Pldw(MemOperand(r0, r1, LSL, 20)), "pldw [r0, r1, lsl #20]\n"); 3837 3838 // PLD literal 3839 COMPARE_BOTH(Pld(MemOperand(pc, minus, 0)), "pld [pc, #-0]\n"); 3840 3841 // PLI immediate 3842 COMPARE_BOTH(Pli(MemOperand(r0, 0)), "pli [r0]\n"); 3843 COMPARE_BOTH(Pli(MemOperand(r1, 123)), "pli [r1, #123]\n"); 3844 COMPARE_BOTH(Pli(MemOperand(r4, -123)), "pli [r4, #-123]\n"); 3845 3846 COMPARE_A32(Pli(MemOperand(r7, -4095)), "pli [r7, #-4095]\n"); 3847 3848 // PLI register 3849 COMPARE_BOTH(Pli(MemOperand(r0, r1)), "pli [r0, r1]\n"); 3850 COMPARE_BOTH(Pli(MemOperand(r0, r1, LSL, 1)), "pli [r0, r1, lsl #1]\n"); 3851 3852 COMPARE_A32(Pli(MemOperand(r0, r1, LSL, 20)), "pli [r0, r1, lsl #20]\n"); 3853 3854 // PLI literal 3855 COMPARE_BOTH(Pli(MemOperand(pc, minus, 0)), "pli [pc, #-0]\n"); 3856 3857 CLEANUP(); 3858} 3859 3860 3861TEST(vcmp_vcmpe) { 3862 SETUP(); 3863 3864 COMPARE_BOTH(Vcmp(F32, s0, s1), "vcmp.f32 s0, s1\n"); 3865 COMPARE_BOTH(Vcmp(F64, d0, d1), "vcmp.f64 d0, d1\n"); 3866 COMPARE_BOTH(Vcmp(F32, s0, 0.0f), "vcmp.f32 s0, #0.0\n"); 3867 COMPARE_BOTH(Vcmp(F64, d0, 0.0), "vcmp.f64 d0, #0.0\n"); 3868 3869 COMPARE_BOTH(Vcmpe(F32, s0, s1), "vcmpe.f32 s0, s1\n"); 3870 COMPARE_BOTH(Vcmpe(F64, d0, d1), "vcmpe.f64 d0, d1\n"); 3871 COMPARE_BOTH(Vcmpe(F32, s0, 0.0f), "vcmpe.f32 s0, #0.0\n"); 3872 COMPARE_BOTH(Vcmpe(F64, d0, 0.0), "vcmpe.f64 d0, #0.0\n"); 3873 3874 CLEANUP(); 3875} 3876 3877 3878TEST(vmrs_vmsr) { 3879 SETUP(); 3880 3881 COMPARE_BOTH(Vmsr(FPSCR, r0), "vmsr FPSCR, r0\n"); 3882 3883 COMPARE_BOTH(Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR), 3884 "vmrs r1, FPSCR\n"); 3885 3886 COMPARE_BOTH(Vmrs(RegisterOrAPSR_nzcv(pc.GetCode()), FPSCR), 3887 "vmrs APSR_nzcv, FPSCR\n"); 3888 3889 CLEANUP(); 3890} 3891 3892 3893TEST(ldm_stm) { 3894 SETUP(); 3895 3896 // ldm/stm 3897 COMPARE_BOTH(Ldm(r0, NO_WRITE_BACK, RegisterList(r1)), "ldm r0, {r1}\n"); 3898 3899 COMPARE_BOTH(Ldm(r1, NO_WRITE_BACK, RegisterList(r2, r5, r9, r10)), 3900 "ldm r1, {r2,r5,r9,r10}\n"); 3901 3902 COMPARE_BOTH(Ldm(r0, WRITE_BACK, RegisterList(r1, r2)), "ldm r0!, {r1,r2}\n"); 3903 3904 COMPARE_BOTH(Stm(r1, NO_WRITE_BACK, RegisterList(r2, r5, r9, r10)), 3905 "stm r1, {r2,r5,r9,r10}\n"); 3906 3907 COMPARE_BOTH(Stm(r0, WRITE_BACK, RegisterList(r1, r2)), "stm r0!, {r1,r2}\n"); 3908 3909 // ldmda/stmda 3910 COMPARE_A32(Ldmda(r11, WRITE_BACK, RegisterList(r0, r1)), 3911 "ldmda r11!, {r0,r1}\n"); 3912 3913 COMPARE_A32(Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3914 "ldmda r11, {r2,r3}\n"); 3915 3916 COMPARE_A32(Stmda(r11, WRITE_BACK, RegisterList(r0, r1)), 3917 "stmda r11!, {r0,r1}\n"); 3918 3919 COMPARE_A32(Stmda(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3920 "stmda r11, {r2,r3}\n"); 3921 3922 // ldmib/stmib 3923 COMPARE_A32(Ldmib(r11, WRITE_BACK, RegisterList(r0, r1)), 3924 "ldmib r11!, {r0,r1}\n"); 3925 3926 COMPARE_A32(Ldmib(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3927 "ldmib r11, {r2,r3}\n"); 3928 3929 COMPARE_A32(Stmib(r11, WRITE_BACK, RegisterList(r0, r1)), 3930 "stmib r11!, {r0,r1}\n"); 3931 3932 COMPARE_A32(Stmib(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3933 "stmib r11, {r2,r3}\n"); 3934 3935 // ldmdb/stmdb 3936 COMPARE_BOTH(Ldmdb(r11, WRITE_BACK, RegisterList(r0, r1)), 3937 "ldmdb r11!, {r0,r1}\n"); 3938 3939 COMPARE_BOTH(Ldmdb(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3940 "ldmdb r11, {r2,r3}\n"); 3941 3942 COMPARE_BOTH(Stmdb(r11, WRITE_BACK, RegisterList(r0, r1)), 3943 "stmdb r11!, {r0,r1}\n"); 3944 3945 COMPARE_BOTH(Stmdb(r11, NO_WRITE_BACK, RegisterList(r2, r3)), 3946 "stmdb r11, {r2,r3}\n"); 3947 3948 CLEANUP(); 3949} 3950 3951 3952#define CHECK_T32_16(ASM, EXP) COMPARE_T32_CHECK_SIZE(ASM, EXP, 2) 3953// For instructions inside an IT block, we need to account for the IT 3954// instruction as well (another 16 bits). 3955#define CHECK_T32_16_IT_BLOCK(ASM, EXP) COMPARE_T32_CHECK_SIZE(ASM, EXP, 4) 3956 3957TEST(macro_assembler_T32_16bit) { 3958 SETUP(); 3959 3960 // Allow the test to use all registers. 3961 UseScratchRegisterScope temps(&masm); 3962 temps.ExcludeAll(); 3963 3964 CHECK_T32_16(Adc(DontCare, r7, r7, r6), "adcs r7, r6\n"); 3965 3966 CHECK_T32_16_IT_BLOCK(Adc(DontCare, eq, r7, r7, r6), 3967 "it eq\n" 3968 "adceq r7, r6\n"); 3969 3970 CHECK_T32_16(Add(DontCare, r6, r7, 7), "adds r6, r7, #7\n"); 3971 3972 CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r6, r7, 7), 3973 "it lt\n" 3974 "addlt r6, r7, #7\n"); 3975 3976 CHECK_T32_16(Add(DontCare, r5, r5, 255), "adds r5, #255\n"); 3977 3978 CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r5, r5, 255), 3979 "it lt\n" 3980 "addlt r5, #255\n"); 3981 3982 // Make sure we select the non flag-setting version here, since 3983 // this can have two potential encodings. 3984 CHECK_T32_16(Add(DontCare, r1, r1, r2), "add r1, r2\n"); 3985 3986 CHECK_T32_16(Add(DontCare, r1, r2, r7), "adds r1, r2, r7\n"); 3987 3988 CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r1, r2, r7), 3989 "it lt\n" 3990 "addlt r1, r2, r7\n"); 3991 3992 CHECK_T32_16(Add(DontCare, r4, r4, r12), "add r4, ip\n"); 3993 3994 CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, r4, r4, r12), 3995 "it eq\n" 3996 "addeq r4, ip\n"); 3997 3998 CHECK_T32_16(Add(DontCare, r0, sp, 1020), "add r0, sp, #1020\n"); 3999 4000 CHECK_T32_16_IT_BLOCK(Add(DontCare, ge, r0, sp, 1020), 4001 "it ge\n" 4002 "addge r0, sp, #1020\n"); 4003 4004 // The equivalent inside an IT block is deprecated. 4005 CHECK_T32_16(Add(DontCare, sp, sp, 508), "add sp, #508\n"); 4006 4007 CHECK_T32_16(Add(DontCare, r7, sp, r7), "add r7, sp, r7\n"); 4008 4009 CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, r7, sp, r7), 4010 "it eq\n" 4011 "addeq r7, sp, r7\n"); 4012 4013 CHECK_T32_16(Add(DontCare, sp, sp, r10), "add sp, r10\n"); 4014 4015 CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, sp, sp, r10), 4016 "it eq\n" 4017 "addeq sp, r10\n"); 4018 4019 CHECK_T32_16(And(DontCare, r7, r7, r6), "ands r7, r6\n"); 4020 4021 CHECK_T32_16_IT_BLOCK(And(DontCare, eq, r7, r7, r6), 4022 "it eq\n" 4023 "andeq r7, r6\n"); 4024 4025 CHECK_T32_16(Asr(DontCare, r0, r1, 32), "asrs r0, r1, #32\n"); 4026 4027 CHECK_T32_16_IT_BLOCK(Asr(DontCare, eq, r0, r1, 32), 4028 "it eq\n" 4029 "asreq r0, r1, #32\n"); 4030 4031 CHECK_T32_16(Asr(DontCare, r0, r0, r1), "asrs r0, r1\n"); 4032 4033 CHECK_T32_16_IT_BLOCK(Asr(DontCare, eq, r0, r0, r1), 4034 "it eq\n" 4035 "asreq r0, r1\n"); 4036 4037 CHECK_T32_16(Bic(DontCare, r7, r7, r6), "bics r7, r6\n"); 4038 4039 CHECK_T32_16_IT_BLOCK(Bic(DontCare, eq, r7, r7, r6), 4040 "it eq\n" 4041 "biceq r7, r6\n"); 4042 4043 CHECK_T32_16(Eor(DontCare, r7, r7, r6), "eors r7, r6\n"); 4044 4045 CHECK_T32_16_IT_BLOCK(Eor(DontCare, eq, r7, r7, r6), 4046 "it eq\n" 4047 "eoreq r7, r6\n"); 4048 4049 CHECK_T32_16(Lsl(DontCare, r0, r1, 31), "lsls r0, r1, #31\n"); 4050 4051 CHECK_T32_16_IT_BLOCK(Lsl(DontCare, eq, r0, r1, 31), 4052 "it eq\n" 4053 "lsleq r0, r1, #31\n"); 4054 4055 CHECK_T32_16(Lsl(DontCare, r0, r0, r1), "lsls r0, r1\n"); 4056 4057 CHECK_T32_16_IT_BLOCK(Lsl(DontCare, eq, r0, r0, r1), 4058 "it eq\n" 4059 "lsleq r0, r1\n"); 4060 4061 CHECK_T32_16(Lsr(DontCare, r0, r1, 32), "lsrs r0, r1, #32\n"); 4062 4063 CHECK_T32_16_IT_BLOCK(Lsr(DontCare, eq, r0, r1, 32), 4064 "it eq\n" 4065 "lsreq r0, r1, #32\n"); 4066 4067 CHECK_T32_16(Lsr(DontCare, r0, r0, r1), "lsrs r0, r1\n"); 4068 4069 CHECK_T32_16_IT_BLOCK(Lsr(DontCare, eq, r0, r0, r1), 4070 "it eq\n" 4071 "lsreq r0, r1\n"); 4072 4073 CHECK_T32_16(Mov(DontCare, r7, 255), "movs r7, #255\n"); 4074 4075 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, 255), 4076 "it eq\n" 4077 "moveq r7, #255\n"); 4078 4079 CHECK_T32_16(Mov(DontCare, r9, r8), "mov r9, r8\n"); 4080 4081 // Check that we don't try to pick the MOVS register-shifted register variant. 4082 CHECK_T32_16(Mov(DontCare, r5, r6), "mov r5, r6\n"); 4083 4084 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r9, r8), 4085 "it eq\n" 4086 "moveq r9, r8\n"); 4087 4088 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, ASR, 1)), "asrs r5, r6, #1\n"); 4089 4090 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, ASR, 32)), "asrs r5, r6, #32\n"); 4091 4092 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSR, 1)), "lsrs r5, r6, #1\n"); 4093 4094 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSR, 32)), "lsrs r5, r6, #32\n"); 4095 4096 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSL, 1)), "lsls r5, r6, #1\n"); 4097 4098 CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSL, 31)), "lsls r5, r6, #31\n"); 4099 4100 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, ASR, 1)), 4101 "it eq\n" 4102 "asreq r5, r6, #1\n"); 4103 4104 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, ASR, 32)), 4105 "it eq\n" 4106 "asreq r5, r6, #32\n"); 4107 4108 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSR, 1)), 4109 "it eq\n" 4110 "lsreq r5, r6, #1\n"); 4111 4112 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSR, 32)), 4113 "it eq\n" 4114 "lsreq r5, r6, #32\n"); 4115 4116 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSL, 1)), 4117 "it eq\n" 4118 "lsleq r5, r6, #1\n"); 4119 4120 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSL, 31)), 4121 "it eq\n" 4122 "lsleq r5, r6, #31\n"); 4123 4124 CHECK_T32_16(Mov(DontCare, r7, Operand(r7, ASR, r6)), "asrs r7, r6\n"); 4125 4126 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, ASR, r6)), 4127 "it eq\n" 4128 "asreq r7, r6\n"); 4129 4130 CHECK_T32_16(Mov(DontCare, r7, Operand(r7, LSR, r6)), "lsrs r7, r6\n"); 4131 4132 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, LSR, r6)), 4133 "it eq\n" 4134 "lsreq r7, r6\n"); 4135 4136 CHECK_T32_16(Mov(DontCare, r7, Operand(r7, LSL, r6)), "lsls r7, r6\n"); 4137 4138 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, LSL, r6)), 4139 "it eq\n" 4140 "lsleq r7, r6\n"); 4141 4142 CHECK_T32_16(Mov(DontCare, r7, Operand(r7, ROR, r6)), "rors r7, r6\n"); 4143 4144 CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, ROR, r6)), 4145 "it eq\n" 4146 "roreq r7, r6\n"); 4147 4148 CHECK_T32_16(Mul(DontCare, r0, r1, r0), "muls r0, r1, r0\n"); 4149 4150 CHECK_T32_16_IT_BLOCK(Mul(DontCare, eq, r0, r1, r0), 4151 "it eq\n" 4152 "muleq r0, r1, r0\n"); 4153 4154 CHECK_T32_16(Mvn(DontCare, r6, r7), "mvns r6, r7\n"); 4155 4156 CHECK_T32_16_IT_BLOCK(Mvn(DontCare, eq, r6, r7), 4157 "it eq\n" 4158 "mvneq r6, r7\n"); 4159 4160 CHECK_T32_16(Orr(DontCare, r7, r7, r6), "orrs r7, r6\n"); 4161 4162 CHECK_T32_16_IT_BLOCK(Orr(DontCare, eq, r7, r7, r6), 4163 "it eq\n" 4164 "orreq r7, r6\n"); 4165 4166 CHECK_T32_16(Ror(DontCare, r0, r0, r1), "rors r0, r1\n"); 4167 4168 CHECK_T32_16_IT_BLOCK(Ror(DontCare, eq, r0, r0, r1), 4169 "it eq\n" 4170 "roreq r0, r1\n"); 4171 4172 CHECK_T32_16(Rsb(DontCare, r7, r6, 0), "rsbs r7, r6, #0\n"); 4173 4174 CHECK_T32_16_IT_BLOCK(Rsb(DontCare, eq, r7, r6, 0), 4175 "it eq\n" 4176 "rsbeq r7, r6, #0\n"); 4177 4178 CHECK_T32_16(Sbc(DontCare, r7, r7, r6), "sbcs r7, r6\n"); 4179 4180 CHECK_T32_16_IT_BLOCK(Sbc(DontCare, eq, r7, r7, r6), 4181 "it eq\n" 4182 "sbceq r7, r6\n"); 4183 4184 CHECK_T32_16(Sub(DontCare, r6, r7, 7), "subs r6, r7, #7\n"); 4185 4186 CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r6, r7, 7), 4187 "it lt\n" 4188 "sublt r6, r7, #7\n"); 4189 4190 CHECK_T32_16(Sub(DontCare, r5, r5, 255), "subs r5, #255\n"); 4191 4192 CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r5, r5, 255), 4193 "it lt\n" 4194 "sublt r5, #255\n"); 4195 4196 CHECK_T32_16(Sub(DontCare, r1, r2, r7), "subs r1, r2, r7\n"); 4197 4198 CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r1, r2, r7), 4199 "it lt\n" 4200 "sublt r1, r2, r7\n"); 4201 4202 // The equivalent inside an IT block is deprecated. 4203 CHECK_T32_16(Sub(DontCare, sp, sp, 508), "sub sp, #508\n"); 4204 4205 // Generate SUBS for ADD. 4206 CHECK_T32_16(Add(DontCare, r0, r1, -1), "subs r0, r1, #1\n"); 4207 4208 CHECK_T32_16(Add(DontCare, r0, r1, -7), "subs r0, r1, #7\n"); 4209 4210 CHECK_T32_16(Add(DontCare, r6, r6, -1), "subs r6, #1\n"); 4211 4212 CHECK_T32_16(Add(DontCare, r6, r6, -255), "subs r6, #255\n"); 4213 4214 // Generate ADDS for SUB. 4215 CHECK_T32_16(Sub(DontCare, r0, r1, -1), "adds r0, r1, #1\n"); 4216 4217 CHECK_T32_16(Sub(DontCare, r0, r1, -7), "adds r0, r1, #7\n"); 4218 4219 CHECK_T32_16(Sub(DontCare, r6, r6, -1), "adds r6, #1\n"); 4220 4221 CHECK_T32_16(Sub(DontCare, r6, r6, -255), "adds r6, #255\n"); 4222 4223 // Check that we don't change the opcode for INT_MIN. 4224 COMPARE_T32(Add(DontCare, r6, r6, 0x80000000), "add r6, #2147483648\n"); 4225 4226 COMPARE_T32(Sub(DontCare, r6, r6, 0x80000000), "sub r6, #2147483648\n"); 4227 4228 CLEANUP(); 4229} 4230#undef CHECK_T32_16 4231#undef CHECK_T32_16_IT_BLOCK 4232 4233TEST(nop_code) { 4234 SETUP(); 4235 4236 COMPARE_BOTH(Nop(), "nop\n"); 4237 4238 COMPARE_BOTH(And(r0, r0, r0), ""); 4239 COMPARE_BOTH(And(DontCare, r0, r0, r0), ""); 4240 4241 COMPARE_BOTH(Mov(r0, r0), ""); 4242 COMPARE_BOTH(Mov(DontCare, r0, r0), ""); 4243 4244 COMPARE_BOTH(Orr(r0, r0, r0), ""); 4245 COMPARE_BOTH(Orr(DontCare, r0, r0, r0), ""); 4246 4247 CLEANUP(); 4248} 4249 4250 4251TEST(minus_zero_offsets) { 4252 SETUP(); 4253 4254 COMPARE_A32(Ldr(r0, MemOperand(pc, minus, 0)), "ldr r0, [pc, #-0]\n"); 4255 COMPARE_T32(Ldr(r0, MemOperand(pc, minus, 0)), "ldr.w r0, [pc, #-0]\n"); 4256 COMPARE_BOTH(Ldrb(r0, MemOperand(pc, minus, 0)), "ldrb r0, [pc, #-0]\n"); 4257 COMPARE_BOTH(Ldrh(r0, MemOperand(pc, minus, 0)), "ldrh r0, [pc, #-0]\n"); 4258 COMPARE_BOTH(Ldrd(r0, r1, MemOperand(pc, minus, 0)), 4259 "ldrd r0, r1, [pc, #-0]\n"); 4260 COMPARE_BOTH(Ldrsb(r0, MemOperand(pc, minus, 0)), "ldrsb r0, [pc, #-0]\n"); 4261 COMPARE_BOTH(Ldrsh(r0, MemOperand(pc, minus, 0)), "ldrsh r0, [pc, #-0]\n"); 4262 COMPARE_BOTH(Pld(MemOperand(pc, minus, 0)), "pld [pc, #-0]\n"); 4263 COMPARE_BOTH(Pli(MemOperand(pc, minus, 0)), "pli [pc, #-0]\n"); 4264 COMPARE_BOTH(Vldr(s0, MemOperand(pc, minus, 0)), "vldr s0, [pc, #-0]\n"); 4265 COMPARE_BOTH(Vldr(d0, MemOperand(pc, minus, 0)), "vldr d0, [pc, #-0]\n"); 4266 4267 // This is an alias of ADR with a minus zero offset. 4268 COMPARE_BOTH(Sub(r0, pc, 0), "sub r0, pc, #0\n"); 4269 4270 CLEANUP(); 4271} 4272 4273 4274TEST(big_add_sub) { 4275 SETUP(); 4276 4277 COMPARE_A32(Add(r0, r1, 0x4321), 4278 "add r0, r1, #33\n" 4279 "add r0, #17152\n"); 4280 COMPARE_T32(Add(r0, r1, 0x4321), 4281 "add r0, r1, #801\n" 4282 "add r0, #16384\n"); 4283 COMPARE_BOTH(Add(r0, r1, 0x432100), 4284 "add r0, r1, #8448\n" 4285 "add r0, #4390912\n"); 4286 COMPARE_BOTH(Add(r0, r1, 0x43000210), 4287 "add r0, r1, #528\n" 4288 "add r0, #1124073472\n"); 4289 COMPARE_BOTH(Add(r0, r1, 0x30c00210), 4290 "add r0, r1, #528\n" 4291 "add r0, #817889280\n"); 4292 COMPARE_BOTH(Add(r0, r1, 0x43000021), 4293 "add r0, r1, #33\n" 4294 "add r0, #1124073472\n"); 4295 COMPARE_T32(Add(r0, r1, 0x54321), 4296 "add r0, r1, #801\n" 4297 "add r0, #344064\n"); 4298 COMPARE_T32(Add(r0, r1, 0x54000321), 4299 "add r0, r1, #801\n" 4300 "add r0, #1409286144\n"); 4301 4302 COMPARE_A32(Sub(r0, r1, 0x4321), 4303 "sub r0, r1, #33\n" 4304 "sub r0, #17152\n"); 4305 COMPARE_T32(Sub(r0, r1, 0x4321), 4306 "sub r0, r1, #801\n" 4307 "sub r0, #16384\n"); 4308 COMPARE_BOTH(Sub(r0, r1, 0x432100), 4309 "sub r0, r1, #8448\n" 4310 "sub r0, #4390912\n"); 4311 COMPARE_BOTH(Sub(r0, r1, 0x43000210), 4312 "sub r0, r1, #528\n" 4313 "sub r0, #1124073472\n"); 4314 COMPARE_BOTH(Sub(r0, r1, 0x30c00210), 4315 "sub r0, r1, #528\n" 4316 "sub r0, #817889280\n"); 4317 COMPARE_BOTH(Sub(r0, r1, 0x43000021), 4318 "sub r0, r1, #33\n" 4319 "sub r0, #1124073472\n"); 4320 COMPARE_T32(Sub(r0, r1, 0x54321), 4321 "sub r0, r1, #801\n" 4322 "sub r0, #344064\n"); 4323 COMPARE_T32(Sub(r0, r1, 0x54000321), 4324 "sub r0, r1, #801\n" 4325 "sub r0, #1409286144\n"); 4326 4327 CLEANUP(); 4328} 4329 4330} // namespace aarch32 4331} // namespace vixl 4332