assembler-aarch32.cc (1002206B)
1 // Copyright 2017, 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 extern "C" { 28 #include <stdint.h> 29 } 30 31 #include <cassert> 32 #include <cstdio> 33 #include <cstdlib> 34 #include <cstring> 35 #include <iostream> 36 37 #include "utils-vixl.h" 38 #include "aarch32/assembler-aarch32.h" 39 #include "aarch32/constants-aarch32.h" 40 #include "aarch32/instructions-aarch32.h" 41 #include "aarch32/operands-aarch32.h" 42 43 namespace vixl { 44 namespace aarch32 { 45 46 void Assembler::EmitT32_16(uint16_t instr) { 47 VIXL_ASSERT(buffer_.Is16bitAligned()); 48 buffer_.Emit16(instr); 49 } 50 51 52 void Assembler::EmitT32_32(uint32_t instr) { 53 VIXL_ASSERT(buffer_.Is16bitAligned()); 54 buffer_.Emit16(static_cast<uint16_t>(instr >> 16)); 55 buffer_.Emit16(static_cast<uint16_t>(instr & 0xffff)); 56 } 57 58 59 void Assembler::EmitA32(uint32_t instr) { 60 VIXL_ASSERT(buffer_.Is32bitAligned()); 61 buffer_.Emit32(instr); 62 } 63 64 65 #ifdef VIXL_DEBUG 66 void Assembler::PerformCheckIT(Condition condition) { 67 if (it_mask_ == 0) { 68 VIXL_ASSERT(IsUsingA32() || condition.Is(al)); 69 } else { 70 VIXL_ASSERT(condition.Is(first_condition_)); 71 // For A32, AdavanceIT() is not called by the assembler. We must call it 72 // in order to check that IT instructions are used consistently with 73 // the following conditional instructions. 74 if (IsUsingA32()) AdvanceIT(); 75 } 76 } 77 #endif 78 79 80 void Assembler::BindHelper(Label* label) { 81 VIXL_ASSERT(!label->IsBound()); 82 label->SetLocation(this, GetCursorOffset()); 83 label->MarkBound(); 84 } 85 86 uint32_t Assembler::Link(uint32_t instr, 87 Location* location, 88 const Location::EmitOperator& op, 89 const ReferenceInfo* info) { 90 location->SetReferenced(); 91 if (location->IsBound()) { 92 return op.Encode(instr, GetCursorOffset(), location); 93 } 94 location->AddForwardRef(GetCursorOffset(), op, info); 95 return instr; 96 } 97 98 99 // Start of generated code. 100 class Dt_L_imm6_1 : public EncodingValue { 101 uint32_t type_; 102 103 public: 104 explicit Dt_L_imm6_1(DataType dt); 105 uint32_t GetTypeEncodingValue() const { return type_; } 106 }; 107 108 Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) { 109 switch (dt.GetValue()) { 110 case S8: 111 type_ = 0x0; 112 SetEncodingValue(0x1); 113 break; 114 case U8: 115 type_ = 0x1; 116 SetEncodingValue(0x1); 117 break; 118 case S16: 119 type_ = 0x0; 120 SetEncodingValue(0x2); 121 break; 122 case U16: 123 type_ = 0x1; 124 SetEncodingValue(0x2); 125 break; 126 case S32: 127 type_ = 0x0; 128 SetEncodingValue(0x4); 129 break; 130 case U32: 131 type_ = 0x1; 132 SetEncodingValue(0x4); 133 break; 134 case S64: 135 type_ = 0x0; 136 SetEncodingValue(0x8); 137 break; 138 case U64: 139 type_ = 0x1; 140 SetEncodingValue(0x8); 141 break; 142 default: 143 VIXL_UNREACHABLE(); 144 type_ = 0x0; 145 break; 146 } 147 } 148 149 class Dt_L_imm6_2 : public EncodingValue { 150 uint32_t type_; 151 152 public: 153 explicit Dt_L_imm6_2(DataType dt); 154 uint32_t GetTypeEncodingValue() const { return type_; } 155 }; 156 157 Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) { 158 switch (dt.GetValue()) { 159 case S8: 160 type_ = 0x1; 161 SetEncodingValue(0x1); 162 break; 163 case S16: 164 type_ = 0x1; 165 SetEncodingValue(0x2); 166 break; 167 case S32: 168 type_ = 0x1; 169 SetEncodingValue(0x4); 170 break; 171 case S64: 172 type_ = 0x1; 173 SetEncodingValue(0x8); 174 break; 175 default: 176 VIXL_UNREACHABLE(); 177 type_ = 0x0; 178 break; 179 } 180 } 181 182 class Dt_L_imm6_3 : public EncodingValue { 183 public: 184 explicit Dt_L_imm6_3(DataType dt); 185 }; 186 187 Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) { 188 switch (dt.GetValue()) { 189 case I8: 190 SetEncodingValue(0x1); 191 break; 192 case I16: 193 SetEncodingValue(0x2); 194 break; 195 case I32: 196 SetEncodingValue(0x4); 197 break; 198 case I64: 199 SetEncodingValue(0x8); 200 break; 201 default: 202 break; 203 } 204 } 205 206 class Dt_L_imm6_4 : public EncodingValue { 207 public: 208 explicit Dt_L_imm6_4(DataType dt); 209 }; 210 211 Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) { 212 switch (dt.GetValue()) { 213 case Untyped8: 214 SetEncodingValue(0x1); 215 break; 216 case Untyped16: 217 SetEncodingValue(0x2); 218 break; 219 case Untyped32: 220 SetEncodingValue(0x4); 221 break; 222 case Untyped64: 223 SetEncodingValue(0x8); 224 break; 225 default: 226 break; 227 } 228 } 229 230 class Dt_imm6_1 : public EncodingValue { 231 uint32_t type_; 232 233 public: 234 explicit Dt_imm6_1(DataType dt); 235 uint32_t GetTypeEncodingValue() const { return type_; } 236 }; 237 238 Dt_imm6_1::Dt_imm6_1(DataType dt) { 239 switch (dt.GetValue()) { 240 case S16: 241 type_ = 0x0; 242 SetEncodingValue(0x1); 243 break; 244 case U16: 245 type_ = 0x1; 246 SetEncodingValue(0x1); 247 break; 248 case S32: 249 type_ = 0x0; 250 SetEncodingValue(0x2); 251 break; 252 case U32: 253 type_ = 0x1; 254 SetEncodingValue(0x2); 255 break; 256 case S64: 257 type_ = 0x0; 258 SetEncodingValue(0x4); 259 break; 260 case U64: 261 type_ = 0x1; 262 SetEncodingValue(0x4); 263 break; 264 default: 265 VIXL_UNREACHABLE(); 266 type_ = 0x0; 267 break; 268 } 269 } 270 271 class Dt_imm6_2 : public EncodingValue { 272 uint32_t type_; 273 274 public: 275 explicit Dt_imm6_2(DataType dt); 276 uint32_t GetTypeEncodingValue() const { return type_; } 277 }; 278 279 Dt_imm6_2::Dt_imm6_2(DataType dt) { 280 switch (dt.GetValue()) { 281 case S16: 282 type_ = 0x1; 283 SetEncodingValue(0x1); 284 break; 285 case S32: 286 type_ = 0x1; 287 SetEncodingValue(0x2); 288 break; 289 case S64: 290 type_ = 0x1; 291 SetEncodingValue(0x4); 292 break; 293 default: 294 VIXL_UNREACHABLE(); 295 type_ = 0x0; 296 break; 297 } 298 } 299 300 class Dt_imm6_3 : public EncodingValue { 301 public: 302 explicit Dt_imm6_3(DataType dt); 303 }; 304 305 Dt_imm6_3::Dt_imm6_3(DataType dt) { 306 switch (dt.GetValue()) { 307 case I16: 308 SetEncodingValue(0x1); 309 break; 310 case I32: 311 SetEncodingValue(0x2); 312 break; 313 case I64: 314 SetEncodingValue(0x4); 315 break; 316 default: 317 break; 318 } 319 } 320 321 class Dt_imm6_4 : public EncodingValue { 322 uint32_t type_; 323 324 public: 325 explicit Dt_imm6_4(DataType dt); 326 uint32_t GetTypeEncodingValue() const { return type_; } 327 }; 328 329 Dt_imm6_4::Dt_imm6_4(DataType dt) { 330 switch (dt.GetValue()) { 331 case S8: 332 type_ = 0x0; 333 SetEncodingValue(0x1); 334 break; 335 case U8: 336 type_ = 0x1; 337 SetEncodingValue(0x1); 338 break; 339 case S16: 340 type_ = 0x0; 341 SetEncodingValue(0x2); 342 break; 343 case U16: 344 type_ = 0x1; 345 SetEncodingValue(0x2); 346 break; 347 case S32: 348 type_ = 0x0; 349 SetEncodingValue(0x4); 350 break; 351 case U32: 352 type_ = 0x1; 353 SetEncodingValue(0x4); 354 break; 355 default: 356 VIXL_UNREACHABLE(); 357 type_ = 0x0; 358 break; 359 } 360 } 361 362 class Dt_op_U_size_1 : public EncodingValue { 363 public: 364 explicit Dt_op_U_size_1(DataType dt); 365 }; 366 367 Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) { 368 switch (dt.GetValue()) { 369 case S8: 370 SetEncodingValue(0x0); 371 break; 372 case S16: 373 SetEncodingValue(0x1); 374 break; 375 case S32: 376 SetEncodingValue(0x2); 377 break; 378 case U8: 379 SetEncodingValue(0x4); 380 break; 381 case U16: 382 SetEncodingValue(0x5); 383 break; 384 case U32: 385 SetEncodingValue(0x6); 386 break; 387 case P8: 388 SetEncodingValue(0x8); 389 break; 390 case P64: 391 SetEncodingValue(0xa); 392 break; 393 default: 394 break; 395 } 396 } 397 398 class Dt_op_size_1 : public EncodingValue { 399 public: 400 explicit Dt_op_size_1(DataType dt); 401 }; 402 403 Dt_op_size_1::Dt_op_size_1(DataType dt) { 404 switch (dt.GetValue()) { 405 case I8: 406 SetEncodingValue(0x0); 407 break; 408 case I16: 409 SetEncodingValue(0x1); 410 break; 411 case I32: 412 SetEncodingValue(0x2); 413 break; 414 case P8: 415 SetEncodingValue(0x4); 416 break; 417 default: 418 break; 419 } 420 } 421 422 class Dt_op_size_2 : public EncodingValue { 423 public: 424 explicit Dt_op_size_2(DataType dt); 425 }; 426 427 Dt_op_size_2::Dt_op_size_2(DataType dt) { 428 switch (dt.GetValue()) { 429 case S8: 430 SetEncodingValue(0x0); 431 break; 432 case S16: 433 SetEncodingValue(0x1); 434 break; 435 case S32: 436 SetEncodingValue(0x2); 437 break; 438 case U8: 439 SetEncodingValue(0x4); 440 break; 441 case U16: 442 SetEncodingValue(0x5); 443 break; 444 case U32: 445 SetEncodingValue(0x6); 446 break; 447 default: 448 break; 449 } 450 } 451 452 class Dt_op_size_3 : public EncodingValue { 453 public: 454 explicit Dt_op_size_3(DataType dt); 455 }; 456 457 Dt_op_size_3::Dt_op_size_3(DataType dt) { 458 switch (dt.GetValue()) { 459 case S16: 460 SetEncodingValue(0x0); 461 break; 462 case S32: 463 SetEncodingValue(0x1); 464 break; 465 case S64: 466 SetEncodingValue(0x2); 467 break; 468 case U16: 469 SetEncodingValue(0x4); 470 break; 471 case U32: 472 SetEncodingValue(0x5); 473 break; 474 case U64: 475 SetEncodingValue(0x6); 476 break; 477 default: 478 break; 479 } 480 } 481 482 class Dt_U_imm3H_1 : public EncodingValue { 483 public: 484 explicit Dt_U_imm3H_1(DataType dt); 485 }; 486 487 Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) { 488 switch (dt.GetValue()) { 489 case S8: 490 SetEncodingValue(0x1); 491 break; 492 case S16: 493 SetEncodingValue(0x2); 494 break; 495 case S32: 496 SetEncodingValue(0x4); 497 break; 498 case U8: 499 SetEncodingValue(0x9); 500 break; 501 case U16: 502 SetEncodingValue(0xa); 503 break; 504 case U32: 505 SetEncodingValue(0xc); 506 break; 507 default: 508 break; 509 } 510 } 511 512 class Dt_U_opc1_opc2_1 : public EncodingValue { 513 public: 514 explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane); 515 }; 516 517 Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) { 518 switch (dt.GetValue()) { 519 case S8: 520 if ((lane.GetLane() & 7) != lane.GetLane()) { 521 return; 522 } 523 SetEncodingValue(0x8 | lane.GetLane()); 524 break; 525 case S16: 526 if ((lane.GetLane() & 3) != lane.GetLane()) { 527 return; 528 } 529 SetEncodingValue(0x1 | (lane.GetLane() << 1)); 530 break; 531 case U8: 532 if ((lane.GetLane() & 7) != lane.GetLane()) { 533 return; 534 } 535 SetEncodingValue(0x18 | lane.GetLane()); 536 break; 537 case U16: 538 if ((lane.GetLane() & 3) != lane.GetLane()) { 539 return; 540 } 541 SetEncodingValue(0x11 | (lane.GetLane() << 1)); 542 break; 543 case Untyped32: 544 if ((lane.GetLane() & 1) != lane.GetLane()) { 545 return; 546 } 547 SetEncodingValue(0x0 | (lane.GetLane() << 2)); 548 break; 549 case kDataTypeValueNone: 550 if ((lane.GetLane() & 1) != lane.GetLane()) { 551 return; 552 } 553 SetEncodingValue(0x0 | (lane.GetLane() << 2)); 554 break; 555 default: 556 break; 557 } 558 } 559 560 class Dt_opc1_opc2_1 : public EncodingValue { 561 public: 562 explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane); 563 }; 564 565 Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) { 566 switch (dt.GetValue()) { 567 case Untyped8: 568 if ((lane.GetLane() & 7) != lane.GetLane()) { 569 return; 570 } 571 SetEncodingValue(0x8 | lane.GetLane()); 572 break; 573 case Untyped16: 574 if ((lane.GetLane() & 3) != lane.GetLane()) { 575 return; 576 } 577 SetEncodingValue(0x1 | (lane.GetLane() << 1)); 578 break; 579 case Untyped32: 580 if ((lane.GetLane() & 1) != lane.GetLane()) { 581 return; 582 } 583 SetEncodingValue(0x0 | (lane.GetLane() << 2)); 584 break; 585 case kDataTypeValueNone: 586 if ((lane.GetLane() & 1) != lane.GetLane()) { 587 return; 588 } 589 SetEncodingValue(0x0 | (lane.GetLane() << 2)); 590 break; 591 default: 592 break; 593 } 594 } 595 596 class Dt_imm4_1 : public EncodingValue { 597 public: 598 explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane); 599 }; 600 601 Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) { 602 switch (dt.GetValue()) { 603 case Untyped8: 604 if ((lane.GetLane() & 7) != lane.GetLane()) { 605 return; 606 } 607 SetEncodingValue(0x1 | (lane.GetLane() << 1)); 608 break; 609 case Untyped16: 610 if ((lane.GetLane() & 3) != lane.GetLane()) { 611 return; 612 } 613 SetEncodingValue(0x2 | (lane.GetLane() << 2)); 614 break; 615 case Untyped32: 616 if ((lane.GetLane() & 1) != lane.GetLane()) { 617 return; 618 } 619 SetEncodingValue(0x4 | (lane.GetLane() << 3)); 620 break; 621 default: 622 break; 623 } 624 } 625 626 class Dt_B_E_1 : public EncodingValue { 627 public: 628 explicit Dt_B_E_1(DataType dt); 629 }; 630 631 Dt_B_E_1::Dt_B_E_1(DataType dt) { 632 switch (dt.GetValue()) { 633 case Untyped8: 634 SetEncodingValue(0x2); 635 break; 636 case Untyped16: 637 SetEncodingValue(0x1); 638 break; 639 case Untyped32: 640 SetEncodingValue(0x0); 641 break; 642 default: 643 break; 644 } 645 } 646 647 class Dt_op_1 : public EncodingValue { 648 public: 649 Dt_op_1(DataType dt1, DataType dt2); 650 }; 651 652 Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) { 653 if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) { 654 SetEncodingValue(0x0); 655 return; 656 } 657 if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) { 658 SetEncodingValue(0x1); 659 return; 660 } 661 if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) { 662 SetEncodingValue(0x2); 663 return; 664 } 665 if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) { 666 SetEncodingValue(0x3); 667 return; 668 } 669 } 670 671 class Dt_op_2 : public EncodingValue { 672 public: 673 explicit Dt_op_2(DataType dt); 674 }; 675 676 Dt_op_2::Dt_op_2(DataType dt) { 677 switch (dt.GetValue()) { 678 case U32: 679 SetEncodingValue(0x0); 680 break; 681 case S32: 682 SetEncodingValue(0x1); 683 break; 684 default: 685 break; 686 } 687 } 688 689 class Dt_op_3 : public EncodingValue { 690 public: 691 explicit Dt_op_3(DataType dt); 692 }; 693 694 Dt_op_3::Dt_op_3(DataType dt) { 695 switch (dt.GetValue()) { 696 case S32: 697 SetEncodingValue(0x0); 698 break; 699 case U32: 700 SetEncodingValue(0x1); 701 break; 702 default: 703 break; 704 } 705 } 706 707 class Dt_U_sx_1 : public EncodingValue { 708 public: 709 explicit Dt_U_sx_1(DataType dt); 710 }; 711 712 Dt_U_sx_1::Dt_U_sx_1(DataType dt) { 713 switch (dt.GetValue()) { 714 case S16: 715 SetEncodingValue(0x0); 716 break; 717 case S32: 718 SetEncodingValue(0x1); 719 break; 720 case U16: 721 SetEncodingValue(0x2); 722 break; 723 case U32: 724 SetEncodingValue(0x3); 725 break; 726 default: 727 break; 728 } 729 } 730 731 class Dt_op_U_1 : public EncodingValue { 732 public: 733 Dt_op_U_1(DataType dt1, DataType dt2); 734 }; 735 736 Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) { 737 if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) { 738 SetEncodingValue(0x0); 739 return; 740 } 741 if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) { 742 SetEncodingValue(0x1); 743 return; 744 } 745 if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) { 746 SetEncodingValue(0x2); 747 return; 748 } 749 if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) { 750 SetEncodingValue(0x3); 751 return; 752 } 753 } 754 755 class Dt_sz_1 : public EncodingValue { 756 public: 757 explicit Dt_sz_1(DataType dt); 758 }; 759 760 Dt_sz_1::Dt_sz_1(DataType dt) { 761 switch (dt.GetValue()) { 762 case F32: 763 SetEncodingValue(0x0); 764 break; 765 default: 766 break; 767 } 768 } 769 770 class Dt_F_size_1 : public EncodingValue { 771 public: 772 explicit Dt_F_size_1(DataType dt); 773 }; 774 775 Dt_F_size_1::Dt_F_size_1(DataType dt) { 776 switch (dt.GetValue()) { 777 case S8: 778 SetEncodingValue(0x0); 779 break; 780 case S16: 781 SetEncodingValue(0x1); 782 break; 783 case S32: 784 SetEncodingValue(0x2); 785 break; 786 case F32: 787 SetEncodingValue(0x6); 788 break; 789 default: 790 break; 791 } 792 } 793 794 class Dt_F_size_2 : public EncodingValue { 795 public: 796 explicit Dt_F_size_2(DataType dt); 797 }; 798 799 Dt_F_size_2::Dt_F_size_2(DataType dt) { 800 switch (dt.GetValue()) { 801 case I8: 802 SetEncodingValue(0x0); 803 break; 804 case I16: 805 SetEncodingValue(0x1); 806 break; 807 case I32: 808 SetEncodingValue(0x2); 809 break; 810 case F32: 811 SetEncodingValue(0x6); 812 break; 813 default: 814 break; 815 } 816 } 817 818 class Dt_F_size_3 : public EncodingValue { 819 public: 820 explicit Dt_F_size_3(DataType dt); 821 }; 822 823 Dt_F_size_3::Dt_F_size_3(DataType dt) { 824 switch (dt.GetValue()) { 825 case I16: 826 SetEncodingValue(0x1); 827 break; 828 case I32: 829 SetEncodingValue(0x2); 830 break; 831 case F32: 832 SetEncodingValue(0x6); 833 break; 834 default: 835 break; 836 } 837 } 838 839 class Dt_F_size_4 : public EncodingValue { 840 public: 841 explicit Dt_F_size_4(DataType dt); 842 }; 843 844 Dt_F_size_4::Dt_F_size_4(DataType dt) { 845 switch (dt.GetValue()) { 846 case U32: 847 SetEncodingValue(0x2); 848 break; 849 case F32: 850 SetEncodingValue(0x6); 851 break; 852 default: 853 break; 854 } 855 } 856 857 class Dt_U_size_1 : public EncodingValue { 858 public: 859 explicit Dt_U_size_1(DataType dt); 860 }; 861 862 Dt_U_size_1::Dt_U_size_1(DataType dt) { 863 switch (dt.GetValue()) { 864 case S8: 865 SetEncodingValue(0x0); 866 break; 867 case S16: 868 SetEncodingValue(0x1); 869 break; 870 case S32: 871 SetEncodingValue(0x2); 872 break; 873 case U8: 874 SetEncodingValue(0x4); 875 break; 876 case U16: 877 SetEncodingValue(0x5); 878 break; 879 case U32: 880 SetEncodingValue(0x6); 881 break; 882 default: 883 break; 884 } 885 } 886 887 class Dt_U_size_2 : public EncodingValue { 888 public: 889 explicit Dt_U_size_2(DataType dt); 890 }; 891 892 Dt_U_size_2::Dt_U_size_2(DataType dt) { 893 switch (dt.GetValue()) { 894 case S16: 895 SetEncodingValue(0x1); 896 break; 897 case S32: 898 SetEncodingValue(0x2); 899 break; 900 case U16: 901 SetEncodingValue(0x5); 902 break; 903 case U32: 904 SetEncodingValue(0x6); 905 break; 906 default: 907 break; 908 } 909 } 910 911 class Dt_U_size_3 : public EncodingValue { 912 public: 913 explicit Dt_U_size_3(DataType dt); 914 }; 915 916 Dt_U_size_3::Dt_U_size_3(DataType dt) { 917 switch (dt.GetValue()) { 918 case S8: 919 SetEncodingValue(0x0); 920 break; 921 case S16: 922 SetEncodingValue(0x1); 923 break; 924 case S32: 925 SetEncodingValue(0x2); 926 break; 927 case S64: 928 SetEncodingValue(0x3); 929 break; 930 case U8: 931 SetEncodingValue(0x4); 932 break; 933 case U16: 934 SetEncodingValue(0x5); 935 break; 936 case U32: 937 SetEncodingValue(0x6); 938 break; 939 case U64: 940 SetEncodingValue(0x7); 941 break; 942 default: 943 break; 944 } 945 } 946 947 class Dt_size_1 : public EncodingValue { 948 public: 949 explicit Dt_size_1(DataType dt); 950 }; 951 952 Dt_size_1::Dt_size_1(DataType dt) { 953 switch (dt.GetValue()) { 954 case Untyped8: 955 SetEncodingValue(0x0); 956 break; 957 default: 958 break; 959 } 960 } 961 962 class Dt_size_2 : public EncodingValue { 963 public: 964 explicit Dt_size_2(DataType dt); 965 }; 966 967 Dt_size_2::Dt_size_2(DataType dt) { 968 switch (dt.GetValue()) { 969 case I8: 970 SetEncodingValue(0x0); 971 break; 972 case I16: 973 SetEncodingValue(0x1); 974 break; 975 case I32: 976 SetEncodingValue(0x2); 977 break; 978 case I64: 979 SetEncodingValue(0x3); 980 break; 981 default: 982 break; 983 } 984 } 985 986 class Dt_size_3 : public EncodingValue { 987 public: 988 explicit Dt_size_3(DataType dt); 989 }; 990 991 Dt_size_3::Dt_size_3(DataType dt) { 992 switch (dt.GetValue()) { 993 case I16: 994 SetEncodingValue(0x0); 995 break; 996 case I32: 997 SetEncodingValue(0x1); 998 break; 999 case I64: 1000 SetEncodingValue(0x2); 1001 break; 1002 default: 1003 break; 1004 } 1005 } 1006 1007 class Dt_size_4 : public EncodingValue { 1008 public: 1009 explicit Dt_size_4(DataType dt); 1010 }; 1011 1012 Dt_size_4::Dt_size_4(DataType dt) { 1013 switch (dt.GetValue()) { 1014 case I8: 1015 SetEncodingValue(0x0); 1016 break; 1017 case I16: 1018 SetEncodingValue(0x1); 1019 break; 1020 case I32: 1021 SetEncodingValue(0x2); 1022 break; 1023 default: 1024 break; 1025 } 1026 } 1027 1028 class Dt_size_5 : public EncodingValue { 1029 public: 1030 explicit Dt_size_5(DataType dt); 1031 }; 1032 1033 Dt_size_5::Dt_size_5(DataType dt) { 1034 switch (dt.GetValue()) { 1035 case S8: 1036 SetEncodingValue(0x0); 1037 break; 1038 case S16: 1039 SetEncodingValue(0x1); 1040 break; 1041 case S32: 1042 SetEncodingValue(0x2); 1043 break; 1044 default: 1045 break; 1046 } 1047 } 1048 1049 class Dt_size_6 : public EncodingValue { 1050 public: 1051 explicit Dt_size_6(DataType dt); 1052 }; 1053 1054 Dt_size_6::Dt_size_6(DataType dt) { 1055 switch (dt.GetValue()) { 1056 case Untyped8: 1057 SetEncodingValue(0x0); 1058 break; 1059 case Untyped16: 1060 SetEncodingValue(0x1); 1061 break; 1062 case Untyped32: 1063 SetEncodingValue(0x2); 1064 break; 1065 case Untyped64: 1066 SetEncodingValue(0x3); 1067 break; 1068 default: 1069 break; 1070 } 1071 } 1072 1073 class Dt_size_7 : public EncodingValue { 1074 public: 1075 explicit Dt_size_7(DataType dt); 1076 }; 1077 1078 Dt_size_7::Dt_size_7(DataType dt) { 1079 switch (dt.GetValue()) { 1080 case Untyped8: 1081 SetEncodingValue(0x0); 1082 break; 1083 case Untyped16: 1084 SetEncodingValue(0x1); 1085 break; 1086 case Untyped32: 1087 SetEncodingValue(0x2); 1088 break; 1089 default: 1090 break; 1091 } 1092 } 1093 1094 class Dt_size_8 : public EncodingValue { 1095 public: 1096 Dt_size_8(DataType dt, Alignment align); 1097 }; 1098 1099 Dt_size_8::Dt_size_8(DataType dt, Alignment align) { 1100 switch (dt.GetValue()) { 1101 case Untyped8: 1102 SetEncodingValue(0x0); 1103 break; 1104 case Untyped16: 1105 SetEncodingValue(0x1); 1106 break; 1107 case Untyped32: 1108 if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) { 1109 SetEncodingValue(0x2); 1110 } else if (align.Is(k128BitAlign)) { 1111 SetEncodingValue(0x3); 1112 } 1113 break; 1114 default: 1115 break; 1116 } 1117 } 1118 1119 class Dt_size_9 : public EncodingValue { 1120 uint32_t type_; 1121 1122 public: 1123 explicit Dt_size_9(DataType dt); 1124 uint32_t GetTypeEncodingValue() const { return type_; } 1125 }; 1126 1127 Dt_size_9::Dt_size_9(DataType dt) { 1128 switch (dt.GetValue()) { 1129 case I16: 1130 type_ = 0x0; 1131 SetEncodingValue(0x1); 1132 break; 1133 case I32: 1134 type_ = 0x0; 1135 SetEncodingValue(0x2); 1136 break; 1137 case F32: 1138 type_ = 0x1; 1139 SetEncodingValue(0x2); 1140 break; 1141 default: 1142 VIXL_UNREACHABLE(); 1143 type_ = 0x0; 1144 break; 1145 } 1146 } 1147 1148 class Dt_size_10 : public EncodingValue { 1149 public: 1150 explicit Dt_size_10(DataType dt); 1151 }; 1152 1153 Dt_size_10::Dt_size_10(DataType dt) { 1154 switch (dt.GetValue()) { 1155 case S8: 1156 case U8: 1157 case I8: 1158 SetEncodingValue(0x0); 1159 break; 1160 case S16: 1161 case U16: 1162 case I16: 1163 SetEncodingValue(0x1); 1164 break; 1165 case S32: 1166 case U32: 1167 case I32: 1168 SetEncodingValue(0x2); 1169 break; 1170 default: 1171 break; 1172 } 1173 } 1174 1175 class Dt_size_11 : public EncodingValue { 1176 uint32_t type_; 1177 1178 public: 1179 explicit Dt_size_11(DataType dt); 1180 uint32_t GetTypeEncodingValue() const { return type_; } 1181 }; 1182 1183 Dt_size_11::Dt_size_11(DataType dt) { 1184 switch (dt.GetValue()) { 1185 case S16: 1186 type_ = 0x0; 1187 SetEncodingValue(0x1); 1188 break; 1189 case U16: 1190 type_ = 0x1; 1191 SetEncodingValue(0x1); 1192 break; 1193 case S32: 1194 type_ = 0x0; 1195 SetEncodingValue(0x2); 1196 break; 1197 case U32: 1198 type_ = 0x1; 1199 SetEncodingValue(0x2); 1200 break; 1201 default: 1202 VIXL_UNREACHABLE(); 1203 type_ = 0x0; 1204 break; 1205 } 1206 } 1207 1208 class Dt_size_12 : public EncodingValue { 1209 uint32_t type_; 1210 1211 public: 1212 explicit Dt_size_12(DataType dt); 1213 uint32_t GetTypeEncodingValue() const { return type_; } 1214 }; 1215 1216 Dt_size_12::Dt_size_12(DataType dt) { 1217 switch (dt.GetValue()) { 1218 case S8: 1219 type_ = 0x0; 1220 SetEncodingValue(0x0); 1221 break; 1222 case U8: 1223 type_ = 0x1; 1224 SetEncodingValue(0x0); 1225 break; 1226 case S16: 1227 type_ = 0x0; 1228 SetEncodingValue(0x1); 1229 break; 1230 case U16: 1231 type_ = 0x1; 1232 SetEncodingValue(0x1); 1233 break; 1234 case S32: 1235 type_ = 0x0; 1236 SetEncodingValue(0x2); 1237 break; 1238 case U32: 1239 type_ = 0x1; 1240 SetEncodingValue(0x2); 1241 break; 1242 default: 1243 VIXL_UNREACHABLE(); 1244 type_ = 0x0; 1245 break; 1246 } 1247 } 1248 1249 class Dt_size_13 : public EncodingValue { 1250 public: 1251 explicit Dt_size_13(DataType dt); 1252 }; 1253 1254 Dt_size_13::Dt_size_13(DataType dt) { 1255 switch (dt.GetValue()) { 1256 case S16: 1257 SetEncodingValue(0x1); 1258 break; 1259 case S32: 1260 SetEncodingValue(0x2); 1261 break; 1262 default: 1263 break; 1264 } 1265 } 1266 1267 class Dt_size_14 : public EncodingValue { 1268 public: 1269 explicit Dt_size_14(DataType dt); 1270 }; 1271 1272 Dt_size_14::Dt_size_14(DataType dt) { 1273 switch (dt.GetValue()) { 1274 case S16: 1275 SetEncodingValue(0x0); 1276 break; 1277 case S32: 1278 SetEncodingValue(0x1); 1279 break; 1280 case S64: 1281 SetEncodingValue(0x2); 1282 break; 1283 default: 1284 break; 1285 } 1286 } 1287 1288 class Dt_size_15 : public EncodingValue { 1289 public: 1290 explicit Dt_size_15(DataType dt); 1291 }; 1292 1293 Dt_size_15::Dt_size_15(DataType dt) { 1294 switch (dt.GetValue()) { 1295 case Untyped8: 1296 SetEncodingValue(0x0); 1297 break; 1298 case Untyped16: 1299 SetEncodingValue(0x1); 1300 break; 1301 default: 1302 break; 1303 } 1304 } 1305 1306 class Dt_size_16 : public EncodingValue { 1307 public: 1308 explicit Dt_size_16(DataType dt); 1309 }; 1310 1311 Dt_size_16::Dt_size_16(DataType dt) { 1312 switch (dt.GetValue()) { 1313 case F32: 1314 SetEncodingValue(0x2); 1315 break; 1316 default: 1317 break; 1318 } 1319 } 1320 1321 class Dt_size_17 : public EncodingValue { 1322 public: 1323 explicit Dt_size_17(DataType dt); 1324 }; 1325 1326 Dt_size_17::Dt_size_17(DataType dt) { 1327 switch (dt.GetValue()) { 1328 case I8: 1329 SetEncodingValue(0x0); 1330 break; 1331 case I16: 1332 SetEncodingValue(0x1); 1333 break; 1334 case I32: 1335 SetEncodingValue(0x2); 1336 break; 1337 default: 1338 break; 1339 } 1340 } 1341 1342 class Index_1 : public EncodingValue { 1343 public: 1344 Index_1(const NeonRegisterList& nreglist, DataType dt); 1345 }; 1346 1347 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) { 1348 switch (dt.GetValue()) { 1349 case Untyped8: { 1350 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1351 return; 1352 } 1353 uint32_t value = nreglist.GetTransferLane() << 1; 1354 if (!nreglist.IsSingleSpaced()) return; 1355 SetEncodingValue(value); 1356 break; 1357 } 1358 case Untyped16: { 1359 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1360 return; 1361 } 1362 uint32_t value = nreglist.GetTransferLane() << 2; 1363 if (nreglist.IsDoubleSpaced()) value |= 2; 1364 SetEncodingValue(value); 1365 break; 1366 } 1367 case Untyped32: { 1368 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1369 return; 1370 } 1371 uint32_t value = nreglist.GetTransferLane() << 3; 1372 if (nreglist.IsDoubleSpaced()) value |= 4; 1373 SetEncodingValue(value); 1374 break; 1375 } 1376 default: 1377 break; 1378 } 1379 } 1380 1381 class Align_index_align_1 : public EncodingValue { 1382 public: 1383 Align_index_align_1(Alignment align, 1384 const NeonRegisterList& nreglist, 1385 DataType dt); 1386 }; 1387 1388 Align_index_align_1::Align_index_align_1(Alignment align, 1389 const NeonRegisterList& nreglist, 1390 DataType dt) { 1391 switch (dt.GetValue()) { 1392 case Untyped8: { 1393 uint32_t value; 1394 if (align.GetType() == kNoAlignment) { 1395 value = 0; 1396 } else { 1397 return; 1398 } 1399 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1400 return; 1401 } 1402 value |= nreglist.GetTransferLane() << 1; 1403 SetEncodingValue(value); 1404 break; 1405 } 1406 case Untyped16: { 1407 uint32_t value; 1408 if (align.GetType() == k16BitAlign) { 1409 value = 1; 1410 } else if (align.GetType() == kNoAlignment) { 1411 value = 0; 1412 } else { 1413 return; 1414 } 1415 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1416 return; 1417 } 1418 value |= nreglist.GetTransferLane() << 2; 1419 SetEncodingValue(value); 1420 break; 1421 } 1422 case Untyped32: { 1423 uint32_t value; 1424 if (align.GetType() == k32BitAlign) { 1425 value = 3; 1426 } else if (align.GetType() == kNoAlignment) { 1427 value = 0; 1428 } else { 1429 return; 1430 } 1431 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1432 return; 1433 } 1434 value |= nreglist.GetTransferLane() << 3; 1435 SetEncodingValue(value); 1436 break; 1437 } 1438 default: 1439 break; 1440 } 1441 } 1442 1443 class Align_index_align_2 : public EncodingValue { 1444 public: 1445 Align_index_align_2(Alignment align, 1446 const NeonRegisterList& nreglist, 1447 DataType dt); 1448 }; 1449 1450 Align_index_align_2::Align_index_align_2(Alignment align, 1451 const NeonRegisterList& nreglist, 1452 DataType dt) { 1453 switch (dt.GetValue()) { 1454 case Untyped8: { 1455 uint32_t value; 1456 if (align.GetType() == k16BitAlign) { 1457 value = 1; 1458 } else if (align.GetType() == kNoAlignment) { 1459 value = 0; 1460 } else { 1461 return; 1462 } 1463 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1464 return; 1465 } 1466 value |= nreglist.GetTransferLane() << 1; 1467 if (!nreglist.IsSingleSpaced()) return; 1468 SetEncodingValue(value); 1469 break; 1470 } 1471 case Untyped16: { 1472 uint32_t value; 1473 if (align.GetType() == k32BitAlign) { 1474 value = 1; 1475 } else if (align.GetType() == kNoAlignment) { 1476 value = 0; 1477 } else { 1478 return; 1479 } 1480 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1481 return; 1482 } 1483 value |= nreglist.GetTransferLane() << 2; 1484 if (nreglist.IsDoubleSpaced()) value |= 2; 1485 SetEncodingValue(value); 1486 break; 1487 } 1488 case Untyped32: { 1489 uint32_t value; 1490 if (align.GetType() == k64BitAlign) { 1491 value = 1; 1492 } else if (align.GetType() == kNoAlignment) { 1493 value = 0; 1494 } else { 1495 return; 1496 } 1497 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1498 return; 1499 } 1500 value |= nreglist.GetTransferLane() << 3; 1501 if (nreglist.IsDoubleSpaced()) value |= 4; 1502 SetEncodingValue(value); 1503 break; 1504 } 1505 default: 1506 break; 1507 } 1508 } 1509 1510 class Align_index_align_3 : public EncodingValue { 1511 public: 1512 Align_index_align_3(Alignment align, 1513 const NeonRegisterList& nreglist, 1514 DataType dt); 1515 }; 1516 1517 Align_index_align_3::Align_index_align_3(Alignment align, 1518 const NeonRegisterList& nreglist, 1519 DataType dt) { 1520 switch (dt.GetValue()) { 1521 case Untyped8: { 1522 uint32_t value; 1523 if (align.GetType() == k32BitAlign) { 1524 value = 1; 1525 } else if (align.GetType() == kNoAlignment) { 1526 value = 0; 1527 } else { 1528 return; 1529 } 1530 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1531 return; 1532 } 1533 value |= nreglist.GetTransferLane() << 1; 1534 if (!nreglist.IsSingleSpaced()) return; 1535 SetEncodingValue(value); 1536 break; 1537 } 1538 case Untyped16: { 1539 uint32_t value; 1540 if (align.GetType() == k64BitAlign) { 1541 value = 1; 1542 } else if (align.GetType() == kNoAlignment) { 1543 value = 0; 1544 } else { 1545 return; 1546 } 1547 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1548 return; 1549 } 1550 value |= nreglist.GetTransferLane() << 2; 1551 if (nreglist.IsDoubleSpaced()) value |= 2; 1552 SetEncodingValue(value); 1553 break; 1554 } 1555 case Untyped32: { 1556 uint32_t value; 1557 if (align.GetType() == k64BitAlign) { 1558 value = 1; 1559 } else if (align.GetType() == k128BitAlign) { 1560 value = 2; 1561 } else if (align.GetType() == kNoAlignment) { 1562 value = 0; 1563 } else { 1564 return; 1565 } 1566 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1567 return; 1568 } 1569 value |= nreglist.GetTransferLane() << 3; 1570 if (nreglist.IsDoubleSpaced()) value |= 4; 1571 SetEncodingValue(value); 1572 break; 1573 } 1574 default: 1575 break; 1576 } 1577 } 1578 1579 class Align_a_1 : public EncodingValue { 1580 public: 1581 Align_a_1(Alignment align, DataType dt); 1582 }; 1583 1584 Align_a_1::Align_a_1(Alignment align, DataType dt) { 1585 switch (align.GetType()) { 1586 case k16BitAlign: 1587 if (dt.Is(Untyped16)) SetEncodingValue(0x1); 1588 break; 1589 case k32BitAlign: 1590 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1591 break; 1592 case kNoAlignment: 1593 SetEncodingValue(0x0); 1594 break; 1595 default: 1596 break; 1597 } 1598 } 1599 1600 class Align_a_2 : public EncodingValue { 1601 public: 1602 Align_a_2(Alignment align, DataType dt); 1603 }; 1604 1605 Align_a_2::Align_a_2(Alignment align, DataType dt) { 1606 switch (align.GetType()) { 1607 case k16BitAlign: 1608 if (dt.Is(Untyped8)) SetEncodingValue(0x1); 1609 break; 1610 case k32BitAlign: 1611 if (dt.Is(Untyped16)) SetEncodingValue(0x1); 1612 break; 1613 case k64BitAlign: 1614 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1615 break; 1616 case kNoAlignment: 1617 SetEncodingValue(0x0); 1618 break; 1619 default: 1620 break; 1621 } 1622 } 1623 1624 class Align_a_3 : public EncodingValue { 1625 public: 1626 Align_a_3(Alignment align, DataType dt); 1627 }; 1628 1629 Align_a_3::Align_a_3(Alignment align, DataType dt) { 1630 switch (align.GetType()) { 1631 case k32BitAlign: 1632 if (dt.Is(Untyped8)) SetEncodingValue(0x1); 1633 break; 1634 case k64BitAlign: 1635 if (dt.Is(Untyped16)) 1636 SetEncodingValue(0x1); 1637 else if (dt.Is(Untyped32)) 1638 SetEncodingValue(0x1); 1639 break; 1640 case k128BitAlign: 1641 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1642 break; 1643 case kNoAlignment: 1644 SetEncodingValue(0x0); 1645 break; 1646 default: 1647 break; 1648 } 1649 } 1650 1651 class Align_align_1 : public EncodingValue { 1652 public: 1653 Align_align_1(Alignment align, const NeonRegisterList& nreglist); 1654 }; 1655 1656 Align_align_1::Align_align_1(Alignment align, 1657 const NeonRegisterList& nreglist) { 1658 switch (align.GetType()) { 1659 case k64BitAlign: 1660 SetEncodingValue(0x1); 1661 break; 1662 case k128BitAlign: 1663 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1664 SetEncodingValue(0x2); 1665 break; 1666 case k256BitAlign: 1667 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1668 SetEncodingValue(0x3); 1669 break; 1670 case kNoAlignment: 1671 SetEncodingValue(0x0); 1672 break; 1673 default: 1674 break; 1675 } 1676 } 1677 1678 class Align_align_2 : public EncodingValue { 1679 public: 1680 Align_align_2(Alignment align, const NeonRegisterList& nreglist); 1681 }; 1682 1683 Align_align_2::Align_align_2(Alignment align, 1684 const NeonRegisterList& nreglist) { 1685 switch (align.GetType()) { 1686 case k64BitAlign: 1687 SetEncodingValue(0x1); 1688 break; 1689 case k128BitAlign: 1690 SetEncodingValue(0x2); 1691 break; 1692 case k256BitAlign: 1693 if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3); 1694 break; 1695 case kNoAlignment: 1696 SetEncodingValue(0x0); 1697 break; 1698 default: 1699 break; 1700 } 1701 } 1702 1703 class Align_align_3 : public EncodingValue { 1704 public: 1705 explicit Align_align_3(Alignment align); 1706 }; 1707 1708 Align_align_3::Align_align_3(Alignment align) { 1709 switch (align.GetType()) { 1710 case k64BitAlign: 1711 SetEncodingValue(0x1); 1712 break; 1713 case kNoAlignment: 1714 SetEncodingValue(0x0); 1715 break; 1716 default: 1717 break; 1718 } 1719 } 1720 1721 class Align_align_4 : public EncodingValue { 1722 public: 1723 explicit Align_align_4(Alignment align); 1724 }; 1725 1726 Align_align_4::Align_align_4(Alignment align) { 1727 switch (align.GetType()) { 1728 case k64BitAlign: 1729 SetEncodingValue(0x1); 1730 break; 1731 case k128BitAlign: 1732 SetEncodingValue(0x2); 1733 break; 1734 case k256BitAlign: 1735 SetEncodingValue(0x3); 1736 break; 1737 case kNoAlignment: 1738 SetEncodingValue(0x0); 1739 break; 1740 default: 1741 break; 1742 } 1743 } 1744 1745 class Align_align_5 : public EncodingValue { 1746 public: 1747 Align_align_5(Alignment align, const NeonRegisterList& nreglist); 1748 }; 1749 1750 Align_align_5::Align_align_5(Alignment align, 1751 const NeonRegisterList& nreglist) { 1752 switch (align.GetType()) { 1753 case k64BitAlign: 1754 SetEncodingValue(0x1); 1755 break; 1756 case k128BitAlign: 1757 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1758 SetEncodingValue(0x2); 1759 break; 1760 case k256BitAlign: 1761 if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3); 1762 break; 1763 case kNoAlignment: 1764 SetEncodingValue(0x0); 1765 break; 1766 default: 1767 break; 1768 } 1769 } 1770 1771 1772 // CBNZ{<q>} <Rn>, <label> ; T1 1773 // CBZ{<q>} <Rn>, <label> ; T1 1774 static const struct ReferenceInfo kT16CbzInfo = 1775 {k16BitT32InstructionSizeInBytes, 1776 0, // Min offset. 1777 126, // Max offset. 1778 2, // Alignment. 1779 ReferenceInfo::kDontAlignPc}; 1780 1781 1782 // B<c>{<q>} <label> ; T1 1783 static const struct ReferenceInfo kT16ConditionalBranchInfo = 1784 {k16BitT32InstructionSizeInBytes, 1785 -256, // Min offset. 1786 254, // Max offset. 1787 2, // Alignment. 1788 ReferenceInfo::kDontAlignPc}; 1789 1790 1791 // ADR{<c>}{<q>} <Rd>, <label> ; T1 1792 // LDR{<c>}{<q>} <Rt>, <label> ; T1 1793 static const struct ReferenceInfo kT16DataInfo = 1794 {k16BitT32InstructionSizeInBytes, 1795 0, // Min offset. 1796 1020, // Max offset. 1797 4, // Alignment. 1798 ReferenceInfo::kAlignPc}; 1799 1800 1801 // B{<c>}{<q>} <label> ; T2 1802 static const struct ReferenceInfo kT16BranchInfo = 1803 {k16BitT32InstructionSizeInBytes, 1804 -2048, // Min offset. 1805 2046, // Max offset. 1806 2, // Alignment. 1807 ReferenceInfo::kDontAlignPc}; 1808 1809 1810 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1 1811 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1 1812 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2 1813 static const struct ReferenceInfo kT32DataInfo = 1814 {k32BitT32InstructionSizeInBytes, 1815 -1020, // Min offset. 1816 1020, // Max offset. 1817 4, // Alignment. 1818 ReferenceInfo::kAlignPc}; 1819 1820 1821 // ADR{<c>}{<q>} <Rd>, <label> ; T3 1822 // LDR{<c>}{<q>} <Rt>, <label> ; T2 1823 // LDRB{<c>}{<q>} <Rt>, <label> ; T1 1824 // LDRH{<c>}{<q>} <Rt>, <label> ; T1 1825 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1 1826 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1 1827 // PLD{<c>}{<q>} <label> ; T1 1828 // PLI{<c>}{<q>} <label> ; T3 1829 static const struct ReferenceInfo kT32FarDataInfo = 1830 {k32BitT32InstructionSizeInBytes, 1831 -4095, // Min offset. 1832 4095, // Max offset. 1833 1, // Alignment. 1834 ReferenceInfo::kAlignPc}; 1835 1836 1837 // B<c>{<q>} <label> ; T3 1838 static const struct ReferenceInfo kT32ConditionalBranchInfo = 1839 {k32BitT32InstructionSizeInBytes, 1840 -1048576, // Min offset. 1841 1048574, // Max offset. 1842 2, // Alignment. 1843 ReferenceInfo::kDontAlignPc}; 1844 1845 1846 // B{<c>}{<q>} <label> ; T4 1847 // BL{<c>}{<q>} <label> ; T1 1848 static const struct ReferenceInfo kT32BranchInfo = 1849 {k32BitT32InstructionSizeInBytes, 1850 -16777216, // Min offset. 1851 16777214, // Max offset. 1852 2, // Alignment. 1853 ReferenceInfo::kDontAlignPc}; 1854 1855 1856 // BLX{<c>}{<q>} <label> ; T2 1857 static const struct ReferenceInfo kT32BlxInfo = 1858 {k32BitT32InstructionSizeInBytes, 1859 -16777216, // Min offset. 1860 16777212, // Max offset. 1861 4, // Alignment. 1862 ReferenceInfo::kAlignPc}; 1863 1864 1865 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1 1866 // LDRH{<c>}{<q>} <Rt>, <label> ; A1 1867 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1 1868 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1 1869 static const struct ReferenceInfo kA32VeryNearDataInfo = 1870 {kA32InstructionSizeInBytes, 1871 -255, // Min offset. 1872 255, // Max offset. 1873 1, // Alignment. 1874 ReferenceInfo::kAlignPc}; 1875 1876 1877 // ADR{<c>}{<q>} <Rd>, <label> ; A1 1878 static const struct ReferenceInfo kA32AdrInfo = {kA32InstructionSizeInBytes, 1879 -256, // Min offset. 1880 256, // Max offset. 1881 1, // Alignment. 1882 ReferenceInfo::kAlignPc}; 1883 1884 1885 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1 1886 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2 1887 static const struct ReferenceInfo kA32DataInfo = {kA32InstructionSizeInBytes, 1888 -1020, // Min offset. 1889 1020, // Max offset. 1890 4, // Alignment. 1891 ReferenceInfo::kAlignPc}; 1892 1893 1894 // LDR{<c>}{<q>} <Rt>, <label> ; A1 1895 // LDRB{<c>}{<q>} <Rt>, <label> ; A1 1896 // PLD{<c>}{<q>} <label> ; A1 1897 // PLI{<c>}{<q>} <label> ; A1 1898 static const struct ReferenceInfo kA32FarDataInfo = {kA32InstructionSizeInBytes, 1899 -4095, // Min offset. 1900 4095, // Max offset. 1901 1, // Alignment. 1902 ReferenceInfo::kAlignPc}; 1903 1904 1905 // B{<c>}{<q>} <label> ; A1 1906 // BL{<c>}{<q>} <label> ; A1 1907 static const struct ReferenceInfo kA32BranchInfo = 1908 {kA32InstructionSizeInBytes, 1909 -33554432, // Min offset. 1910 33554428, // Max offset. 1911 4, // Alignment. 1912 ReferenceInfo::kDontAlignPc}; 1913 1914 1915 // BLX{<c>}{<q>} <label> ; A2 1916 static const struct ReferenceInfo kA32BlxInfo = {kA32InstructionSizeInBytes, 1917 -33554432, // Min offset. 1918 33554430, // Max offset. 1919 2, // Alignment. 1920 ReferenceInfo::kAlignPc}; 1921 1922 1923 void Assembler::adc(Condition cond, 1924 EncodingSize size, 1925 Register rd, 1926 Register rn, 1927 const Operand& operand) { 1928 VIXL_ASSERT(AllowAssembler()); 1929 CheckIT(cond); 1930 if (operand.IsImmediate()) { 1931 uint32_t imm = operand.GetImmediate(); 1932 if (IsUsingT32()) { 1933 ImmediateT32 immediate_t32(imm); 1934 // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 1935 if (!size.IsNarrow() && immediate_t32.IsValid() && 1936 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 1937 EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 1938 (immediate_t32.GetEncodingValue() & 0xff) | 1939 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 1940 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 1941 AdvanceIT(); 1942 return; 1943 } 1944 } else { 1945 ImmediateA32 immediate_a32(imm); 1946 // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 1947 if (immediate_a32.IsValid() && cond.IsNotNever()) { 1948 EmitA32(0x02a00000U | (cond.GetCondition() << 28) | 1949 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 1950 immediate_a32.GetEncodingValue()); 1951 return; 1952 } 1953 } 1954 } 1955 if (operand.IsImmediateShiftedRegister()) { 1956 Register rm = operand.GetBaseRegister(); 1957 if (operand.IsPlainRegister()) { 1958 if (IsUsingT32()) { 1959 // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 1960 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 1961 rm.IsLow()) { 1962 EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); 1963 AdvanceIT(); 1964 return; 1965 } 1966 } 1967 } 1968 Shift shift = operand.GetShift(); 1969 uint32_t amount = operand.GetShiftAmount(); 1970 if (IsUsingT32()) { 1971 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 1972 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 1973 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 1974 uint32_t amount_ = amount % 32; 1975 EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 1976 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 1977 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 1978 AdvanceIT(); 1979 return; 1980 } 1981 } else { 1982 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 1983 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 1984 uint32_t amount_ = amount % 32; 1985 EmitA32(0x00a00000U | (cond.GetCondition() << 28) | 1986 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 1987 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 1988 return; 1989 } 1990 } 1991 } 1992 if (operand.IsRegisterShiftedRegister()) { 1993 Register rm = operand.GetBaseRegister(); 1994 Shift shift = operand.GetShift(); 1995 Register rs = operand.GetShiftRegister(); 1996 if (IsUsingA32()) { 1997 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 1998 if (cond.IsNotNever() && 1999 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2000 AllowUnpredictable())) { 2001 EmitA32(0x00a00010U | (cond.GetCondition() << 28) | 2002 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2003 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2004 return; 2005 } 2006 } 2007 } 2008 Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); 2009 } 2010 2011 void Assembler::adcs(Condition cond, 2012 EncodingSize size, 2013 Register rd, 2014 Register rn, 2015 const Operand& operand) { 2016 VIXL_ASSERT(AllowAssembler()); 2017 CheckIT(cond); 2018 if (operand.IsImmediate()) { 2019 uint32_t imm = operand.GetImmediate(); 2020 if (IsUsingT32()) { 2021 ImmediateT32 immediate_t32(imm); 2022 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 2023 if (!size.IsNarrow() && immediate_t32.IsValid() && 2024 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 2025 EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2026 (immediate_t32.GetEncodingValue() & 0xff) | 2027 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2028 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2029 AdvanceIT(); 2030 return; 2031 } 2032 } else { 2033 ImmediateA32 immediate_a32(imm); 2034 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2035 if (immediate_a32.IsValid() && cond.IsNotNever()) { 2036 EmitA32(0x02b00000U | (cond.GetCondition() << 28) | 2037 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2038 immediate_a32.GetEncodingValue()); 2039 return; 2040 } 2041 } 2042 } 2043 if (operand.IsImmediateShiftedRegister()) { 2044 Register rm = operand.GetBaseRegister(); 2045 if (operand.IsPlainRegister()) { 2046 if (IsUsingT32()) { 2047 // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 2048 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2049 rm.IsLow()) { 2050 EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); 2051 AdvanceIT(); 2052 return; 2053 } 2054 } 2055 } 2056 Shift shift = operand.GetShift(); 2057 uint32_t amount = operand.GetShiftAmount(); 2058 if (IsUsingT32()) { 2059 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 2060 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 2061 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2062 uint32_t amount_ = amount % 32; 2063 EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2064 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2065 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2066 AdvanceIT(); 2067 return; 2068 } 2069 } else { 2070 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2071 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 2072 uint32_t amount_ = amount % 32; 2073 EmitA32(0x00b00000U | (cond.GetCondition() << 28) | 2074 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2075 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2076 return; 2077 } 2078 } 2079 } 2080 if (operand.IsRegisterShiftedRegister()) { 2081 Register rm = operand.GetBaseRegister(); 2082 Shift shift = operand.GetShift(); 2083 Register rs = operand.GetShiftRegister(); 2084 if (IsUsingA32()) { 2085 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2086 if (cond.IsNotNever() && 2087 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2088 AllowUnpredictable())) { 2089 EmitA32(0x00b00010U | (cond.GetCondition() << 28) | 2090 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2091 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2092 return; 2093 } 2094 } 2095 } 2096 Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); 2097 } 2098 2099 void Assembler::add(Condition cond, 2100 EncodingSize size, 2101 Register rd, 2102 Register rn, 2103 const Operand& operand) { 2104 VIXL_ASSERT(AllowAssembler()); 2105 CheckIT(cond); 2106 if (operand.IsImmediate()) { 2107 uint32_t imm = operand.GetImmediate(); 2108 if (IsUsingT32()) { 2109 ImmediateT32 immediate_t32(imm); 2110 // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1 2111 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && 2112 ((imm % 4) == 0)) { 2113 uint32_t imm_ = imm >> 2; 2114 EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); 2115 AdvanceIT(); 2116 return; 2117 } 2118 // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1 2119 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2120 (imm <= 7)) { 2121 EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 2122 AdvanceIT(); 2123 return; 2124 } 2125 // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 2126 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2127 (imm <= 255)) { 2128 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2129 AdvanceIT(); 2130 return; 2131 } 2132 // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1 2133 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && 2134 ((imm % 4) == 0)) { 2135 uint32_t imm_ = imm >> 2; 2136 EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); 2137 AdvanceIT(); 2138 return; 2139 } 2140 // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2 2141 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && 2142 ((imm % 4) == 0)) { 2143 uint32_t imm_ = imm >> 2; 2144 EmitT32_16(0xb000 | imm_); 2145 AdvanceIT(); 2146 return; 2147 } 2148 // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3 2149 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && 2150 (!rd.IsPC() || AllowUnpredictable())) { 2151 EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2152 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2153 AdvanceIT(); 2154 return; 2155 } 2156 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 2157 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 2158 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 2159 EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2160 (immediate_t32.GetEncodingValue() & 0xff) | 2161 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2162 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2163 AdvanceIT(); 2164 return; 2165 } 2166 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 2167 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 2168 (!rd.IsPC() || AllowUnpredictable())) { 2169 EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2170 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2171 AdvanceIT(); 2172 return; 2173 } 2174 // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3 2175 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 2176 (!rd.IsPC() || AllowUnpredictable())) { 2177 EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | 2178 (immediate_t32.GetEncodingValue() & 0xff) | 2179 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2180 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2181 AdvanceIT(); 2182 return; 2183 } 2184 // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4 2185 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && 2186 (!rd.IsPC() || AllowUnpredictable())) { 2187 EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2188 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2189 AdvanceIT(); 2190 return; 2191 } 2192 } else { 2193 ImmediateA32 immediate_a32(imm); 2194 // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1 2195 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { 2196 EmitA32(0x028f0000U | (cond.GetCondition() << 28) | 2197 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2198 return; 2199 } 2200 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2201 if (immediate_a32.IsValid() && cond.IsNotNever() && 2202 ((rn.GetCode() & 0xd) != 0xd)) { 2203 EmitA32(0x02800000U | (cond.GetCondition() << 28) | 2204 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2205 immediate_a32.GetEncodingValue()); 2206 return; 2207 } 2208 // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 2209 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 2210 EmitA32(0x028d0000U | (cond.GetCondition() << 28) | 2211 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2212 return; 2213 } 2214 } 2215 } 2216 if (operand.IsImmediateShiftedRegister()) { 2217 Register rm = operand.GetBaseRegister(); 2218 if (operand.IsPlainRegister()) { 2219 if (IsUsingT32()) { 2220 // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 2221 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2222 rm.IsLow()) { 2223 EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | 2224 (rm.GetCode() << 6)); 2225 AdvanceIT(); 2226 return; 2227 } 2228 // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2 2229 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && 2230 (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && 2231 (!rd.IsPC() || !rm.IsPC())) || 2232 AllowUnpredictable())) { 2233 EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | 2234 ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 2235 AdvanceIT(); 2236 return; 2237 } 2238 // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1 2239 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && 2240 ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 2241 AllowUnpredictable())) { 2242 EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | 2243 ((rd.GetCode() & 0x8) << 4)); 2244 AdvanceIT(); 2245 return; 2246 } 2247 // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2 2248 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { 2249 EmitT32_16(0x4485 | (rm.GetCode() << 3)); 2250 AdvanceIT(); 2251 return; 2252 } 2253 } 2254 } 2255 Shift shift = operand.GetShift(); 2256 uint32_t amount = operand.GetShiftAmount(); 2257 if (IsUsingT32()) { 2258 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 2259 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 2260 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2261 uint32_t amount_ = amount % 32; 2262 EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2263 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2264 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2265 AdvanceIT(); 2266 return; 2267 } 2268 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 2269 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 2270 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2271 uint32_t amount_ = amount % 32; 2272 EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | 2273 (operand.GetTypeEncodingValue() << 4) | 2274 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2275 AdvanceIT(); 2276 return; 2277 } 2278 } else { 2279 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2280 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 2281 uint32_t amount_ = amount % 32; 2282 EmitA32(0x00800000U | (cond.GetCondition() << 28) | 2283 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2284 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2285 return; 2286 } 2287 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 2288 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 2289 uint32_t amount_ = amount % 32; 2290 EmitA32(0x008d0000U | (cond.GetCondition() << 28) | 2291 (rd.GetCode() << 12) | rm.GetCode() | 2292 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2293 return; 2294 } 2295 } 2296 } 2297 if (operand.IsRegisterShiftedRegister()) { 2298 Register rm = operand.GetBaseRegister(); 2299 Shift shift = operand.GetShift(); 2300 Register rs = operand.GetShiftRegister(); 2301 if (IsUsingA32()) { 2302 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2303 if (cond.IsNotNever() && 2304 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2305 AllowUnpredictable())) { 2306 EmitA32(0x00800010U | (cond.GetCondition() << 28) | 2307 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2308 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2309 return; 2310 } 2311 } 2312 } 2313 Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); 2314 } 2315 2316 void Assembler::add(Condition cond, Register rd, const Operand& operand) { 2317 VIXL_ASSERT(AllowAssembler()); 2318 CheckIT(cond); 2319 if (operand.IsImmediate()) { 2320 uint32_t imm = operand.GetImmediate(); 2321 if (IsUsingT32()) { 2322 // ADD<c>{<q>} <Rdn>, #<imm8> ; T2 2323 if (InITBlock() && rd.IsLow() && (imm <= 255)) { 2324 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2325 AdvanceIT(); 2326 return; 2327 } 2328 } 2329 } 2330 if (operand.IsPlainRegister()) { 2331 Register rm = operand.GetBaseRegister(); 2332 if (IsUsingT32()) { 2333 // ADD<c>{<q>} <Rdn>, <Rm> ; T2 2334 if (InITBlock() && !rm.Is(sp) && 2335 (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && 2336 (!rd.IsPC() || !rm.IsPC())) || 2337 AllowUnpredictable())) { 2338 EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | 2339 (rm.GetCode() << 3)); 2340 AdvanceIT(); 2341 return; 2342 } 2343 } 2344 } 2345 Delegate(kAdd, &Assembler::add, cond, rd, operand); 2346 } 2347 2348 void Assembler::adds(Condition cond, 2349 EncodingSize size, 2350 Register rd, 2351 Register rn, 2352 const Operand& operand) { 2353 VIXL_ASSERT(AllowAssembler()); 2354 CheckIT(cond); 2355 if (operand.IsImmediate()) { 2356 uint32_t imm = operand.GetImmediate(); 2357 if (IsUsingT32()) { 2358 ImmediateT32 immediate_t32(imm); 2359 // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1 2360 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2361 (imm <= 7)) { 2362 EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 2363 AdvanceIT(); 2364 return; 2365 } 2366 // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 2367 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2368 (imm <= 255)) { 2369 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2370 AdvanceIT(); 2371 return; 2372 } 2373 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 2374 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 2375 !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { 2376 EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2377 (immediate_t32.GetEncodingValue() & 0xff) | 2378 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2379 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2380 AdvanceIT(); 2381 return; 2382 } 2383 // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3 2384 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 2385 !rd.Is(pc)) { 2386 EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | 2387 (immediate_t32.GetEncodingValue() & 0xff) | 2388 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2389 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2390 AdvanceIT(); 2391 return; 2392 } 2393 } else { 2394 ImmediateA32 immediate_a32(imm); 2395 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2396 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { 2397 EmitA32(0x02900000U | (cond.GetCondition() << 28) | 2398 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2399 immediate_a32.GetEncodingValue()); 2400 return; 2401 } 2402 // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 2403 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 2404 EmitA32(0x029d0000U | (cond.GetCondition() << 28) | 2405 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2406 return; 2407 } 2408 } 2409 } 2410 if (operand.IsImmediateShiftedRegister()) { 2411 Register rm = operand.GetBaseRegister(); 2412 if (operand.IsPlainRegister()) { 2413 if (IsUsingT32()) { 2414 // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1 2415 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2416 rm.IsLow()) { 2417 EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | 2418 (rm.GetCode() << 6)); 2419 AdvanceIT(); 2420 return; 2421 } 2422 } 2423 } 2424 Shift shift = operand.GetShift(); 2425 uint32_t amount = operand.GetShiftAmount(); 2426 if (IsUsingT32()) { 2427 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 2428 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 2429 !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2430 uint32_t amount_ = amount % 32; 2431 EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2432 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2433 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2434 AdvanceIT(); 2435 return; 2436 } 2437 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 2438 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 2439 !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { 2440 uint32_t amount_ = amount % 32; 2441 EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | 2442 (operand.GetTypeEncodingValue() << 4) | 2443 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2444 AdvanceIT(); 2445 return; 2446 } 2447 } else { 2448 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2449 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 2450 uint32_t amount_ = amount % 32; 2451 EmitA32(0x00900000U | (cond.GetCondition() << 28) | 2452 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2453 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2454 return; 2455 } 2456 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 2457 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 2458 uint32_t amount_ = amount % 32; 2459 EmitA32(0x009d0000U | (cond.GetCondition() << 28) | 2460 (rd.GetCode() << 12) | rm.GetCode() | 2461 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2462 return; 2463 } 2464 } 2465 } 2466 if (operand.IsRegisterShiftedRegister()) { 2467 Register rm = operand.GetBaseRegister(); 2468 Shift shift = operand.GetShift(); 2469 Register rs = operand.GetShiftRegister(); 2470 if (IsUsingA32()) { 2471 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2472 if (cond.IsNotNever() && 2473 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2474 AllowUnpredictable())) { 2475 EmitA32(0x00900010U | (cond.GetCondition() << 28) | 2476 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2477 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2478 return; 2479 } 2480 } 2481 } 2482 Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand); 2483 } 2484 2485 void Assembler::adds(Register rd, const Operand& operand) { 2486 VIXL_ASSERT(AllowAssembler()); 2487 CheckIT(al); 2488 if (operand.IsImmediate()) { 2489 uint32_t imm = operand.GetImmediate(); 2490 if (IsUsingT32()) { 2491 // ADDS{<q>} <Rdn>, #<imm8> ; T2 2492 if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) { 2493 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2494 AdvanceIT(); 2495 return; 2496 } 2497 } 2498 } 2499 Delegate(kAdds, &Assembler::adds, rd, operand); 2500 } 2501 2502 void Assembler::addw(Condition cond, 2503 Register rd, 2504 Register rn, 2505 const Operand& operand) { 2506 VIXL_ASSERT(AllowAssembler()); 2507 CheckIT(cond); 2508 if (operand.IsImmediate()) { 2509 uint32_t imm = operand.GetImmediate(); 2510 if (IsUsingT32()) { 2511 // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3 2512 if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2513 EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2514 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2515 AdvanceIT(); 2516 return; 2517 } 2518 // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 2519 if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 2520 (!rd.IsPC() || AllowUnpredictable())) { 2521 EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2522 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2523 AdvanceIT(); 2524 return; 2525 } 2526 // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4 2527 if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2528 EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2529 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2530 AdvanceIT(); 2531 return; 2532 } 2533 } 2534 } 2535 Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand); 2536 } 2537 2538 void Assembler::adr(Condition cond, 2539 EncodingSize size, 2540 Register rd, 2541 Location* location) { 2542 VIXL_ASSERT(AllowAssembler()); 2543 CheckIT(cond); 2544 Location::Offset offset = 2545 location->IsBound() 2546 ? location->GetLocation() - 2547 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 2548 : 0; 2549 if (IsUsingT32()) { 2550 int32_t neg_offset = -offset; 2551 // ADR{<c>}{<q>} <Rd>, <label> ; T1 2552 if (!size.IsWide() && rd.IsLow() && 2553 ((location->IsBound() && (offset >= 0) && (offset <= 1020) && 2554 ((offset & 0x3) == 0)) || 2555 (!location->IsBound() && size.IsNarrow()))) { 2556 static class EmitOp : public Location::EmitOperator { 2557 public: 2558 EmitOp() : Location::EmitOperator(T32) {} 2559 virtual uint32_t Encode(uint32_t instr, 2560 Location::Offset program_counter, 2561 const Location* loc) const VIXL_OVERRIDE { 2562 program_counter += kT32PcDelta; 2563 Location::Offset off = 2564 loc->GetLocation() - AlignDown(program_counter, 4); 2565 VIXL_ASSERT((off >= 0) && (off <= 1020) && ((off & 0x3) == 0)); 2566 const int32_t target = off >> 2; 2567 return instr | (target & 0xff); 2568 } 2569 } immop; 2570 EmitT32_16( 2571 Link(0xa000 | (rd.GetCode() << 8), location, immop, &kT16DataInfo)); 2572 AdvanceIT(); 2573 return; 2574 } 2575 // ADR{<c>}{<q>} <Rd>, <label> ; T2 2576 if (!size.IsNarrow() && location->IsBound() && (neg_offset > 0) && 2577 (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2578 EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) | 2579 ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15)); 2580 AdvanceIT(); 2581 return; 2582 } 2583 // ADR{<c>}{<q>} <Rd>, <label> ; T3 2584 if (!size.IsNarrow() && 2585 (!location->IsBound() || ((offset >= 0) && (offset <= 4095))) && 2586 (!rd.IsPC() || AllowUnpredictable())) { 2587 static class EmitOp : public Location::EmitOperator { 2588 public: 2589 EmitOp() : Location::EmitOperator(T32) {} 2590 virtual uint32_t Encode(uint32_t instr, 2591 Location::Offset program_counter, 2592 const Location* loc) const VIXL_OVERRIDE { 2593 program_counter += kT32PcDelta; 2594 Location::Offset off = 2595 loc->GetLocation() - AlignDown(program_counter, 4); 2596 int32_t target; 2597 if ((off >= 0) && (off <= 4095)) { 2598 target = off; 2599 } else { 2600 target = -off; 2601 VIXL_ASSERT((target >= 0) && (target <= 4095)); 2602 // Emit the T2 encoding. 2603 instr |= 0x00a00000; 2604 } 2605 return instr | (target & 0xff) | ((target & 0x700) << 4) | 2606 ((target & 0x800) << 15); 2607 } 2608 } immop; 2609 EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8), 2610 location, 2611 immop, 2612 &kT32FarDataInfo)); 2613 AdvanceIT(); 2614 return; 2615 } 2616 } else { 2617 ImmediateA32 positive_immediate_a32(offset); 2618 ImmediateA32 negative_immediate_a32(-offset); 2619 // ADR{<c>}{<q>} <Rd>, <label> ; A1 2620 if ((!location->IsBound() || positive_immediate_a32.IsValid()) && 2621 cond.IsNotNever()) { 2622 static class EmitOp : public Location::EmitOperator { 2623 public: 2624 EmitOp() : Location::EmitOperator(A32) {} 2625 virtual uint32_t Encode(uint32_t instr, 2626 Location::Offset program_counter, 2627 const Location* loc) const VIXL_OVERRIDE { 2628 program_counter += kA32PcDelta; 2629 Location::Offset off = 2630 loc->GetLocation() - AlignDown(program_counter, 4); 2631 int32_t target; 2632 ImmediateA32 pos_imm_a32(off); 2633 if (pos_imm_a32.IsValid()) { 2634 target = pos_imm_a32.GetEncodingValue(); 2635 } else { 2636 ImmediateA32 neg_imm_a32(-off); 2637 VIXL_ASSERT(neg_imm_a32.IsValid()); 2638 // Emit the A2 encoding. 2639 target = neg_imm_a32.GetEncodingValue(); 2640 instr = (instr & ~0x00f00000) | 0x00400000; 2641 } 2642 return instr | (target & 0xfff); 2643 } 2644 } immop; 2645 EmitA32( 2646 Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12), 2647 location, 2648 immop, 2649 &kA32AdrInfo)); 2650 return; 2651 } 2652 // ADR{<c>}{<q>} <Rd>, <label> ; A2 2653 if (location->IsBound() && negative_immediate_a32.IsValid() && 2654 cond.IsNotNever()) { 2655 EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 2656 negative_immediate_a32.GetEncodingValue()); 2657 return; 2658 } 2659 } 2660 Delegate(kAdr, &Assembler::adr, cond, size, rd, location); 2661 } 2662 2663 bool Assembler::adr_info(Condition cond, 2664 EncodingSize size, 2665 Register rd, 2666 Location* location, 2667 const struct ReferenceInfo** info) { 2668 VIXL_ASSERT(!location->IsBound()); 2669 USE(location); 2670 if (IsUsingT32()) { 2671 // ADR{<c>}{<q>} <Rd>, <label> ; T1 2672 if (!size.IsWide() && rd.IsLow() && size.IsNarrow()) { 2673 *info = &kT16DataInfo; 2674 return true; 2675 } 2676 // Skipped T2, as it is a negative offset variant. 2677 // The minimum offset is included in the corresponding 2678 // positive variant. 2679 // ADR{<c>}{<q>} <Rd>, <label> ; T3 2680 if (!size.IsNarrow()) { 2681 *info = &kT32FarDataInfo; 2682 return true; 2683 } 2684 } else { 2685 // ADR{<c>}{<q>} <Rd>, <label> ; A1 2686 if (cond.IsNotNever()) { 2687 *info = &kA32AdrInfo; 2688 return true; 2689 } 2690 // Skipped A2, as it is a negative offset variant. 2691 // The minimum offset is included in the corresponding 2692 // positive variant. 2693 } 2694 return false; 2695 } 2696 2697 void Assembler::and_(Condition cond, 2698 EncodingSize size, 2699 Register rd, 2700 Register rn, 2701 const Operand& operand) { 2702 VIXL_ASSERT(AllowAssembler()); 2703 CheckIT(cond); 2704 if (operand.IsImmediate()) { 2705 uint32_t imm = operand.GetImmediate(); 2706 if (IsUsingT32()) { 2707 ImmediateT32 immediate_t32(imm); 2708 // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 2709 if (!size.IsNarrow() && immediate_t32.IsValid() && 2710 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 2711 EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2712 (immediate_t32.GetEncodingValue() & 0xff) | 2713 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2714 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2715 AdvanceIT(); 2716 return; 2717 } 2718 } else { 2719 ImmediateA32 immediate_a32(imm); 2720 // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2721 if (immediate_a32.IsValid() && cond.IsNotNever()) { 2722 EmitA32(0x02000000U | (cond.GetCondition() << 28) | 2723 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2724 immediate_a32.GetEncodingValue()); 2725 return; 2726 } 2727 } 2728 } 2729 if (operand.IsImmediateShiftedRegister()) { 2730 Register rm = operand.GetBaseRegister(); 2731 if (operand.IsPlainRegister()) { 2732 if (IsUsingT32()) { 2733 // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 2734 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2735 rm.IsLow()) { 2736 EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3)); 2737 AdvanceIT(); 2738 return; 2739 } 2740 } 2741 } 2742 Shift shift = operand.GetShift(); 2743 uint32_t amount = operand.GetShiftAmount(); 2744 if (IsUsingT32()) { 2745 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 2746 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 2747 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2748 uint32_t amount_ = amount % 32; 2749 EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2750 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2751 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2752 AdvanceIT(); 2753 return; 2754 } 2755 } else { 2756 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2757 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 2758 uint32_t amount_ = amount % 32; 2759 EmitA32(0x00000000U | (cond.GetCondition() << 28) | 2760 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2761 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2762 return; 2763 } 2764 } 2765 } 2766 if (operand.IsRegisterShiftedRegister()) { 2767 Register rm = operand.GetBaseRegister(); 2768 Shift shift = operand.GetShift(); 2769 Register rs = operand.GetShiftRegister(); 2770 if (IsUsingA32()) { 2771 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2772 if (cond.IsNotNever() && 2773 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2774 AllowUnpredictable())) { 2775 EmitA32(0x00000010U | (cond.GetCondition() << 28) | 2776 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2777 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2778 return; 2779 } 2780 } 2781 } 2782 Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand); 2783 } 2784 2785 void Assembler::ands(Condition cond, 2786 EncodingSize size, 2787 Register rd, 2788 Register rn, 2789 const Operand& operand) { 2790 VIXL_ASSERT(AllowAssembler()); 2791 CheckIT(cond); 2792 if (operand.IsImmediate()) { 2793 uint32_t imm = operand.GetImmediate(); 2794 if (IsUsingT32()) { 2795 ImmediateT32 immediate_t32(imm); 2796 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 2797 if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) && 2798 (!rn.IsPC() || AllowUnpredictable())) { 2799 EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2800 (immediate_t32.GetEncodingValue() & 0xff) | 2801 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2802 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2803 AdvanceIT(); 2804 return; 2805 } 2806 } else { 2807 ImmediateA32 immediate_a32(imm); 2808 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2809 if (immediate_a32.IsValid() && cond.IsNotNever()) { 2810 EmitA32(0x02100000U | (cond.GetCondition() << 28) | 2811 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2812 immediate_a32.GetEncodingValue()); 2813 return; 2814 } 2815 } 2816 } 2817 if (operand.IsImmediateShiftedRegister()) { 2818 Register rm = operand.GetBaseRegister(); 2819 if (operand.IsPlainRegister()) { 2820 if (IsUsingT32()) { 2821 // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 2822 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2823 rm.IsLow()) { 2824 EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3)); 2825 AdvanceIT(); 2826 return; 2827 } 2828 } 2829 } 2830 Shift shift = operand.GetShift(); 2831 uint32_t amount = operand.GetShiftAmount(); 2832 if (IsUsingT32()) { 2833 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 2834 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) && 2835 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2836 uint32_t amount_ = amount % 32; 2837 EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2838 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2839 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2840 AdvanceIT(); 2841 return; 2842 } 2843 } else { 2844 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2845 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 2846 uint32_t amount_ = amount % 32; 2847 EmitA32(0x00100000U | (cond.GetCondition() << 28) | 2848 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2849 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2850 return; 2851 } 2852 } 2853 } 2854 if (operand.IsRegisterShiftedRegister()) { 2855 Register rm = operand.GetBaseRegister(); 2856 Shift shift = operand.GetShift(); 2857 Register rs = operand.GetShiftRegister(); 2858 if (IsUsingA32()) { 2859 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2860 if (cond.IsNotNever() && 2861 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2862 AllowUnpredictable())) { 2863 EmitA32(0x00100010U | (cond.GetCondition() << 28) | 2864 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2865 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2866 return; 2867 } 2868 } 2869 } 2870 Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand); 2871 } 2872 2873 void Assembler::asr(Condition cond, 2874 EncodingSize size, 2875 Register rd, 2876 Register rm, 2877 const Operand& operand) { 2878 VIXL_ASSERT(AllowAssembler()); 2879 CheckIT(cond); 2880 if (operand.IsImmediate()) { 2881 uint32_t imm = operand.GetImmediate(); 2882 if (IsUsingT32()) { 2883 // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 2884 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 2885 (imm >= 1) && (imm <= 32)) { 2886 uint32_t amount_ = imm % 32; 2887 EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) | 2888 (amount_ << 6)); 2889 AdvanceIT(); 2890 return; 2891 } 2892 // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 2893 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) && 2894 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2895 uint32_t amount_ = imm % 32; 2896 EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() | 2897 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2898 AdvanceIT(); 2899 return; 2900 } 2901 } else { 2902 // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 2903 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 2904 uint32_t amount_ = imm % 32; 2905 EmitA32(0x01a00040U | (cond.GetCondition() << 28) | 2906 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 2907 return; 2908 } 2909 } 2910 } 2911 if (operand.IsPlainRegister()) { 2912 Register rs = operand.GetBaseRegister(); 2913 if (IsUsingT32()) { 2914 // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 2915 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 2916 rs.IsLow()) { 2917 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 2918 AdvanceIT(); 2919 return; 2920 } 2921 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 2922 if (!size.IsNarrow() && 2923 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 2924 EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 2925 rs.GetCode()); 2926 AdvanceIT(); 2927 return; 2928 } 2929 } else { 2930 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 2931 if (cond.IsNotNever() && 2932 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 2933 EmitA32(0x01a00050U | (cond.GetCondition() << 28) | 2934 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 2935 return; 2936 } 2937 } 2938 } 2939 Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand); 2940 } 2941 2942 void Assembler::asrs(Condition cond, 2943 EncodingSize size, 2944 Register rd, 2945 Register rm, 2946 const Operand& operand) { 2947 VIXL_ASSERT(AllowAssembler()); 2948 CheckIT(cond); 2949 if (operand.IsImmediate()) { 2950 uint32_t imm = operand.GetImmediate(); 2951 if (IsUsingT32()) { 2952 // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 2953 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 2954 (imm >= 1) && (imm <= 32)) { 2955 uint32_t amount_ = imm % 32; 2956 EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) | 2957 (amount_ << 6)); 2958 AdvanceIT(); 2959 return; 2960 } 2961 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 2962 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) && 2963 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2964 uint32_t amount_ = imm % 32; 2965 EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() | 2966 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2967 AdvanceIT(); 2968 return; 2969 } 2970 } else { 2971 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 2972 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 2973 uint32_t amount_ = imm % 32; 2974 EmitA32(0x01b00040U | (cond.GetCondition() << 28) | 2975 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 2976 return; 2977 } 2978 } 2979 } 2980 if (operand.IsPlainRegister()) { 2981 Register rs = operand.GetBaseRegister(); 2982 if (IsUsingT32()) { 2983 // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 2984 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 2985 rs.IsLow()) { 2986 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 2987 AdvanceIT(); 2988 return; 2989 } 2990 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 2991 if (!size.IsNarrow() && 2992 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 2993 EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 2994 rs.GetCode()); 2995 AdvanceIT(); 2996 return; 2997 } 2998 } else { 2999 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 3000 if (cond.IsNotNever() && 3001 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 3002 EmitA32(0x01b00050U | (cond.GetCondition() << 28) | 3003 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 3004 return; 3005 } 3006 } 3007 } 3008 Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand); 3009 } 3010 3011 void Assembler::b(Condition cond, EncodingSize size, Location* location) { 3012 VIXL_ASSERT(AllowAssembler()); 3013 Location::Offset offset = 3014 location->IsBound() 3015 ? location->GetLocation() - 3016 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3017 : 0; 3018 if (IsUsingT32()) { 3019 // B<c>{<q>} <label> ; T1 3020 if (OutsideITBlock() && !size.IsWide() && 3021 ((location->IsBound() && (offset >= -256) && (offset <= 254) && 3022 ((offset & 0x1) == 0)) || 3023 (!location->IsBound() && size.IsNarrow())) && 3024 !cond.Is(al) && cond.IsNotNever()) { 3025 static class EmitOp : public Location::EmitOperator { 3026 public: 3027 EmitOp() : Location::EmitOperator(T32) {} 3028 virtual uint32_t Encode(uint32_t instr, 3029 Location::Offset program_counter, 3030 const Location* loc) const VIXL_OVERRIDE { 3031 program_counter += kT32PcDelta; 3032 Location::Offset off = loc->GetLocation() - program_counter; 3033 VIXL_ASSERT((off >= -256) && (off <= 254) && ((off & 0x1) == 0)); 3034 const int32_t target = off >> 1; 3035 return instr | (target & 0xff); 3036 } 3037 } immop; 3038 EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8), 3039 location, 3040 immop, 3041 &kT16ConditionalBranchInfo)); 3042 AdvanceIT(); 3043 return; 3044 } 3045 // B{<c>}{<q>} <label> ; T2 3046 if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && 3047 ((location->IsBound() && (offset >= -2048) && (offset <= 2046) && 3048 ((offset & 0x1) == 0)) || 3049 (!location->IsBound() && size.IsNarrow()))) { 3050 CheckIT(cond); 3051 static class EmitOp : public Location::EmitOperator { 3052 public: 3053 EmitOp() : Location::EmitOperator(T32) {} 3054 virtual uint32_t Encode(uint32_t instr, 3055 Location::Offset program_counter, 3056 const Location* loc) const VIXL_OVERRIDE { 3057 program_counter += kT32PcDelta; 3058 Location::Offset off = loc->GetLocation() - program_counter; 3059 VIXL_ASSERT((off >= -2048) && (off <= 2046) && ((off & 0x1) == 0)); 3060 const int32_t target = off >> 1; 3061 return instr | (target & 0x7ff); 3062 } 3063 } immop; 3064 EmitT32_16(Link(0xe000, location, immop, &kT16BranchInfo)); 3065 AdvanceIT(); 3066 return; 3067 } 3068 // B<c>{<q>} <label> ; T3 3069 if (OutsideITBlock() && !size.IsNarrow() && 3070 ((location->IsBound() && (offset >= -1048576) && (offset <= 1048574) && 3071 ((offset & 0x1) == 0)) || 3072 !location->IsBound()) && 3073 !cond.Is(al) && cond.IsNotNever()) { 3074 static class EmitOp : public Location::EmitOperator { 3075 public: 3076 EmitOp() : Location::EmitOperator(T32) {} 3077 virtual uint32_t Encode(uint32_t instr, 3078 Location::Offset program_counter, 3079 const Location* loc) const VIXL_OVERRIDE { 3080 program_counter += kT32PcDelta; 3081 Location::Offset off = loc->GetLocation() - program_counter; 3082 VIXL_ASSERT((off >= -1048576) && (off <= 1048574) && 3083 ((off & 0x1) == 0)); 3084 const int32_t target = off >> 1; 3085 return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) | 3086 ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) | 3087 ((target & 0x80000) << 7); 3088 } 3089 } immop; 3090 EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22), 3091 location, 3092 immop, 3093 &kT32ConditionalBranchInfo)); 3094 AdvanceIT(); 3095 return; 3096 } 3097 // B{<c>}{<q>} <label> ; T4 3098 if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() && 3099 ((location->IsBound() && (offset >= -16777216) && 3100 (offset <= 16777214) && ((offset & 0x1) == 0)) || 3101 !location->IsBound())) { 3102 CheckIT(cond); 3103 static class EmitOp : public Location::EmitOperator { 3104 public: 3105 EmitOp() : Location::EmitOperator(T32) {} 3106 virtual uint32_t Encode(uint32_t instr, 3107 Location::Offset program_counter, 3108 const Location* loc) const VIXL_OVERRIDE { 3109 program_counter += kT32PcDelta; 3110 Location::Offset off = loc->GetLocation() - program_counter; 3111 VIXL_ASSERT((off >= -16777216) && (off <= 16777214) && 3112 ((off & 0x1) == 0)); 3113 int32_t target = off >> 1; 3114 uint32_t S = target & (1 << 23); 3115 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21); 3116 return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) | 3117 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) | 3118 ((target & 0x800000) << 3); 3119 } 3120 } immop; 3121 EmitT32_32(Link(0xf0009000U, location, immop, &kT32BranchInfo)); 3122 AdvanceIT(); 3123 return; 3124 } 3125 } else { 3126 // B{<c>}{<q>} <label> ; A1 3127 if (((location->IsBound() && (offset >= -33554432) && 3128 (offset <= 33554428) && ((offset & 0x3) == 0)) || 3129 !location->IsBound()) && 3130 cond.IsNotNever()) { 3131 static class EmitOp : public Location::EmitOperator { 3132 public: 3133 EmitOp() : Location::EmitOperator(A32) {} 3134 virtual uint32_t Encode(uint32_t instr, 3135 Location::Offset program_counter, 3136 const Location* loc) const VIXL_OVERRIDE { 3137 program_counter += kA32PcDelta; 3138 Location::Offset off = loc->GetLocation() - program_counter; 3139 VIXL_ASSERT((off >= -33554432) && (off <= 33554428) && 3140 ((off & 0x3) == 0)); 3141 const int32_t target = off >> 2; 3142 return instr | (target & 0xffffff); 3143 } 3144 } immop; 3145 EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28), 3146 location, 3147 immop, 3148 &kA32BranchInfo)); 3149 return; 3150 } 3151 } 3152 Delegate(kB, &Assembler::b, cond, size, location); 3153 } 3154 3155 bool Assembler::b_info(Condition cond, 3156 EncodingSize size, 3157 Location* location, 3158 const struct ReferenceInfo** info) { 3159 VIXL_ASSERT(!location->IsBound()); 3160 USE(location); 3161 if (IsUsingT32()) { 3162 // B<c>{<q>} <label> ; T1 3163 if (OutsideITBlock() && !size.IsWide() && size.IsNarrow() && !cond.Is(al) && 3164 cond.IsNotNever()) { 3165 *info = &kT16ConditionalBranchInfo; 3166 return true; 3167 } 3168 // B{<c>}{<q>} <label> ; T2 3169 if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && size.IsNarrow()) { 3170 *info = &kT16BranchInfo; 3171 return true; 3172 } 3173 // B<c>{<q>} <label> ; T3 3174 if (OutsideITBlock() && !size.IsNarrow() && !cond.Is(al) && 3175 cond.IsNotNever()) { 3176 *info = &kT32ConditionalBranchInfo; 3177 return true; 3178 } 3179 // B{<c>}{<q>} <label> ; T4 3180 if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow()) { 3181 *info = &kT32BranchInfo; 3182 return true; 3183 } 3184 } else { 3185 // B{<c>}{<q>} <label> ; A1 3186 if (cond.IsNotNever()) { 3187 *info = &kA32BranchInfo; 3188 return true; 3189 } 3190 } 3191 return false; 3192 } 3193 3194 void Assembler::bfc(Condition cond, Register rd, uint32_t lsb, uint32_t width) { 3195 VIXL_ASSERT(AllowAssembler()); 3196 CheckIT(cond); 3197 if (IsUsingT32()) { 3198 // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1 3199 if ((lsb <= 31) && (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) || 3200 AllowUnpredictable())) { 3201 uint32_t msb = lsb + width - 1; 3202 EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) | 3203 ((lsb & 0x1c) << 10) | msb); 3204 AdvanceIT(); 3205 return; 3206 } 3207 } else { 3208 // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1 3209 if ((lsb <= 31) && cond.IsNotNever() && 3210 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) || 3211 AllowUnpredictable())) { 3212 uint32_t msb = lsb + width - 1; 3213 EmitA32(0x07c0001fU | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3214 (lsb << 7) | (msb << 16)); 3215 return; 3216 } 3217 } 3218 Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, width); 3219 } 3220 3221 void Assembler::bfi( 3222 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) { 3223 VIXL_ASSERT(AllowAssembler()); 3224 CheckIT(cond); 3225 if (IsUsingT32()) { 3226 // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 3227 if ((lsb <= 31) && !rn.Is(pc) && 3228 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) || 3229 AllowUnpredictable())) { 3230 uint32_t msb = lsb + width - 1; 3231 EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3232 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb); 3233 AdvanceIT(); 3234 return; 3235 } 3236 } else { 3237 // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 3238 if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) && 3239 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) || 3240 AllowUnpredictable())) { 3241 uint32_t msb = lsb + width - 1; 3242 EmitA32(0x07c00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3243 rn.GetCode() | (lsb << 7) | (msb << 16)); 3244 return; 3245 } 3246 } 3247 Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, width); 3248 } 3249 3250 void Assembler::bic(Condition cond, 3251 EncodingSize size, 3252 Register rd, 3253 Register rn, 3254 const Operand& operand) { 3255 VIXL_ASSERT(AllowAssembler()); 3256 CheckIT(cond); 3257 if (operand.IsImmediate()) { 3258 uint32_t imm = operand.GetImmediate(); 3259 if (IsUsingT32()) { 3260 ImmediateT32 immediate_t32(imm); 3261 // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 3262 if (!size.IsNarrow() && immediate_t32.IsValid() && 3263 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 3264 EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3265 (immediate_t32.GetEncodingValue() & 0xff) | 3266 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3267 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3268 AdvanceIT(); 3269 return; 3270 } 3271 } else { 3272 ImmediateA32 immediate_a32(imm); 3273 // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 3274 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3275 EmitA32(0x03c00000U | (cond.GetCondition() << 28) | 3276 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 3277 immediate_a32.GetEncodingValue()); 3278 return; 3279 } 3280 } 3281 } 3282 if (operand.IsImmediateShiftedRegister()) { 3283 Register rm = operand.GetBaseRegister(); 3284 if (operand.IsPlainRegister()) { 3285 if (IsUsingT32()) { 3286 // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 3287 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 3288 rm.IsLow()) { 3289 EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3)); 3290 AdvanceIT(); 3291 return; 3292 } 3293 } 3294 } 3295 Shift shift = operand.GetShift(); 3296 uint32_t amount = operand.GetShiftAmount(); 3297 if (IsUsingT32()) { 3298 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 3299 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 3300 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3301 uint32_t amount_ = amount % 32; 3302 EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3303 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 3304 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3305 AdvanceIT(); 3306 return; 3307 } 3308 } else { 3309 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 3310 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3311 uint32_t amount_ = amount % 32; 3312 EmitA32(0x01c00000U | (cond.GetCondition() << 28) | 3313 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3314 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3315 return; 3316 } 3317 } 3318 } 3319 if (operand.IsRegisterShiftedRegister()) { 3320 Register rm = operand.GetBaseRegister(); 3321 Shift shift = operand.GetShift(); 3322 Register rs = operand.GetShiftRegister(); 3323 if (IsUsingA32()) { 3324 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 3325 if (cond.IsNotNever() && 3326 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 3327 AllowUnpredictable())) { 3328 EmitA32(0x01c00010U | (cond.GetCondition() << 28) | 3329 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3330 (shift.GetType() << 5) | (rs.GetCode() << 8)); 3331 return; 3332 } 3333 } 3334 } 3335 Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand); 3336 } 3337 3338 void Assembler::bics(Condition cond, 3339 EncodingSize size, 3340 Register rd, 3341 Register rn, 3342 const Operand& operand) { 3343 VIXL_ASSERT(AllowAssembler()); 3344 CheckIT(cond); 3345 if (operand.IsImmediate()) { 3346 uint32_t imm = operand.GetImmediate(); 3347 if (IsUsingT32()) { 3348 ImmediateT32 immediate_t32(imm); 3349 // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 3350 if (!size.IsNarrow() && immediate_t32.IsValid() && 3351 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 3352 EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3353 (immediate_t32.GetEncodingValue() & 0xff) | 3354 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3355 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3356 AdvanceIT(); 3357 return; 3358 } 3359 } else { 3360 ImmediateA32 immediate_a32(imm); 3361 // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 3362 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3363 EmitA32(0x03d00000U | (cond.GetCondition() << 28) | 3364 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 3365 immediate_a32.GetEncodingValue()); 3366 return; 3367 } 3368 } 3369 } 3370 if (operand.IsImmediateShiftedRegister()) { 3371 Register rm = operand.GetBaseRegister(); 3372 if (operand.IsPlainRegister()) { 3373 if (IsUsingT32()) { 3374 // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 3375 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 3376 rm.IsLow()) { 3377 EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3)); 3378 AdvanceIT(); 3379 return; 3380 } 3381 } 3382 } 3383 Shift shift = operand.GetShift(); 3384 uint32_t amount = operand.GetShiftAmount(); 3385 if (IsUsingT32()) { 3386 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 3387 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 3388 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3389 uint32_t amount_ = amount % 32; 3390 EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3391 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 3392 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3393 AdvanceIT(); 3394 return; 3395 } 3396 } else { 3397 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 3398 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3399 uint32_t amount_ = amount % 32; 3400 EmitA32(0x01d00000U | (cond.GetCondition() << 28) | 3401 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3402 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3403 return; 3404 } 3405 } 3406 } 3407 if (operand.IsRegisterShiftedRegister()) { 3408 Register rm = operand.GetBaseRegister(); 3409 Shift shift = operand.GetShift(); 3410 Register rs = operand.GetShiftRegister(); 3411 if (IsUsingA32()) { 3412 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 3413 if (cond.IsNotNever() && 3414 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 3415 AllowUnpredictable())) { 3416 EmitA32(0x01d00010U | (cond.GetCondition() << 28) | 3417 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3418 (shift.GetType() << 5) | (rs.GetCode() << 8)); 3419 return; 3420 } 3421 } 3422 } 3423 Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand); 3424 } 3425 3426 void Assembler::bkpt(Condition cond, uint32_t imm) { 3427 VIXL_ASSERT(AllowAssembler()); 3428 CheckIT(cond); 3429 if (IsUsingT32()) { 3430 // BKPT{<q>} {#}<imm> ; T1 3431 if ((imm <= 255)) { 3432 EmitT32_16(0xbe00 | imm); 3433 AdvanceIT(); 3434 return; 3435 } 3436 } else { 3437 // BKPT{<q>} {#}<imm> ; A1 3438 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 3439 EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) | 3440 ((imm & 0xfff0) << 4)); 3441 return; 3442 } 3443 } 3444 Delegate(kBkpt, &Assembler::bkpt, cond, imm); 3445 } 3446 3447 void Assembler::bl(Condition cond, Location* location) { 3448 VIXL_ASSERT(AllowAssembler()); 3449 CheckIT(cond); 3450 Location::Offset offset = 3451 location->IsBound() 3452 ? location->GetLocation() - 3453 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3454 : 0; 3455 if (IsUsingT32()) { 3456 // BL{<c>}{<q>} <label> ; T1 3457 if (((location->IsBound() && (offset >= -16777216) && 3458 (offset <= 16777214) && ((offset & 0x1) == 0)) || 3459 !location->IsBound()) && 3460 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) { 3461 static class EmitOp : public Location::EmitOperator { 3462 public: 3463 EmitOp() : Location::EmitOperator(T32) {} 3464 virtual uint32_t Encode(uint32_t instr, 3465 Location::Offset program_counter, 3466 const Location* loc) const VIXL_OVERRIDE { 3467 program_counter += kT32PcDelta; 3468 Location::Offset off = loc->GetLocation() - program_counter; 3469 VIXL_ASSERT((off >= -16777216) && (off <= 16777214) && 3470 ((off & 0x1) == 0)); 3471 int32_t target = off >> 1; 3472 uint32_t S = target & (1 << 23); 3473 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21); 3474 return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) | 3475 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) | 3476 ((target & 0x800000) << 3); 3477 } 3478 } immop; 3479 EmitT32_32(Link(0xf000d000U, location, immop, &kT32BranchInfo)); 3480 AdvanceIT(); 3481 return; 3482 } 3483 } else { 3484 // BL{<c>}{<q>} <label> ; A1 3485 if (((location->IsBound() && (offset >= -33554432) && 3486 (offset <= 33554428) && ((offset & 0x3) == 0)) || 3487 !location->IsBound()) && 3488 cond.IsNotNever()) { 3489 static class EmitOp : public Location::EmitOperator { 3490 public: 3491 EmitOp() : Location::EmitOperator(A32) {} 3492 virtual uint32_t Encode(uint32_t instr, 3493 Location::Offset program_counter, 3494 const Location* loc) const VIXL_OVERRIDE { 3495 program_counter += kA32PcDelta; 3496 Location::Offset off = loc->GetLocation() - program_counter; 3497 VIXL_ASSERT((off >= -33554432) && (off <= 33554428) && 3498 ((off & 0x3) == 0)); 3499 const int32_t target = off >> 2; 3500 return instr | (target & 0xffffff); 3501 } 3502 } immop; 3503 EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28), 3504 location, 3505 immop, 3506 &kA32BranchInfo)); 3507 return; 3508 } 3509 } 3510 Delegate(kBl, &Assembler::bl, cond, location); 3511 } 3512 3513 bool Assembler::bl_info(Condition cond, 3514 Location* location, 3515 const struct ReferenceInfo** info) { 3516 VIXL_ASSERT(!location->IsBound()); 3517 USE(location); 3518 if (IsUsingT32()) { 3519 // BL{<c>}{<q>} <label> ; T1 3520 if (true) { 3521 *info = &kT32BranchInfo; 3522 return true; 3523 } 3524 } else { 3525 // BL{<c>}{<q>} <label> ; A1 3526 if (cond.IsNotNever()) { 3527 *info = &kA32BranchInfo; 3528 return true; 3529 } 3530 } 3531 return false; 3532 } 3533 3534 void Assembler::blx(Condition cond, Location* location) { 3535 VIXL_ASSERT(AllowAssembler()); 3536 CheckIT(cond); 3537 Location::Offset offset = 3538 location->IsBound() 3539 ? location->GetLocation() - 3540 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 3541 : 0; 3542 if (IsUsingT32()) { 3543 // BLX{<c>}{<q>} <label> ; T2 3544 if (((location->IsBound() && (offset >= -16777216) && 3545 (offset <= 16777212) && ((offset & 0x3) == 0)) || 3546 !location->IsBound()) && 3547 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) { 3548 static class EmitOp : public Location::EmitOperator { 3549 public: 3550 EmitOp() : Location::EmitOperator(T32) {} 3551 virtual uint32_t Encode(uint32_t instr, 3552 Location::Offset program_counter, 3553 const Location* loc) const VIXL_OVERRIDE { 3554 program_counter += kT32PcDelta; 3555 Location::Offset off = 3556 loc->GetLocation() - AlignDown(program_counter, 4); 3557 VIXL_ASSERT((off >= -16777216) && (off <= 16777212) && 3558 ((off & 0x3) == 0)); 3559 int32_t target = off >> 2; 3560 uint32_t S = target & (1 << 22); 3561 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20); 3562 return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) | 3563 ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) | 3564 ((target & 0x400000) << 4); 3565 } 3566 } immop; 3567 EmitT32_32(Link(0xf000c000U, location, immop, &kT32BlxInfo)); 3568 AdvanceIT(); 3569 return; 3570 } 3571 } else { 3572 // BLX{<c>}{<q>} <label> ; A2 3573 if (((location->IsBound() && (offset >= -33554432) && 3574 (offset <= 33554430) && ((offset & 0x1) == 0)) || 3575 !location->IsBound())) { 3576 if (cond.Is(al) || AllowStronglyDiscouraged()) { 3577 static class EmitOp : public Location::EmitOperator { 3578 public: 3579 EmitOp() : Location::EmitOperator(A32) {} 3580 virtual uint32_t Encode(uint32_t instr, 3581 Location::Offset program_counter, 3582 const Location* loc) const VIXL_OVERRIDE { 3583 program_counter += kA32PcDelta; 3584 Location::Offset off = 3585 loc->GetLocation() - AlignDown(program_counter, 4); 3586 VIXL_ASSERT((off >= -33554432) && (off <= 33554430) && 3587 ((off & 0x1) == 0)); 3588 const int32_t target = off >> 1; 3589 return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1); 3590 } 3591 } immop; 3592 EmitA32(Link(0xfa000000U, location, immop, &kA32BlxInfo)); 3593 return; 3594 } 3595 } 3596 } 3597 Delegate(kBlx, &Assembler::blx, cond, location); 3598 } 3599 3600 bool Assembler::blx_info(Condition cond, 3601 Location* location, 3602 const struct ReferenceInfo** info) { 3603 VIXL_ASSERT(!location->IsBound()); 3604 USE(location); 3605 USE(cond); 3606 if (IsUsingT32()) { 3607 // BLX{<c>}{<q>} <label> ; T2 3608 if (true) { 3609 *info = &kT32BlxInfo; 3610 return true; 3611 } 3612 } else { 3613 // BLX{<c>}{<q>} <label> ; A2 3614 if (true) { 3615 *info = &kA32BlxInfo; 3616 return true; 3617 } 3618 } 3619 return false; 3620 } 3621 3622 void Assembler::blx(Condition cond, Register rm) { 3623 VIXL_ASSERT(AllowAssembler()); 3624 CheckIT(cond); 3625 if (IsUsingT32()) { 3626 // BLX{<c>}{<q>} <Rm> ; T1 3627 if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) || 3628 AllowUnpredictable())) { 3629 EmitT32_16(0x4780 | (rm.GetCode() << 3)); 3630 AdvanceIT(); 3631 return; 3632 } 3633 } else { 3634 // BLX{<c>}{<q>} <Rm> ; A1 3635 if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) { 3636 EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode()); 3637 return; 3638 } 3639 } 3640 Delegate(kBlx, &Assembler::blx, cond, rm); 3641 } 3642 3643 void Assembler::bx(Condition cond, Register rm) { 3644 VIXL_ASSERT(AllowAssembler()); 3645 CheckIT(cond); 3646 if (IsUsingT32()) { 3647 // BX{<c>}{<q>} <Rm> ; T1 3648 if ((OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) { 3649 EmitT32_16(0x4700 | (rm.GetCode() << 3)); 3650 AdvanceIT(); 3651 return; 3652 } 3653 } else { 3654 // BX{<c>}{<q>} <Rm> ; A1 3655 if (cond.IsNotNever()) { 3656 EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode()); 3657 return; 3658 } 3659 } 3660 Delegate(kBx, &Assembler::bx, cond, rm); 3661 } 3662 3663 void Assembler::bxj(Condition cond, Register rm) { 3664 VIXL_ASSERT(AllowAssembler()); 3665 CheckIT(cond); 3666 if (IsUsingT32()) { 3667 // BXJ{<c>}{<q>} <Rm> ; T1 3668 if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) || 3669 AllowUnpredictable())) { 3670 EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16)); 3671 AdvanceIT(); 3672 return; 3673 } 3674 } else { 3675 // BXJ{<c>}{<q>} <Rm> ; A1 3676 if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) { 3677 EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode()); 3678 return; 3679 } 3680 } 3681 Delegate(kBxj, &Assembler::bxj, cond, rm); 3682 } 3683 3684 void Assembler::cbnz(Register rn, Location* location) { 3685 VIXL_ASSERT(AllowAssembler()); 3686 CheckIT(al); 3687 Location::Offset offset = 3688 location->IsBound() 3689 ? location->GetLocation() - 3690 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3691 : 0; 3692 if (IsUsingT32()) { 3693 // CBNZ{<q>} <Rn>, <label> ; T1 3694 if (rn.IsLow() && ((location->IsBound() && (offset >= 0) && 3695 (offset <= 126) && ((offset & 0x1) == 0)) || 3696 !location->IsBound())) { 3697 static class EmitOp : public Location::EmitOperator { 3698 public: 3699 EmitOp() : Location::EmitOperator(T32) {} 3700 virtual uint32_t Encode(uint32_t instr, 3701 Location::Offset program_counter, 3702 const Location* loc) const VIXL_OVERRIDE { 3703 program_counter += kT32PcDelta; 3704 Location::Offset off = loc->GetLocation() - program_counter; 3705 VIXL_ASSERT((off >= 0) && (off <= 126) && ((off & 0x1) == 0)); 3706 const int32_t target = off >> 1; 3707 return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4); 3708 } 3709 } immop; 3710 EmitT32_16(Link(0xb900 | rn.GetCode(), location, immop, &kT16CbzInfo)); 3711 AdvanceIT(); 3712 return; 3713 } 3714 } 3715 Delegate(kCbnz, &Assembler::cbnz, rn, location); 3716 } 3717 3718 bool Assembler::cbnz_info(Register rn, 3719 Location* location, 3720 const struct ReferenceInfo** info) { 3721 VIXL_ASSERT(!location->IsBound()); 3722 USE(location); 3723 if (IsUsingT32()) { 3724 // CBNZ{<q>} <Rn>, <label> ; T1 3725 if (rn.IsLow()) { 3726 *info = &kT16CbzInfo; 3727 return true; 3728 } 3729 } 3730 return false; 3731 } 3732 3733 void Assembler::cbz(Register rn, Location* location) { 3734 VIXL_ASSERT(AllowAssembler()); 3735 CheckIT(al); 3736 Location::Offset offset = 3737 location->IsBound() 3738 ? location->GetLocation() - 3739 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3740 : 0; 3741 if (IsUsingT32()) { 3742 // CBZ{<q>} <Rn>, <label> ; T1 3743 if (rn.IsLow() && ((location->IsBound() && (offset >= 0) && 3744 (offset <= 126) && ((offset & 0x1) == 0)) || 3745 !location->IsBound())) { 3746 static class EmitOp : public Location::EmitOperator { 3747 public: 3748 EmitOp() : Location::EmitOperator(T32) {} 3749 virtual uint32_t Encode(uint32_t instr, 3750 Location::Offset program_counter, 3751 const Location* loc) const VIXL_OVERRIDE { 3752 program_counter += kT32PcDelta; 3753 Location::Offset off = loc->GetLocation() - program_counter; 3754 VIXL_ASSERT((off >= 0) && (off <= 126) && ((off & 0x1) == 0)); 3755 const int32_t target = off >> 1; 3756 return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4); 3757 } 3758 } immop; 3759 EmitT32_16(Link(0xb100 | rn.GetCode(), location, immop, &kT16CbzInfo)); 3760 AdvanceIT(); 3761 return; 3762 } 3763 } 3764 Delegate(kCbz, &Assembler::cbz, rn, location); 3765 } 3766 3767 bool Assembler::cbz_info(Register rn, 3768 Location* location, 3769 const struct ReferenceInfo** info) { 3770 VIXL_ASSERT(!location->IsBound()); 3771 USE(location); 3772 if (IsUsingT32()) { 3773 // CBZ{<q>} <Rn>, <label> ; T1 3774 if (rn.IsLow()) { 3775 *info = &kT16CbzInfo; 3776 return true; 3777 } 3778 } 3779 return false; 3780 } 3781 3782 void Assembler::clrex(Condition cond) { 3783 VIXL_ASSERT(AllowAssembler()); 3784 CheckIT(cond); 3785 if (IsUsingT32()) { 3786 // CLREX{<c>}{<q>} ; T1 3787 EmitT32_32(0xf3bf8f2fU); 3788 AdvanceIT(); 3789 return; 3790 } else { 3791 // CLREX{<c>}{<q>} ; A1 3792 if (cond.Is(al)) { 3793 EmitA32(0xf57ff01fU); 3794 return; 3795 } 3796 } 3797 Delegate(kClrex, &Assembler::clrex, cond); 3798 } 3799 3800 void Assembler::clz(Condition cond, Register rd, Register rm) { 3801 VIXL_ASSERT(AllowAssembler()); 3802 CheckIT(cond); 3803 if (IsUsingT32()) { 3804 // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1 3805 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3806 EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() | 3807 (rm.GetCode() << 16)); 3808 AdvanceIT(); 3809 return; 3810 } 3811 } else { 3812 // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1 3813 if (cond.IsNotNever() && 3814 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3815 EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3816 rm.GetCode()); 3817 return; 3818 } 3819 } 3820 Delegate(kClz, &Assembler::clz, cond, rd, rm); 3821 } 3822 3823 void Assembler::cmn(Condition cond, 3824 EncodingSize size, 3825 Register rn, 3826 const Operand& operand) { 3827 VIXL_ASSERT(AllowAssembler()); 3828 CheckIT(cond); 3829 if (operand.IsImmediate()) { 3830 uint32_t imm = operand.GetImmediate(); 3831 if (IsUsingT32()) { 3832 ImmediateT32 immediate_t32(imm); 3833 // CMN{<c>}{<q>} <Rn>, #<const> ; T1 3834 if (!size.IsNarrow() && immediate_t32.IsValid() && 3835 (!rn.IsPC() || AllowUnpredictable())) { 3836 EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) | 3837 (immediate_t32.GetEncodingValue() & 0xff) | 3838 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3839 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3840 AdvanceIT(); 3841 return; 3842 } 3843 } else { 3844 ImmediateA32 immediate_a32(imm); 3845 // CMN{<c>}{<q>} <Rn>, #<const> ; A1 3846 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3847 EmitA32(0x03700000U | (cond.GetCondition() << 28) | 3848 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 3849 return; 3850 } 3851 } 3852 } 3853 if (operand.IsImmediateShiftedRegister()) { 3854 Register rm = operand.GetBaseRegister(); 3855 if (operand.IsPlainRegister()) { 3856 if (IsUsingT32()) { 3857 // CMN{<c>}{<q>} <Rn>, <Rm> ; T1 3858 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 3859 EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3)); 3860 AdvanceIT(); 3861 return; 3862 } 3863 } 3864 } 3865 Shift shift = operand.GetShift(); 3866 uint32_t amount = operand.GetShiftAmount(); 3867 if (IsUsingT32()) { 3868 // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2 3869 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 3870 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3871 uint32_t amount_ = amount % 32; 3872 EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() | 3873 (operand.GetTypeEncodingValue() << 4) | 3874 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3875 AdvanceIT(); 3876 return; 3877 } 3878 } else { 3879 // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 3880 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3881 uint32_t amount_ = amount % 32; 3882 EmitA32(0x01700000U | (cond.GetCondition() << 28) | 3883 (rn.GetCode() << 16) | rm.GetCode() | 3884 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3885 return; 3886 } 3887 } 3888 } 3889 if (operand.IsRegisterShiftedRegister()) { 3890 Register rm = operand.GetBaseRegister(); 3891 Shift shift = operand.GetShift(); 3892 Register rs = operand.GetShiftRegister(); 3893 if (IsUsingA32()) { 3894 // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 3895 if (cond.IsNotNever() && 3896 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 3897 EmitA32(0x01700010U | (cond.GetCondition() << 28) | 3898 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 3899 (rs.GetCode() << 8)); 3900 return; 3901 } 3902 } 3903 } 3904 Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand); 3905 } 3906 3907 void Assembler::cmp(Condition cond, 3908 EncodingSize size, 3909 Register rn, 3910 const Operand& operand) { 3911 VIXL_ASSERT(AllowAssembler()); 3912 CheckIT(cond); 3913 if (operand.IsImmediate()) { 3914 uint32_t imm = operand.GetImmediate(); 3915 if (IsUsingT32()) { 3916 ImmediateT32 immediate_t32(imm); 3917 // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1 3918 if (!size.IsWide() && rn.IsLow() && (imm <= 255)) { 3919 EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm); 3920 AdvanceIT(); 3921 return; 3922 } 3923 // CMP{<c>}{<q>} <Rn>, #<const> ; T2 3924 if (!size.IsNarrow() && immediate_t32.IsValid() && 3925 (!rn.IsPC() || AllowUnpredictable())) { 3926 EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) | 3927 (immediate_t32.GetEncodingValue() & 0xff) | 3928 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3929 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3930 AdvanceIT(); 3931 return; 3932 } 3933 } else { 3934 ImmediateA32 immediate_a32(imm); 3935 // CMP{<c>}{<q>} <Rn>, #<const> ; A1 3936 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3937 EmitA32(0x03500000U | (cond.GetCondition() << 28) | 3938 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 3939 return; 3940 } 3941 } 3942 } 3943 if (operand.IsImmediateShiftedRegister()) { 3944 Register rm = operand.GetBaseRegister(); 3945 if (operand.IsPlainRegister()) { 3946 if (IsUsingT32()) { 3947 // CMP{<c>}{<q>} <Rn>, <Rm> ; T1 3948 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 3949 EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3)); 3950 AdvanceIT(); 3951 return; 3952 } 3953 // CMP{<c>}{<q>} <Rn>, <Rm> ; T2 3954 if (!size.IsWide() && 3955 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3956 EmitT32_16(0x4500 | (rn.GetCode() & 0x7) | 3957 ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 3958 AdvanceIT(); 3959 return; 3960 } 3961 } 3962 } 3963 Shift shift = operand.GetShift(); 3964 uint32_t amount = operand.GetShiftAmount(); 3965 if (IsUsingT32()) { 3966 // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3 3967 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 3968 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3969 uint32_t amount_ = amount % 32; 3970 EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() | 3971 (operand.GetTypeEncodingValue() << 4) | 3972 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3973 AdvanceIT(); 3974 return; 3975 } 3976 } else { 3977 // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 3978 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3979 uint32_t amount_ = amount % 32; 3980 EmitA32(0x01500000U | (cond.GetCondition() << 28) | 3981 (rn.GetCode() << 16) | rm.GetCode() | 3982 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3983 return; 3984 } 3985 } 3986 } 3987 if (operand.IsRegisterShiftedRegister()) { 3988 Register rm = operand.GetBaseRegister(); 3989 Shift shift = operand.GetShift(); 3990 Register rs = operand.GetShiftRegister(); 3991 if (IsUsingA32()) { 3992 // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 3993 if (cond.IsNotNever() && 3994 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 3995 EmitA32(0x01500010U | (cond.GetCondition() << 28) | 3996 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 3997 (rs.GetCode() << 8)); 3998 return; 3999 } 4000 } 4001 } 4002 Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand); 4003 } 4004 4005 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) { 4006 VIXL_ASSERT(AllowAssembler()); 4007 CheckIT(cond); 4008 if (IsUsingT32()) { 4009 // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1 4010 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4011 AllowUnpredictable())) { 4012 EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4013 rm.GetCode()); 4014 AdvanceIT(); 4015 return; 4016 } 4017 } else { 4018 // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1 4019 if ((cond.Is(al) || AllowUnpredictable()) && 4020 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4021 EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4022 (rn.GetCode() << 16) | rm.GetCode()); 4023 return; 4024 } 4025 } 4026 Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm); 4027 } 4028 4029 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) { 4030 VIXL_ASSERT(AllowAssembler()); 4031 CheckIT(cond); 4032 if (IsUsingT32()) { 4033 // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1 4034 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4035 AllowUnpredictable())) { 4036 EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4037 rm.GetCode()); 4038 AdvanceIT(); 4039 return; 4040 } 4041 } else { 4042 // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1 4043 if ((cond.Is(al) || AllowUnpredictable()) && 4044 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4045 EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4046 (rn.GetCode() << 16) | rm.GetCode()); 4047 return; 4048 } 4049 } 4050 Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm); 4051 } 4052 4053 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) { 4054 VIXL_ASSERT(AllowAssembler()); 4055 CheckIT(cond); 4056 if (IsUsingT32()) { 4057 // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1 4058 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4059 AllowUnpredictable())) { 4060 EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4061 rm.GetCode()); 4062 AdvanceIT(); 4063 return; 4064 } 4065 } else { 4066 // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1 4067 if ((cond.Is(al) || AllowUnpredictable()) && 4068 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4069 EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4070 (rn.GetCode() << 16) | rm.GetCode()); 4071 return; 4072 } 4073 } 4074 Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm); 4075 } 4076 4077 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) { 4078 VIXL_ASSERT(AllowAssembler()); 4079 CheckIT(cond); 4080 if (IsUsingT32()) { 4081 // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1 4082 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4083 AllowUnpredictable())) { 4084 EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4085 rm.GetCode()); 4086 AdvanceIT(); 4087 return; 4088 } 4089 } else { 4090 // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1 4091 if ((cond.Is(al) || AllowUnpredictable()) && 4092 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4093 EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4094 (rn.GetCode() << 16) | rm.GetCode()); 4095 return; 4096 } 4097 } 4098 Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm); 4099 } 4100 4101 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) { 4102 VIXL_ASSERT(AllowAssembler()); 4103 CheckIT(cond); 4104 if (IsUsingT32()) { 4105 // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1 4106 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4107 AllowUnpredictable())) { 4108 EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4109 rm.GetCode()); 4110 AdvanceIT(); 4111 return; 4112 } 4113 } else { 4114 // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1 4115 if ((cond.Is(al) || AllowUnpredictable()) && 4116 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4117 EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4118 (rn.GetCode() << 16) | rm.GetCode()); 4119 return; 4120 } 4121 } 4122 Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm); 4123 } 4124 4125 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) { 4126 VIXL_ASSERT(AllowAssembler()); 4127 CheckIT(cond); 4128 if (IsUsingT32()) { 4129 // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1 4130 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4131 AllowUnpredictable())) { 4132 EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4133 rm.GetCode()); 4134 AdvanceIT(); 4135 return; 4136 } 4137 } else { 4138 // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1 4139 if ((cond.Is(al) || AllowUnpredictable()) && 4140 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4141 EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4142 (rn.GetCode() << 16) | rm.GetCode()); 4143 return; 4144 } 4145 } 4146 Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm); 4147 } 4148 4149 void Assembler::dmb(Condition cond, MemoryBarrier option) { 4150 VIXL_ASSERT(AllowAssembler()); 4151 CheckIT(cond); 4152 if (IsUsingT32()) { 4153 // DMB{<c>}{<q>} {<option>} ; T1 4154 EmitT32_32(0xf3bf8f50U | option.GetType()); 4155 AdvanceIT(); 4156 return; 4157 } else { 4158 // DMB{<c>}{<q>} {<option>} ; A1 4159 if (cond.Is(al)) { 4160 EmitA32(0xf57ff050U | option.GetType()); 4161 return; 4162 } 4163 } 4164 Delegate(kDmb, &Assembler::dmb, cond, option); 4165 } 4166 4167 void Assembler::dsb(Condition cond, MemoryBarrier option) { 4168 VIXL_ASSERT(AllowAssembler()); 4169 CheckIT(cond); 4170 if (IsUsingT32()) { 4171 // DSB{<c>}{<q>} {<option>} ; T1 4172 EmitT32_32(0xf3bf8f40U | option.GetType()); 4173 AdvanceIT(); 4174 return; 4175 } else { 4176 // DSB{<c>}{<q>} {<option>} ; A1 4177 if (cond.Is(al)) { 4178 EmitA32(0xf57ff040U | option.GetType()); 4179 return; 4180 } 4181 } 4182 Delegate(kDsb, &Assembler::dsb, cond, option); 4183 } 4184 4185 void Assembler::eor(Condition cond, 4186 EncodingSize size, 4187 Register rd, 4188 Register rn, 4189 const Operand& operand) { 4190 VIXL_ASSERT(AllowAssembler()); 4191 CheckIT(cond); 4192 if (operand.IsImmediate()) { 4193 uint32_t imm = operand.GetImmediate(); 4194 if (IsUsingT32()) { 4195 ImmediateT32 immediate_t32(imm); 4196 // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 4197 if (!size.IsNarrow() && immediate_t32.IsValid() && 4198 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4199 EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4200 (immediate_t32.GetEncodingValue() & 0xff) | 4201 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 4202 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 4203 AdvanceIT(); 4204 return; 4205 } 4206 } else { 4207 ImmediateA32 immediate_a32(imm); 4208 // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 4209 if (immediate_a32.IsValid() && cond.IsNotNever()) { 4210 EmitA32(0x02200000U | (cond.GetCondition() << 28) | 4211 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 4212 immediate_a32.GetEncodingValue()); 4213 return; 4214 } 4215 } 4216 } 4217 if (operand.IsImmediateShiftedRegister()) { 4218 Register rm = operand.GetBaseRegister(); 4219 if (operand.IsPlainRegister()) { 4220 if (IsUsingT32()) { 4221 // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 4222 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 4223 rm.IsLow()) { 4224 EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3)); 4225 AdvanceIT(); 4226 return; 4227 } 4228 } 4229 } 4230 Shift shift = operand.GetShift(); 4231 uint32_t amount = operand.GetShiftAmount(); 4232 if (IsUsingT32()) { 4233 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 4234 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 4235 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4236 uint32_t amount_ = amount % 32; 4237 EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4238 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 4239 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 4240 AdvanceIT(); 4241 return; 4242 } 4243 } else { 4244 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 4245 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 4246 uint32_t amount_ = amount % 32; 4247 EmitA32(0x00200000U | (cond.GetCondition() << 28) | 4248 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4249 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 4250 return; 4251 } 4252 } 4253 } 4254 if (operand.IsRegisterShiftedRegister()) { 4255 Register rm = operand.GetBaseRegister(); 4256 Shift shift = operand.GetShift(); 4257 Register rs = operand.GetShiftRegister(); 4258 if (IsUsingA32()) { 4259 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 4260 if (cond.IsNotNever() && 4261 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 4262 AllowUnpredictable())) { 4263 EmitA32(0x00200010U | (cond.GetCondition() << 28) | 4264 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4265 (shift.GetType() << 5) | (rs.GetCode() << 8)); 4266 return; 4267 } 4268 } 4269 } 4270 Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand); 4271 } 4272 4273 void Assembler::eors(Condition cond, 4274 EncodingSize size, 4275 Register rd, 4276 Register rn, 4277 const Operand& operand) { 4278 VIXL_ASSERT(AllowAssembler()); 4279 CheckIT(cond); 4280 if (operand.IsImmediate()) { 4281 uint32_t imm = operand.GetImmediate(); 4282 if (IsUsingT32()) { 4283 ImmediateT32 immediate_t32(imm); 4284 // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 4285 if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) && 4286 (!rn.IsPC() || AllowUnpredictable())) { 4287 EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4288 (immediate_t32.GetEncodingValue() & 0xff) | 4289 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 4290 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 4291 AdvanceIT(); 4292 return; 4293 } 4294 } else { 4295 ImmediateA32 immediate_a32(imm); 4296 // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 4297 if (immediate_a32.IsValid() && cond.IsNotNever()) { 4298 EmitA32(0x02300000U | (cond.GetCondition() << 28) | 4299 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 4300 immediate_a32.GetEncodingValue()); 4301 return; 4302 } 4303 } 4304 } 4305 if (operand.IsImmediateShiftedRegister()) { 4306 Register rm = operand.GetBaseRegister(); 4307 if (operand.IsPlainRegister()) { 4308 if (IsUsingT32()) { 4309 // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 4310 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 4311 rm.IsLow()) { 4312 EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3)); 4313 AdvanceIT(); 4314 return; 4315 } 4316 } 4317 } 4318 Shift shift = operand.GetShift(); 4319 uint32_t amount = operand.GetShiftAmount(); 4320 if (IsUsingT32()) { 4321 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 4322 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) && 4323 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4324 uint32_t amount_ = amount % 32; 4325 EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4326 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 4327 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 4328 AdvanceIT(); 4329 return; 4330 } 4331 } else { 4332 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 4333 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 4334 uint32_t amount_ = amount % 32; 4335 EmitA32(0x00300000U | (cond.GetCondition() << 28) | 4336 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4337 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 4338 return; 4339 } 4340 } 4341 } 4342 if (operand.IsRegisterShiftedRegister()) { 4343 Register rm = operand.GetBaseRegister(); 4344 Shift shift = operand.GetShift(); 4345 Register rs = operand.GetShiftRegister(); 4346 if (IsUsingA32()) { 4347 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 4348 if (cond.IsNotNever() && 4349 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 4350 AllowUnpredictable())) { 4351 EmitA32(0x00300010U | (cond.GetCondition() << 28) | 4352 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4353 (shift.GetType() << 5) | (rs.GetCode() << 8)); 4354 return; 4355 } 4356 } 4357 } 4358 Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand); 4359 } 4360 4361 void Assembler::fldmdbx(Condition cond, 4362 Register rn, 4363 WriteBack write_back, 4364 DRegisterList dreglist) { 4365 VIXL_ASSERT(AllowAssembler()); 4366 CheckIT(cond); 4367 if (IsUsingT32()) { 4368 // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1 4369 if (write_back.DoesWriteBack() && 4370 (((dreglist.GetLength() <= 16) && 4371 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4372 AllowUnpredictable())) { 4373 const DRegister& dreg = dreglist.GetFirstDRegister(); 4374 unsigned len = dreglist.GetLength() * 2; 4375 EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 4376 (len & 0xff)); 4377 AdvanceIT(); 4378 return; 4379 } 4380 } else { 4381 // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1 4382 if (write_back.DoesWriteBack() && cond.IsNotNever() && 4383 (((dreglist.GetLength() <= 16) && 4384 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4385 AllowUnpredictable())) { 4386 const DRegister& dreg = dreglist.GetFirstDRegister(); 4387 unsigned len = dreglist.GetLength() * 2; 4388 EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4389 dreg.Encode(22, 12) | (len & 0xff)); 4390 return; 4391 } 4392 } 4393 Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist); 4394 } 4395 4396 void Assembler::fldmiax(Condition cond, 4397 Register rn, 4398 WriteBack write_back, 4399 DRegisterList dreglist) { 4400 VIXL_ASSERT(AllowAssembler()); 4401 CheckIT(cond); 4402 if (IsUsingT32()) { 4403 // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1 4404 if ((((dreglist.GetLength() <= 16) && 4405 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4406 AllowUnpredictable())) { 4407 const DRegister& dreg = dreglist.GetFirstDRegister(); 4408 unsigned len = dreglist.GetLength() * 2; 4409 EmitT32_32(0xec900b01U | (rn.GetCode() << 16) | 4410 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4411 (len & 0xff)); 4412 AdvanceIT(); 4413 return; 4414 } 4415 } else { 4416 // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1 4417 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 4418 (dreglist.GetLastDRegister().GetCode() < 16) && 4419 (!rn.IsPC() || !write_back.DoesWriteBack())) || 4420 AllowUnpredictable())) { 4421 const DRegister& dreg = dreglist.GetFirstDRegister(); 4422 unsigned len = dreglist.GetLength() * 2; 4423 EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4424 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4425 (len & 0xff)); 4426 return; 4427 } 4428 } 4429 Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist); 4430 } 4431 4432 void Assembler::fstmdbx(Condition cond, 4433 Register rn, 4434 WriteBack write_back, 4435 DRegisterList dreglist) { 4436 VIXL_ASSERT(AllowAssembler()); 4437 CheckIT(cond); 4438 if (IsUsingT32()) { 4439 // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1 4440 if (write_back.DoesWriteBack() && 4441 (((dreglist.GetLength() <= 16) && 4442 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4443 AllowUnpredictable())) { 4444 const DRegister& dreg = dreglist.GetFirstDRegister(); 4445 unsigned len = dreglist.GetLength() * 2; 4446 EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 4447 (len & 0xff)); 4448 AdvanceIT(); 4449 return; 4450 } 4451 } else { 4452 // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1 4453 if (write_back.DoesWriteBack() && cond.IsNotNever() && 4454 (((dreglist.GetLength() <= 16) && 4455 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4456 AllowUnpredictable())) { 4457 const DRegister& dreg = dreglist.GetFirstDRegister(); 4458 unsigned len = dreglist.GetLength() * 2; 4459 EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4460 dreg.Encode(22, 12) | (len & 0xff)); 4461 return; 4462 } 4463 } 4464 Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist); 4465 } 4466 4467 void Assembler::fstmiax(Condition cond, 4468 Register rn, 4469 WriteBack write_back, 4470 DRegisterList dreglist) { 4471 VIXL_ASSERT(AllowAssembler()); 4472 CheckIT(cond); 4473 if (IsUsingT32()) { 4474 // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1 4475 if ((((dreglist.GetLength() <= 16) && 4476 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4477 AllowUnpredictable())) { 4478 const DRegister& dreg = dreglist.GetFirstDRegister(); 4479 unsigned len = dreglist.GetLength() * 2; 4480 EmitT32_32(0xec800b01U | (rn.GetCode() << 16) | 4481 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4482 (len & 0xff)); 4483 AdvanceIT(); 4484 return; 4485 } 4486 } else { 4487 // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1 4488 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 4489 (dreglist.GetLastDRegister().GetCode() < 16) && 4490 (!rn.IsPC() || !write_back.DoesWriteBack())) || 4491 AllowUnpredictable())) { 4492 const DRegister& dreg = dreglist.GetFirstDRegister(); 4493 unsigned len = dreglist.GetLength() * 2; 4494 EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4495 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4496 (len & 0xff)); 4497 return; 4498 } 4499 } 4500 Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist); 4501 } 4502 4503 void Assembler::hlt(Condition cond, uint32_t imm) { 4504 VIXL_ASSERT(AllowAssembler()); 4505 CheckIT(cond); 4506 if (IsUsingT32()) { 4507 // HLT{<q>} {#}<imm> ; T1 4508 if ((imm <= 63)) { 4509 EmitT32_16(0xba80 | imm); 4510 AdvanceIT(); 4511 return; 4512 } 4513 } else { 4514 // HLT{<q>} {#}<imm> ; A1 4515 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 4516 EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) | 4517 ((imm & 0xfff0) << 4)); 4518 return; 4519 } 4520 } 4521 Delegate(kHlt, &Assembler::hlt, cond, imm); 4522 } 4523 4524 void Assembler::hvc(Condition cond, uint32_t imm) { 4525 VIXL_ASSERT(AllowAssembler()); 4526 CheckIT(cond); 4527 if (IsUsingT32()) { 4528 // HVC{<q>} {#}<imm16> ; T1 4529 if ((imm <= 65535) && (OutsideITBlock() || AllowUnpredictable())) { 4530 EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4)); 4531 AdvanceIT(); 4532 return; 4533 } 4534 } else { 4535 // HVC{<q>} {#}<imm16> ; A1 4536 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 4537 EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) | 4538 ((imm & 0xfff0) << 4)); 4539 return; 4540 } 4541 } 4542 Delegate(kHvc, &Assembler::hvc, cond, imm); 4543 } 4544 4545 void Assembler::isb(Condition cond, MemoryBarrier option) { 4546 VIXL_ASSERT(AllowAssembler()); 4547 CheckIT(cond); 4548 if (IsUsingT32()) { 4549 // ISB{<c>}{<q>} {<option>} ; T1 4550 EmitT32_32(0xf3bf8f60U | option.GetType()); 4551 AdvanceIT(); 4552 return; 4553 } else { 4554 // ISB{<c>}{<q>} {<option>} ; A1 4555 if (cond.Is(al)) { 4556 EmitA32(0xf57ff060U | option.GetType()); 4557 return; 4558 } 4559 } 4560 Delegate(kIsb, &Assembler::isb, cond, option); 4561 } 4562 4563 void Assembler::it(Condition cond, uint16_t mask) { 4564 VIXL_ASSERT(AllowAssembler()); 4565 CheckNotIT(); 4566 if (mask != 0) { 4567 if ((cond.GetCondition() & 0x1) != 0) { 4568 if ((mask & 0x1) != 0) { 4569 mask ^= 0xE; 4570 } else if ((mask & 0x2) != 0) { 4571 mask ^= 0xC; 4572 } else if ((mask & 0x4) != 0) { 4573 mask ^= 0x8; 4574 } 4575 } 4576 if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask); 4577 SetIT(cond, mask); 4578 return; 4579 } 4580 DelegateIt(cond, mask); 4581 } 4582 4583 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) { 4584 VIXL_ASSERT(AllowAssembler()); 4585 CheckIT(cond); 4586 if (operand.IsImmediateZero()) { 4587 Register rn = operand.GetBaseRegister(); 4588 if (IsUsingT32()) { 4589 // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1 4590 if (operand.IsOffset() && 4591 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4592 EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4593 AdvanceIT(); 4594 return; 4595 } 4596 } else { 4597 // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1 4598 if (operand.IsOffset() && cond.IsNotNever() && 4599 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4600 EmitA32(0x01900c9fU | (cond.GetCondition() << 28) | 4601 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4602 return; 4603 } 4604 } 4605 } 4606 Delegate(kLda, &Assembler::lda, cond, rt, operand); 4607 } 4608 4609 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) { 4610 VIXL_ASSERT(AllowAssembler()); 4611 CheckIT(cond); 4612 if (operand.IsImmediateZero()) { 4613 Register rn = operand.GetBaseRegister(); 4614 if (IsUsingT32()) { 4615 // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1 4616 if (operand.IsOffset() && 4617 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4618 EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4619 AdvanceIT(); 4620 return; 4621 } 4622 } else { 4623 // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1 4624 if (operand.IsOffset() && cond.IsNotNever() && 4625 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4626 EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) | 4627 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4628 return; 4629 } 4630 } 4631 } 4632 Delegate(kLdab, &Assembler::ldab, cond, rt, operand); 4633 } 4634 4635 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) { 4636 VIXL_ASSERT(AllowAssembler()); 4637 CheckIT(cond); 4638 if (operand.IsImmediateZero()) { 4639 Register rn = operand.GetBaseRegister(); 4640 if (IsUsingT32()) { 4641 // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1 4642 if (operand.IsOffset() && 4643 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4644 EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4645 AdvanceIT(); 4646 return; 4647 } 4648 } else { 4649 // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1 4650 if (operand.IsOffset() && cond.IsNotNever() && 4651 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4652 EmitA32(0x01900e9fU | (cond.GetCondition() << 28) | 4653 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4654 return; 4655 } 4656 } 4657 } 4658 Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand); 4659 } 4660 4661 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) { 4662 VIXL_ASSERT(AllowAssembler()); 4663 CheckIT(cond); 4664 if (operand.IsImmediateZero()) { 4665 Register rn = operand.GetBaseRegister(); 4666 if (IsUsingT32()) { 4667 // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1 4668 if (operand.IsOffset() && 4669 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4670 EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4671 AdvanceIT(); 4672 return; 4673 } 4674 } else { 4675 // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1 4676 if (operand.IsOffset() && cond.IsNotNever() && 4677 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4678 EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) | 4679 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4680 return; 4681 } 4682 } 4683 } 4684 Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand); 4685 } 4686 4687 void Assembler::ldaexd(Condition cond, 4688 Register rt, 4689 Register rt2, 4690 const MemOperand& operand) { 4691 VIXL_ASSERT(AllowAssembler()); 4692 CheckIT(cond); 4693 if (operand.IsImmediateZero()) { 4694 Register rn = operand.GetBaseRegister(); 4695 if (IsUsingT32()) { 4696 // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1 4697 if (operand.IsOffset() && 4698 ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4699 EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 4700 (rn.GetCode() << 16)); 4701 AdvanceIT(); 4702 return; 4703 } 4704 } else { 4705 // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1 4706 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 4707 operand.IsOffset() && cond.IsNotNever() && 4708 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) || 4709 AllowUnpredictable())) { 4710 EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) | 4711 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4712 return; 4713 } 4714 } 4715 } 4716 Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand); 4717 } 4718 4719 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) { 4720 VIXL_ASSERT(AllowAssembler()); 4721 CheckIT(cond); 4722 if (operand.IsImmediateZero()) { 4723 Register rn = operand.GetBaseRegister(); 4724 if (IsUsingT32()) { 4725 // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1 4726 if (operand.IsOffset() && 4727 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4728 EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4729 AdvanceIT(); 4730 return; 4731 } 4732 } else { 4733 // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1 4734 if (operand.IsOffset() && cond.IsNotNever() && 4735 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4736 EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) | 4737 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4738 return; 4739 } 4740 } 4741 } 4742 Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand); 4743 } 4744 4745 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) { 4746 VIXL_ASSERT(AllowAssembler()); 4747 CheckIT(cond); 4748 if (operand.IsImmediateZero()) { 4749 Register rn = operand.GetBaseRegister(); 4750 if (IsUsingT32()) { 4751 // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1 4752 if (operand.IsOffset() && 4753 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4754 EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4755 AdvanceIT(); 4756 return; 4757 } 4758 } else { 4759 // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1 4760 if (operand.IsOffset() && cond.IsNotNever() && 4761 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4762 EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) | 4763 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4764 return; 4765 } 4766 } 4767 } 4768 Delegate(kLdah, &Assembler::ldah, cond, rt, operand); 4769 } 4770 4771 void Assembler::ldm(Condition cond, 4772 EncodingSize size, 4773 Register rn, 4774 WriteBack write_back, 4775 RegisterList registers) { 4776 VIXL_ASSERT(AllowAssembler()); 4777 CheckIT(cond); 4778 if (IsUsingT32()) { 4779 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1 4780 if (!size.IsWide() && rn.IsLow() && 4781 (((registers.GetList() & (1 << rn.GetCode())) == 0) == 4782 write_back.DoesWriteBack()) && 4783 ((registers.GetList() & ~0xff) == 0)) { 4784 EmitT32_16(0xc800 | (rn.GetCode() << 8) | 4785 GetRegisterListEncoding(registers, 0, 8)); 4786 AdvanceIT(); 4787 return; 4788 } 4789 // LDM{<c>}{<q>} SP!, <registers> ; T1 4790 if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() && 4791 registers.IsR0toR7orPC()) { 4792 EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) | 4793 GetRegisterListEncoding(registers, 0, 8)); 4794 AdvanceIT(); 4795 return; 4796 } 4797 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2 4798 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) && 4799 (!rn.IsPC() || AllowUnpredictable())) { 4800 EmitT32_32(0xe8900000U | (rn.GetCode() << 16) | 4801 (write_back.GetWriteBackUint32() << 21) | 4802 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4803 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4804 GetRegisterListEncoding(registers, 0, 13)); 4805 AdvanceIT(); 4806 return; 4807 } 4808 } else { 4809 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1 4810 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4811 EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4812 (write_back.GetWriteBackUint32() << 21) | 4813 GetRegisterListEncoding(registers, 0, 16)); 4814 return; 4815 } 4816 } 4817 Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers); 4818 } 4819 4820 void Assembler::ldmda(Condition cond, 4821 Register rn, 4822 WriteBack write_back, 4823 RegisterList registers) { 4824 VIXL_ASSERT(AllowAssembler()); 4825 CheckIT(cond); 4826 if (IsUsingA32()) { 4827 // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4828 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4829 EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4830 (write_back.GetWriteBackUint32() << 21) | 4831 GetRegisterListEncoding(registers, 0, 16)); 4832 return; 4833 } 4834 } 4835 Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers); 4836 } 4837 4838 void Assembler::ldmdb(Condition cond, 4839 Register rn, 4840 WriteBack write_back, 4841 RegisterList registers) { 4842 VIXL_ASSERT(AllowAssembler()); 4843 CheckIT(cond); 4844 if (IsUsingT32()) { 4845 // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1 4846 if (((registers.GetList() & ~0xdfff) == 0) && 4847 (!rn.IsPC() || AllowUnpredictable())) { 4848 EmitT32_32(0xe9100000U | (rn.GetCode() << 16) | 4849 (write_back.GetWriteBackUint32() << 21) | 4850 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4851 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4852 GetRegisterListEncoding(registers, 0, 13)); 4853 AdvanceIT(); 4854 return; 4855 } 4856 } else { 4857 // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1 4858 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4859 EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4860 (write_back.GetWriteBackUint32() << 21) | 4861 GetRegisterListEncoding(registers, 0, 16)); 4862 return; 4863 } 4864 } 4865 Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers); 4866 } 4867 4868 void Assembler::ldmea(Condition cond, 4869 Register rn, 4870 WriteBack write_back, 4871 RegisterList registers) { 4872 VIXL_ASSERT(AllowAssembler()); 4873 CheckIT(cond); 4874 if (IsUsingT32()) { 4875 // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1 4876 if (((registers.GetList() & ~0xdfff) == 0) && 4877 (!rn.IsPC() || AllowUnpredictable())) { 4878 EmitT32_32(0xe9100000U | (rn.GetCode() << 16) | 4879 (write_back.GetWriteBackUint32() << 21) | 4880 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4881 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4882 GetRegisterListEncoding(registers, 0, 13)); 4883 AdvanceIT(); 4884 return; 4885 } 4886 } else { 4887 // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4888 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4889 EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4890 (write_back.GetWriteBackUint32() << 21) | 4891 GetRegisterListEncoding(registers, 0, 16)); 4892 return; 4893 } 4894 } 4895 Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers); 4896 } 4897 4898 void Assembler::ldmed(Condition cond, 4899 Register rn, 4900 WriteBack write_back, 4901 RegisterList registers) { 4902 VIXL_ASSERT(AllowAssembler()); 4903 CheckIT(cond); 4904 if (IsUsingA32()) { 4905 // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1 4906 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4907 EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4908 (write_back.GetWriteBackUint32() << 21) | 4909 GetRegisterListEncoding(registers, 0, 16)); 4910 return; 4911 } 4912 } 4913 Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers); 4914 } 4915 4916 void Assembler::ldmfa(Condition cond, 4917 Register rn, 4918 WriteBack write_back, 4919 RegisterList registers) { 4920 VIXL_ASSERT(AllowAssembler()); 4921 CheckIT(cond); 4922 if (IsUsingA32()) { 4923 // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4924 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4925 EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4926 (write_back.GetWriteBackUint32() << 21) | 4927 GetRegisterListEncoding(registers, 0, 16)); 4928 return; 4929 } 4930 } 4931 Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers); 4932 } 4933 4934 void Assembler::ldmfd(Condition cond, 4935 EncodingSize size, 4936 Register rn, 4937 WriteBack write_back, 4938 RegisterList registers) { 4939 VIXL_ASSERT(AllowAssembler()); 4940 CheckIT(cond); 4941 if (IsUsingT32()) { 4942 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1 4943 if (!size.IsWide() && rn.IsLow() && 4944 (((registers.GetList() & (1 << rn.GetCode())) == 0) == 4945 write_back.DoesWriteBack()) && 4946 ((registers.GetList() & ~0xff) == 0)) { 4947 EmitT32_16(0xc800 | (rn.GetCode() << 8) | 4948 GetRegisterListEncoding(registers, 0, 8)); 4949 AdvanceIT(); 4950 return; 4951 } 4952 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2 4953 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) && 4954 (!rn.IsPC() || AllowUnpredictable())) { 4955 EmitT32_32(0xe8900000U | (rn.GetCode() << 16) | 4956 (write_back.GetWriteBackUint32() << 21) | 4957 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4958 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4959 GetRegisterListEncoding(registers, 0, 13)); 4960 AdvanceIT(); 4961 return; 4962 } 4963 } else { 4964 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1 4965 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4966 EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4967 (write_back.GetWriteBackUint32() << 21) | 4968 GetRegisterListEncoding(registers, 0, 16)); 4969 return; 4970 } 4971 } 4972 Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers); 4973 } 4974 4975 void Assembler::ldmib(Condition cond, 4976 Register rn, 4977 WriteBack write_back, 4978 RegisterList registers) { 4979 VIXL_ASSERT(AllowAssembler()); 4980 CheckIT(cond); 4981 if (IsUsingA32()) { 4982 // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1 4983 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4984 EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4985 (write_back.GetWriteBackUint32() << 21) | 4986 GetRegisterListEncoding(registers, 0, 16)); 4987 return; 4988 } 4989 } 4990 Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers); 4991 } 4992 4993 void Assembler::ldr(Condition cond, 4994 EncodingSize size, 4995 Register rt, 4996 const MemOperand& operand) { 4997 VIXL_ASSERT(AllowAssembler()); 4998 CheckIT(cond); 4999 if (operand.IsImmediate()) { 5000 Register rn = operand.GetBaseRegister(); 5001 int32_t offset = operand.GetOffsetImmediate(); 5002 if (IsUsingT32()) { 5003 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 5004 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 5005 (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) { 5006 int32_t offset_ = offset >> 2; 5007 EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) | 5008 ((offset_ & 0x1f) << 6)); 5009 AdvanceIT(); 5010 return; 5011 } 5012 // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2 5013 if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) && 5014 ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) { 5015 int32_t offset_ = offset >> 2; 5016 EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff)); 5017 AdvanceIT(); 5018 return; 5019 } 5020 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3 5021 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5022 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 5023 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5024 AllowUnpredictable())) { 5025 EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5026 (offset & 0xfff)); 5027 AdvanceIT(); 5028 return; 5029 } 5030 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4 5031 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5032 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 5033 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5034 AllowUnpredictable())) { 5035 EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5036 (-offset & 0xff)); 5037 AdvanceIT(); 5038 return; 5039 } 5040 // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4 5041 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5042 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 5043 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5044 AllowUnpredictable())) { 5045 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5046 uint32_t offset_ = abs(offset); 5047 EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5048 offset_ | (sign << 9)); 5049 AdvanceIT(); 5050 return; 5051 } 5052 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4 5053 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5054 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 5055 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5056 AllowUnpredictable())) { 5057 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5058 uint32_t offset_ = abs(offset); 5059 EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5060 offset_ | (sign << 9)); 5061 AdvanceIT(); 5062 return; 5063 } 5064 // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2 5065 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 5066 rn.Is(pc) && operand.IsOffset() && 5067 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5068 AllowUnpredictable())) { 5069 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5070 uint32_t offset_ = abs(offset); 5071 EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 5072 AdvanceIT(); 5073 return; 5074 } 5075 } else { 5076 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 5077 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 5078 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5079 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5080 uint32_t offset_ = abs(offset); 5081 EmitA32(0x05100000U | (cond.GetCondition() << 28) | 5082 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5083 (sign << 23)); 5084 return; 5085 } 5086 // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 5087 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 5088 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5089 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5090 uint32_t offset_ = abs(offset); 5091 EmitA32(0x04100000U | (cond.GetCondition() << 28) | 5092 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5093 (sign << 23)); 5094 return; 5095 } 5096 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 5097 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 5098 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5099 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5100 uint32_t offset_ = abs(offset); 5101 EmitA32(0x05300000U | (cond.GetCondition() << 28) | 5102 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5103 (sign << 23)); 5104 return; 5105 } 5106 // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 5107 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 5108 operand.IsOffset() && cond.IsNotNever()) { 5109 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5110 uint32_t offset_ = abs(offset); 5111 EmitA32(0x051f0000U | (cond.GetCondition() << 28) | 5112 (rt.GetCode() << 12) | offset_ | (sign << 23)); 5113 return; 5114 } 5115 } 5116 } 5117 if (operand.IsPlainRegister()) { 5118 Register rn = operand.GetBaseRegister(); 5119 Sign sign = operand.GetSign(); 5120 Register rm = operand.GetOffsetRegister(); 5121 if (IsUsingT32()) { 5122 // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 5123 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 5124 sign.IsPlus() && operand.IsOffset()) { 5125 EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) | 5126 (rm.GetCode() << 6)); 5127 AdvanceIT(); 5128 return; 5129 } 5130 } 5131 } 5132 if (operand.IsShiftedRegister()) { 5133 Register rn = operand.GetBaseRegister(); 5134 Sign sign = operand.GetSign(); 5135 Register rm = operand.GetOffsetRegister(); 5136 Shift shift = operand.GetShift(); 5137 uint32_t amount = operand.GetShiftAmount(); 5138 if (IsUsingT32()) { 5139 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 5140 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 5141 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 5142 ((!rm.IsPC() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) || 5143 AllowUnpredictable())) { 5144 EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5145 rm.GetCode() | (amount << 4)); 5146 AdvanceIT(); 5147 return; 5148 } 5149 } else { 5150 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 5151 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() && 5152 (!rm.IsPC() || AllowUnpredictable())) { 5153 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5154 uint32_t shift_ = TypeEncodingValue(shift); 5155 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5156 EmitA32(0x07100000U | (cond.GetCondition() << 28) | 5157 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5158 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5159 return; 5160 } 5161 // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 5162 if (operand.IsShiftValid() && operand.IsPostIndex() && 5163 cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) { 5164 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5165 uint32_t shift_ = TypeEncodingValue(shift); 5166 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5167 EmitA32(0x06100000U | (cond.GetCondition() << 28) | 5168 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5169 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5170 return; 5171 } 5172 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 5173 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() && 5174 (!rm.IsPC() || AllowUnpredictable())) { 5175 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5176 uint32_t shift_ = TypeEncodingValue(shift); 5177 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5178 EmitA32(0x07300000U | (cond.GetCondition() << 28) | 5179 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5180 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5181 return; 5182 } 5183 } 5184 } 5185 Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand); 5186 } 5187 5188 void Assembler::ldr(Condition cond, 5189 EncodingSize size, 5190 Register rt, 5191 Location* location) { 5192 VIXL_ASSERT(AllowAssembler()); 5193 CheckIT(cond); 5194 Location::Offset offset = 5195 location->IsBound() 5196 ? location->GetLocation() - 5197 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5198 : 0; 5199 if (IsUsingT32()) { 5200 // LDR{<c>}{<q>} <Rt>, <label> ; T1 5201 if (!size.IsWide() && rt.IsLow() && 5202 ((location->IsBound() && (offset >= 0) && (offset <= 1020) && 5203 ((offset & 0x3) == 0)) || 5204 (!location->IsBound() && size.IsNarrow()))) { 5205 static class EmitOp : public Location::EmitOperator { 5206 public: 5207 EmitOp() : Location::EmitOperator(T32) {} 5208 virtual uint32_t Encode(uint32_t instr, 5209 Location::Offset program_counter, 5210 const Location* loc) const VIXL_OVERRIDE { 5211 program_counter += kT32PcDelta; 5212 Location::Offset off = 5213 loc->GetLocation() - AlignDown(program_counter, 4); 5214 VIXL_ASSERT((off >= 0) && (off <= 1020) && ((off & 0x3) == 0)); 5215 const int32_t target = off >> 2; 5216 return instr | (target & 0xff); 5217 } 5218 } immop; 5219 EmitT32_16( 5220 Link(0x4800 | (rt.GetCode() << 8), location, immop, &kT16DataInfo)); 5221 AdvanceIT(); 5222 return; 5223 } 5224 // LDR{<c>}{<q>} <Rt>, <label> ; T2 5225 if (!size.IsNarrow() && 5226 ((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5227 !location->IsBound()) && 5228 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5229 AllowUnpredictable())) { 5230 static class EmitOp : public Location::EmitOperator { 5231 public: 5232 EmitOp() : Location::EmitOperator(T32) {} 5233 virtual uint32_t Encode(uint32_t instr, 5234 Location::Offset program_counter, 5235 const Location* loc) const VIXL_OVERRIDE { 5236 program_counter += kT32PcDelta; 5237 Location::Offset off = 5238 loc->GetLocation() - AlignDown(program_counter, 4); 5239 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 5240 uint32_t U = (off >= 0); 5241 int32_t target = abs(off) | (U << 12); 5242 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5243 } 5244 } immop; 5245 EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12), 5246 location, 5247 immop, 5248 &kT32FarDataInfo)); 5249 AdvanceIT(); 5250 return; 5251 } 5252 } else { 5253 // LDR{<c>}{<q>} <Rt>, <label> ; A1 5254 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5255 !location->IsBound()) && 5256 cond.IsNotNever()) { 5257 static class EmitOp : public Location::EmitOperator { 5258 public: 5259 EmitOp() : Location::EmitOperator(A32) {} 5260 virtual uint32_t Encode(uint32_t instr, 5261 Location::Offset program_counter, 5262 const Location* loc) const VIXL_OVERRIDE { 5263 program_counter += kA32PcDelta; 5264 Location::Offset off = 5265 loc->GetLocation() - AlignDown(program_counter, 4); 5266 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 5267 uint32_t U = (off >= 0); 5268 int32_t target = abs(off) | (U << 12); 5269 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5270 } 5271 } immop; 5272 EmitA32( 5273 Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5274 location, 5275 immop, 5276 &kA32FarDataInfo)); 5277 return; 5278 } 5279 } 5280 Delegate(kLdr, &Assembler::ldr, cond, size, rt, location); 5281 } 5282 5283 bool Assembler::ldr_info(Condition cond, 5284 EncodingSize size, 5285 Register rt, 5286 Location* location, 5287 const struct ReferenceInfo** info) { 5288 VIXL_ASSERT(!location->IsBound()); 5289 USE(location); 5290 if (IsUsingT32()) { 5291 // LDR{<c>}{<q>} <Rt>, <label> ; T1 5292 if (!size.IsWide() && rt.IsLow() && size.IsNarrow()) { 5293 *info = &kT16DataInfo; 5294 return true; 5295 } 5296 // LDR{<c>}{<q>} <Rt>, <label> ; T2 5297 if (!size.IsNarrow()) { 5298 *info = &kT32FarDataInfo; 5299 return true; 5300 } 5301 } else { 5302 // LDR{<c>}{<q>} <Rt>, <label> ; A1 5303 if (cond.IsNotNever()) { 5304 *info = &kA32FarDataInfo; 5305 return true; 5306 } 5307 } 5308 return false; 5309 } 5310 5311 void Assembler::ldrb(Condition cond, 5312 EncodingSize size, 5313 Register rt, 5314 const MemOperand& operand) { 5315 VIXL_ASSERT(AllowAssembler()); 5316 CheckIT(cond); 5317 if (operand.IsImmediate()) { 5318 Register rn = operand.GetBaseRegister(); 5319 int32_t offset = operand.GetOffsetImmediate(); 5320 if (IsUsingT32()) { 5321 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 5322 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 5323 (offset <= 31) && operand.IsOffset()) { 5324 EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) | 5325 ((offset & 0x1f) << 6)); 5326 AdvanceIT(); 5327 return; 5328 } 5329 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 5330 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5331 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5332 EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5333 (offset & 0xfff)); 5334 AdvanceIT(); 5335 return; 5336 } 5337 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 5338 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5339 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5340 EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5341 (-offset & 0xff)); 5342 AdvanceIT(); 5343 return; 5344 } 5345 // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 5346 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5347 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5348 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5349 uint32_t offset_ = abs(offset); 5350 EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5351 offset_ | (sign << 9)); 5352 AdvanceIT(); 5353 return; 5354 } 5355 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 5356 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5357 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5358 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5359 uint32_t offset_ = abs(offset); 5360 EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5361 offset_ | (sign << 9)); 5362 AdvanceIT(); 5363 return; 5364 } 5365 // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 5366 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 5367 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 5368 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5369 uint32_t offset_ = abs(offset); 5370 EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 5371 AdvanceIT(); 5372 return; 5373 } 5374 } else { 5375 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 5376 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 5377 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5378 (!rt.IsPC() || AllowUnpredictable())) { 5379 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5380 uint32_t offset_ = abs(offset); 5381 EmitA32(0x05500000U | (cond.GetCondition() << 28) | 5382 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5383 (sign << 23)); 5384 return; 5385 } 5386 // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 5387 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 5388 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5389 (!rt.IsPC() || AllowUnpredictable())) { 5390 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5391 uint32_t offset_ = abs(offset); 5392 EmitA32(0x04500000U | (cond.GetCondition() << 28) | 5393 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5394 (sign << 23)); 5395 return; 5396 } 5397 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 5398 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 5399 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5400 (!rt.IsPC() || AllowUnpredictable())) { 5401 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5402 uint32_t offset_ = abs(offset); 5403 EmitA32(0x05700000U | (cond.GetCondition() << 28) | 5404 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5405 (sign << 23)); 5406 return; 5407 } 5408 // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 5409 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 5410 operand.IsOffset() && cond.IsNotNever() && 5411 (!rt.IsPC() || AllowUnpredictable())) { 5412 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5413 uint32_t offset_ = abs(offset); 5414 EmitA32(0x055f0000U | (cond.GetCondition() << 28) | 5415 (rt.GetCode() << 12) | offset_ | (sign << 23)); 5416 return; 5417 } 5418 } 5419 } 5420 if (operand.IsPlainRegister()) { 5421 Register rn = operand.GetBaseRegister(); 5422 Sign sign = operand.GetSign(); 5423 Register rm = operand.GetOffsetRegister(); 5424 if (IsUsingT32()) { 5425 // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 5426 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 5427 sign.IsPlus() && operand.IsOffset()) { 5428 EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) | 5429 (rm.GetCode() << 6)); 5430 AdvanceIT(); 5431 return; 5432 } 5433 } 5434 } 5435 if (operand.IsShiftedRegister()) { 5436 Register rn = operand.GetBaseRegister(); 5437 Sign sign = operand.GetSign(); 5438 Register rm = operand.GetOffsetRegister(); 5439 Shift shift = operand.GetShift(); 5440 uint32_t amount = operand.GetShiftAmount(); 5441 if (IsUsingT32()) { 5442 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 5443 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 5444 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) && 5445 (!rm.IsPC() || AllowUnpredictable())) { 5446 EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5447 rm.GetCode() | (amount << 4)); 5448 AdvanceIT(); 5449 return; 5450 } 5451 } else { 5452 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 5453 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() && 5454 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 5455 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5456 uint32_t shift_ = TypeEncodingValue(shift); 5457 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5458 EmitA32(0x07500000U | (cond.GetCondition() << 28) | 5459 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5460 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5461 return; 5462 } 5463 // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 5464 if (operand.IsShiftValid() && operand.IsPostIndex() && 5465 cond.IsNotNever() && 5466 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 5467 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5468 uint32_t shift_ = TypeEncodingValue(shift); 5469 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5470 EmitA32(0x06500000U | (cond.GetCondition() << 28) | 5471 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5472 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5473 return; 5474 } 5475 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 5476 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() && 5477 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 5478 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5479 uint32_t shift_ = TypeEncodingValue(shift); 5480 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5481 EmitA32(0x07700000U | (cond.GetCondition() << 28) | 5482 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5483 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5484 return; 5485 } 5486 } 5487 } 5488 Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand); 5489 } 5490 5491 void Assembler::ldrb(Condition cond, Register rt, Location* location) { 5492 VIXL_ASSERT(AllowAssembler()); 5493 CheckIT(cond); 5494 Location::Offset offset = 5495 location->IsBound() 5496 ? location->GetLocation() - 5497 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5498 : 0; 5499 if (IsUsingT32()) { 5500 // LDRB{<c>}{<q>} <Rt>, <label> ; T1 5501 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5502 !location->IsBound()) && 5503 !rt.Is(pc)) { 5504 static class EmitOp : public Location::EmitOperator { 5505 public: 5506 EmitOp() : Location::EmitOperator(T32) {} 5507 virtual uint32_t Encode(uint32_t instr, 5508 Location::Offset program_counter, 5509 const Location* loc) const VIXL_OVERRIDE { 5510 program_counter += kT32PcDelta; 5511 Location::Offset off = 5512 loc->GetLocation() - AlignDown(program_counter, 4); 5513 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 5514 uint32_t U = (off >= 0); 5515 int32_t target = abs(off) | (U << 12); 5516 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5517 } 5518 } immop; 5519 EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12), 5520 location, 5521 immop, 5522 &kT32FarDataInfo)); 5523 AdvanceIT(); 5524 return; 5525 } 5526 } else { 5527 // LDRB{<c>}{<q>} <Rt>, <label> ; A1 5528 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5529 !location->IsBound()) && 5530 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 5531 static class EmitOp : public Location::EmitOperator { 5532 public: 5533 EmitOp() : Location::EmitOperator(A32) {} 5534 virtual uint32_t Encode(uint32_t instr, 5535 Location::Offset program_counter, 5536 const Location* loc) const VIXL_OVERRIDE { 5537 program_counter += kA32PcDelta; 5538 Location::Offset off = 5539 loc->GetLocation() - AlignDown(program_counter, 4); 5540 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 5541 uint32_t U = (off >= 0); 5542 int32_t target = abs(off) | (U << 12); 5543 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5544 } 5545 } immop; 5546 EmitA32( 5547 Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5548 location, 5549 immop, 5550 &kA32FarDataInfo)); 5551 return; 5552 } 5553 } 5554 Delegate(kLdrb, &Assembler::ldrb, cond, rt, location); 5555 } 5556 5557 bool Assembler::ldrb_info(Condition cond, 5558 Register rt, 5559 Location* location, 5560 const struct ReferenceInfo** info) { 5561 VIXL_ASSERT(!location->IsBound()); 5562 USE(location); 5563 if (IsUsingT32()) { 5564 // LDRB{<c>}{<q>} <Rt>, <label> ; T1 5565 if (!rt.Is(pc)) { 5566 *info = &kT32FarDataInfo; 5567 return true; 5568 } 5569 } else { 5570 // LDRB{<c>}{<q>} <Rt>, <label> ; A1 5571 if (cond.IsNotNever()) { 5572 *info = &kA32FarDataInfo; 5573 return true; 5574 } 5575 } 5576 return false; 5577 } 5578 5579 void Assembler::ldrd(Condition cond, 5580 Register rt, 5581 Register rt2, 5582 const MemOperand& operand) { 5583 VIXL_ASSERT(AllowAssembler()); 5584 CheckIT(cond); 5585 if (operand.IsImmediate()) { 5586 Register rn = operand.GetBaseRegister(); 5587 int32_t offset = operand.GetOffsetImmediate(); 5588 if (IsUsingT32()) { 5589 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1 5590 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5591 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 5592 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5593 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5594 uint32_t offset_ = abs(offset) >> 2; 5595 EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5596 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5597 AdvanceIT(); 5598 return; 5599 } 5600 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1 5601 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5602 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 5603 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5604 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5605 uint32_t offset_ = abs(offset) >> 2; 5606 EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5607 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5608 AdvanceIT(); 5609 return; 5610 } 5611 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1 5612 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5613 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 5614 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5615 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5616 uint32_t offset_ = abs(offset) >> 2; 5617 EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5618 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5619 AdvanceIT(); 5620 return; 5621 } 5622 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1 5623 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 5624 operand.IsOffset() && 5625 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5626 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5627 uint32_t offset_ = abs(offset); 5628 EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5629 offset_ | (sign << 23)); 5630 AdvanceIT(); 5631 return; 5632 } 5633 } else { 5634 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1 5635 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5636 (offset >= -255) && (offset <= 255) && operand.IsOffset() && 5637 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5638 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 5639 AllowUnpredictable())) { 5640 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5641 uint32_t offset_ = abs(offset); 5642 EmitA32(0x014000d0U | (cond.GetCondition() << 28) | 5643 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5644 ((offset_ & 0xf0) << 4) | (sign << 23)); 5645 return; 5646 } 5647 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1 5648 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5649 (offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 5650 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5651 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 5652 AllowUnpredictable())) { 5653 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5654 uint32_t offset_ = abs(offset); 5655 EmitA32(0x004000d0U | (cond.GetCondition() << 28) | 5656 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5657 ((offset_ & 0xf0) << 4) | (sign << 23)); 5658 return; 5659 } 5660 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1 5661 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5662 (offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 5663 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5664 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 5665 AllowUnpredictable())) { 5666 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5667 uint32_t offset_ = abs(offset); 5668 EmitA32(0x016000d0U | (cond.GetCondition() << 28) | 5669 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5670 ((offset_ & 0xf0) << 4) | (sign << 23)); 5671 return; 5672 } 5673 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1 5674 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5675 (offset >= -255) && (offset <= 255) && rn.Is(pc) && 5676 operand.IsOffset() && cond.IsNotNever() && 5677 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 5678 AllowUnpredictable())) { 5679 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5680 uint32_t offset_ = abs(offset); 5681 EmitA32(0x014f00d0U | (cond.GetCondition() << 28) | 5682 (rt.GetCode() << 12) | (offset_ & 0xf) | 5683 ((offset_ & 0xf0) << 4) | (sign << 23)); 5684 return; 5685 } 5686 } 5687 } 5688 if (operand.IsPlainRegister()) { 5689 Register rn = operand.GetBaseRegister(); 5690 Sign sign = operand.GetSign(); 5691 Register rm = operand.GetOffsetRegister(); 5692 if (IsUsingA32()) { 5693 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1 5694 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5695 operand.IsOffset() && cond.IsNotNever() && 5696 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 5697 AllowUnpredictable())) { 5698 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5699 EmitA32(0x010000d0U | (cond.GetCondition() << 28) | 5700 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5701 (sign_ << 23)); 5702 return; 5703 } 5704 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1 5705 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5706 operand.IsPostIndex() && cond.IsNotNever() && 5707 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 5708 AllowUnpredictable())) { 5709 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5710 EmitA32(0x000000d0U | (cond.GetCondition() << 28) | 5711 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5712 (sign_ << 23)); 5713 return; 5714 } 5715 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1 5716 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5717 operand.IsPreIndex() && cond.IsNotNever() && 5718 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 5719 AllowUnpredictable())) { 5720 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5721 EmitA32(0x012000d0U | (cond.GetCondition() << 28) | 5722 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5723 (sign_ << 23)); 5724 return; 5725 } 5726 } 5727 } 5728 Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand); 5729 } 5730 5731 void Assembler::ldrd(Condition cond, 5732 Register rt, 5733 Register rt2, 5734 Location* location) { 5735 VIXL_ASSERT(AllowAssembler()); 5736 CheckIT(cond); 5737 Location::Offset offset = 5738 location->IsBound() 5739 ? location->GetLocation() - 5740 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5741 : 0; 5742 if (IsUsingT32()) { 5743 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1 5744 if (((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 5745 ((offset & 0x3) == 0)) || 5746 !location->IsBound()) && 5747 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5748 static class EmitOp : public Location::EmitOperator { 5749 public: 5750 EmitOp() : Location::EmitOperator(T32) {} 5751 virtual uint32_t Encode(uint32_t instr, 5752 Location::Offset program_counter, 5753 const Location* loc) const VIXL_OVERRIDE { 5754 program_counter += kT32PcDelta; 5755 Location::Offset off = 5756 loc->GetLocation() - AlignDown(program_counter, 4); 5757 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0)); 5758 int32_t target = off >> 2; 5759 uint32_t U = (target >= 0); 5760 target = abs(target) | (U << 8); 5761 return instr | (target & 0xff) | ((target & 0x100) << 15); 5762 } 5763 } immop; 5764 EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8), 5765 location, 5766 immop, 5767 &kT32DataInfo)); 5768 AdvanceIT(); 5769 return; 5770 } 5771 } else { 5772 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1 5773 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5774 ((location->IsBound() && (offset >= -255) && (offset <= 255)) || 5775 !location->IsBound()) && 5776 cond.IsNotNever() && 5777 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || AllowUnpredictable())) { 5778 static class EmitOp : public Location::EmitOperator { 5779 public: 5780 EmitOp() : Location::EmitOperator(A32) {} 5781 virtual uint32_t Encode(uint32_t instr, 5782 Location::Offset program_counter, 5783 const Location* loc) const VIXL_OVERRIDE { 5784 program_counter += kA32PcDelta; 5785 Location::Offset off = 5786 loc->GetLocation() - AlignDown(program_counter, 4); 5787 VIXL_ASSERT((off >= -255) && (off <= 255)); 5788 uint32_t U = (off >= 0); 5789 int32_t target = abs(off) | (U << 8); 5790 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 5791 ((target & 0x100) << 15); 5792 } 5793 } immop; 5794 EmitA32( 5795 Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5796 location, 5797 immop, 5798 &kA32VeryNearDataInfo)); 5799 return; 5800 } 5801 } 5802 Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, location); 5803 } 5804 5805 bool Assembler::ldrd_info(Condition cond, 5806 Register rt, 5807 Register rt2, 5808 Location* location, 5809 const struct ReferenceInfo** info) { 5810 VIXL_ASSERT(!location->IsBound()); 5811 USE(location); 5812 if (IsUsingT32()) { 5813 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1 5814 if (true) { 5815 *info = &kT32DataInfo; 5816 return true; 5817 } 5818 } else { 5819 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1 5820 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5821 cond.IsNotNever()) { 5822 *info = &kA32VeryNearDataInfo; 5823 return true; 5824 } 5825 } 5826 return false; 5827 } 5828 5829 void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) { 5830 VIXL_ASSERT(AllowAssembler()); 5831 CheckIT(cond); 5832 if (operand.IsImmediate()) { 5833 Register rn = operand.GetBaseRegister(); 5834 int32_t offset = operand.GetOffsetImmediate(); 5835 if (IsUsingT32()) { 5836 // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1 5837 if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) && 5838 operand.IsOffset() && 5839 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5840 int32_t offset_ = offset >> 2; 5841 EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5842 (offset_ & 0xff)); 5843 AdvanceIT(); 5844 return; 5845 } 5846 } else { 5847 // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1 5848 if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() && 5849 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5850 EmitA32(0x01900f9fU | (cond.GetCondition() << 28) | 5851 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5852 return; 5853 } 5854 } 5855 } 5856 Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand); 5857 } 5858 5859 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) { 5860 VIXL_ASSERT(AllowAssembler()); 5861 CheckIT(cond); 5862 if (operand.IsImmediateZero()) { 5863 Register rn = operand.GetBaseRegister(); 5864 if (IsUsingT32()) { 5865 // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1 5866 if (operand.IsOffset() && 5867 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5868 EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5869 AdvanceIT(); 5870 return; 5871 } 5872 } else { 5873 // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1 5874 if (operand.IsOffset() && cond.IsNotNever() && 5875 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5876 EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) | 5877 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5878 return; 5879 } 5880 } 5881 } 5882 Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand); 5883 } 5884 5885 void Assembler::ldrexd(Condition cond, 5886 Register rt, 5887 Register rt2, 5888 const MemOperand& operand) { 5889 VIXL_ASSERT(AllowAssembler()); 5890 CheckIT(cond); 5891 if (operand.IsImmediateZero()) { 5892 Register rn = operand.GetBaseRegister(); 5893 if (IsUsingT32()) { 5894 // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1 5895 if (operand.IsOffset() && 5896 ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5897 EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5898 (rn.GetCode() << 16)); 5899 AdvanceIT(); 5900 return; 5901 } 5902 } else { 5903 // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1 5904 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5905 operand.IsOffset() && cond.IsNotNever() && 5906 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) || 5907 AllowUnpredictable())) { 5908 EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) | 5909 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5910 return; 5911 } 5912 } 5913 } 5914 Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand); 5915 } 5916 5917 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) { 5918 VIXL_ASSERT(AllowAssembler()); 5919 CheckIT(cond); 5920 if (operand.IsImmediateZero()) { 5921 Register rn = operand.GetBaseRegister(); 5922 if (IsUsingT32()) { 5923 // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1 5924 if (operand.IsOffset() && 5925 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5926 EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5927 AdvanceIT(); 5928 return; 5929 } 5930 } else { 5931 // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1 5932 if (operand.IsOffset() && cond.IsNotNever() && 5933 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5934 EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) | 5935 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5936 return; 5937 } 5938 } 5939 } 5940 Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand); 5941 } 5942 5943 void Assembler::ldrh(Condition cond, 5944 EncodingSize size, 5945 Register rt, 5946 const MemOperand& operand) { 5947 VIXL_ASSERT(AllowAssembler()); 5948 CheckIT(cond); 5949 if (operand.IsImmediate()) { 5950 Register rn = operand.GetBaseRegister(); 5951 int32_t offset = operand.GetOffsetImmediate(); 5952 if (IsUsingT32()) { 5953 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 5954 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 5955 (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) { 5956 int32_t offset_ = offset >> 1; 5957 EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) | 5958 ((offset_ & 0x1f) << 6)); 5959 AdvanceIT(); 5960 return; 5961 } 5962 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 5963 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5964 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5965 EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5966 (offset & 0xfff)); 5967 AdvanceIT(); 5968 return; 5969 } 5970 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 5971 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5972 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5973 EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5974 (-offset & 0xff)); 5975 AdvanceIT(); 5976 return; 5977 } 5978 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 5979 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5980 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5981 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5982 uint32_t offset_ = abs(offset); 5983 EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5984 offset_ | (sign << 9)); 5985 AdvanceIT(); 5986 return; 5987 } 5988 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 5989 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5990 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5991 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5992 uint32_t offset_ = abs(offset); 5993 EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5994 offset_ | (sign << 9)); 5995 AdvanceIT(); 5996 return; 5997 } 5998 // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 5999 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 6000 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 6001 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6002 uint32_t offset_ = abs(offset); 6003 EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 6004 AdvanceIT(); 6005 return; 6006 } 6007 } else { 6008 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 6009 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 6010 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6011 (!rt.IsPC() || AllowUnpredictable())) { 6012 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6013 uint32_t offset_ = abs(offset); 6014 EmitA32(0x015000b0U | (cond.GetCondition() << 28) | 6015 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6016 ((offset_ & 0xf0) << 4) | (sign << 23)); 6017 return; 6018 } 6019 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 6020 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 6021 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6022 (!rt.IsPC() || AllowUnpredictable())) { 6023 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6024 uint32_t offset_ = abs(offset); 6025 EmitA32(0x005000b0U | (cond.GetCondition() << 28) | 6026 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6027 ((offset_ & 0xf0) << 4) | (sign << 23)); 6028 return; 6029 } 6030 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 6031 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 6032 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6033 (!rt.IsPC() || AllowUnpredictable())) { 6034 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6035 uint32_t offset_ = abs(offset); 6036 EmitA32(0x017000b0U | (cond.GetCondition() << 28) | 6037 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6038 ((offset_ & 0xf0) << 4) | (sign << 23)); 6039 return; 6040 } 6041 // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 6042 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 6043 operand.IsOffset() && cond.IsNotNever() && 6044 (!rt.IsPC() || AllowUnpredictable())) { 6045 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6046 uint32_t offset_ = abs(offset); 6047 EmitA32(0x015f00b0U | (cond.GetCondition() << 28) | 6048 (rt.GetCode() << 12) | (offset_ & 0xf) | 6049 ((offset_ & 0xf0) << 4) | (sign << 23)); 6050 return; 6051 } 6052 } 6053 } 6054 if (operand.IsPlainRegister()) { 6055 Register rn = operand.GetBaseRegister(); 6056 Sign sign = operand.GetSign(); 6057 Register rm = operand.GetOffsetRegister(); 6058 if (IsUsingT32()) { 6059 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 6060 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 6061 sign.IsPlus() && operand.IsOffset()) { 6062 EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) | 6063 (rm.GetCode() << 6)); 6064 AdvanceIT(); 6065 return; 6066 } 6067 } else { 6068 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 6069 if (operand.IsOffset() && cond.IsNotNever() && 6070 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6071 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6072 EmitA32(0x011000b0U | (cond.GetCondition() << 28) | 6073 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6074 (sign_ << 23)); 6075 return; 6076 } 6077 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 6078 if (operand.IsPostIndex() && cond.IsNotNever() && 6079 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6080 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6081 EmitA32(0x001000b0U | (cond.GetCondition() << 28) | 6082 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6083 (sign_ << 23)); 6084 return; 6085 } 6086 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 6087 if (operand.IsPreIndex() && cond.IsNotNever() && 6088 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6089 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6090 EmitA32(0x013000b0U | (cond.GetCondition() << 28) | 6091 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6092 (sign_ << 23)); 6093 return; 6094 } 6095 } 6096 } 6097 if (operand.IsShiftedRegister()) { 6098 Register rn = operand.GetBaseRegister(); 6099 Sign sign = operand.GetSign(); 6100 Register rm = operand.GetOffsetRegister(); 6101 Shift shift = operand.GetShift(); 6102 uint32_t amount = operand.GetShiftAmount(); 6103 if (IsUsingT32()) { 6104 // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 6105 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 6106 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) && 6107 (!rm.IsPC() || AllowUnpredictable())) { 6108 EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6109 rm.GetCode() | (amount << 4)); 6110 AdvanceIT(); 6111 return; 6112 } 6113 } 6114 } 6115 Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand); 6116 } 6117 6118 void Assembler::ldrh(Condition cond, Register rt, Location* location) { 6119 VIXL_ASSERT(AllowAssembler()); 6120 CheckIT(cond); 6121 Location::Offset offset = 6122 location->IsBound() 6123 ? location->GetLocation() - 6124 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 6125 : 0; 6126 if (IsUsingT32()) { 6127 // LDRH{<c>}{<q>} <Rt>, <label> ; T1 6128 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 6129 !location->IsBound()) && 6130 !rt.Is(pc)) { 6131 static class EmitOp : public Location::EmitOperator { 6132 public: 6133 EmitOp() : Location::EmitOperator(T32) {} 6134 virtual uint32_t Encode(uint32_t instr, 6135 Location::Offset program_counter, 6136 const Location* loc) const VIXL_OVERRIDE { 6137 program_counter += kT32PcDelta; 6138 Location::Offset off = 6139 loc->GetLocation() - AlignDown(program_counter, 4); 6140 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 6141 uint32_t U = (off >= 0); 6142 int32_t target = abs(off) | (U << 12); 6143 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 6144 } 6145 } immop; 6146 EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12), 6147 location, 6148 immop, 6149 &kT32FarDataInfo)); 6150 AdvanceIT(); 6151 return; 6152 } 6153 } else { 6154 // LDRH{<c>}{<q>} <Rt>, <label> ; A1 6155 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) || 6156 !location->IsBound()) && 6157 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 6158 static class EmitOp : public Location::EmitOperator { 6159 public: 6160 EmitOp() : Location::EmitOperator(A32) {} 6161 virtual uint32_t Encode(uint32_t instr, 6162 Location::Offset program_counter, 6163 const Location* loc) const VIXL_OVERRIDE { 6164 program_counter += kA32PcDelta; 6165 Location::Offset off = 6166 loc->GetLocation() - AlignDown(program_counter, 4); 6167 VIXL_ASSERT((off >= -255) && (off <= 255)); 6168 uint32_t U = (off >= 0); 6169 int32_t target = abs(off) | (U << 8); 6170 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 6171 ((target & 0x100) << 15); 6172 } 6173 } immop; 6174 EmitA32( 6175 Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 6176 location, 6177 immop, 6178 &kA32VeryNearDataInfo)); 6179 return; 6180 } 6181 } 6182 Delegate(kLdrh, &Assembler::ldrh, cond, rt, location); 6183 } 6184 6185 bool Assembler::ldrh_info(Condition cond, 6186 Register rt, 6187 Location* location, 6188 const struct ReferenceInfo** info) { 6189 VIXL_ASSERT(!location->IsBound()); 6190 USE(location); 6191 if (IsUsingT32()) { 6192 // LDRH{<c>}{<q>} <Rt>, <label> ; T1 6193 if (!rt.Is(pc)) { 6194 *info = &kT32FarDataInfo; 6195 return true; 6196 } 6197 } else { 6198 // LDRH{<c>}{<q>} <Rt>, <label> ; A1 6199 if (cond.IsNotNever()) { 6200 *info = &kA32VeryNearDataInfo; 6201 return true; 6202 } 6203 } 6204 return false; 6205 } 6206 6207 void Assembler::ldrsb(Condition cond, 6208 EncodingSize size, 6209 Register rt, 6210 const MemOperand& operand) { 6211 VIXL_ASSERT(AllowAssembler()); 6212 CheckIT(cond); 6213 if (operand.IsImmediate()) { 6214 Register rn = operand.GetBaseRegister(); 6215 int32_t offset = operand.GetOffsetImmediate(); 6216 if (IsUsingT32()) { 6217 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 6218 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 6219 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6220 EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6221 (offset & 0xfff)); 6222 AdvanceIT(); 6223 return; 6224 } 6225 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2 6226 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 6227 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6228 EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6229 (-offset & 0xff)); 6230 AdvanceIT(); 6231 return; 6232 } 6233 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2 6234 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 6235 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 6236 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6237 uint32_t offset_ = abs(offset); 6238 EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6239 offset_ | (sign << 9)); 6240 AdvanceIT(); 6241 return; 6242 } 6243 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2 6244 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 6245 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 6246 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6247 uint32_t offset_ = abs(offset); 6248 EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6249 offset_ | (sign << 9)); 6250 AdvanceIT(); 6251 return; 6252 } 6253 // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 6254 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 6255 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 6256 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6257 uint32_t offset_ = abs(offset); 6258 EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 6259 AdvanceIT(); 6260 return; 6261 } 6262 } else { 6263 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1 6264 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 6265 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6266 (!rt.IsPC() || AllowUnpredictable())) { 6267 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6268 uint32_t offset_ = abs(offset); 6269 EmitA32(0x015000d0U | (cond.GetCondition() << 28) | 6270 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6271 ((offset_ & 0xf0) << 4) | (sign << 23)); 6272 return; 6273 } 6274 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1 6275 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 6276 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6277 (!rt.IsPC() || AllowUnpredictable())) { 6278 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6279 uint32_t offset_ = abs(offset); 6280 EmitA32(0x005000d0U | (cond.GetCondition() << 28) | 6281 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6282 ((offset_ & 0xf0) << 4) | (sign << 23)); 6283 return; 6284 } 6285 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1 6286 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 6287 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6288 (!rt.IsPC() || AllowUnpredictable())) { 6289 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6290 uint32_t offset_ = abs(offset); 6291 EmitA32(0x017000d0U | (cond.GetCondition() << 28) | 6292 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6293 ((offset_ & 0xf0) << 4) | (sign << 23)); 6294 return; 6295 } 6296 // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 6297 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 6298 operand.IsOffset() && cond.IsNotNever() && 6299 (!rt.IsPC() || AllowUnpredictable())) { 6300 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6301 uint32_t offset_ = abs(offset); 6302 EmitA32(0x015f00d0U | (cond.GetCondition() << 28) | 6303 (rt.GetCode() << 12) | (offset_ & 0xf) | 6304 ((offset_ & 0xf0) << 4) | (sign << 23)); 6305 return; 6306 } 6307 } 6308 } 6309 if (operand.IsPlainRegister()) { 6310 Register rn = operand.GetBaseRegister(); 6311 Sign sign = operand.GetSign(); 6312 Register rm = operand.GetOffsetRegister(); 6313 if (IsUsingT32()) { 6314 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 6315 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 6316 sign.IsPlus() && operand.IsOffset()) { 6317 EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) | 6318 (rm.GetCode() << 6)); 6319 AdvanceIT(); 6320 return; 6321 } 6322 } else { 6323 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 6324 if (operand.IsOffset() && cond.IsNotNever() && 6325 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6326 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6327 EmitA32(0x011000d0U | (cond.GetCondition() << 28) | 6328 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6329 (sign_ << 23)); 6330 return; 6331 } 6332 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 6333 if (operand.IsPostIndex() && cond.IsNotNever() && 6334 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6335 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6336 EmitA32(0x001000d0U | (cond.GetCondition() << 28) | 6337 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6338 (sign_ << 23)); 6339 return; 6340 } 6341 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 6342 if (operand.IsPreIndex() && cond.IsNotNever() && 6343 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6344 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6345 EmitA32(0x013000d0U | (cond.GetCondition() << 28) | 6346 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6347 (sign_ << 23)); 6348 return; 6349 } 6350 } 6351 } 6352 if (operand.IsShiftedRegister()) { 6353 Register rn = operand.GetBaseRegister(); 6354 Sign sign = operand.GetSign(); 6355 Register rm = operand.GetOffsetRegister(); 6356 Shift shift = operand.GetShift(); 6357 uint32_t amount = operand.GetShiftAmount(); 6358 if (IsUsingT32()) { 6359 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 6360 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 6361 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) && 6362 (!rm.IsPC() || AllowUnpredictable())) { 6363 EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6364 rm.GetCode() | (amount << 4)); 6365 AdvanceIT(); 6366 return; 6367 } 6368 } 6369 } 6370 Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand); 6371 } 6372 6373 void Assembler::ldrsb(Condition cond, Register rt, Location* location) { 6374 VIXL_ASSERT(AllowAssembler()); 6375 CheckIT(cond); 6376 Location::Offset offset = 6377 location->IsBound() 6378 ? location->GetLocation() - 6379 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 6380 : 0; 6381 if (IsUsingT32()) { 6382 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1 6383 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 6384 !location->IsBound()) && 6385 !rt.Is(pc)) { 6386 static class EmitOp : public Location::EmitOperator { 6387 public: 6388 EmitOp() : Location::EmitOperator(T32) {} 6389 virtual uint32_t Encode(uint32_t instr, 6390 Location::Offset program_counter, 6391 const Location* loc) const VIXL_OVERRIDE { 6392 program_counter += kT32PcDelta; 6393 Location::Offset off = 6394 loc->GetLocation() - AlignDown(program_counter, 4); 6395 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 6396 uint32_t U = (off >= 0); 6397 int32_t target = abs(off) | (U << 12); 6398 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 6399 } 6400 } immop; 6401 EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12), 6402 location, 6403 immop, 6404 &kT32FarDataInfo)); 6405 AdvanceIT(); 6406 return; 6407 } 6408 } else { 6409 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1 6410 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) || 6411 !location->IsBound()) && 6412 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 6413 static class EmitOp : public Location::EmitOperator { 6414 public: 6415 EmitOp() : Location::EmitOperator(A32) {} 6416 virtual uint32_t Encode(uint32_t instr, 6417 Location::Offset program_counter, 6418 const Location* loc) const VIXL_OVERRIDE { 6419 program_counter += kA32PcDelta; 6420 Location::Offset off = 6421 loc->GetLocation() - AlignDown(program_counter, 4); 6422 VIXL_ASSERT((off >= -255) && (off <= 255)); 6423 uint32_t U = (off >= 0); 6424 int32_t target = abs(off) | (U << 8); 6425 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 6426 ((target & 0x100) << 15); 6427 } 6428 } immop; 6429 EmitA32( 6430 Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 6431 location, 6432 immop, 6433 &kA32VeryNearDataInfo)); 6434 return; 6435 } 6436 } 6437 Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, location); 6438 } 6439 6440 bool Assembler::ldrsb_info(Condition cond, 6441 Register rt, 6442 Location* location, 6443 const struct ReferenceInfo** info) { 6444 VIXL_ASSERT(!location->IsBound()); 6445 USE(location); 6446 if (IsUsingT32()) { 6447 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1 6448 if (!rt.Is(pc)) { 6449 *info = &kT32FarDataInfo; 6450 return true; 6451 } 6452 } else { 6453 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1 6454 if (cond.IsNotNever()) { 6455 *info = &kA32VeryNearDataInfo; 6456 return true; 6457 } 6458 } 6459 return false; 6460 } 6461 6462 void Assembler::ldrsh(Condition cond, 6463 EncodingSize size, 6464 Register rt, 6465 const MemOperand& operand) { 6466 VIXL_ASSERT(AllowAssembler()); 6467 CheckIT(cond); 6468 if (operand.IsImmediate()) { 6469 Register rn = operand.GetBaseRegister(); 6470 int32_t offset = operand.GetOffsetImmediate(); 6471 if (IsUsingT32()) { 6472 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 6473 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 6474 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6475 EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6476 (offset & 0xfff)); 6477 AdvanceIT(); 6478 return; 6479 } 6480 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2 6481 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 6482 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6483 EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6484 (-offset & 0xff)); 6485 AdvanceIT(); 6486 return; 6487 } 6488 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2 6489 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 6490 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 6491 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6492 uint32_t offset_ = abs(offset); 6493 EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6494 offset_ | (sign << 9)); 6495 AdvanceIT(); 6496 return; 6497 } 6498 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2 6499 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 6500 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 6501 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6502 uint32_t offset_ = abs(offset); 6503 EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6504 offset_ | (sign << 9)); 6505 AdvanceIT(); 6506 return; 6507 } 6508 // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 6509 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 6510 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 6511 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6512 uint32_t offset_ = abs(offset); 6513 EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 6514 AdvanceIT(); 6515 return; 6516 } 6517 } else { 6518 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1 6519 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 6520 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6521 (!rt.IsPC() || AllowUnpredictable())) { 6522 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6523 uint32_t offset_ = abs(offset); 6524 EmitA32(0x015000f0U | (cond.GetCondition() << 28) | 6525 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6526 ((offset_ & 0xf0) << 4) | (sign << 23)); 6527 return; 6528 } 6529 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1 6530 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 6531 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6532 (!rt.IsPC() || AllowUnpredictable())) { 6533 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6534 uint32_t offset_ = abs(offset); 6535 EmitA32(0x005000f0U | (cond.GetCondition() << 28) | 6536 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6537 ((offset_ & 0xf0) << 4) | (sign << 23)); 6538 return; 6539 } 6540 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1 6541 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 6542 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6543 (!rt.IsPC() || AllowUnpredictable())) { 6544 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6545 uint32_t offset_ = abs(offset); 6546 EmitA32(0x017000f0U | (cond.GetCondition() << 28) | 6547 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6548 ((offset_ & 0xf0) << 4) | (sign << 23)); 6549 return; 6550 } 6551 // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 6552 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 6553 operand.IsOffset() && cond.IsNotNever() && 6554 (!rt.IsPC() || AllowUnpredictable())) { 6555 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6556 uint32_t offset_ = abs(offset); 6557 EmitA32(0x015f00f0U | (cond.GetCondition() << 28) | 6558 (rt.GetCode() << 12) | (offset_ & 0xf) | 6559 ((offset_ & 0xf0) << 4) | (sign << 23)); 6560 return; 6561 } 6562 } 6563 } 6564 if (operand.IsPlainRegister()) { 6565 Register rn = operand.GetBaseRegister(); 6566 Sign sign = operand.GetSign(); 6567 Register rm = operand.GetOffsetRegister(); 6568 if (IsUsingT32()) { 6569 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 6570 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 6571 sign.IsPlus() && operand.IsOffset()) { 6572 EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) | 6573 (rm.GetCode() << 6)); 6574 AdvanceIT(); 6575 return; 6576 } 6577 } else { 6578 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 6579 if (operand.IsOffset() && cond.IsNotNever() && 6580 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6581 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6582 EmitA32(0x011000f0U | (cond.GetCondition() << 28) | 6583 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6584 (sign_ << 23)); 6585 return; 6586 } 6587 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 6588 if (operand.IsPostIndex() && cond.IsNotNever() && 6589 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6590 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6591 EmitA32(0x001000f0U | (cond.GetCondition() << 28) | 6592 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6593 (sign_ << 23)); 6594 return; 6595 } 6596 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 6597 if (operand.IsPreIndex() && cond.IsNotNever() && 6598 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6599 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6600 EmitA32(0x013000f0U | (cond.GetCondition() << 28) | 6601 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6602 (sign_ << 23)); 6603 return; 6604 } 6605 } 6606 } 6607 if (operand.IsShiftedRegister()) { 6608 Register rn = operand.GetBaseRegister(); 6609 Sign sign = operand.GetSign(); 6610 Register rm = operand.GetOffsetRegister(); 6611 Shift shift = operand.GetShift(); 6612 uint32_t amount = operand.GetShiftAmount(); 6613 if (IsUsingT32()) { 6614 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 6615 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 6616 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) && 6617 (!rm.IsPC() || AllowUnpredictable())) { 6618 EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6619 rm.GetCode() | (amount << 4)); 6620 AdvanceIT(); 6621 return; 6622 } 6623 } 6624 } 6625 Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand); 6626 } 6627 6628 void Assembler::ldrsh(Condition cond, Register rt, Location* location) { 6629 VIXL_ASSERT(AllowAssembler()); 6630 CheckIT(cond); 6631 Location::Offset offset = 6632 location->IsBound() 6633 ? location->GetLocation() - 6634 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 6635 : 0; 6636 if (IsUsingT32()) { 6637 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1 6638 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 6639 !location->IsBound()) && 6640 !rt.Is(pc)) { 6641 static class EmitOp : public Location::EmitOperator { 6642 public: 6643 EmitOp() : Location::EmitOperator(T32) {} 6644 virtual uint32_t Encode(uint32_t instr, 6645 Location::Offset program_counter, 6646 const Location* loc) const VIXL_OVERRIDE { 6647 program_counter += kT32PcDelta; 6648 Location::Offset off = 6649 loc->GetLocation() - AlignDown(program_counter, 4); 6650 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 6651 uint32_t U = (off >= 0); 6652 int32_t target = abs(off) | (U << 12); 6653 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 6654 } 6655 } immop; 6656 EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12), 6657 location, 6658 immop, 6659 &kT32FarDataInfo)); 6660 AdvanceIT(); 6661 return; 6662 } 6663 } else { 6664 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1 6665 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) || 6666 !location->IsBound()) && 6667 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 6668 static class EmitOp : public Location::EmitOperator { 6669 public: 6670 EmitOp() : Location::EmitOperator(A32) {} 6671 virtual uint32_t Encode(uint32_t instr, 6672 Location::Offset program_counter, 6673 const Location* loc) const VIXL_OVERRIDE { 6674 program_counter += kA32PcDelta; 6675 Location::Offset off = 6676 loc->GetLocation() - AlignDown(program_counter, 4); 6677 VIXL_ASSERT((off >= -255) && (off <= 255)); 6678 uint32_t U = (off >= 0); 6679 int32_t target = abs(off) | (U << 8); 6680 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 6681 ((target & 0x100) << 15); 6682 } 6683 } immop; 6684 EmitA32( 6685 Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 6686 location, 6687 immop, 6688 &kA32VeryNearDataInfo)); 6689 return; 6690 } 6691 } 6692 Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, location); 6693 } 6694 6695 bool Assembler::ldrsh_info(Condition cond, 6696 Register rt, 6697 Location* location, 6698 const struct ReferenceInfo** info) { 6699 VIXL_ASSERT(!location->IsBound()); 6700 USE(location); 6701 if (IsUsingT32()) { 6702 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1 6703 if (!rt.Is(pc)) { 6704 *info = &kT32FarDataInfo; 6705 return true; 6706 } 6707 } else { 6708 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1 6709 if (cond.IsNotNever()) { 6710 *info = &kA32VeryNearDataInfo; 6711 return true; 6712 } 6713 } 6714 return false; 6715 } 6716 6717 void Assembler::lsl(Condition cond, 6718 EncodingSize size, 6719 Register rd, 6720 Register rm, 6721 const Operand& operand) { 6722 VIXL_ASSERT(AllowAssembler()); 6723 CheckIT(cond); 6724 if (operand.IsImmediate()) { 6725 uint32_t imm = operand.GetImmediate(); 6726 if (IsUsingT32()) { 6727 // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6728 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6729 (imm >= 1) && (imm <= 31)) { 6730 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6)); 6731 AdvanceIT(); 6732 return; 6733 } 6734 // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6735 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) && 6736 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6737 EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6738 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 6739 AdvanceIT(); 6740 return; 6741 } 6742 } else { 6743 // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6744 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 6745 EmitA32(0x01a00000U | (cond.GetCondition() << 28) | 6746 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 6747 return; 6748 } 6749 } 6750 } 6751 if (operand.IsPlainRegister()) { 6752 Register rs = operand.GetBaseRegister(); 6753 if (IsUsingT32()) { 6754 // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6755 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6756 rs.IsLow()) { 6757 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 6758 AdvanceIT(); 6759 return; 6760 } 6761 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6762 if (!size.IsNarrow() && 6763 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6764 EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6765 rs.GetCode()); 6766 AdvanceIT(); 6767 return; 6768 } 6769 } else { 6770 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6771 if (cond.IsNotNever() && 6772 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6773 EmitA32(0x01a00010U | (cond.GetCondition() << 28) | 6774 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6775 return; 6776 } 6777 } 6778 } 6779 Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand); 6780 } 6781 6782 void Assembler::lsls(Condition cond, 6783 EncodingSize size, 6784 Register rd, 6785 Register rm, 6786 const Operand& operand) { 6787 VIXL_ASSERT(AllowAssembler()); 6788 CheckIT(cond); 6789 if (operand.IsImmediate()) { 6790 uint32_t imm = operand.GetImmediate(); 6791 if (IsUsingT32()) { 6792 // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6793 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6794 (imm >= 1) && (imm <= 31)) { 6795 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6)); 6796 AdvanceIT(); 6797 return; 6798 } 6799 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6800 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) && 6801 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6802 EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6803 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 6804 AdvanceIT(); 6805 return; 6806 } 6807 } else { 6808 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6809 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 6810 EmitA32(0x01b00000U | (cond.GetCondition() << 28) | 6811 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 6812 return; 6813 } 6814 } 6815 } 6816 if (operand.IsPlainRegister()) { 6817 Register rs = operand.GetBaseRegister(); 6818 if (IsUsingT32()) { 6819 // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6820 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6821 rs.IsLow()) { 6822 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 6823 AdvanceIT(); 6824 return; 6825 } 6826 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6827 if (!size.IsNarrow() && 6828 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6829 EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6830 rs.GetCode()); 6831 AdvanceIT(); 6832 return; 6833 } 6834 } else { 6835 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6836 if (cond.IsNotNever() && 6837 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6838 EmitA32(0x01b00010U | (cond.GetCondition() << 28) | 6839 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6840 return; 6841 } 6842 } 6843 } 6844 Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand); 6845 } 6846 6847 void Assembler::lsr(Condition cond, 6848 EncodingSize size, 6849 Register rd, 6850 Register rm, 6851 const Operand& operand) { 6852 VIXL_ASSERT(AllowAssembler()); 6853 CheckIT(cond); 6854 if (operand.IsImmediate()) { 6855 uint32_t imm = operand.GetImmediate(); 6856 if (IsUsingT32()) { 6857 // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6858 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6859 (imm >= 1) && (imm <= 32)) { 6860 uint32_t amount_ = imm % 32; 6861 EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) | 6862 (amount_ << 6)); 6863 AdvanceIT(); 6864 return; 6865 } 6866 // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6867 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) && 6868 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6869 uint32_t amount_ = imm % 32; 6870 EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() | 6871 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6872 AdvanceIT(); 6873 return; 6874 } 6875 } else { 6876 // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6877 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 6878 uint32_t amount_ = imm % 32; 6879 EmitA32(0x01a00020U | (cond.GetCondition() << 28) | 6880 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 6881 return; 6882 } 6883 } 6884 } 6885 if (operand.IsPlainRegister()) { 6886 Register rs = operand.GetBaseRegister(); 6887 if (IsUsingT32()) { 6888 // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6889 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6890 rs.IsLow()) { 6891 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 6892 AdvanceIT(); 6893 return; 6894 } 6895 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6896 if (!size.IsNarrow() && 6897 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6898 EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6899 rs.GetCode()); 6900 AdvanceIT(); 6901 return; 6902 } 6903 } else { 6904 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6905 if (cond.IsNotNever() && 6906 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6907 EmitA32(0x01a00030U | (cond.GetCondition() << 28) | 6908 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6909 return; 6910 } 6911 } 6912 } 6913 Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand); 6914 } 6915 6916 void Assembler::lsrs(Condition cond, 6917 EncodingSize size, 6918 Register rd, 6919 Register rm, 6920 const Operand& operand) { 6921 VIXL_ASSERT(AllowAssembler()); 6922 CheckIT(cond); 6923 if (operand.IsImmediate()) { 6924 uint32_t imm = operand.GetImmediate(); 6925 if (IsUsingT32()) { 6926 // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6927 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6928 (imm >= 1) && (imm <= 32)) { 6929 uint32_t amount_ = imm % 32; 6930 EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) | 6931 (amount_ << 6)); 6932 AdvanceIT(); 6933 return; 6934 } 6935 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6936 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) && 6937 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6938 uint32_t amount_ = imm % 32; 6939 EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() | 6940 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6941 AdvanceIT(); 6942 return; 6943 } 6944 } else { 6945 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6946 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 6947 uint32_t amount_ = imm % 32; 6948 EmitA32(0x01b00020U | (cond.GetCondition() << 28) | 6949 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 6950 return; 6951 } 6952 } 6953 } 6954 if (operand.IsPlainRegister()) { 6955 Register rs = operand.GetBaseRegister(); 6956 if (IsUsingT32()) { 6957 // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6958 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6959 rs.IsLow()) { 6960 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 6961 AdvanceIT(); 6962 return; 6963 } 6964 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6965 if (!size.IsNarrow() && 6966 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6967 EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6968 rs.GetCode()); 6969 AdvanceIT(); 6970 return; 6971 } 6972 } else { 6973 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6974 if (cond.IsNotNever() && 6975 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6976 EmitA32(0x01b00030U | (cond.GetCondition() << 28) | 6977 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6978 return; 6979 } 6980 } 6981 } 6982 Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand); 6983 } 6984 6985 void Assembler::mla( 6986 Condition cond, Register rd, Register rn, Register rm, Register ra) { 6987 VIXL_ASSERT(AllowAssembler()); 6988 CheckIT(cond); 6989 if (IsUsingT32()) { 6990 // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 6991 if (!ra.Is(pc) && 6992 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6993 EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 6994 rm.GetCode() | (ra.GetCode() << 12)); 6995 AdvanceIT(); 6996 return; 6997 } 6998 } else { 6999 // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 7000 if (cond.IsNotNever() && 7001 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 7002 AllowUnpredictable())) { 7003 EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 7004 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 7005 return; 7006 } 7007 } 7008 Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra); 7009 } 7010 7011 void Assembler::mlas( 7012 Condition cond, Register rd, Register rn, Register rm, Register ra) { 7013 VIXL_ASSERT(AllowAssembler()); 7014 CheckIT(cond); 7015 if (IsUsingA32()) { 7016 // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 7017 if (cond.IsNotNever() && 7018 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 7019 AllowUnpredictable())) { 7020 EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 7021 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 7022 return; 7023 } 7024 } 7025 Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra); 7026 } 7027 7028 void Assembler::mls( 7029 Condition cond, Register rd, Register rn, Register rm, Register ra) { 7030 VIXL_ASSERT(AllowAssembler()); 7031 CheckIT(cond); 7032 if (IsUsingT32()) { 7033 // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 7034 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 7035 AllowUnpredictable())) { 7036 EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7037 rm.GetCode() | (ra.GetCode() << 12)); 7038 AdvanceIT(); 7039 return; 7040 } 7041 } else { 7042 // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 7043 if (cond.IsNotNever() && 7044 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 7045 AllowUnpredictable())) { 7046 EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 7047 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 7048 return; 7049 } 7050 } 7051 Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra); 7052 } 7053 7054 void Assembler::mov(Condition cond, 7055 EncodingSize size, 7056 Register rd, 7057 const Operand& operand) { 7058 VIXL_ASSERT(AllowAssembler()); 7059 CheckIT(cond); 7060 if (operand.IsImmediateShiftedRegister()) { 7061 Register rm = operand.GetBaseRegister(); 7062 if (operand.IsPlainRegister()) { 7063 if (IsUsingT32()) { 7064 // MOV{<c>}{<q>} <Rd>, <Rm> ; T1 7065 if (!size.IsWide() && 7066 ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 7067 AllowUnpredictable())) { 7068 EmitT32_16(0x4600 | (rd.GetCode() & 0x7) | 7069 ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 7070 AdvanceIT(); 7071 return; 7072 } 7073 } 7074 } 7075 Shift shift = operand.GetShift(); 7076 uint32_t amount = operand.GetShiftAmount(); 7077 if (IsUsingT32()) { 7078 // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 7079 if (InITBlock() && !size.IsWide() && rd.IsLow() && 7080 shift.IsValidAmount(amount) && rm.IsLow() && 7081 (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) && 7082 ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) { 7083 uint32_t amount_ = amount % 32; 7084 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | 7085 (operand.GetTypeEncodingValue() << 11) | (amount_ << 6)); 7086 AdvanceIT(); 7087 return; 7088 } 7089 // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3 7090 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 7091 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7092 uint32_t amount_ = amount % 32; 7093 EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() | 7094 (operand.GetTypeEncodingValue() << 4) | 7095 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7096 AdvanceIT(); 7097 return; 7098 } 7099 } else { 7100 // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 7101 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7102 uint32_t amount_ = amount % 32; 7103 EmitA32(0x01a00000U | (cond.GetCondition() << 28) | 7104 (rd.GetCode() << 12) | rm.GetCode() | 7105 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7106 return; 7107 } 7108 } 7109 } 7110 if (operand.IsRegisterShiftedRegister()) { 7111 Register rm = operand.GetBaseRegister(); 7112 Shift shift = operand.GetShift(); 7113 Register rs = operand.GetShiftRegister(); 7114 if (IsUsingT32()) { 7115 // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1 7116 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7117 shift.IsASR() && rs.IsLow()) { 7118 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 7119 AdvanceIT(); 7120 return; 7121 } 7122 // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1 7123 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7124 shift.IsLSL() && rs.IsLow()) { 7125 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 7126 AdvanceIT(); 7127 return; 7128 } 7129 // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1 7130 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7131 shift.IsLSR() && rs.IsLow()) { 7132 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 7133 AdvanceIT(); 7134 return; 7135 } 7136 // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1 7137 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7138 shift.IsROR() && rs.IsLow()) { 7139 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 7140 AdvanceIT(); 7141 return; 7142 } 7143 // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2 7144 if (!size.IsNarrow() && 7145 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7146 EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 7147 (shift.GetType() << 21) | rs.GetCode()); 7148 AdvanceIT(); 7149 return; 7150 } 7151 } else { 7152 // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7153 if (cond.IsNotNever() && 7154 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7155 EmitA32(0x01a00010U | (cond.GetCondition() << 28) | 7156 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7157 (rs.GetCode() << 8)); 7158 return; 7159 } 7160 } 7161 } 7162 if (operand.IsImmediate()) { 7163 uint32_t imm = operand.GetImmediate(); 7164 if (IsUsingT32()) { 7165 ImmediateT32 immediate_t32(imm); 7166 // MOV<c>{<q>} <Rd>, #<imm8> ; T1 7167 if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) { 7168 EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm); 7169 AdvanceIT(); 7170 return; 7171 } 7172 // MOV{<c>}{<q>} <Rd>, #<const> ; T2 7173 if (!size.IsNarrow() && immediate_t32.IsValid() && 7174 (!rd.IsPC() || AllowUnpredictable())) { 7175 EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) | 7176 (immediate_t32.GetEncodingValue() & 0xff) | 7177 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7178 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7179 AdvanceIT(); 7180 return; 7181 } 7182 // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3 7183 if (!size.IsNarrow() && (imm <= 65535) && 7184 (!rd.IsPC() || AllowUnpredictable())) { 7185 EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) | 7186 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 7187 ((imm & 0xf000) << 4)); 7188 AdvanceIT(); 7189 return; 7190 } 7191 } else { 7192 ImmediateA32 immediate_a32(imm); 7193 // MOV{<c>}{<q>} <Rd>, #<const> ; A1 7194 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7195 EmitA32(0x03a00000U | (cond.GetCondition() << 28) | 7196 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 7197 return; 7198 } 7199 // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2 7200 if ((imm <= 65535) && cond.IsNotNever() && 7201 (!rd.IsPC() || AllowUnpredictable())) { 7202 EmitA32(0x03000000U | (cond.GetCondition() << 28) | 7203 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 7204 return; 7205 } 7206 } 7207 } 7208 Delegate(kMov, &Assembler::mov, cond, size, rd, operand); 7209 } 7210 7211 void Assembler::movs(Condition cond, 7212 EncodingSize size, 7213 Register rd, 7214 const Operand& operand) { 7215 VIXL_ASSERT(AllowAssembler()); 7216 CheckIT(cond); 7217 if (operand.IsImmediateShiftedRegister()) { 7218 Register rm = operand.GetBaseRegister(); 7219 Shift shift = operand.GetShift(); 7220 uint32_t amount = operand.GetShiftAmount(); 7221 if (IsUsingT32()) { 7222 // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 7223 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && 7224 shift.IsValidAmount(amount) && rm.IsLow() && 7225 (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) { 7226 uint32_t amount_ = amount % 32; 7227 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | 7228 (operand.GetTypeEncodingValue() << 11) | (amount_ << 6)); 7229 AdvanceIT(); 7230 return; 7231 } 7232 // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3 7233 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 7234 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7235 uint32_t amount_ = amount % 32; 7236 EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() | 7237 (operand.GetTypeEncodingValue() << 4) | 7238 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7239 AdvanceIT(); 7240 return; 7241 } 7242 } else { 7243 // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 7244 if (shift.IsValidAmount(amount) && cond.IsNotNever() && 7245 (!rd.IsPC() || AllowUnpredictable())) { 7246 uint32_t amount_ = amount % 32; 7247 EmitA32(0x01b00000U | (cond.GetCondition() << 28) | 7248 (rd.GetCode() << 12) | rm.GetCode() | 7249 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7250 return; 7251 } 7252 } 7253 } 7254 if (operand.IsRegisterShiftedRegister()) { 7255 Register rm = operand.GetBaseRegister(); 7256 Shift shift = operand.GetShift(); 7257 Register rs = operand.GetShiftRegister(); 7258 if (IsUsingT32()) { 7259 // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1 7260 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7261 shift.IsASR() && rs.IsLow()) { 7262 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 7263 AdvanceIT(); 7264 return; 7265 } 7266 // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1 7267 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7268 shift.IsLSL() && rs.IsLow()) { 7269 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 7270 AdvanceIT(); 7271 return; 7272 } 7273 // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1 7274 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7275 shift.IsLSR() && rs.IsLow()) { 7276 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 7277 AdvanceIT(); 7278 return; 7279 } 7280 // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1 7281 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7282 shift.IsROR() && rs.IsLow()) { 7283 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 7284 AdvanceIT(); 7285 return; 7286 } 7287 // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2 7288 if (!size.IsNarrow() && 7289 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7290 EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 7291 (shift.GetType() << 21) | rs.GetCode()); 7292 AdvanceIT(); 7293 return; 7294 } 7295 } else { 7296 // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7297 if (cond.IsNotNever() && 7298 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7299 EmitA32(0x01b00010U | (cond.GetCondition() << 28) | 7300 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7301 (rs.GetCode() << 8)); 7302 return; 7303 } 7304 } 7305 } 7306 if (operand.IsImmediate()) { 7307 uint32_t imm = operand.GetImmediate(); 7308 if (IsUsingT32()) { 7309 ImmediateT32 immediate_t32(imm); 7310 // MOVS{<q>} <Rd>, #<imm8> ; T1 7311 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) { 7312 EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm); 7313 AdvanceIT(); 7314 return; 7315 } 7316 // MOVS{<c>}{<q>} <Rd>, #<const> ; T2 7317 if (!size.IsNarrow() && immediate_t32.IsValid() && 7318 (!rd.IsPC() || AllowUnpredictable())) { 7319 EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) | 7320 (immediate_t32.GetEncodingValue() & 0xff) | 7321 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7322 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7323 AdvanceIT(); 7324 return; 7325 } 7326 } else { 7327 ImmediateA32 immediate_a32(imm); 7328 // MOVS{<c>}{<q>} <Rd>, #<const> ; A1 7329 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7330 EmitA32(0x03b00000U | (cond.GetCondition() << 28) | 7331 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 7332 return; 7333 } 7334 } 7335 } 7336 Delegate(kMovs, &Assembler::movs, cond, size, rd, operand); 7337 } 7338 7339 void Assembler::movt(Condition cond, Register rd, const Operand& operand) { 7340 VIXL_ASSERT(AllowAssembler()); 7341 CheckIT(cond); 7342 if (operand.IsImmediate()) { 7343 uint32_t imm = operand.GetImmediate(); 7344 if (IsUsingT32()) { 7345 // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1 7346 if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) { 7347 EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) | 7348 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 7349 ((imm & 0xf000) << 4)); 7350 AdvanceIT(); 7351 return; 7352 } 7353 } else { 7354 // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1 7355 if ((imm <= 65535) && cond.IsNotNever() && 7356 (!rd.IsPC() || AllowUnpredictable())) { 7357 EmitA32(0x03400000U | (cond.GetCondition() << 28) | 7358 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 7359 return; 7360 } 7361 } 7362 } 7363 Delegate(kMovt, &Assembler::movt, cond, rd, operand); 7364 } 7365 7366 void Assembler::movw(Condition cond, Register rd, const Operand& operand) { 7367 VIXL_ASSERT(AllowAssembler()); 7368 CheckIT(cond); 7369 if (operand.IsImmediate()) { 7370 uint32_t imm = operand.GetImmediate(); 7371 if (IsUsingT32()) { 7372 // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3 7373 if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) { 7374 EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) | 7375 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 7376 ((imm & 0xf000) << 4)); 7377 AdvanceIT(); 7378 return; 7379 } 7380 } else { 7381 // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2 7382 if ((imm <= 65535) && cond.IsNotNever() && 7383 (!rd.IsPC() || AllowUnpredictable())) { 7384 EmitA32(0x03000000U | (cond.GetCondition() << 28) | 7385 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 7386 return; 7387 } 7388 } 7389 } 7390 Delegate(kMovw, &Assembler::movw, cond, rd, operand); 7391 } 7392 7393 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) { 7394 VIXL_ASSERT(AllowAssembler()); 7395 CheckIT(cond); 7396 if (IsUsingT32()) { 7397 // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1 7398 if ((!rd.IsPC() || AllowUnpredictable())) { 7399 EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20)); 7400 AdvanceIT(); 7401 return; 7402 } 7403 } else { 7404 // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1 7405 if (cond.IsNotNever() && (!rd.IsPC() || AllowUnpredictable())) { 7406 EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7407 (spec_reg.GetReg() << 22)); 7408 return; 7409 } 7410 } 7411 Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg); 7412 } 7413 7414 void Assembler::msr(Condition cond, 7415 MaskedSpecialRegister spec_reg, 7416 const Operand& operand) { 7417 VIXL_ASSERT(AllowAssembler()); 7418 CheckIT(cond); 7419 if (operand.IsImmediate()) { 7420 uint32_t imm = operand.GetImmediate(); 7421 if (IsUsingA32()) { 7422 ImmediateA32 immediate_a32(imm); 7423 // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1 7424 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7425 EmitA32(0x0320f000U | (cond.GetCondition() << 28) | 7426 ((spec_reg.GetReg() & 0xf) << 16) | 7427 ((spec_reg.GetReg() & 0x10) << 18) | 7428 immediate_a32.GetEncodingValue()); 7429 return; 7430 } 7431 } 7432 } 7433 if (operand.IsPlainRegister()) { 7434 Register rn = operand.GetBaseRegister(); 7435 if (IsUsingT32()) { 7436 // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1 7437 if ((!rn.IsPC() || AllowUnpredictable())) { 7438 EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) | 7439 ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16)); 7440 AdvanceIT(); 7441 return; 7442 } 7443 } else { 7444 // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1 7445 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 7446 EmitA32(0x0120f000U | (cond.GetCondition() << 28) | 7447 ((spec_reg.GetReg() & 0xf) << 16) | 7448 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode()); 7449 return; 7450 } 7451 } 7452 } 7453 Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand); 7454 } 7455 7456 void Assembler::mul( 7457 Condition cond, EncodingSize size, Register rd, Register rn, Register rm) { 7458 VIXL_ASSERT(AllowAssembler()); 7459 CheckIT(cond); 7460 if (IsUsingT32()) { 7461 // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1 7462 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() && 7463 rm.IsLow()) { 7464 EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3)); 7465 AdvanceIT(); 7466 return; 7467 } 7468 // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2 7469 if (!size.IsNarrow() && 7470 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7471 EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7472 rm.GetCode()); 7473 AdvanceIT(); 7474 return; 7475 } 7476 } else { 7477 // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1 7478 if (cond.IsNotNever() && 7479 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7480 EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 7481 rn.GetCode() | (rm.GetCode() << 8)); 7482 return; 7483 } 7484 } 7485 Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm); 7486 } 7487 7488 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) { 7489 VIXL_ASSERT(AllowAssembler()); 7490 CheckIT(cond); 7491 if (IsUsingT32()) { 7492 // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1 7493 if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) { 7494 EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3)); 7495 AdvanceIT(); 7496 return; 7497 } 7498 } else { 7499 // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1 7500 if (cond.IsNotNever() && 7501 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7502 EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 7503 rn.GetCode() | (rm.GetCode() << 8)); 7504 return; 7505 } 7506 } 7507 Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm); 7508 } 7509 7510 void Assembler::mvn(Condition cond, 7511 EncodingSize size, 7512 Register rd, 7513 const Operand& operand) { 7514 VIXL_ASSERT(AllowAssembler()); 7515 CheckIT(cond); 7516 if (operand.IsImmediate()) { 7517 uint32_t imm = operand.GetImmediate(); 7518 if (IsUsingT32()) { 7519 ImmediateT32 immediate_t32(imm); 7520 // MVN{<c>}{<q>} <Rd>, #<const> ; T1 7521 if (!size.IsNarrow() && immediate_t32.IsValid() && 7522 (!rd.IsPC() || AllowUnpredictable())) { 7523 EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) | 7524 (immediate_t32.GetEncodingValue() & 0xff) | 7525 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7526 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7527 AdvanceIT(); 7528 return; 7529 } 7530 } else { 7531 ImmediateA32 immediate_a32(imm); 7532 // MVN{<c>}{<q>} <Rd>, #<const> ; A1 7533 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7534 EmitA32(0x03e00000U | (cond.GetCondition() << 28) | 7535 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 7536 return; 7537 } 7538 } 7539 } 7540 if (operand.IsImmediateShiftedRegister()) { 7541 Register rm = operand.GetBaseRegister(); 7542 if (operand.IsPlainRegister()) { 7543 if (IsUsingT32()) { 7544 // MVN<c>{<q>} <Rd>, <Rm> ; T1 7545 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) { 7546 EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3)); 7547 AdvanceIT(); 7548 return; 7549 } 7550 } 7551 } 7552 Shift shift = operand.GetShift(); 7553 uint32_t amount = operand.GetShiftAmount(); 7554 if (IsUsingT32()) { 7555 // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 7556 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 7557 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7558 uint32_t amount_ = amount % 32; 7559 EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() | 7560 (operand.GetTypeEncodingValue() << 4) | 7561 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7562 AdvanceIT(); 7563 return; 7564 } 7565 } else { 7566 // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 7567 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7568 uint32_t amount_ = amount % 32; 7569 EmitA32(0x01e00000U | (cond.GetCondition() << 28) | 7570 (rd.GetCode() << 12) | rm.GetCode() | 7571 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7572 return; 7573 } 7574 } 7575 } 7576 if (operand.IsRegisterShiftedRegister()) { 7577 Register rm = operand.GetBaseRegister(); 7578 Shift shift = operand.GetShift(); 7579 Register rs = operand.GetShiftRegister(); 7580 if (IsUsingA32()) { 7581 // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7582 if (cond.IsNotNever() && 7583 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7584 EmitA32(0x01e00010U | (cond.GetCondition() << 28) | 7585 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7586 (rs.GetCode() << 8)); 7587 return; 7588 } 7589 } 7590 } 7591 Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand); 7592 } 7593 7594 void Assembler::mvns(Condition cond, 7595 EncodingSize size, 7596 Register rd, 7597 const Operand& operand) { 7598 VIXL_ASSERT(AllowAssembler()); 7599 CheckIT(cond); 7600 if (operand.IsImmediate()) { 7601 uint32_t imm = operand.GetImmediate(); 7602 if (IsUsingT32()) { 7603 ImmediateT32 immediate_t32(imm); 7604 // MVNS{<c>}{<q>} <Rd>, #<const> ; T1 7605 if (!size.IsNarrow() && immediate_t32.IsValid() && 7606 (!rd.IsPC() || AllowUnpredictable())) { 7607 EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) | 7608 (immediate_t32.GetEncodingValue() & 0xff) | 7609 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7610 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7611 AdvanceIT(); 7612 return; 7613 } 7614 } else { 7615 ImmediateA32 immediate_a32(imm); 7616 // MVNS{<c>}{<q>} <Rd>, #<const> ; A1 7617 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7618 EmitA32(0x03f00000U | (cond.GetCondition() << 28) | 7619 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 7620 return; 7621 } 7622 } 7623 } 7624 if (operand.IsImmediateShiftedRegister()) { 7625 Register rm = operand.GetBaseRegister(); 7626 if (operand.IsPlainRegister()) { 7627 if (IsUsingT32()) { 7628 // MVNS{<q>} <Rd>, <Rm> ; T1 7629 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) { 7630 EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3)); 7631 AdvanceIT(); 7632 return; 7633 } 7634 } 7635 } 7636 Shift shift = operand.GetShift(); 7637 uint32_t amount = operand.GetShiftAmount(); 7638 if (IsUsingT32()) { 7639 // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 7640 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 7641 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7642 uint32_t amount_ = amount % 32; 7643 EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() | 7644 (operand.GetTypeEncodingValue() << 4) | 7645 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7646 AdvanceIT(); 7647 return; 7648 } 7649 } else { 7650 // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 7651 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7652 uint32_t amount_ = amount % 32; 7653 EmitA32(0x01f00000U | (cond.GetCondition() << 28) | 7654 (rd.GetCode() << 12) | rm.GetCode() | 7655 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7656 return; 7657 } 7658 } 7659 } 7660 if (operand.IsRegisterShiftedRegister()) { 7661 Register rm = operand.GetBaseRegister(); 7662 Shift shift = operand.GetShift(); 7663 Register rs = operand.GetShiftRegister(); 7664 if (IsUsingA32()) { 7665 // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7666 if (cond.IsNotNever() && 7667 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7668 EmitA32(0x01f00010U | (cond.GetCondition() << 28) | 7669 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7670 (rs.GetCode() << 8)); 7671 return; 7672 } 7673 } 7674 } 7675 Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand); 7676 } 7677 7678 void Assembler::nop(Condition cond, EncodingSize size) { 7679 VIXL_ASSERT(AllowAssembler()); 7680 CheckIT(cond); 7681 if (IsUsingT32()) { 7682 // NOP{<c>}{<q>} ; T1 7683 if (!size.IsWide()) { 7684 EmitT32_16(0xbf00); 7685 AdvanceIT(); 7686 return; 7687 } 7688 // NOP{<c>}.W ; T2 7689 if (!size.IsNarrow()) { 7690 EmitT32_32(0xf3af8000U); 7691 AdvanceIT(); 7692 return; 7693 } 7694 } else { 7695 // NOP{<c>}{<q>} ; A1 7696 if (cond.IsNotNever()) { 7697 EmitA32(0x0320f000U | (cond.GetCondition() << 28)); 7698 return; 7699 } 7700 } 7701 Delegate(kNop, &Assembler::nop, cond, size); 7702 } 7703 7704 void Assembler::orn(Condition cond, 7705 Register rd, 7706 Register rn, 7707 const Operand& operand) { 7708 VIXL_ASSERT(AllowAssembler()); 7709 CheckIT(cond); 7710 if (operand.IsImmediate()) { 7711 uint32_t imm = operand.GetImmediate(); 7712 if (IsUsingT32()) { 7713 ImmediateT32 immediate_t32(imm); 7714 // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7715 if (immediate_t32.IsValid() && !rn.Is(pc) && 7716 (!rd.IsPC() || AllowUnpredictable())) { 7717 EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7718 (immediate_t32.GetEncodingValue() & 0xff) | 7719 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7720 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7721 AdvanceIT(); 7722 return; 7723 } 7724 } 7725 } 7726 if (operand.IsImmediateShiftedRegister()) { 7727 Register rm = operand.GetBaseRegister(); 7728 Shift shift = operand.GetShift(); 7729 uint32_t amount = operand.GetShiftAmount(); 7730 if (IsUsingT32()) { 7731 // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 7732 if (shift.IsValidAmount(amount) && !rn.Is(pc) && 7733 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7734 uint32_t amount_ = amount % 32; 7735 EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7736 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7737 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7738 AdvanceIT(); 7739 return; 7740 } 7741 } 7742 } 7743 Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand); 7744 } 7745 7746 void Assembler::orns(Condition cond, 7747 Register rd, 7748 Register rn, 7749 const Operand& operand) { 7750 VIXL_ASSERT(AllowAssembler()); 7751 CheckIT(cond); 7752 if (operand.IsImmediate()) { 7753 uint32_t imm = operand.GetImmediate(); 7754 if (IsUsingT32()) { 7755 ImmediateT32 immediate_t32(imm); 7756 // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7757 if (immediate_t32.IsValid() && !rn.Is(pc) && 7758 (!rd.IsPC() || AllowUnpredictable())) { 7759 EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7760 (immediate_t32.GetEncodingValue() & 0xff) | 7761 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7762 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7763 AdvanceIT(); 7764 return; 7765 } 7766 } 7767 } 7768 if (operand.IsImmediateShiftedRegister()) { 7769 Register rm = operand.GetBaseRegister(); 7770 Shift shift = operand.GetShift(); 7771 uint32_t amount = operand.GetShiftAmount(); 7772 if (IsUsingT32()) { 7773 // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 7774 if (shift.IsValidAmount(amount) && !rn.Is(pc) && 7775 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7776 uint32_t amount_ = amount % 32; 7777 EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7778 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7779 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7780 AdvanceIT(); 7781 return; 7782 } 7783 } 7784 } 7785 Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand); 7786 } 7787 7788 void Assembler::orr(Condition cond, 7789 EncodingSize size, 7790 Register rd, 7791 Register rn, 7792 const Operand& operand) { 7793 VIXL_ASSERT(AllowAssembler()); 7794 CheckIT(cond); 7795 if (operand.IsImmediate()) { 7796 uint32_t imm = operand.GetImmediate(); 7797 if (IsUsingT32()) { 7798 ImmediateT32 immediate_t32(imm); 7799 // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7800 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) && 7801 (!rd.IsPC() || AllowUnpredictable())) { 7802 EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7803 (immediate_t32.GetEncodingValue() & 0xff) | 7804 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7805 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7806 AdvanceIT(); 7807 return; 7808 } 7809 } else { 7810 ImmediateA32 immediate_a32(imm); 7811 // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 7812 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7813 EmitA32(0x03800000U | (cond.GetCondition() << 28) | 7814 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 7815 immediate_a32.GetEncodingValue()); 7816 return; 7817 } 7818 } 7819 } 7820 if (operand.IsImmediateShiftedRegister()) { 7821 Register rm = operand.GetBaseRegister(); 7822 if (operand.IsPlainRegister()) { 7823 if (IsUsingT32()) { 7824 // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 7825 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 7826 rm.IsLow()) { 7827 EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3)); 7828 AdvanceIT(); 7829 return; 7830 } 7831 } 7832 } 7833 Shift shift = operand.GetShift(); 7834 uint32_t amount = operand.GetShiftAmount(); 7835 if (IsUsingT32()) { 7836 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 7837 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) && 7838 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7839 uint32_t amount_ = amount % 32; 7840 EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7841 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7842 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7843 AdvanceIT(); 7844 return; 7845 } 7846 } else { 7847 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 7848 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7849 uint32_t amount_ = amount % 32; 7850 EmitA32(0x01800000U | (cond.GetCondition() << 28) | 7851 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7852 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7853 return; 7854 } 7855 } 7856 } 7857 if (operand.IsRegisterShiftedRegister()) { 7858 Register rm = operand.GetBaseRegister(); 7859 Shift shift = operand.GetShift(); 7860 Register rs = operand.GetShiftRegister(); 7861 if (IsUsingA32()) { 7862 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 7863 if (cond.IsNotNever() && 7864 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 7865 AllowUnpredictable())) { 7866 EmitA32(0x01800010U | (cond.GetCondition() << 28) | 7867 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7868 (shift.GetType() << 5) | (rs.GetCode() << 8)); 7869 return; 7870 } 7871 } 7872 } 7873 Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand); 7874 } 7875 7876 void Assembler::orrs(Condition cond, 7877 EncodingSize size, 7878 Register rd, 7879 Register rn, 7880 const Operand& operand) { 7881 VIXL_ASSERT(AllowAssembler()); 7882 CheckIT(cond); 7883 if (operand.IsImmediate()) { 7884 uint32_t imm = operand.GetImmediate(); 7885 if (IsUsingT32()) { 7886 ImmediateT32 immediate_t32(imm); 7887 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7888 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) && 7889 (!rd.IsPC() || AllowUnpredictable())) { 7890 EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7891 (immediate_t32.GetEncodingValue() & 0xff) | 7892 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7893 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7894 AdvanceIT(); 7895 return; 7896 } 7897 } else { 7898 ImmediateA32 immediate_a32(imm); 7899 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 7900 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7901 EmitA32(0x03900000U | (cond.GetCondition() << 28) | 7902 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 7903 immediate_a32.GetEncodingValue()); 7904 return; 7905 } 7906 } 7907 } 7908 if (operand.IsImmediateShiftedRegister()) { 7909 Register rm = operand.GetBaseRegister(); 7910 if (operand.IsPlainRegister()) { 7911 if (IsUsingT32()) { 7912 // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 7913 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 7914 rm.IsLow()) { 7915 EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3)); 7916 AdvanceIT(); 7917 return; 7918 } 7919 } 7920 } 7921 Shift shift = operand.GetShift(); 7922 uint32_t amount = operand.GetShiftAmount(); 7923 if (IsUsingT32()) { 7924 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 7925 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) && 7926 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7927 uint32_t amount_ = amount % 32; 7928 EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7929 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7930 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7931 AdvanceIT(); 7932 return; 7933 } 7934 } else { 7935 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 7936 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7937 uint32_t amount_ = amount % 32; 7938 EmitA32(0x01900000U | (cond.GetCondition() << 28) | 7939 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7940 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7941 return; 7942 } 7943 } 7944 } 7945 if (operand.IsRegisterShiftedRegister()) { 7946 Register rm = operand.GetBaseRegister(); 7947 Shift shift = operand.GetShift(); 7948 Register rs = operand.GetShiftRegister(); 7949 if (IsUsingA32()) { 7950 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 7951 if (cond.IsNotNever() && 7952 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 7953 AllowUnpredictable())) { 7954 EmitA32(0x01900010U | (cond.GetCondition() << 28) | 7955 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7956 (shift.GetType() << 5) | (rs.GetCode() << 8)); 7957 return; 7958 } 7959 } 7960 } 7961 Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand); 7962 } 7963 7964 void Assembler::pkhbt(Condition cond, 7965 Register rd, 7966 Register rn, 7967 const Operand& operand) { 7968 VIXL_ASSERT(AllowAssembler()); 7969 CheckIT(cond); 7970 if (operand.IsImmediateShiftedRegister()) { 7971 Register rm = operand.GetBaseRegister(); 7972 Shift shift = operand.GetShift(); 7973 uint32_t amount = operand.GetShiftAmount(); 7974 if (IsUsingT32()) { 7975 // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1 7976 if (shift.IsLSL() && shift.IsValidAmount(amount) && 7977 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7978 EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7979 rm.GetCode() | ((amount & 0x3) << 6) | 7980 ((amount & 0x1c) << 10)); 7981 AdvanceIT(); 7982 return; 7983 } 7984 } else { 7985 // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1 7986 if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever() && 7987 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7988 EmitA32(0x06800010U | (cond.GetCondition() << 28) | 7989 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7990 (amount << 7)); 7991 return; 7992 } 7993 } 7994 } 7995 Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand); 7996 } 7997 7998 void Assembler::pkhtb(Condition cond, 7999 Register rd, 8000 Register rn, 8001 const Operand& operand) { 8002 VIXL_ASSERT(AllowAssembler()); 8003 CheckIT(cond); 8004 if (operand.IsImmediateShiftedRegister()) { 8005 Register rm = operand.GetBaseRegister(); 8006 Shift shift = operand.GetShift(); 8007 uint32_t amount = operand.GetShiftAmount(); 8008 if (IsUsingT32()) { 8009 // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1 8010 if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) && 8011 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8012 uint32_t amount_ = amount % 32; 8013 EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8014 rm.GetCode() | ((amount_ & 0x3) << 6) | 8015 ((amount_ & 0x1c) << 10)); 8016 AdvanceIT(); 8017 return; 8018 } 8019 } else { 8020 // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1 8021 if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) && 8022 cond.IsNotNever() && 8023 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8024 uint32_t amount_ = amount % 32; 8025 EmitA32(0x06800050U | (cond.GetCondition() << 28) | 8026 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8027 (amount_ << 7)); 8028 return; 8029 } 8030 } 8031 } 8032 Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand); 8033 } 8034 8035 void Assembler::pld(Condition cond, Location* location) { 8036 VIXL_ASSERT(AllowAssembler()); 8037 CheckIT(cond); 8038 Location::Offset offset = 8039 location->IsBound() 8040 ? location->GetLocation() - 8041 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 8042 : 0; 8043 if (IsUsingT32()) { 8044 // PLD{<c>}{<q>} <label> ; T1 8045 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 8046 !location->IsBound())) { 8047 static class EmitOp : public Location::EmitOperator { 8048 public: 8049 EmitOp() : Location::EmitOperator(T32) {} 8050 virtual uint32_t Encode(uint32_t instr, 8051 Location::Offset program_counter, 8052 const Location* loc) const VIXL_OVERRIDE { 8053 program_counter += kT32PcDelta; 8054 Location::Offset off = 8055 loc->GetLocation() - AlignDown(program_counter, 4); 8056 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 8057 uint32_t U = (off >= 0); 8058 int32_t target = abs(off) | (U << 12); 8059 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 8060 } 8061 } immop; 8062 EmitT32_32(Link(0xf81ff000U, location, immop, &kT32FarDataInfo)); 8063 AdvanceIT(); 8064 return; 8065 } 8066 } else { 8067 // PLD{<c>}{<q>} <label> ; A1 8068 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 8069 !location->IsBound())) { 8070 if (cond.Is(al)) { 8071 static class EmitOp : public Location::EmitOperator { 8072 public: 8073 EmitOp() : Location::EmitOperator(A32) {} 8074 virtual uint32_t Encode(uint32_t instr, 8075 Location::Offset program_counter, 8076 const Location* loc) const VIXL_OVERRIDE { 8077 program_counter += kA32PcDelta; 8078 Location::Offset off = 8079 loc->GetLocation() - AlignDown(program_counter, 4); 8080 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 8081 uint32_t U = (off >= 0); 8082 int32_t target = abs(off) | (U << 12); 8083 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 8084 } 8085 } immop; 8086 EmitA32(Link(0xf55ff000U, location, immop, &kA32FarDataInfo)); 8087 return; 8088 } 8089 } 8090 } 8091 Delegate(kPld, &Assembler::pld, cond, location); 8092 } 8093 8094 bool Assembler::pld_info(Condition cond, 8095 Location* location, 8096 const struct ReferenceInfo** info) { 8097 VIXL_ASSERT(!location->IsBound()); 8098 USE(location); 8099 USE(cond); 8100 if (IsUsingT32()) { 8101 // PLD{<c>}{<q>} <label> ; T1 8102 if (true) { 8103 *info = &kT32FarDataInfo; 8104 return true; 8105 } 8106 } else { 8107 // PLD{<c>}{<q>} <label> ; A1 8108 if (true) { 8109 *info = &kA32FarDataInfo; 8110 return true; 8111 } 8112 } 8113 return false; 8114 } 8115 8116 void Assembler::pld(Condition cond, const MemOperand& operand) { 8117 VIXL_ASSERT(AllowAssembler()); 8118 CheckIT(cond); 8119 if (operand.IsImmediate()) { 8120 Register rn = operand.GetBaseRegister(); 8121 int32_t offset = operand.GetOffsetImmediate(); 8122 if (IsUsingT32()) { 8123 // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1 8124 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 8125 operand.IsOffset()) { 8126 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8127 uint32_t offset_ = abs(offset); 8128 EmitT32_32(0xf81ff000U | offset_ | (sign << 23)); 8129 AdvanceIT(); 8130 return; 8131 } 8132 } else { 8133 // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1 8134 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 8135 operand.IsOffset()) { 8136 if (cond.Is(al)) { 8137 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8138 uint32_t offset_ = abs(offset); 8139 EmitA32(0xf55ff000U | offset_ | (sign << 23)); 8140 return; 8141 } 8142 } 8143 } 8144 } 8145 if (operand.IsImmediate()) { 8146 Register rn = operand.GetBaseRegister(); 8147 int32_t offset = operand.GetOffsetImmediate(); 8148 if (IsUsingT32()) { 8149 // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 8150 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 8151 ((rn.GetCode() & 0xf) != 0xf)) { 8152 EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 8153 AdvanceIT(); 8154 return; 8155 } 8156 // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 8157 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 8158 ((rn.GetCode() & 0xf) != 0xf)) { 8159 EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 8160 AdvanceIT(); 8161 return; 8162 } 8163 } else { 8164 // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1 8165 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 8166 ((rn.GetCode() & 0xf) != 0xf)) { 8167 if (cond.Is(al)) { 8168 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8169 uint32_t offset_ = abs(offset); 8170 EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 8171 return; 8172 } 8173 } 8174 } 8175 } 8176 if (operand.IsShiftedRegister()) { 8177 Register rn = operand.GetBaseRegister(); 8178 Sign sign = operand.GetSign(); 8179 Register rm = operand.GetOffsetRegister(); 8180 Shift shift = operand.GetShift(); 8181 uint32_t amount = operand.GetShiftAmount(); 8182 if (IsUsingT32()) { 8183 // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 8184 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 8185 ((rn.GetCode() & 0xf) != 0xf) && 8186 (!rm.IsPC() || AllowUnpredictable())) { 8187 EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() | 8188 (amount << 4)); 8189 AdvanceIT(); 8190 return; 8191 } 8192 } else { 8193 // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 8194 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() && 8195 (!rm.IsPC() || AllowUnpredictable())) { 8196 if (cond.Is(al)) { 8197 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8198 uint32_t amount_ = amount % 32; 8199 EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() | 8200 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 8201 return; 8202 } 8203 } 8204 // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 8205 if (shift.IsRRX() && operand.IsOffset() && 8206 (!rm.IsPC() || AllowUnpredictable())) { 8207 if (cond.Is(al)) { 8208 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8209 EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() | 8210 (sign_ << 23)); 8211 return; 8212 } 8213 } 8214 } 8215 } 8216 Delegate(kPld, &Assembler::pld, cond, operand); 8217 } 8218 8219 void Assembler::pldw(Condition cond, const MemOperand& operand) { 8220 VIXL_ASSERT(AllowAssembler()); 8221 CheckIT(cond); 8222 if (operand.IsImmediate()) { 8223 Register rn = operand.GetBaseRegister(); 8224 int32_t offset = operand.GetOffsetImmediate(); 8225 if (IsUsingT32()) { 8226 // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 8227 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 8228 ((rn.GetCode() & 0xf) != 0xf)) { 8229 EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 8230 AdvanceIT(); 8231 return; 8232 } 8233 // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 8234 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 8235 ((rn.GetCode() & 0xf) != 0xf)) { 8236 EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 8237 AdvanceIT(); 8238 return; 8239 } 8240 } else { 8241 // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1 8242 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 8243 ((rn.GetCode() & 0xf) != 0xf)) { 8244 if (cond.Is(al)) { 8245 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8246 uint32_t offset_ = abs(offset); 8247 EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 8248 return; 8249 } 8250 } 8251 } 8252 } 8253 if (operand.IsShiftedRegister()) { 8254 Register rn = operand.GetBaseRegister(); 8255 Sign sign = operand.GetSign(); 8256 Register rm = operand.GetOffsetRegister(); 8257 Shift shift = operand.GetShift(); 8258 uint32_t amount = operand.GetShiftAmount(); 8259 if (IsUsingT32()) { 8260 // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 8261 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 8262 ((rn.GetCode() & 0xf) != 0xf) && 8263 (!rm.IsPC() || AllowUnpredictable())) { 8264 EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() | 8265 (amount << 4)); 8266 AdvanceIT(); 8267 return; 8268 } 8269 } else { 8270 // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 8271 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() && 8272 (!rm.IsPC() || AllowUnpredictable())) { 8273 if (cond.Is(al)) { 8274 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8275 uint32_t amount_ = amount % 32; 8276 EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() | 8277 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 8278 return; 8279 } 8280 } 8281 // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 8282 if (shift.IsRRX() && operand.IsOffset() && 8283 (!rm.IsPC() || AllowUnpredictable())) { 8284 if (cond.Is(al)) { 8285 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8286 EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() | 8287 (sign_ << 23)); 8288 return; 8289 } 8290 } 8291 } 8292 } 8293 Delegate(kPldw, &Assembler::pldw, cond, operand); 8294 } 8295 8296 void Assembler::pli(Condition cond, const MemOperand& operand) { 8297 VIXL_ASSERT(AllowAssembler()); 8298 CheckIT(cond); 8299 if (operand.IsImmediate()) { 8300 Register rn = operand.GetBaseRegister(); 8301 int32_t offset = operand.GetOffsetImmediate(); 8302 if (IsUsingT32()) { 8303 // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 8304 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 8305 ((rn.GetCode() & 0xf) != 0xf)) { 8306 EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 8307 AdvanceIT(); 8308 return; 8309 } 8310 // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 8311 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 8312 ((rn.GetCode() & 0xf) != 0xf)) { 8313 EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 8314 AdvanceIT(); 8315 return; 8316 } 8317 } else { 8318 // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1 8319 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 8320 ((rn.GetCode() & 0xf) != 0xf)) { 8321 if (cond.Is(al)) { 8322 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8323 uint32_t offset_ = abs(offset); 8324 EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 8325 return; 8326 } 8327 } 8328 } 8329 } 8330 if (operand.IsImmediate()) { 8331 Register rn = operand.GetBaseRegister(); 8332 int32_t offset = operand.GetOffsetImmediate(); 8333 if (IsUsingT32()) { 8334 // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3 8335 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 8336 operand.IsOffset()) { 8337 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8338 uint32_t offset_ = abs(offset); 8339 EmitT32_32(0xf91ff000U | offset_ | (sign << 23)); 8340 AdvanceIT(); 8341 return; 8342 } 8343 } else { 8344 // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1 8345 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 8346 operand.IsOffset()) { 8347 if (cond.Is(al)) { 8348 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8349 uint32_t offset_ = abs(offset); 8350 EmitA32(0xf45ff000U | offset_ | (sign << 23)); 8351 return; 8352 } 8353 } 8354 } 8355 } 8356 if (operand.IsShiftedRegister()) { 8357 Register rn = operand.GetBaseRegister(); 8358 Sign sign = operand.GetSign(); 8359 Register rm = operand.GetOffsetRegister(); 8360 Shift shift = operand.GetShift(); 8361 uint32_t amount = operand.GetShiftAmount(); 8362 if (IsUsingT32()) { 8363 // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 8364 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 8365 ((rn.GetCode() & 0xf) != 0xf) && 8366 (!rm.IsPC() || AllowUnpredictable())) { 8367 EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() | 8368 (amount << 4)); 8369 AdvanceIT(); 8370 return; 8371 } 8372 } else { 8373 // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 8374 if (shift.IsRRX() && operand.IsOffset() && 8375 (!rm.IsPC() || AllowUnpredictable())) { 8376 if (cond.Is(al)) { 8377 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8378 EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() | 8379 (sign_ << 23)); 8380 return; 8381 } 8382 } 8383 // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 8384 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() && 8385 (!rm.IsPC() || AllowUnpredictable())) { 8386 if (cond.Is(al)) { 8387 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8388 uint32_t amount_ = amount % 32; 8389 EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() | 8390 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 8391 return; 8392 } 8393 } 8394 } 8395 } 8396 Delegate(kPli, &Assembler::pli, cond, operand); 8397 } 8398 8399 void Assembler::pli(Condition cond, Location* location) { 8400 VIXL_ASSERT(AllowAssembler()); 8401 CheckIT(cond); 8402 Location::Offset offset = 8403 location->IsBound() 8404 ? location->GetLocation() - 8405 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 8406 : 0; 8407 if (IsUsingT32()) { 8408 // PLI{<c>}{<q>} <label> ; T3 8409 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 8410 !location->IsBound())) { 8411 static class EmitOp : public Location::EmitOperator { 8412 public: 8413 EmitOp() : Location::EmitOperator(T32) {} 8414 virtual uint32_t Encode(uint32_t instr, 8415 Location::Offset program_counter, 8416 const Location* loc) const VIXL_OVERRIDE { 8417 program_counter += kT32PcDelta; 8418 Location::Offset off = 8419 loc->GetLocation() - AlignDown(program_counter, 4); 8420 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 8421 uint32_t U = (off >= 0); 8422 int32_t target = abs(off) | (U << 12); 8423 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 8424 } 8425 } immop; 8426 EmitT32_32(Link(0xf91ff000U, location, immop, &kT32FarDataInfo)); 8427 AdvanceIT(); 8428 return; 8429 } 8430 } else { 8431 // PLI{<c>}{<q>} <label> ; A1 8432 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 8433 !location->IsBound())) { 8434 if (cond.Is(al)) { 8435 static class EmitOp : public Location::EmitOperator { 8436 public: 8437 EmitOp() : Location::EmitOperator(A32) {} 8438 virtual uint32_t Encode(uint32_t instr, 8439 Location::Offset program_counter, 8440 const Location* loc) const VIXL_OVERRIDE { 8441 program_counter += kA32PcDelta; 8442 Location::Offset off = 8443 loc->GetLocation() - AlignDown(program_counter, 4); 8444 VIXL_ASSERT((off >= -4095) && (off <= 4095)); 8445 uint32_t U = (off >= 0); 8446 int32_t target = abs(off) | (U << 12); 8447 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 8448 } 8449 } immop; 8450 EmitA32(Link(0xf45ff000U, location, immop, &kA32FarDataInfo)); 8451 return; 8452 } 8453 } 8454 } 8455 Delegate(kPli, &Assembler::pli, cond, location); 8456 } 8457 8458 bool Assembler::pli_info(Condition cond, 8459 Location* location, 8460 const struct ReferenceInfo** info) { 8461 VIXL_ASSERT(!location->IsBound()); 8462 USE(location); 8463 USE(cond); 8464 if (IsUsingT32()) { 8465 // PLI{<c>}{<q>} <label> ; T3 8466 if (true) { 8467 *info = &kT32FarDataInfo; 8468 return true; 8469 } 8470 } else { 8471 // PLI{<c>}{<q>} <label> ; A1 8472 if (true) { 8473 *info = &kA32FarDataInfo; 8474 return true; 8475 } 8476 } 8477 return false; 8478 } 8479 8480 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) { 8481 VIXL_ASSERT(AllowAssembler()); 8482 CheckIT(cond); 8483 if (!registers.IsEmpty() || AllowUnpredictable()) { 8484 if (IsUsingT32()) { 8485 // A branch out of an IT block should be the last instruction in the 8486 // block. 8487 if (!registers.Includes(pc) || OutsideITBlockAndAlOrLast(cond) || 8488 AllowUnpredictable()) { 8489 // POP{<c>}{<q>} <registers> ; T1 8490 if (!size.IsWide() && registers.IsR0toR7orPC()) { 8491 EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) | 8492 GetRegisterListEncoding(registers, 0, 8)); 8493 AdvanceIT(); 8494 return; 8495 } 8496 // POP{<c>}{<q>} <registers> ; T2 8497 // Alias of: LDM{<c>}{<q>} SP!, <registers> ; T2 8498 if (!size.IsNarrow() && 8499 ((!registers.Includes(sp) && (registers.GetCount() > 1) && 8500 !(registers.Includes(pc) && registers.Includes(lr))) || 8501 AllowUnpredictable())) { 8502 EmitT32_32(0xe8bd0000U | GetRegisterListEncoding(registers, 0, 16)); 8503 AdvanceIT(); 8504 return; 8505 } 8506 } 8507 } else { 8508 // POP{<c>}{<q>} <registers> ; A1 8509 // Alias of: LDM{<c>}{<q>} SP!, <registers> ; A1 8510 if (cond.IsNotNever() && 8511 (!registers.Includes(sp) || AllowUnpredictable())) { 8512 EmitA32(0x08bd0000U | (cond.GetCondition() << 28) | 8513 GetRegisterListEncoding(registers, 0, 16)); 8514 return; 8515 } 8516 } 8517 } 8518 Delegate(kPop, &Assembler::pop, cond, size, registers); 8519 } 8520 8521 void Assembler::pop(Condition cond, EncodingSize size, Register rt) { 8522 VIXL_ASSERT(AllowAssembler()); 8523 CheckIT(cond); 8524 if (!rt.IsSP() || AllowUnpredictable()) { 8525 if (IsUsingT32()) { 8526 // POP{<c>}{<q>} <single_register_list> ; T4 8527 // Alias of: LDR{<c>}{<q>} <Rt>, [SP], #4 ; T4 8528 if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond) || 8529 AllowUnpredictable())) { 8530 EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12)); 8531 AdvanceIT(); 8532 return; 8533 } 8534 } else { 8535 // POP{<c>}{<q>} <single_register_list> ; A1 8536 // Alias of: LDR{<c>}{<q>} <Rt>, [SP], #4 ; T1 8537 if (cond.IsNotNever()) { 8538 EmitA32(0x049d0004U | (cond.GetCondition() << 28) | 8539 (rt.GetCode() << 12)); 8540 return; 8541 } 8542 } 8543 } 8544 Delegate(kPop, &Assembler::pop, cond, size, rt); 8545 } 8546 8547 void Assembler::push(Condition cond, 8548 EncodingSize size, 8549 RegisterList registers) { 8550 VIXL_ASSERT(AllowAssembler()); 8551 CheckIT(cond); 8552 if (!registers.IsEmpty() || AllowUnpredictable()) { 8553 if (IsUsingT32()) { 8554 // PUSH{<c>}{<q>} <registers> ; T1 8555 if (!size.IsWide() && registers.IsR0toR7orLR()) { 8556 EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) | 8557 GetRegisterListEncoding(registers, 0, 8)); 8558 AdvanceIT(); 8559 return; 8560 } 8561 // PUSH{<c>}{<q>} <registers> ; T1 8562 // Alias of: STMDB SP!, <registers> ; T1 8563 if (!size.IsNarrow() && !registers.Includes(pc) && 8564 ((!registers.Includes(sp) && (registers.GetCount() > 1)) || 8565 AllowUnpredictable())) { 8566 EmitT32_32(0xe92d0000U | GetRegisterListEncoding(registers, 0, 15)); 8567 AdvanceIT(); 8568 return; 8569 } 8570 } else { 8571 // PUSH{<c>}{<q>} <registers> ; A1 8572 // Alias of: STMDB SP!, <registers> ; A1 8573 if (cond.IsNotNever() && 8574 // For A32, sp can appear in the list, but stores an UNKNOWN value if 8575 // it is not the lowest-valued register. 8576 (!registers.Includes(sp) || 8577 registers.GetFirstAvailableRegister().IsSP() || 8578 AllowUnpredictable())) { 8579 EmitA32(0x092d0000U | (cond.GetCondition() << 28) | 8580 GetRegisterListEncoding(registers, 0, 16)); 8581 return; 8582 } 8583 } 8584 } 8585 Delegate(kPush, &Assembler::push, cond, size, registers); 8586 } 8587 8588 void Assembler::push(Condition cond, EncodingSize size, Register rt) { 8589 VIXL_ASSERT(AllowAssembler()); 8590 CheckIT(cond); 8591 if (IsUsingT32()) { 8592 // PUSH{<c>}{<q>} <single_register_list> ; T4 8593 // Alias of: STR{<c>}{<q>} <Rt>, [SP, #4]! ; T4 8594 if (!size.IsNarrow() && 8595 ((!rt.IsPC() && !rt.IsSP()) || AllowUnpredictable())) { 8596 EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12)); 8597 AdvanceIT(); 8598 return; 8599 } 8600 } else { 8601 // PUSH{<c>}{<q>} <single_register_list> ; A1 8602 // Alias of: STR{<c>}{<q>} <Rt>, [SP, #4]! ; A1 8603 if (cond.IsNotNever() && (!rt.IsSP() || AllowUnpredictable())) { 8604 EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12)); 8605 return; 8606 } 8607 } 8608 Delegate(kPush, &Assembler::push, cond, size, rt); 8609 } 8610 8611 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) { 8612 VIXL_ASSERT(AllowAssembler()); 8613 CheckIT(cond); 8614 if (IsUsingT32()) { 8615 // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 8616 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8617 EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() | 8618 (rn.GetCode() << 16)); 8619 AdvanceIT(); 8620 return; 8621 } 8622 } else { 8623 // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 8624 if (cond.IsNotNever() && 8625 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8626 EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8627 rm.GetCode() | (rn.GetCode() << 16)); 8628 return; 8629 } 8630 } 8631 Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn); 8632 } 8633 8634 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) { 8635 VIXL_ASSERT(AllowAssembler()); 8636 CheckIT(cond); 8637 if (IsUsingT32()) { 8638 // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8639 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8640 EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8641 rm.GetCode()); 8642 AdvanceIT(); 8643 return; 8644 } 8645 } else { 8646 // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8647 if (cond.IsNotNever() && 8648 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8649 EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8650 (rn.GetCode() << 16) | rm.GetCode()); 8651 return; 8652 } 8653 } 8654 Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm); 8655 } 8656 8657 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) { 8658 VIXL_ASSERT(AllowAssembler()); 8659 CheckIT(cond); 8660 if (IsUsingT32()) { 8661 // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8662 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8663 EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8664 rm.GetCode()); 8665 AdvanceIT(); 8666 return; 8667 } 8668 } else { 8669 // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8670 if (cond.IsNotNever() && 8671 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8672 EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8673 (rn.GetCode() << 16) | rm.GetCode()); 8674 return; 8675 } 8676 } 8677 Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm); 8678 } 8679 8680 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) { 8681 VIXL_ASSERT(AllowAssembler()); 8682 CheckIT(cond); 8683 if (IsUsingT32()) { 8684 // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8685 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8686 EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8687 rm.GetCode()); 8688 AdvanceIT(); 8689 return; 8690 } 8691 } else { 8692 // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8693 if (cond.IsNotNever() && 8694 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8695 EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8696 (rn.GetCode() << 16) | rm.GetCode()); 8697 return; 8698 } 8699 } 8700 Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm); 8701 } 8702 8703 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) { 8704 VIXL_ASSERT(AllowAssembler()); 8705 CheckIT(cond); 8706 if (IsUsingT32()) { 8707 // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 8708 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8709 EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() | 8710 (rn.GetCode() << 16)); 8711 AdvanceIT(); 8712 return; 8713 } 8714 } else { 8715 // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 8716 if (cond.IsNotNever() && 8717 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8718 EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8719 rm.GetCode() | (rn.GetCode() << 16)); 8720 return; 8721 } 8722 } 8723 Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn); 8724 } 8725 8726 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) { 8727 VIXL_ASSERT(AllowAssembler()); 8728 CheckIT(cond); 8729 if (IsUsingT32()) { 8730 // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 8731 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8732 EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() | 8733 (rn.GetCode() << 16)); 8734 AdvanceIT(); 8735 return; 8736 } 8737 } else { 8738 // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 8739 if (cond.IsNotNever() && 8740 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8741 EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8742 rm.GetCode() | (rn.GetCode() << 16)); 8743 return; 8744 } 8745 } 8746 Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn); 8747 } 8748 8749 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) { 8750 VIXL_ASSERT(AllowAssembler()); 8751 CheckIT(cond); 8752 if (IsUsingT32()) { 8753 // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8754 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8755 EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8756 rm.GetCode()); 8757 AdvanceIT(); 8758 return; 8759 } 8760 } else { 8761 // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8762 if (cond.IsNotNever() && 8763 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8764 EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8765 (rn.GetCode() << 16) | rm.GetCode()); 8766 return; 8767 } 8768 } 8769 Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm); 8770 } 8771 8772 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) { 8773 VIXL_ASSERT(AllowAssembler()); 8774 CheckIT(cond); 8775 if (IsUsingT32()) { 8776 // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 8777 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8778 EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() | 8779 (rn.GetCode() << 16)); 8780 AdvanceIT(); 8781 return; 8782 } 8783 } else { 8784 // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 8785 if (cond.IsNotNever() && 8786 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8787 EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8788 rm.GetCode() | (rn.GetCode() << 16)); 8789 return; 8790 } 8791 } 8792 Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn); 8793 } 8794 8795 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) { 8796 VIXL_ASSERT(AllowAssembler()); 8797 CheckIT(cond); 8798 if (IsUsingT32()) { 8799 // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8800 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8801 EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8802 rm.GetCode()); 8803 AdvanceIT(); 8804 return; 8805 } 8806 } else { 8807 // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8808 if (cond.IsNotNever() && 8809 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8810 EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8811 (rn.GetCode() << 16) | rm.GetCode()); 8812 return; 8813 } 8814 } 8815 Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm); 8816 } 8817 8818 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) { 8819 VIXL_ASSERT(AllowAssembler()); 8820 CheckIT(cond); 8821 if (IsUsingT32()) { 8822 // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8823 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8824 EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8825 rm.GetCode()); 8826 AdvanceIT(); 8827 return; 8828 } 8829 } else { 8830 // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8831 if (cond.IsNotNever() && 8832 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8833 EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8834 (rn.GetCode() << 16) | rm.GetCode()); 8835 return; 8836 } 8837 } 8838 Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm); 8839 } 8840 8841 void Assembler::rbit(Condition cond, Register rd, Register rm) { 8842 VIXL_ASSERT(AllowAssembler()); 8843 CheckIT(cond); 8844 if (IsUsingT32()) { 8845 // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1 8846 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8847 EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() | 8848 (rm.GetCode() << 16)); 8849 AdvanceIT(); 8850 return; 8851 } 8852 } else { 8853 // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1 8854 if (cond.IsNotNever() && 8855 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8856 EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8857 rm.GetCode()); 8858 return; 8859 } 8860 } 8861 Delegate(kRbit, &Assembler::rbit, cond, rd, rm); 8862 } 8863 8864 void Assembler::rev(Condition cond, 8865 EncodingSize size, 8866 Register rd, 8867 Register rm) { 8868 VIXL_ASSERT(AllowAssembler()); 8869 CheckIT(cond); 8870 if (IsUsingT32()) { 8871 // REV{<c>}{<q>} <Rd>, <Rm> ; T1 8872 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8873 EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3)); 8874 AdvanceIT(); 8875 return; 8876 } 8877 // REV{<c>}{<q>} <Rd>, <Rm> ; T2 8878 if (!size.IsNarrow() && 8879 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8880 EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() | 8881 (rm.GetCode() << 16)); 8882 AdvanceIT(); 8883 return; 8884 } 8885 } else { 8886 // REV{<c>}{<q>} <Rd>, <Rm> ; A1 8887 if (cond.IsNotNever() && 8888 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8889 EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8890 rm.GetCode()); 8891 return; 8892 } 8893 } 8894 Delegate(kRev, &Assembler::rev, cond, size, rd, rm); 8895 } 8896 8897 void Assembler::rev16(Condition cond, 8898 EncodingSize size, 8899 Register rd, 8900 Register rm) { 8901 VIXL_ASSERT(AllowAssembler()); 8902 CheckIT(cond); 8903 if (IsUsingT32()) { 8904 // REV16{<c>}{<q>} <Rd>, <Rm> ; T1 8905 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8906 EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3)); 8907 AdvanceIT(); 8908 return; 8909 } 8910 // REV16{<c>}{<q>} <Rd>, <Rm> ; T2 8911 if (!size.IsNarrow() && 8912 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8913 EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() | 8914 (rm.GetCode() << 16)); 8915 AdvanceIT(); 8916 return; 8917 } 8918 } else { 8919 // REV16{<c>}{<q>} <Rd>, <Rm> ; A1 8920 if (cond.IsNotNever() && 8921 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8922 EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8923 rm.GetCode()); 8924 return; 8925 } 8926 } 8927 Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm); 8928 } 8929 8930 void Assembler::revsh(Condition cond, 8931 EncodingSize size, 8932 Register rd, 8933 Register rm) { 8934 VIXL_ASSERT(AllowAssembler()); 8935 CheckIT(cond); 8936 if (IsUsingT32()) { 8937 // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1 8938 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8939 EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3)); 8940 AdvanceIT(); 8941 return; 8942 } 8943 // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2 8944 if (!size.IsNarrow() && 8945 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8946 EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() | 8947 (rm.GetCode() << 16)); 8948 AdvanceIT(); 8949 return; 8950 } 8951 } else { 8952 // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1 8953 if (cond.IsNotNever() && 8954 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8955 EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8956 rm.GetCode()); 8957 return; 8958 } 8959 } 8960 Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm); 8961 } 8962 8963 void Assembler::ror(Condition cond, 8964 EncodingSize size, 8965 Register rd, 8966 Register rm, 8967 const Operand& operand) { 8968 VIXL_ASSERT(AllowAssembler()); 8969 CheckIT(cond); 8970 if (operand.IsImmediate()) { 8971 uint32_t imm = operand.GetImmediate(); 8972 if (IsUsingT32()) { 8973 // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 8974 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) && 8975 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8976 EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() | 8977 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 8978 AdvanceIT(); 8979 return; 8980 } 8981 } else { 8982 // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 8983 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 8984 EmitA32(0x01a00060U | (cond.GetCondition() << 28) | 8985 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 8986 return; 8987 } 8988 } 8989 } 8990 if (operand.IsPlainRegister()) { 8991 Register rs = operand.GetBaseRegister(); 8992 if (IsUsingT32()) { 8993 // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 8994 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 8995 rs.IsLow()) { 8996 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 8997 AdvanceIT(); 8998 return; 8999 } 9000 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 9001 if (!size.IsNarrow() && 9002 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 9003 EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 9004 rs.GetCode()); 9005 AdvanceIT(); 9006 return; 9007 } 9008 } else { 9009 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 9010 if (cond.IsNotNever() && 9011 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 9012 EmitA32(0x01a00070U | (cond.GetCondition() << 28) | 9013 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 9014 return; 9015 } 9016 } 9017 } 9018 Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand); 9019 } 9020 9021 void Assembler::rors(Condition cond, 9022 EncodingSize size, 9023 Register rd, 9024 Register rm, 9025 const Operand& operand) { 9026 VIXL_ASSERT(AllowAssembler()); 9027 CheckIT(cond); 9028 if (operand.IsImmediate()) { 9029 uint32_t imm = operand.GetImmediate(); 9030 if (IsUsingT32()) { 9031 // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 9032 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) && 9033 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9034 EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() | 9035 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 9036 AdvanceIT(); 9037 return; 9038 } 9039 } else { 9040 // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 9041 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 9042 EmitA32(0x01b00060U | (cond.GetCondition() << 28) | 9043 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 9044 return; 9045 } 9046 } 9047 } 9048 if (operand.IsPlainRegister()) { 9049 Register rs = operand.GetBaseRegister(); 9050 if (IsUsingT32()) { 9051 // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 9052 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 9053 rs.IsLow()) { 9054 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 9055 AdvanceIT(); 9056 return; 9057 } 9058 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 9059 if (!size.IsNarrow() && 9060 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 9061 EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 9062 rs.GetCode()); 9063 AdvanceIT(); 9064 return; 9065 } 9066 } else { 9067 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 9068 if (cond.IsNotNever() && 9069 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 9070 EmitA32(0x01b00070U | (cond.GetCondition() << 28) | 9071 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 9072 return; 9073 } 9074 } 9075 } 9076 Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand); 9077 } 9078 9079 void Assembler::rrx(Condition cond, Register rd, Register rm) { 9080 VIXL_ASSERT(AllowAssembler()); 9081 CheckIT(cond); 9082 if (IsUsingT32()) { 9083 // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3 9084 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9085 EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode()); 9086 AdvanceIT(); 9087 return; 9088 } 9089 } else { 9090 // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1 9091 if (cond.IsNotNever()) { 9092 EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9093 rm.GetCode()); 9094 return; 9095 } 9096 } 9097 Delegate(kRrx, &Assembler::rrx, cond, rd, rm); 9098 } 9099 9100 void Assembler::rrxs(Condition cond, Register rd, Register rm) { 9101 VIXL_ASSERT(AllowAssembler()); 9102 CheckIT(cond); 9103 if (IsUsingT32()) { 9104 // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3 9105 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9106 EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode()); 9107 AdvanceIT(); 9108 return; 9109 } 9110 } else { 9111 // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1 9112 if (cond.IsNotNever()) { 9113 EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9114 rm.GetCode()); 9115 return; 9116 } 9117 } 9118 Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm); 9119 } 9120 9121 void Assembler::rsb(Condition cond, 9122 EncodingSize size, 9123 Register rd, 9124 Register rn, 9125 const Operand& operand) { 9126 VIXL_ASSERT(AllowAssembler()); 9127 CheckIT(cond); 9128 if (operand.IsImmediate()) { 9129 uint32_t imm = operand.GetImmediate(); 9130 if (IsUsingT32()) { 9131 ImmediateT32 immediate_t32(imm); 9132 // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1 9133 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 9134 (imm == 0)) { 9135 EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3)); 9136 AdvanceIT(); 9137 return; 9138 } 9139 // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2 9140 if (!size.IsNarrow() && immediate_t32.IsValid() && 9141 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 9142 EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9143 (immediate_t32.GetEncodingValue() & 0xff) | 9144 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 9145 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 9146 AdvanceIT(); 9147 return; 9148 } 9149 } else { 9150 ImmediateA32 immediate_a32(imm); 9151 // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9152 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9153 EmitA32(0x02600000U | (cond.GetCondition() << 28) | 9154 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9155 immediate_a32.GetEncodingValue()); 9156 return; 9157 } 9158 } 9159 } 9160 if (operand.IsImmediateShiftedRegister()) { 9161 Register rm = operand.GetBaseRegister(); 9162 Shift shift = operand.GetShift(); 9163 uint32_t amount = operand.GetShiftAmount(); 9164 if (IsUsingT32()) { 9165 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 9166 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 9167 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9168 uint32_t amount_ = amount % 32; 9169 EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9170 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 9171 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 9172 AdvanceIT(); 9173 return; 9174 } 9175 } else { 9176 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9177 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9178 uint32_t amount_ = amount % 32; 9179 EmitA32(0x00600000U | (cond.GetCondition() << 28) | 9180 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9181 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9182 return; 9183 } 9184 } 9185 } 9186 if (operand.IsRegisterShiftedRegister()) { 9187 Register rm = operand.GetBaseRegister(); 9188 Shift shift = operand.GetShift(); 9189 Register rs = operand.GetShiftRegister(); 9190 if (IsUsingA32()) { 9191 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9192 if (cond.IsNotNever() && 9193 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9194 AllowUnpredictable())) { 9195 EmitA32(0x00600010U | (cond.GetCondition() << 28) | 9196 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9197 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9198 return; 9199 } 9200 } 9201 } 9202 Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand); 9203 } 9204 9205 void Assembler::rsbs(Condition cond, 9206 EncodingSize size, 9207 Register rd, 9208 Register rn, 9209 const Operand& operand) { 9210 VIXL_ASSERT(AllowAssembler()); 9211 CheckIT(cond); 9212 if (operand.IsImmediate()) { 9213 uint32_t imm = operand.GetImmediate(); 9214 if (IsUsingT32()) { 9215 ImmediateT32 immediate_t32(imm); 9216 // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1 9217 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 9218 (imm == 0)) { 9219 EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3)); 9220 AdvanceIT(); 9221 return; 9222 } 9223 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2 9224 if (!size.IsNarrow() && immediate_t32.IsValid() && 9225 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 9226 EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9227 (immediate_t32.GetEncodingValue() & 0xff) | 9228 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 9229 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 9230 AdvanceIT(); 9231 return; 9232 } 9233 } else { 9234 ImmediateA32 immediate_a32(imm); 9235 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9236 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9237 EmitA32(0x02700000U | (cond.GetCondition() << 28) | 9238 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9239 immediate_a32.GetEncodingValue()); 9240 return; 9241 } 9242 } 9243 } 9244 if (operand.IsImmediateShiftedRegister()) { 9245 Register rm = operand.GetBaseRegister(); 9246 Shift shift = operand.GetShift(); 9247 uint32_t amount = operand.GetShiftAmount(); 9248 if (IsUsingT32()) { 9249 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 9250 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 9251 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9252 uint32_t amount_ = amount % 32; 9253 EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9254 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 9255 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 9256 AdvanceIT(); 9257 return; 9258 } 9259 } else { 9260 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9261 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9262 uint32_t amount_ = amount % 32; 9263 EmitA32(0x00700000U | (cond.GetCondition() << 28) | 9264 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9265 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9266 return; 9267 } 9268 } 9269 } 9270 if (operand.IsRegisterShiftedRegister()) { 9271 Register rm = operand.GetBaseRegister(); 9272 Shift shift = operand.GetShift(); 9273 Register rs = operand.GetShiftRegister(); 9274 if (IsUsingA32()) { 9275 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9276 if (cond.IsNotNever() && 9277 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9278 AllowUnpredictable())) { 9279 EmitA32(0x00700010U | (cond.GetCondition() << 28) | 9280 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9281 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9282 return; 9283 } 9284 } 9285 } 9286 Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand); 9287 } 9288 9289 void Assembler::rsc(Condition cond, 9290 Register rd, 9291 Register rn, 9292 const Operand& operand) { 9293 VIXL_ASSERT(AllowAssembler()); 9294 CheckIT(cond); 9295 if (operand.IsImmediate()) { 9296 uint32_t imm = operand.GetImmediate(); 9297 if (IsUsingA32()) { 9298 ImmediateA32 immediate_a32(imm); 9299 // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9300 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9301 EmitA32(0x02e00000U | (cond.GetCondition() << 28) | 9302 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9303 immediate_a32.GetEncodingValue()); 9304 return; 9305 } 9306 } 9307 } 9308 if (operand.IsImmediateShiftedRegister()) { 9309 Register rm = operand.GetBaseRegister(); 9310 Shift shift = operand.GetShift(); 9311 uint32_t amount = operand.GetShiftAmount(); 9312 if (IsUsingA32()) { 9313 // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9314 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9315 uint32_t amount_ = amount % 32; 9316 EmitA32(0x00e00000U | (cond.GetCondition() << 28) | 9317 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9318 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9319 return; 9320 } 9321 } 9322 } 9323 if (operand.IsRegisterShiftedRegister()) { 9324 Register rm = operand.GetBaseRegister(); 9325 Shift shift = operand.GetShift(); 9326 Register rs = operand.GetShiftRegister(); 9327 if (IsUsingA32()) { 9328 // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9329 if (cond.IsNotNever() && 9330 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9331 AllowUnpredictable())) { 9332 EmitA32(0x00e00010U | (cond.GetCondition() << 28) | 9333 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9334 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9335 return; 9336 } 9337 } 9338 } 9339 Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand); 9340 } 9341 9342 void Assembler::rscs(Condition cond, 9343 Register rd, 9344 Register rn, 9345 const Operand& operand) { 9346 VIXL_ASSERT(AllowAssembler()); 9347 CheckIT(cond); 9348 if (operand.IsImmediate()) { 9349 uint32_t imm = operand.GetImmediate(); 9350 if (IsUsingA32()) { 9351 ImmediateA32 immediate_a32(imm); 9352 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9353 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9354 EmitA32(0x02f00000U | (cond.GetCondition() << 28) | 9355 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9356 immediate_a32.GetEncodingValue()); 9357 return; 9358 } 9359 } 9360 } 9361 if (operand.IsImmediateShiftedRegister()) { 9362 Register rm = operand.GetBaseRegister(); 9363 Shift shift = operand.GetShift(); 9364 uint32_t amount = operand.GetShiftAmount(); 9365 if (IsUsingA32()) { 9366 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9367 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9368 uint32_t amount_ = amount % 32; 9369 EmitA32(0x00f00000U | (cond.GetCondition() << 28) | 9370 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9371 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9372 return; 9373 } 9374 } 9375 } 9376 if (operand.IsRegisterShiftedRegister()) { 9377 Register rm = operand.GetBaseRegister(); 9378 Shift shift = operand.GetShift(); 9379 Register rs = operand.GetShiftRegister(); 9380 if (IsUsingA32()) { 9381 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9382 if (cond.IsNotNever() && 9383 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9384 AllowUnpredictable())) { 9385 EmitA32(0x00f00010U | (cond.GetCondition() << 28) | 9386 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9387 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9388 return; 9389 } 9390 } 9391 } 9392 Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand); 9393 } 9394 9395 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) { 9396 VIXL_ASSERT(AllowAssembler()); 9397 CheckIT(cond); 9398 if (IsUsingT32()) { 9399 // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9400 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9401 EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9402 rm.GetCode()); 9403 AdvanceIT(); 9404 return; 9405 } 9406 } else { 9407 // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9408 if (cond.IsNotNever() && 9409 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9410 EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9411 (rn.GetCode() << 16) | rm.GetCode()); 9412 return; 9413 } 9414 } 9415 Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm); 9416 } 9417 9418 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) { 9419 VIXL_ASSERT(AllowAssembler()); 9420 CheckIT(cond); 9421 if (IsUsingT32()) { 9422 // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9423 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9424 EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9425 rm.GetCode()); 9426 AdvanceIT(); 9427 return; 9428 } 9429 } else { 9430 // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9431 if (cond.IsNotNever() && 9432 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9433 EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9434 (rn.GetCode() << 16) | rm.GetCode()); 9435 return; 9436 } 9437 } 9438 Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm); 9439 } 9440 9441 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) { 9442 VIXL_ASSERT(AllowAssembler()); 9443 CheckIT(cond); 9444 if (IsUsingT32()) { 9445 // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9446 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9447 EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9448 rm.GetCode()); 9449 AdvanceIT(); 9450 return; 9451 } 9452 } else { 9453 // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9454 if (cond.IsNotNever() && 9455 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9456 EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9457 (rn.GetCode() << 16) | rm.GetCode()); 9458 return; 9459 } 9460 } 9461 Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm); 9462 } 9463 9464 void Assembler::sbc(Condition cond, 9465 EncodingSize size, 9466 Register rd, 9467 Register rn, 9468 const Operand& operand) { 9469 VIXL_ASSERT(AllowAssembler()); 9470 CheckIT(cond); 9471 if (operand.IsImmediate()) { 9472 uint32_t imm = operand.GetImmediate(); 9473 if (IsUsingT32()) { 9474 ImmediateT32 immediate_t32(imm); 9475 // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 9476 if (!size.IsNarrow() && immediate_t32.IsValid() && 9477 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 9478 EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9479 (immediate_t32.GetEncodingValue() & 0xff) | 9480 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 9481 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 9482 AdvanceIT(); 9483 return; 9484 } 9485 } else { 9486 ImmediateA32 immediate_a32(imm); 9487 // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9488 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9489 EmitA32(0x02c00000U | (cond.GetCondition() << 28) | 9490 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9491 immediate_a32.GetEncodingValue()); 9492 return; 9493 } 9494 } 9495 } 9496 if (operand.IsImmediateShiftedRegister()) { 9497 Register rm = operand.GetBaseRegister(); 9498 if (operand.IsPlainRegister()) { 9499 if (IsUsingT32()) { 9500 // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 9501 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 9502 rm.IsLow()) { 9503 EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3)); 9504 AdvanceIT(); 9505 return; 9506 } 9507 } 9508 } 9509 Shift shift = operand.GetShift(); 9510 uint32_t amount = operand.GetShiftAmount(); 9511 if (IsUsingT32()) { 9512 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 9513 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 9514 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9515 uint32_t amount_ = amount % 32; 9516 EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9517 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 9518 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 9519 AdvanceIT(); 9520 return; 9521 } 9522 } else { 9523 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9524 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9525 uint32_t amount_ = amount % 32; 9526 EmitA32(0x00c00000U | (cond.GetCondition() << 28) | 9527 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9528 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9529 return; 9530 } 9531 } 9532 } 9533 if (operand.IsRegisterShiftedRegister()) { 9534 Register rm = operand.GetBaseRegister(); 9535 Shift shift = operand.GetShift(); 9536 Register rs = operand.GetShiftRegister(); 9537 if (IsUsingA32()) { 9538 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9539 if (cond.IsNotNever() && 9540 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9541 AllowUnpredictable())) { 9542 EmitA32(0x00c00010U | (cond.GetCondition() << 28) | 9543 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9544 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9545 return; 9546 } 9547 } 9548 } 9549 Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand); 9550 } 9551 9552 void Assembler::sbcs(Condition cond, 9553 EncodingSize size, 9554 Register rd, 9555 Register rn, 9556 const Operand& operand) { 9557 VIXL_ASSERT(AllowAssembler()); 9558 CheckIT(cond); 9559 if (operand.IsImmediate()) { 9560 uint32_t imm = operand.GetImmediate(); 9561 if (IsUsingT32()) { 9562 ImmediateT32 immediate_t32(imm); 9563 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 9564 if (!size.IsNarrow() && immediate_t32.IsValid() && 9565 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 9566 EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9567 (immediate_t32.GetEncodingValue() & 0xff) | 9568 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 9569 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 9570 AdvanceIT(); 9571 return; 9572 } 9573 } else { 9574 ImmediateA32 immediate_a32(imm); 9575 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9576 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9577 EmitA32(0x02d00000U | (cond.GetCondition() << 28) | 9578 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9579 immediate_a32.GetEncodingValue()); 9580 return; 9581 } 9582 } 9583 } 9584 if (operand.IsImmediateShiftedRegister()) { 9585 Register rm = operand.GetBaseRegister(); 9586 if (operand.IsPlainRegister()) { 9587 if (IsUsingT32()) { 9588 // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 9589 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 9590 rm.IsLow()) { 9591 EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3)); 9592 AdvanceIT(); 9593 return; 9594 } 9595 } 9596 } 9597 Shift shift = operand.GetShift(); 9598 uint32_t amount = operand.GetShiftAmount(); 9599 if (IsUsingT32()) { 9600 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 9601 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 9602 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9603 uint32_t amount_ = amount % 32; 9604 EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9605 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 9606 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 9607 AdvanceIT(); 9608 return; 9609 } 9610 } else { 9611 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9612 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9613 uint32_t amount_ = amount % 32; 9614 EmitA32(0x00d00000U | (cond.GetCondition() << 28) | 9615 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9616 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9617 return; 9618 } 9619 } 9620 } 9621 if (operand.IsRegisterShiftedRegister()) { 9622 Register rm = operand.GetBaseRegister(); 9623 Shift shift = operand.GetShift(); 9624 Register rs = operand.GetShiftRegister(); 9625 if (IsUsingA32()) { 9626 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9627 if (cond.IsNotNever() && 9628 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9629 AllowUnpredictable())) { 9630 EmitA32(0x00d00010U | (cond.GetCondition() << 28) | 9631 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9632 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9633 return; 9634 } 9635 } 9636 } 9637 Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand); 9638 } 9639 9640 void Assembler::sbfx( 9641 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) { 9642 VIXL_ASSERT(AllowAssembler()); 9643 CheckIT(cond); 9644 if (IsUsingT32()) { 9645 // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 9646 if ((lsb <= 31) && 9647 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) || 9648 AllowUnpredictable())) { 9649 uint32_t widthm1 = width - 1; 9650 EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9651 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1); 9652 AdvanceIT(); 9653 return; 9654 } 9655 } else { 9656 // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 9657 if ((lsb <= 31) && cond.IsNotNever() && 9658 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) || 9659 AllowUnpredictable())) { 9660 uint32_t widthm1 = width - 1; 9661 EmitA32(0x07a00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9662 rn.GetCode() | (lsb << 7) | (widthm1 << 16)); 9663 return; 9664 } 9665 } 9666 Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, width); 9667 } 9668 9669 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) { 9670 VIXL_ASSERT(AllowAssembler()); 9671 CheckIT(cond); 9672 if (IsUsingT32()) { 9673 // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9674 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9675 EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9676 rm.GetCode()); 9677 AdvanceIT(); 9678 return; 9679 } 9680 } else { 9681 // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9682 if (cond.IsNotNever() && 9683 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9684 EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9685 rn.GetCode() | (rm.GetCode() << 8)); 9686 return; 9687 } 9688 } 9689 Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm); 9690 } 9691 9692 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) { 9693 VIXL_ASSERT(AllowAssembler()); 9694 CheckIT(cond); 9695 if (IsUsingT32()) { 9696 // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9697 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9698 EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9699 rm.GetCode()); 9700 AdvanceIT(); 9701 return; 9702 } 9703 } else { 9704 // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9705 if (cond.IsNotNever() && 9706 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9707 EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9708 (rn.GetCode() << 16) | rm.GetCode()); 9709 return; 9710 } 9711 } 9712 Delegate(kSel, &Assembler::sel, cond, rd, rn, rm); 9713 } 9714 9715 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) { 9716 VIXL_ASSERT(AllowAssembler()); 9717 CheckIT(cond); 9718 if (IsUsingT32()) { 9719 // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9720 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9721 EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9722 rm.GetCode()); 9723 AdvanceIT(); 9724 return; 9725 } 9726 } else { 9727 // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9728 if (cond.IsNotNever() && 9729 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9730 EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9731 (rn.GetCode() << 16) | rm.GetCode()); 9732 return; 9733 } 9734 } 9735 Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm); 9736 } 9737 9738 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) { 9739 VIXL_ASSERT(AllowAssembler()); 9740 CheckIT(cond); 9741 if (IsUsingT32()) { 9742 // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9743 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9744 EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9745 rm.GetCode()); 9746 AdvanceIT(); 9747 return; 9748 } 9749 } else { 9750 // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9751 if (cond.IsNotNever() && 9752 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9753 EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9754 (rn.GetCode() << 16) | rm.GetCode()); 9755 return; 9756 } 9757 } 9758 Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm); 9759 } 9760 9761 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) { 9762 VIXL_ASSERT(AllowAssembler()); 9763 CheckIT(cond); 9764 if (IsUsingT32()) { 9765 // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9766 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9767 EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9768 rm.GetCode()); 9769 AdvanceIT(); 9770 return; 9771 } 9772 } else { 9773 // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9774 if (cond.IsNotNever() && 9775 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9776 EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9777 (rn.GetCode() << 16) | rm.GetCode()); 9778 return; 9779 } 9780 } 9781 Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm); 9782 } 9783 9784 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) { 9785 VIXL_ASSERT(AllowAssembler()); 9786 CheckIT(cond); 9787 if (IsUsingT32()) { 9788 // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9789 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9790 EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9791 rm.GetCode()); 9792 AdvanceIT(); 9793 return; 9794 } 9795 } else { 9796 // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9797 if (cond.IsNotNever() && 9798 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9799 EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9800 (rn.GetCode() << 16) | rm.GetCode()); 9801 return; 9802 } 9803 } 9804 Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm); 9805 } 9806 9807 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) { 9808 VIXL_ASSERT(AllowAssembler()); 9809 CheckIT(cond); 9810 if (IsUsingT32()) { 9811 // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9812 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9813 EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9814 rm.GetCode()); 9815 AdvanceIT(); 9816 return; 9817 } 9818 } else { 9819 // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9820 if (cond.IsNotNever() && 9821 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9822 EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9823 (rn.GetCode() << 16) | rm.GetCode()); 9824 return; 9825 } 9826 } 9827 Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm); 9828 } 9829 9830 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) { 9831 VIXL_ASSERT(AllowAssembler()); 9832 CheckIT(cond); 9833 if (IsUsingT32()) { 9834 // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9835 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9836 EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9837 rm.GetCode()); 9838 AdvanceIT(); 9839 return; 9840 } 9841 } else { 9842 // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9843 if (cond.IsNotNever() && 9844 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9845 EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9846 (rn.GetCode() << 16) | rm.GetCode()); 9847 return; 9848 } 9849 } 9850 Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm); 9851 } 9852 9853 void Assembler::smlabb( 9854 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9855 VIXL_ASSERT(AllowAssembler()); 9856 CheckIT(cond); 9857 if (IsUsingT32()) { 9858 // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9859 if (!ra.Is(pc) && 9860 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9861 EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9862 rm.GetCode() | (ra.GetCode() << 12)); 9863 AdvanceIT(); 9864 return; 9865 } 9866 } else { 9867 // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9868 if (cond.IsNotNever() && 9869 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 9870 AllowUnpredictable())) { 9871 EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9872 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9873 return; 9874 } 9875 } 9876 Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra); 9877 } 9878 9879 void Assembler::smlabt( 9880 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9881 VIXL_ASSERT(AllowAssembler()); 9882 CheckIT(cond); 9883 if (IsUsingT32()) { 9884 // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9885 if (!ra.Is(pc) && 9886 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9887 EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9888 rm.GetCode() | (ra.GetCode() << 12)); 9889 AdvanceIT(); 9890 return; 9891 } 9892 } else { 9893 // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9894 if (cond.IsNotNever() && 9895 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 9896 AllowUnpredictable())) { 9897 EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9898 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9899 return; 9900 } 9901 } 9902 Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra); 9903 } 9904 9905 void Assembler::smlad( 9906 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9907 VIXL_ASSERT(AllowAssembler()); 9908 CheckIT(cond); 9909 if (IsUsingT32()) { 9910 // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9911 if (!ra.Is(pc) && 9912 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9913 EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9914 rm.GetCode() | (ra.GetCode() << 12)); 9915 AdvanceIT(); 9916 return; 9917 } 9918 } else { 9919 // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9920 if (cond.IsNotNever() && !ra.Is(pc) && 9921 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9922 EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9923 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9924 return; 9925 } 9926 } 9927 Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra); 9928 } 9929 9930 void Assembler::smladx( 9931 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9932 VIXL_ASSERT(AllowAssembler()); 9933 CheckIT(cond); 9934 if (IsUsingT32()) { 9935 // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9936 if (!ra.Is(pc) && 9937 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9938 EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9939 rm.GetCode() | (ra.GetCode() << 12)); 9940 AdvanceIT(); 9941 return; 9942 } 9943 } else { 9944 // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9945 if (cond.IsNotNever() && !ra.Is(pc) && 9946 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9947 EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9948 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9949 return; 9950 } 9951 } 9952 Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra); 9953 } 9954 9955 void Assembler::smlal( 9956 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9957 VIXL_ASSERT(AllowAssembler()); 9958 CheckIT(cond); 9959 if (IsUsingT32()) { 9960 // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9961 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9962 AllowUnpredictable())) { 9963 EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9964 (rn.GetCode() << 16) | rm.GetCode()); 9965 AdvanceIT(); 9966 return; 9967 } 9968 } else { 9969 // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9970 if (cond.IsNotNever() && 9971 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9972 AllowUnpredictable())) { 9973 EmitA32(0x00e00090U | (cond.GetCondition() << 28) | 9974 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9975 (rm.GetCode() << 8)); 9976 return; 9977 } 9978 } 9979 Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm); 9980 } 9981 9982 void Assembler::smlalbb( 9983 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9984 VIXL_ASSERT(AllowAssembler()); 9985 CheckIT(cond); 9986 if (IsUsingT32()) { 9987 // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9988 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9989 AllowUnpredictable())) { 9990 EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9991 (rn.GetCode() << 16) | rm.GetCode()); 9992 AdvanceIT(); 9993 return; 9994 } 9995 } else { 9996 // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9997 if (cond.IsNotNever() && 9998 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9999 AllowUnpredictable())) { 10000 EmitA32(0x01400080U | (cond.GetCondition() << 28) | 10001 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10002 (rm.GetCode() << 8)); 10003 return; 10004 } 10005 } 10006 Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm); 10007 } 10008 10009 void Assembler::smlalbt( 10010 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10011 VIXL_ASSERT(AllowAssembler()); 10012 CheckIT(cond); 10013 if (IsUsingT32()) { 10014 // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10015 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10016 AllowUnpredictable())) { 10017 EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10018 (rn.GetCode() << 16) | rm.GetCode()); 10019 AdvanceIT(); 10020 return; 10021 } 10022 } else { 10023 // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10024 if (cond.IsNotNever() && 10025 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10026 AllowUnpredictable())) { 10027 EmitA32(0x014000c0U | (cond.GetCondition() << 28) | 10028 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10029 (rm.GetCode() << 8)); 10030 return; 10031 } 10032 } 10033 Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm); 10034 } 10035 10036 void Assembler::smlald( 10037 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10038 VIXL_ASSERT(AllowAssembler()); 10039 CheckIT(cond); 10040 if (IsUsingT32()) { 10041 // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10042 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10043 AllowUnpredictable())) { 10044 EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10045 (rn.GetCode() << 16) | rm.GetCode()); 10046 AdvanceIT(); 10047 return; 10048 } 10049 } else { 10050 // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10051 if (cond.IsNotNever() && 10052 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10053 AllowUnpredictable())) { 10054 EmitA32(0x07400010U | (cond.GetCondition() << 28) | 10055 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10056 (rm.GetCode() << 8)); 10057 return; 10058 } 10059 } 10060 Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm); 10061 } 10062 10063 void Assembler::smlaldx( 10064 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10065 VIXL_ASSERT(AllowAssembler()); 10066 CheckIT(cond); 10067 if (IsUsingT32()) { 10068 // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10069 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10070 AllowUnpredictable())) { 10071 EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10072 (rn.GetCode() << 16) | rm.GetCode()); 10073 AdvanceIT(); 10074 return; 10075 } 10076 } else { 10077 // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10078 if (cond.IsNotNever() && 10079 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10080 AllowUnpredictable())) { 10081 EmitA32(0x07400030U | (cond.GetCondition() << 28) | 10082 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10083 (rm.GetCode() << 8)); 10084 return; 10085 } 10086 } 10087 Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm); 10088 } 10089 10090 void Assembler::smlals( 10091 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10092 VIXL_ASSERT(AllowAssembler()); 10093 CheckIT(cond); 10094 if (IsUsingA32()) { 10095 // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10096 if (cond.IsNotNever() && 10097 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10098 AllowUnpredictable())) { 10099 EmitA32(0x00f00090U | (cond.GetCondition() << 28) | 10100 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10101 (rm.GetCode() << 8)); 10102 return; 10103 } 10104 } 10105 Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm); 10106 } 10107 10108 void Assembler::smlaltb( 10109 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10110 VIXL_ASSERT(AllowAssembler()); 10111 CheckIT(cond); 10112 if (IsUsingT32()) { 10113 // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10114 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10115 AllowUnpredictable())) { 10116 EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10117 (rn.GetCode() << 16) | rm.GetCode()); 10118 AdvanceIT(); 10119 return; 10120 } 10121 } else { 10122 // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10123 if (cond.IsNotNever() && 10124 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10125 AllowUnpredictable())) { 10126 EmitA32(0x014000a0U | (cond.GetCondition() << 28) | 10127 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10128 (rm.GetCode() << 8)); 10129 return; 10130 } 10131 } 10132 Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm); 10133 } 10134 10135 void Assembler::smlaltt( 10136 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10137 VIXL_ASSERT(AllowAssembler()); 10138 CheckIT(cond); 10139 if (IsUsingT32()) { 10140 // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10141 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10142 AllowUnpredictable())) { 10143 EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10144 (rn.GetCode() << 16) | rm.GetCode()); 10145 AdvanceIT(); 10146 return; 10147 } 10148 } else { 10149 // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10150 if (cond.IsNotNever() && 10151 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10152 AllowUnpredictable())) { 10153 EmitA32(0x014000e0U | (cond.GetCondition() << 28) | 10154 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10155 (rm.GetCode() << 8)); 10156 return; 10157 } 10158 } 10159 Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm); 10160 } 10161 10162 void Assembler::smlatb( 10163 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10164 VIXL_ASSERT(AllowAssembler()); 10165 CheckIT(cond); 10166 if (IsUsingT32()) { 10167 // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10168 if (!ra.Is(pc) && 10169 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10170 EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10171 rm.GetCode() | (ra.GetCode() << 12)); 10172 AdvanceIT(); 10173 return; 10174 } 10175 } else { 10176 // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10177 if (cond.IsNotNever() && 10178 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10179 AllowUnpredictable())) { 10180 EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10181 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10182 return; 10183 } 10184 } 10185 Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra); 10186 } 10187 10188 void Assembler::smlatt( 10189 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10190 VIXL_ASSERT(AllowAssembler()); 10191 CheckIT(cond); 10192 if (IsUsingT32()) { 10193 // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10194 if (!ra.Is(pc) && 10195 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10196 EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10197 rm.GetCode() | (ra.GetCode() << 12)); 10198 AdvanceIT(); 10199 return; 10200 } 10201 } else { 10202 // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10203 if (cond.IsNotNever() && 10204 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10205 AllowUnpredictable())) { 10206 EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10207 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10208 return; 10209 } 10210 } 10211 Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra); 10212 } 10213 10214 void Assembler::smlawb( 10215 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10216 VIXL_ASSERT(AllowAssembler()); 10217 CheckIT(cond); 10218 if (IsUsingT32()) { 10219 // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10220 if (!ra.Is(pc) && 10221 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10222 EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10223 rm.GetCode() | (ra.GetCode() << 12)); 10224 AdvanceIT(); 10225 return; 10226 } 10227 } else { 10228 // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10229 if (cond.IsNotNever() && 10230 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10231 AllowUnpredictable())) { 10232 EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10233 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10234 return; 10235 } 10236 } 10237 Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra); 10238 } 10239 10240 void Assembler::smlawt( 10241 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10242 VIXL_ASSERT(AllowAssembler()); 10243 CheckIT(cond); 10244 if (IsUsingT32()) { 10245 // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10246 if (!ra.Is(pc) && 10247 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10248 EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10249 rm.GetCode() | (ra.GetCode() << 12)); 10250 AdvanceIT(); 10251 return; 10252 } 10253 } else { 10254 // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10255 if (cond.IsNotNever() && 10256 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10257 AllowUnpredictable())) { 10258 EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10259 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10260 return; 10261 } 10262 } 10263 Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra); 10264 } 10265 10266 void Assembler::smlsd( 10267 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10268 VIXL_ASSERT(AllowAssembler()); 10269 CheckIT(cond); 10270 if (IsUsingT32()) { 10271 // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10272 if (!ra.Is(pc) && 10273 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10274 EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10275 rm.GetCode() | (ra.GetCode() << 12)); 10276 AdvanceIT(); 10277 return; 10278 } 10279 } else { 10280 // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10281 if (cond.IsNotNever() && !ra.Is(pc) && 10282 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10283 EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10284 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10285 return; 10286 } 10287 } 10288 Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra); 10289 } 10290 10291 void Assembler::smlsdx( 10292 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10293 VIXL_ASSERT(AllowAssembler()); 10294 CheckIT(cond); 10295 if (IsUsingT32()) { 10296 // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10297 if (!ra.Is(pc) && 10298 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10299 EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10300 rm.GetCode() | (ra.GetCode() << 12)); 10301 AdvanceIT(); 10302 return; 10303 } 10304 } else { 10305 // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10306 if (cond.IsNotNever() && !ra.Is(pc) && 10307 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10308 EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10309 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10310 return; 10311 } 10312 } 10313 Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra); 10314 } 10315 10316 void Assembler::smlsld( 10317 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10318 VIXL_ASSERT(AllowAssembler()); 10319 CheckIT(cond); 10320 if (IsUsingT32()) { 10321 // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10322 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10323 AllowUnpredictable())) { 10324 EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10325 (rn.GetCode() << 16) | rm.GetCode()); 10326 AdvanceIT(); 10327 return; 10328 } 10329 } else { 10330 // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10331 if (cond.IsNotNever() && 10332 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10333 AllowUnpredictable())) { 10334 EmitA32(0x07400050U | (cond.GetCondition() << 28) | 10335 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10336 (rm.GetCode() << 8)); 10337 return; 10338 } 10339 } 10340 Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm); 10341 } 10342 10343 void Assembler::smlsldx( 10344 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10345 VIXL_ASSERT(AllowAssembler()); 10346 CheckIT(cond); 10347 if (IsUsingT32()) { 10348 // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10349 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10350 AllowUnpredictable())) { 10351 EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10352 (rn.GetCode() << 16) | rm.GetCode()); 10353 AdvanceIT(); 10354 return; 10355 } 10356 } else { 10357 // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10358 if (cond.IsNotNever() && 10359 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10360 AllowUnpredictable())) { 10361 EmitA32(0x07400070U | (cond.GetCondition() << 28) | 10362 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10363 (rm.GetCode() << 8)); 10364 return; 10365 } 10366 } 10367 Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm); 10368 } 10369 10370 void Assembler::smmla( 10371 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10372 VIXL_ASSERT(AllowAssembler()); 10373 CheckIT(cond); 10374 if (IsUsingT32()) { 10375 // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10376 if (!ra.Is(pc) && 10377 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10378 EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10379 rm.GetCode() | (ra.GetCode() << 12)); 10380 AdvanceIT(); 10381 return; 10382 } 10383 } else { 10384 // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10385 if (cond.IsNotNever() && !ra.Is(pc) && 10386 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10387 EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10388 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10389 return; 10390 } 10391 } 10392 Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra); 10393 } 10394 10395 void Assembler::smmlar( 10396 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10397 VIXL_ASSERT(AllowAssembler()); 10398 CheckIT(cond); 10399 if (IsUsingT32()) { 10400 // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10401 if (!ra.Is(pc) && 10402 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10403 EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10404 rm.GetCode() | (ra.GetCode() << 12)); 10405 AdvanceIT(); 10406 return; 10407 } 10408 } else { 10409 // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10410 if (cond.IsNotNever() && !ra.Is(pc) && 10411 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10412 EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10413 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10414 return; 10415 } 10416 } 10417 Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra); 10418 } 10419 10420 void Assembler::smmls( 10421 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10422 VIXL_ASSERT(AllowAssembler()); 10423 CheckIT(cond); 10424 if (IsUsingT32()) { 10425 // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10426 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10427 AllowUnpredictable())) { 10428 EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10429 rm.GetCode() | (ra.GetCode() << 12)); 10430 AdvanceIT(); 10431 return; 10432 } 10433 } else { 10434 // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10435 if (cond.IsNotNever() && 10436 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10437 AllowUnpredictable())) { 10438 EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10439 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10440 return; 10441 } 10442 } 10443 Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra); 10444 } 10445 10446 void Assembler::smmlsr( 10447 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10448 VIXL_ASSERT(AllowAssembler()); 10449 CheckIT(cond); 10450 if (IsUsingT32()) { 10451 // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10452 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10453 AllowUnpredictable())) { 10454 EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10455 rm.GetCode() | (ra.GetCode() << 12)); 10456 AdvanceIT(); 10457 return; 10458 } 10459 } else { 10460 // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10461 if (cond.IsNotNever() && 10462 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10463 AllowUnpredictable())) { 10464 EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10465 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10466 return; 10467 } 10468 } 10469 Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra); 10470 } 10471 10472 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) { 10473 VIXL_ASSERT(AllowAssembler()); 10474 CheckIT(cond); 10475 if (IsUsingT32()) { 10476 // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10477 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10478 EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10479 rm.GetCode()); 10480 AdvanceIT(); 10481 return; 10482 } 10483 } else { 10484 // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10485 if (cond.IsNotNever() && 10486 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10487 EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10488 rn.GetCode() | (rm.GetCode() << 8)); 10489 return; 10490 } 10491 } 10492 Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm); 10493 } 10494 10495 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) { 10496 VIXL_ASSERT(AllowAssembler()); 10497 CheckIT(cond); 10498 if (IsUsingT32()) { 10499 // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10500 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10501 EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10502 rm.GetCode()); 10503 AdvanceIT(); 10504 return; 10505 } 10506 } else { 10507 // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10508 if (cond.IsNotNever() && 10509 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10510 EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10511 rn.GetCode() | (rm.GetCode() << 8)); 10512 return; 10513 } 10514 } 10515 Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm); 10516 } 10517 10518 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) { 10519 VIXL_ASSERT(AllowAssembler()); 10520 CheckIT(cond); 10521 if (IsUsingT32()) { 10522 // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10523 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10524 EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10525 rm.GetCode()); 10526 AdvanceIT(); 10527 return; 10528 } 10529 } else { 10530 // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10531 if (cond.IsNotNever() && 10532 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10533 EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10534 rn.GetCode() | (rm.GetCode() << 8)); 10535 return; 10536 } 10537 } 10538 Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm); 10539 } 10540 10541 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) { 10542 VIXL_ASSERT(AllowAssembler()); 10543 CheckIT(cond); 10544 if (IsUsingT32()) { 10545 // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10546 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10547 EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10548 rm.GetCode()); 10549 AdvanceIT(); 10550 return; 10551 } 10552 } else { 10553 // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10554 if (cond.IsNotNever() && 10555 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10556 EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10557 rn.GetCode() | (rm.GetCode() << 8)); 10558 return; 10559 } 10560 } 10561 Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm); 10562 } 10563 10564 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) { 10565 VIXL_ASSERT(AllowAssembler()); 10566 CheckIT(cond); 10567 if (IsUsingT32()) { 10568 // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10569 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10570 EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10571 rm.GetCode()); 10572 AdvanceIT(); 10573 return; 10574 } 10575 } else { 10576 // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10577 if (cond.IsNotNever() && 10578 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10579 EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10580 rn.GetCode() | (rm.GetCode() << 8)); 10581 return; 10582 } 10583 } 10584 Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm); 10585 } 10586 10587 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) { 10588 VIXL_ASSERT(AllowAssembler()); 10589 CheckIT(cond); 10590 if (IsUsingT32()) { 10591 // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10592 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10593 EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10594 rm.GetCode()); 10595 AdvanceIT(); 10596 return; 10597 } 10598 } else { 10599 // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10600 if (cond.IsNotNever() && 10601 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10602 EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10603 rn.GetCode() | (rm.GetCode() << 8)); 10604 return; 10605 } 10606 } 10607 Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm); 10608 } 10609 10610 void Assembler::smull( 10611 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10612 VIXL_ASSERT(AllowAssembler()); 10613 CheckIT(cond); 10614 if (IsUsingT32()) { 10615 // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10616 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10617 AllowUnpredictable())) { 10618 EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10619 (rn.GetCode() << 16) | rm.GetCode()); 10620 AdvanceIT(); 10621 return; 10622 } 10623 } else { 10624 // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10625 if (cond.IsNotNever() && 10626 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10627 AllowUnpredictable())) { 10628 EmitA32(0x00c00090U | (cond.GetCondition() << 28) | 10629 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10630 (rm.GetCode() << 8)); 10631 return; 10632 } 10633 } 10634 Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm); 10635 } 10636 10637 void Assembler::smulls( 10638 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10639 VIXL_ASSERT(AllowAssembler()); 10640 CheckIT(cond); 10641 if (IsUsingA32()) { 10642 // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10643 if (cond.IsNotNever() && 10644 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10645 AllowUnpredictable())) { 10646 EmitA32(0x00d00090U | (cond.GetCondition() << 28) | 10647 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10648 (rm.GetCode() << 8)); 10649 return; 10650 } 10651 } 10652 Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm); 10653 } 10654 10655 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) { 10656 VIXL_ASSERT(AllowAssembler()); 10657 CheckIT(cond); 10658 if (IsUsingT32()) { 10659 // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10660 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10661 EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10662 rm.GetCode()); 10663 AdvanceIT(); 10664 return; 10665 } 10666 } else { 10667 // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10668 if (cond.IsNotNever() && 10669 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10670 EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10671 rn.GetCode() | (rm.GetCode() << 8)); 10672 return; 10673 } 10674 } 10675 Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm); 10676 } 10677 10678 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) { 10679 VIXL_ASSERT(AllowAssembler()); 10680 CheckIT(cond); 10681 if (IsUsingT32()) { 10682 // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10683 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10684 EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10685 rm.GetCode()); 10686 AdvanceIT(); 10687 return; 10688 } 10689 } else { 10690 // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10691 if (cond.IsNotNever() && 10692 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10693 EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10694 rn.GetCode() | (rm.GetCode() << 8)); 10695 return; 10696 } 10697 } 10698 Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm); 10699 } 10700 10701 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) { 10702 VIXL_ASSERT(AllowAssembler()); 10703 CheckIT(cond); 10704 if (IsUsingT32()) { 10705 // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10706 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10707 EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10708 rm.GetCode()); 10709 AdvanceIT(); 10710 return; 10711 } 10712 } else { 10713 // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10714 if (cond.IsNotNever() && 10715 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10716 EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10717 rn.GetCode() | (rm.GetCode() << 8)); 10718 return; 10719 } 10720 } 10721 Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm); 10722 } 10723 10724 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) { 10725 VIXL_ASSERT(AllowAssembler()); 10726 CheckIT(cond); 10727 if (IsUsingT32()) { 10728 // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10729 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10730 EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10731 rm.GetCode()); 10732 AdvanceIT(); 10733 return; 10734 } 10735 } else { 10736 // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10737 if (cond.IsNotNever() && 10738 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10739 EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10740 rn.GetCode() | (rm.GetCode() << 8)); 10741 return; 10742 } 10743 } 10744 Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm); 10745 } 10746 10747 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) { 10748 VIXL_ASSERT(AllowAssembler()); 10749 CheckIT(cond); 10750 if (IsUsingT32()) { 10751 // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10752 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10753 EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10754 rm.GetCode()); 10755 AdvanceIT(); 10756 return; 10757 } 10758 } else { 10759 // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10760 if (cond.IsNotNever() && 10761 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10762 EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10763 rn.GetCode() | (rm.GetCode() << 8)); 10764 return; 10765 } 10766 } 10767 Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm); 10768 } 10769 10770 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) { 10771 VIXL_ASSERT(AllowAssembler()); 10772 CheckIT(cond); 10773 if (IsUsingT32()) { 10774 // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10775 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10776 EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10777 rm.GetCode()); 10778 AdvanceIT(); 10779 return; 10780 } 10781 } else { 10782 // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10783 if (cond.IsNotNever() && 10784 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10785 EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10786 rn.GetCode() | (rm.GetCode() << 8)); 10787 return; 10788 } 10789 } 10790 Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm); 10791 } 10792 10793 void Assembler::ssat(Condition cond, 10794 Register rd, 10795 uint32_t imm, 10796 const Operand& operand) { 10797 VIXL_ASSERT(AllowAssembler()); 10798 CheckIT(cond); 10799 if (operand.IsImmediateShiftedRegister()) { 10800 Register rn = operand.GetBaseRegister(); 10801 Shift shift = operand.GetShift(); 10802 uint32_t amount = operand.GetShiftAmount(); 10803 if (IsUsingT32()) { 10804 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1 10805 if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) && 10806 (amount <= 31) && 10807 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10808 uint32_t imm_ = imm - 1; 10809 EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ | 10810 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 10811 ((amount & 0x1c) << 10)); 10812 AdvanceIT(); 10813 return; 10814 } 10815 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1 10816 if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) && 10817 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10818 uint32_t imm_ = imm - 1; 10819 EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ | 10820 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 10821 ((amount & 0x1c) << 10)); 10822 AdvanceIT(); 10823 return; 10824 } 10825 } else { 10826 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1 10827 if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) && 10828 (amount <= 32) && cond.IsNotNever() && 10829 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10830 uint32_t imm_ = imm - 1; 10831 uint32_t amount_ = amount % 32; 10832 EmitA32(0x06a00050U | (cond.GetCondition() << 28) | 10833 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() | 10834 (amount_ << 7)); 10835 return; 10836 } 10837 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1 10838 if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) && 10839 cond.IsNotNever() && 10840 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10841 uint32_t imm_ = imm - 1; 10842 EmitA32(0x06a00010U | (cond.GetCondition() << 28) | 10843 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() | 10844 (amount << 7)); 10845 return; 10846 } 10847 } 10848 } 10849 Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand); 10850 } 10851 10852 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) { 10853 VIXL_ASSERT(AllowAssembler()); 10854 CheckIT(cond); 10855 if (IsUsingT32()) { 10856 // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1 10857 if ((imm >= 1) && (imm <= 16) && 10858 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10859 uint32_t imm_ = imm - 1; 10860 EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ | 10861 (rn.GetCode() << 16)); 10862 AdvanceIT(); 10863 return; 10864 } 10865 } else { 10866 // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1 10867 if ((imm >= 1) && (imm <= 16) && cond.IsNotNever() && 10868 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10869 uint32_t imm_ = imm - 1; 10870 EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 10871 (imm_ << 16) | rn.GetCode()); 10872 return; 10873 } 10874 } 10875 Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn); 10876 } 10877 10878 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) { 10879 VIXL_ASSERT(AllowAssembler()); 10880 CheckIT(cond); 10881 if (IsUsingT32()) { 10882 // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10883 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10884 EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10885 rm.GetCode()); 10886 AdvanceIT(); 10887 return; 10888 } 10889 } else { 10890 // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10891 if (cond.IsNotNever() && 10892 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10893 EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 10894 (rn.GetCode() << 16) | rm.GetCode()); 10895 return; 10896 } 10897 } 10898 Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm); 10899 } 10900 10901 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) { 10902 VIXL_ASSERT(AllowAssembler()); 10903 CheckIT(cond); 10904 if (IsUsingT32()) { 10905 // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10906 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10907 EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10908 rm.GetCode()); 10909 AdvanceIT(); 10910 return; 10911 } 10912 } else { 10913 // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10914 if (cond.IsNotNever() && 10915 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10916 EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 10917 (rn.GetCode() << 16) | rm.GetCode()); 10918 return; 10919 } 10920 } 10921 Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm); 10922 } 10923 10924 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) { 10925 VIXL_ASSERT(AllowAssembler()); 10926 CheckIT(cond); 10927 if (IsUsingT32()) { 10928 // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10929 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10930 EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10931 rm.GetCode()); 10932 AdvanceIT(); 10933 return; 10934 } 10935 } else { 10936 // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10937 if (cond.IsNotNever() && 10938 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10939 EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 10940 (rn.GetCode() << 16) | rm.GetCode()); 10941 return; 10942 } 10943 } 10944 Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm); 10945 } 10946 10947 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) { 10948 VIXL_ASSERT(AllowAssembler()); 10949 CheckIT(cond); 10950 if (operand.IsImmediateZero()) { 10951 Register rn = operand.GetBaseRegister(); 10952 if (IsUsingT32()) { 10953 // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1 10954 if (operand.IsOffset() && 10955 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10956 EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 10957 AdvanceIT(); 10958 return; 10959 } 10960 } else { 10961 // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1 10962 if (operand.IsOffset() && cond.IsNotNever() && 10963 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10964 EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 10965 (rn.GetCode() << 16)); 10966 return; 10967 } 10968 } 10969 } 10970 Delegate(kStl, &Assembler::stl, cond, rt, operand); 10971 } 10972 10973 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) { 10974 VIXL_ASSERT(AllowAssembler()); 10975 CheckIT(cond); 10976 if (operand.IsImmediateZero()) { 10977 Register rn = operand.GetBaseRegister(); 10978 if (IsUsingT32()) { 10979 // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1 10980 if (operand.IsOffset() && 10981 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10982 EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 10983 AdvanceIT(); 10984 return; 10985 } 10986 } else { 10987 // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1 10988 if (operand.IsOffset() && cond.IsNotNever() && 10989 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10990 EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 10991 (rn.GetCode() << 16)); 10992 return; 10993 } 10994 } 10995 } 10996 Delegate(kStlb, &Assembler::stlb, cond, rt, operand); 10997 } 10998 10999 void Assembler::stlex(Condition cond, 11000 Register rd, 11001 Register rt, 11002 const MemOperand& operand) { 11003 VIXL_ASSERT(AllowAssembler()); 11004 CheckIT(cond); 11005 if (operand.IsImmediateZero()) { 11006 Register rn = operand.GetBaseRegister(); 11007 if (IsUsingT32()) { 11008 // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 11009 if (operand.IsOffset() && 11010 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11011 EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) | 11012 (rn.GetCode() << 16)); 11013 AdvanceIT(); 11014 return; 11015 } 11016 } else { 11017 // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 11018 if (operand.IsOffset() && cond.IsNotNever() && 11019 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11020 EmitA32(0x01800e90U | (cond.GetCondition() << 28) | 11021 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11022 return; 11023 } 11024 } 11025 } 11026 Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand); 11027 } 11028 11029 void Assembler::stlexb(Condition cond, 11030 Register rd, 11031 Register rt, 11032 const MemOperand& operand) { 11033 VIXL_ASSERT(AllowAssembler()); 11034 CheckIT(cond); 11035 if (operand.IsImmediateZero()) { 11036 Register rn = operand.GetBaseRegister(); 11037 if (IsUsingT32()) { 11038 // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 11039 if (operand.IsOffset() && 11040 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11041 EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) | 11042 (rn.GetCode() << 16)); 11043 AdvanceIT(); 11044 return; 11045 } 11046 } else { 11047 // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 11048 if (operand.IsOffset() && cond.IsNotNever() && 11049 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11050 EmitA32(0x01c00e90U | (cond.GetCondition() << 28) | 11051 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11052 return; 11053 } 11054 } 11055 } 11056 Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand); 11057 } 11058 11059 void Assembler::stlexd(Condition cond, 11060 Register rd, 11061 Register rt, 11062 Register rt2, 11063 const MemOperand& operand) { 11064 VIXL_ASSERT(AllowAssembler()); 11065 CheckIT(cond); 11066 if (operand.IsImmediateZero()) { 11067 Register rn = operand.GetBaseRegister(); 11068 if (IsUsingT32()) { 11069 // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1 11070 if (operand.IsOffset() && 11071 ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || 11072 AllowUnpredictable())) { 11073 EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) | 11074 (rt2.GetCode() << 8) | (rn.GetCode() << 16)); 11075 AdvanceIT(); 11076 return; 11077 } 11078 } else { 11079 // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1 11080 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11081 operand.IsOffset() && cond.IsNotNever() && 11082 ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() && 11083 !rn.IsPC()) || 11084 AllowUnpredictable())) { 11085 EmitA32(0x01a00e90U | (cond.GetCondition() << 28) | 11086 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11087 return; 11088 } 11089 } 11090 } 11091 Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand); 11092 } 11093 11094 void Assembler::stlexh(Condition cond, 11095 Register rd, 11096 Register rt, 11097 const MemOperand& operand) { 11098 VIXL_ASSERT(AllowAssembler()); 11099 CheckIT(cond); 11100 if (operand.IsImmediateZero()) { 11101 Register rn = operand.GetBaseRegister(); 11102 if (IsUsingT32()) { 11103 // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 11104 if (operand.IsOffset() && 11105 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11106 EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) | 11107 (rn.GetCode() << 16)); 11108 AdvanceIT(); 11109 return; 11110 } 11111 } else { 11112 // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 11113 if (operand.IsOffset() && cond.IsNotNever() && 11114 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11115 EmitA32(0x01e00e90U | (cond.GetCondition() << 28) | 11116 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11117 return; 11118 } 11119 } 11120 } 11121 Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand); 11122 } 11123 11124 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) { 11125 VIXL_ASSERT(AllowAssembler()); 11126 CheckIT(cond); 11127 if (operand.IsImmediateZero()) { 11128 Register rn = operand.GetBaseRegister(); 11129 if (IsUsingT32()) { 11130 // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1 11131 if (operand.IsOffset() && 11132 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11133 EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 11134 AdvanceIT(); 11135 return; 11136 } 11137 } else { 11138 // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1 11139 if (operand.IsOffset() && cond.IsNotNever() && 11140 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11141 EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 11142 (rn.GetCode() << 16)); 11143 return; 11144 } 11145 } 11146 } 11147 Delegate(kStlh, &Assembler::stlh, cond, rt, operand); 11148 } 11149 11150 void Assembler::stm(Condition cond, 11151 EncodingSize size, 11152 Register rn, 11153 WriteBack write_back, 11154 RegisterList registers) { 11155 VIXL_ASSERT(AllowAssembler()); 11156 CheckIT(cond); 11157 if (IsUsingT32()) { 11158 // STM{<c>}{<q>} <Rn>!, <registers> ; T1 11159 if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() && 11160 ((registers.GetList() & ~0xff) == 0)) { 11161 EmitT32_16(0xc000 | (rn.GetCode() << 8) | 11162 GetRegisterListEncoding(registers, 0, 8)); 11163 AdvanceIT(); 11164 return; 11165 } 11166 // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2 11167 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) && 11168 (!rn.IsPC() || AllowUnpredictable())) { 11169 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 11170 (write_back.GetWriteBackUint32() << 21) | 11171 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11172 GetRegisterListEncoding(registers, 0, 13)); 11173 AdvanceIT(); 11174 return; 11175 } 11176 } else { 11177 // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1 11178 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11179 EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11180 (write_back.GetWriteBackUint32() << 21) | 11181 GetRegisterListEncoding(registers, 0, 16)); 11182 return; 11183 } 11184 } 11185 Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers); 11186 } 11187 11188 void Assembler::stmda(Condition cond, 11189 Register rn, 11190 WriteBack write_back, 11191 RegisterList registers) { 11192 VIXL_ASSERT(AllowAssembler()); 11193 CheckIT(cond); 11194 if (IsUsingA32()) { 11195 // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1 11196 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11197 EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11198 (write_back.GetWriteBackUint32() << 21) | 11199 GetRegisterListEncoding(registers, 0, 16)); 11200 return; 11201 } 11202 } 11203 Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers); 11204 } 11205 11206 void Assembler::stmdb(Condition cond, 11207 EncodingSize size, 11208 Register rn, 11209 WriteBack write_back, 11210 RegisterList registers) { 11211 VIXL_ASSERT(AllowAssembler()); 11212 CheckIT(cond); 11213 if (IsUsingT32()) { 11214 // STMDB{<c>}{<q>} SP!, <registers> ; T1 11215 if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() && 11216 registers.IsR0toR7orLR()) { 11217 EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) | 11218 GetRegisterListEncoding(registers, 0, 8)); 11219 AdvanceIT(); 11220 return; 11221 } 11222 // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1 11223 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) && 11224 (!rn.IsPC() || AllowUnpredictable())) { 11225 EmitT32_32(0xe9000000U | (rn.GetCode() << 16) | 11226 (write_back.GetWriteBackUint32() << 21) | 11227 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11228 GetRegisterListEncoding(registers, 0, 13)); 11229 AdvanceIT(); 11230 return; 11231 } 11232 } else { 11233 // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1 11234 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11235 EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11236 (write_back.GetWriteBackUint32() << 21) | 11237 GetRegisterListEncoding(registers, 0, 16)); 11238 return; 11239 } 11240 } 11241 Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers); 11242 } 11243 11244 void Assembler::stmea(Condition cond, 11245 EncodingSize size, 11246 Register rn, 11247 WriteBack write_back, 11248 RegisterList registers) { 11249 VIXL_ASSERT(AllowAssembler()); 11250 CheckIT(cond); 11251 if (IsUsingT32()) { 11252 // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1 11253 if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() && 11254 ((registers.GetList() & ~0xff) == 0)) { 11255 EmitT32_16(0xc000 | (rn.GetCode() << 8) | 11256 GetRegisterListEncoding(registers, 0, 8)); 11257 AdvanceIT(); 11258 return; 11259 } 11260 // STMEA{<c>}.W <Rn>{!}, <registers> ; T2 11261 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) && 11262 (!rn.IsPC() || AllowUnpredictable())) { 11263 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 11264 (write_back.GetWriteBackUint32() << 21) | 11265 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11266 GetRegisterListEncoding(registers, 0, 13)); 11267 AdvanceIT(); 11268 return; 11269 } 11270 // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2 11271 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) && 11272 (!rn.IsPC() || AllowUnpredictable())) { 11273 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 11274 (write_back.GetWriteBackUint32() << 21) | 11275 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11276 GetRegisterListEncoding(registers, 0, 13)); 11277 AdvanceIT(); 11278 return; 11279 } 11280 } else { 11281 // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1 11282 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11283 EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11284 (write_back.GetWriteBackUint32() << 21) | 11285 GetRegisterListEncoding(registers, 0, 16)); 11286 return; 11287 } 11288 } 11289 Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers); 11290 } 11291 11292 void Assembler::stmed(Condition cond, 11293 Register rn, 11294 WriteBack write_back, 11295 RegisterList registers) { 11296 VIXL_ASSERT(AllowAssembler()); 11297 CheckIT(cond); 11298 if (IsUsingA32()) { 11299 // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1 11300 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11301 EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11302 (write_back.GetWriteBackUint32() << 21) | 11303 GetRegisterListEncoding(registers, 0, 16)); 11304 return; 11305 } 11306 } 11307 Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers); 11308 } 11309 11310 void Assembler::stmfa(Condition cond, 11311 Register rn, 11312 WriteBack write_back, 11313 RegisterList registers) { 11314 VIXL_ASSERT(AllowAssembler()); 11315 CheckIT(cond); 11316 if (IsUsingA32()) { 11317 // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1 11318 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11319 EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11320 (write_back.GetWriteBackUint32() << 21) | 11321 GetRegisterListEncoding(registers, 0, 16)); 11322 return; 11323 } 11324 } 11325 Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers); 11326 } 11327 11328 void Assembler::stmfd(Condition cond, 11329 Register rn, 11330 WriteBack write_back, 11331 RegisterList registers) { 11332 VIXL_ASSERT(AllowAssembler()); 11333 CheckIT(cond); 11334 if (IsUsingT32()) { 11335 // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1 11336 if (((registers.GetList() & ~0x5fff) == 0) && 11337 (!rn.IsPC() || AllowUnpredictable())) { 11338 EmitT32_32(0xe9000000U | (rn.GetCode() << 16) | 11339 (write_back.GetWriteBackUint32() << 21) | 11340 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11341 GetRegisterListEncoding(registers, 0, 13)); 11342 AdvanceIT(); 11343 return; 11344 } 11345 } else { 11346 // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1 11347 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11348 EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11349 (write_back.GetWriteBackUint32() << 21) | 11350 GetRegisterListEncoding(registers, 0, 16)); 11351 return; 11352 } 11353 } 11354 Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers); 11355 } 11356 11357 void Assembler::stmib(Condition cond, 11358 Register rn, 11359 WriteBack write_back, 11360 RegisterList registers) { 11361 VIXL_ASSERT(AllowAssembler()); 11362 CheckIT(cond); 11363 if (IsUsingA32()) { 11364 // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1 11365 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11366 EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11367 (write_back.GetWriteBackUint32() << 21) | 11368 GetRegisterListEncoding(registers, 0, 16)); 11369 return; 11370 } 11371 } 11372 Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers); 11373 } 11374 11375 void Assembler::str(Condition cond, 11376 EncodingSize size, 11377 Register rt, 11378 const MemOperand& operand) { 11379 VIXL_ASSERT(AllowAssembler()); 11380 CheckIT(cond); 11381 if (operand.IsImmediate()) { 11382 Register rn = operand.GetBaseRegister(); 11383 int32_t offset = operand.GetOffsetImmediate(); 11384 if (IsUsingT32()) { 11385 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 11386 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 11387 (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) { 11388 int32_t offset_ = offset >> 2; 11389 EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) | 11390 ((offset_ & 0x1f) << 6)); 11391 AdvanceIT(); 11392 return; 11393 } 11394 // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2 11395 if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) && 11396 ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) { 11397 int32_t offset_ = offset >> 2; 11398 EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff)); 11399 AdvanceIT(); 11400 return; 11401 } 11402 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3 11403 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 11404 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11405 (!rt.IsPC() || AllowUnpredictable())) { 11406 EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11407 (offset & 0xfff)); 11408 AdvanceIT(); 11409 return; 11410 } 11411 // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4 11412 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 11413 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11414 (!rt.IsPC() || AllowUnpredictable())) { 11415 EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11416 (-offset & 0xff)); 11417 AdvanceIT(); 11418 return; 11419 } 11420 // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4 11421 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11422 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11423 (!rt.IsPC() || AllowUnpredictable())) { 11424 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11425 uint32_t offset_ = abs(offset); 11426 EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11427 offset_ | (sign << 9)); 11428 AdvanceIT(); 11429 return; 11430 } 11431 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4 11432 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11433 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11434 (!rt.IsPC() || AllowUnpredictable())) { 11435 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11436 uint32_t offset_ = abs(offset); 11437 EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11438 offset_ | (sign << 9)); 11439 AdvanceIT(); 11440 return; 11441 } 11442 } else { 11443 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 11444 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 11445 cond.IsNotNever()) { 11446 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11447 uint32_t offset_ = abs(offset); 11448 EmitA32(0x05000000U | (cond.GetCondition() << 28) | 11449 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11450 (sign << 23)); 11451 return; 11452 } 11453 // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 11454 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 11455 cond.IsNotNever()) { 11456 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11457 uint32_t offset_ = abs(offset); 11458 EmitA32(0x04000000U | (cond.GetCondition() << 28) | 11459 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11460 (sign << 23)); 11461 return; 11462 } 11463 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 11464 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 11465 cond.IsNotNever()) { 11466 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11467 uint32_t offset_ = abs(offset); 11468 EmitA32(0x05200000U | (cond.GetCondition() << 28) | 11469 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11470 (sign << 23)); 11471 return; 11472 } 11473 } 11474 } 11475 if (operand.IsPlainRegister()) { 11476 Register rn = operand.GetBaseRegister(); 11477 Sign sign = operand.GetSign(); 11478 Register rm = operand.GetOffsetRegister(); 11479 if (IsUsingT32()) { 11480 // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 11481 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 11482 sign.IsPlus() && operand.IsOffset()) { 11483 EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) | 11484 (rm.GetCode() << 6)); 11485 AdvanceIT(); 11486 return; 11487 } 11488 } 11489 } 11490 if (operand.IsShiftedRegister()) { 11491 Register rn = operand.GetBaseRegister(); 11492 Sign sign = operand.GetSign(); 11493 Register rm = operand.GetOffsetRegister(); 11494 Shift shift = operand.GetShift(); 11495 uint32_t amount = operand.GetShiftAmount(); 11496 if (IsUsingT32()) { 11497 // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 11498 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 11499 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11500 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11501 EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11502 rm.GetCode() | (amount << 4)); 11503 AdvanceIT(); 11504 return; 11505 } 11506 } else { 11507 // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 11508 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() && 11509 (!rm.IsPC() || AllowUnpredictable())) { 11510 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11511 uint32_t shift_ = TypeEncodingValue(shift); 11512 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11513 EmitA32(0x07000000U | (cond.GetCondition() << 28) | 11514 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11515 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11516 return; 11517 } 11518 // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 11519 if (operand.IsShiftValid() && operand.IsPostIndex() && 11520 cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) { 11521 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11522 uint32_t shift_ = TypeEncodingValue(shift); 11523 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11524 EmitA32(0x06000000U | (cond.GetCondition() << 28) | 11525 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11526 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11527 return; 11528 } 11529 // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 11530 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() && 11531 (!rm.IsPC() || AllowUnpredictable())) { 11532 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11533 uint32_t shift_ = TypeEncodingValue(shift); 11534 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11535 EmitA32(0x07200000U | (cond.GetCondition() << 28) | 11536 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11537 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11538 return; 11539 } 11540 } 11541 } 11542 Delegate(kStr, &Assembler::str, cond, size, rt, operand); 11543 } 11544 11545 void Assembler::strb(Condition cond, 11546 EncodingSize size, 11547 Register rt, 11548 const MemOperand& operand) { 11549 VIXL_ASSERT(AllowAssembler()); 11550 CheckIT(cond); 11551 if (operand.IsImmediate()) { 11552 Register rn = operand.GetBaseRegister(); 11553 int32_t offset = operand.GetOffsetImmediate(); 11554 if (IsUsingT32()) { 11555 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 11556 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 11557 (offset <= 31) && operand.IsOffset()) { 11558 EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) | 11559 ((offset & 0x1f) << 6)); 11560 AdvanceIT(); 11561 return; 11562 } 11563 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 11564 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 11565 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11566 (!rt.IsPC() || AllowUnpredictable())) { 11567 EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11568 (offset & 0xfff)); 11569 AdvanceIT(); 11570 return; 11571 } 11572 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 11573 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 11574 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11575 (!rt.IsPC() || AllowUnpredictable())) { 11576 EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11577 (-offset & 0xff)); 11578 AdvanceIT(); 11579 return; 11580 } 11581 // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 11582 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11583 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11584 (!rt.IsPC() || AllowUnpredictable())) { 11585 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11586 uint32_t offset_ = abs(offset); 11587 EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11588 offset_ | (sign << 9)); 11589 AdvanceIT(); 11590 return; 11591 } 11592 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 11593 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11594 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11595 (!rt.IsPC() || AllowUnpredictable())) { 11596 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11597 uint32_t offset_ = abs(offset); 11598 EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11599 offset_ | (sign << 9)); 11600 AdvanceIT(); 11601 return; 11602 } 11603 } else { 11604 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 11605 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 11606 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11607 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11608 uint32_t offset_ = abs(offset); 11609 EmitA32(0x05400000U | (cond.GetCondition() << 28) | 11610 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11611 (sign << 23)); 11612 return; 11613 } 11614 // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 11615 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 11616 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11617 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11618 uint32_t offset_ = abs(offset); 11619 EmitA32(0x04400000U | (cond.GetCondition() << 28) | 11620 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11621 (sign << 23)); 11622 return; 11623 } 11624 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 11625 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 11626 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11627 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11628 uint32_t offset_ = abs(offset); 11629 EmitA32(0x05600000U | (cond.GetCondition() << 28) | 11630 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11631 (sign << 23)); 11632 return; 11633 } 11634 } 11635 } 11636 if (operand.IsPlainRegister()) { 11637 Register rn = operand.GetBaseRegister(); 11638 Sign sign = operand.GetSign(); 11639 Register rm = operand.GetOffsetRegister(); 11640 if (IsUsingT32()) { 11641 // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 11642 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 11643 sign.IsPlus() && operand.IsOffset()) { 11644 EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) | 11645 (rm.GetCode() << 6)); 11646 AdvanceIT(); 11647 return; 11648 } 11649 } 11650 } 11651 if (operand.IsShiftedRegister()) { 11652 Register rn = operand.GetBaseRegister(); 11653 Sign sign = operand.GetSign(); 11654 Register rm = operand.GetOffsetRegister(); 11655 Shift shift = operand.GetShift(); 11656 uint32_t amount = operand.GetShiftAmount(); 11657 if (IsUsingT32()) { 11658 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 11659 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 11660 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11661 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11662 EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11663 rm.GetCode() | (amount << 4)); 11664 AdvanceIT(); 11665 return; 11666 } 11667 } else { 11668 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 11669 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() && 11670 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11671 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11672 uint32_t shift_ = TypeEncodingValue(shift); 11673 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11674 EmitA32(0x07400000U | (cond.GetCondition() << 28) | 11675 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11676 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11677 return; 11678 } 11679 // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 11680 if (operand.IsShiftValid() && operand.IsPostIndex() && 11681 cond.IsNotNever() && 11682 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11683 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11684 uint32_t shift_ = TypeEncodingValue(shift); 11685 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11686 EmitA32(0x06400000U | (cond.GetCondition() << 28) | 11687 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11688 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11689 return; 11690 } 11691 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 11692 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() && 11693 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11694 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11695 uint32_t shift_ = TypeEncodingValue(shift); 11696 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11697 EmitA32(0x07600000U | (cond.GetCondition() << 28) | 11698 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11699 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11700 return; 11701 } 11702 } 11703 } 11704 Delegate(kStrb, &Assembler::strb, cond, size, rt, operand); 11705 } 11706 11707 void Assembler::strd(Condition cond, 11708 Register rt, 11709 Register rt2, 11710 const MemOperand& operand) { 11711 VIXL_ASSERT(AllowAssembler()); 11712 CheckIT(cond); 11713 if (operand.IsImmediate()) { 11714 Register rn = operand.GetBaseRegister(); 11715 int32_t offset = operand.GetOffsetImmediate(); 11716 if (IsUsingT32()) { 11717 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1 11718 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 11719 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11720 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 11721 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11722 uint32_t offset_ = abs(offset) >> 2; 11723 EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 11724 (rn.GetCode() << 16) | offset_ | (sign << 23)); 11725 AdvanceIT(); 11726 return; 11727 } 11728 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1 11729 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 11730 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11731 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 11732 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11733 uint32_t offset_ = abs(offset) >> 2; 11734 EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 11735 (rn.GetCode() << 16) | offset_ | (sign << 23)); 11736 AdvanceIT(); 11737 return; 11738 } 11739 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1 11740 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 11741 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11742 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 11743 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11744 uint32_t offset_ = abs(offset) >> 2; 11745 EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 11746 (rn.GetCode() << 16) | offset_ | (sign << 23)); 11747 AdvanceIT(); 11748 return; 11749 } 11750 } else { 11751 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1 11752 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11753 (offset >= -255) && (offset <= 255) && operand.IsOffset() && 11754 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 11755 AllowUnpredictable())) { 11756 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11757 uint32_t offset_ = abs(offset); 11758 EmitA32(0x014000f0U | (cond.GetCondition() << 28) | 11759 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11760 ((offset_ & 0xf0) << 4) | (sign << 23)); 11761 return; 11762 } 11763 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1 11764 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11765 (offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 11766 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 11767 AllowUnpredictable())) { 11768 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11769 uint32_t offset_ = abs(offset); 11770 EmitA32(0x004000f0U | (cond.GetCondition() << 28) | 11771 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11772 ((offset_ & 0xf0) << 4) | (sign << 23)); 11773 return; 11774 } 11775 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1 11776 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11777 (offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 11778 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 11779 AllowUnpredictable())) { 11780 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11781 uint32_t offset_ = abs(offset); 11782 EmitA32(0x016000f0U | (cond.GetCondition() << 28) | 11783 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11784 ((offset_ & 0xf0) << 4) | (sign << 23)); 11785 return; 11786 } 11787 } 11788 } 11789 if (operand.IsPlainRegister()) { 11790 Register rn = operand.GetBaseRegister(); 11791 Sign sign = operand.GetSign(); 11792 Register rm = operand.GetOffsetRegister(); 11793 if (IsUsingA32()) { 11794 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1 11795 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11796 operand.IsOffset() && cond.IsNotNever() && 11797 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 11798 AllowUnpredictable())) { 11799 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11800 EmitA32(0x010000f0U | (cond.GetCondition() << 28) | 11801 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11802 (sign_ << 23)); 11803 return; 11804 } 11805 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1 11806 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11807 operand.IsPostIndex() && cond.IsNotNever() && 11808 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 11809 AllowUnpredictable())) { 11810 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11811 EmitA32(0x000000f0U | (cond.GetCondition() << 28) | 11812 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11813 (sign_ << 23)); 11814 return; 11815 } 11816 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1 11817 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11818 operand.IsPreIndex() && cond.IsNotNever() && 11819 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 11820 AllowUnpredictable())) { 11821 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11822 EmitA32(0x012000f0U | (cond.GetCondition() << 28) | 11823 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11824 (sign_ << 23)); 11825 return; 11826 } 11827 } 11828 } 11829 Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand); 11830 } 11831 11832 void Assembler::strex(Condition cond, 11833 Register rd, 11834 Register rt, 11835 const MemOperand& operand) { 11836 VIXL_ASSERT(AllowAssembler()); 11837 CheckIT(cond); 11838 if (operand.IsImmediate()) { 11839 Register rn = operand.GetBaseRegister(); 11840 int32_t offset = operand.GetOffsetImmediate(); 11841 if (IsUsingT32()) { 11842 // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1 11843 if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) && 11844 operand.IsOffset() && 11845 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11846 int32_t offset_ = offset >> 2; 11847 EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) | 11848 (rn.GetCode() << 16) | (offset_ & 0xff)); 11849 AdvanceIT(); 11850 return; 11851 } 11852 } else { 11853 // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1 11854 if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() && 11855 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11856 EmitA32(0x01800f90U | (cond.GetCondition() << 28) | 11857 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11858 return; 11859 } 11860 } 11861 } 11862 Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand); 11863 } 11864 11865 void Assembler::strexb(Condition cond, 11866 Register rd, 11867 Register rt, 11868 const MemOperand& operand) { 11869 VIXL_ASSERT(AllowAssembler()); 11870 CheckIT(cond); 11871 if (operand.IsImmediateZero()) { 11872 Register rn = operand.GetBaseRegister(); 11873 if (IsUsingT32()) { 11874 // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 11875 if (operand.IsOffset() && 11876 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11877 EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) | 11878 (rn.GetCode() << 16)); 11879 AdvanceIT(); 11880 return; 11881 } 11882 } else { 11883 // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 11884 if (operand.IsOffset() && cond.IsNotNever() && 11885 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11886 EmitA32(0x01c00f90U | (cond.GetCondition() << 28) | 11887 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11888 return; 11889 } 11890 } 11891 } 11892 Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand); 11893 } 11894 11895 void Assembler::strexd(Condition cond, 11896 Register rd, 11897 Register rt, 11898 Register rt2, 11899 const MemOperand& operand) { 11900 VIXL_ASSERT(AllowAssembler()); 11901 CheckIT(cond); 11902 if (operand.IsImmediateZero()) { 11903 Register rn = operand.GetBaseRegister(); 11904 if (IsUsingT32()) { 11905 // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1 11906 if (operand.IsOffset() && 11907 ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || 11908 AllowUnpredictable())) { 11909 EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) | 11910 (rt2.GetCode() << 8) | (rn.GetCode() << 16)); 11911 AdvanceIT(); 11912 return; 11913 } 11914 } else { 11915 // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1 11916 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11917 operand.IsOffset() && cond.IsNotNever() && 11918 ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() && 11919 !rn.IsPC()) || 11920 AllowUnpredictable())) { 11921 EmitA32(0x01a00f90U | (cond.GetCondition() << 28) | 11922 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11923 return; 11924 } 11925 } 11926 } 11927 Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand); 11928 } 11929 11930 void Assembler::strexh(Condition cond, 11931 Register rd, 11932 Register rt, 11933 const MemOperand& operand) { 11934 VIXL_ASSERT(AllowAssembler()); 11935 CheckIT(cond); 11936 if (operand.IsImmediateZero()) { 11937 Register rn = operand.GetBaseRegister(); 11938 if (IsUsingT32()) { 11939 // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 11940 if (operand.IsOffset() && 11941 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11942 EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) | 11943 (rn.GetCode() << 16)); 11944 AdvanceIT(); 11945 return; 11946 } 11947 } else { 11948 // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 11949 if (operand.IsOffset() && cond.IsNotNever() && 11950 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11951 EmitA32(0x01e00f90U | (cond.GetCondition() << 28) | 11952 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11953 return; 11954 } 11955 } 11956 } 11957 Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand); 11958 } 11959 11960 void Assembler::strh(Condition cond, 11961 EncodingSize size, 11962 Register rt, 11963 const MemOperand& operand) { 11964 VIXL_ASSERT(AllowAssembler()); 11965 CheckIT(cond); 11966 if (operand.IsImmediate()) { 11967 Register rn = operand.GetBaseRegister(); 11968 int32_t offset = operand.GetOffsetImmediate(); 11969 if (IsUsingT32()) { 11970 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 11971 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 11972 (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) { 11973 int32_t offset_ = offset >> 1; 11974 EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) | 11975 ((offset_ & 0x1f) << 6)); 11976 AdvanceIT(); 11977 return; 11978 } 11979 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 11980 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 11981 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11982 (!rt.IsPC() || AllowUnpredictable())) { 11983 EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11984 (offset & 0xfff)); 11985 AdvanceIT(); 11986 return; 11987 } 11988 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 11989 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 11990 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11991 (!rt.IsPC() || AllowUnpredictable())) { 11992 EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11993 (-offset & 0xff)); 11994 AdvanceIT(); 11995 return; 11996 } 11997 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 11998 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11999 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 12000 (!rt.IsPC() || AllowUnpredictable())) { 12001 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 12002 uint32_t offset_ = abs(offset); 12003 EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 12004 offset_ | (sign << 9)); 12005 AdvanceIT(); 12006 return; 12007 } 12008 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 12009 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 12010 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 12011 (!rt.IsPC() || AllowUnpredictable())) { 12012 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 12013 uint32_t offset_ = abs(offset); 12014 EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 12015 offset_ | (sign << 9)); 12016 AdvanceIT(); 12017 return; 12018 } 12019 } else { 12020 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 12021 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 12022 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 12023 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 12024 uint32_t offset_ = abs(offset); 12025 EmitA32(0x014000b0U | (cond.GetCondition() << 28) | 12026 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 12027 ((offset_ & 0xf0) << 4) | (sign << 23)); 12028 return; 12029 } 12030 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 12031 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 12032 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 12033 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 12034 uint32_t offset_ = abs(offset); 12035 EmitA32(0x004000b0U | (cond.GetCondition() << 28) | 12036 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 12037 ((offset_ & 0xf0) << 4) | (sign << 23)); 12038 return; 12039 } 12040 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 12041 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 12042 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 12043 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 12044 uint32_t offset_ = abs(offset); 12045 EmitA32(0x016000b0U | (cond.GetCondition() << 28) | 12046 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 12047 ((offset_ & 0xf0) << 4) | (sign << 23)); 12048 return; 12049 } 12050 } 12051 } 12052 if (operand.IsPlainRegister()) { 12053 Register rn = operand.GetBaseRegister(); 12054 Sign sign = operand.GetSign(); 12055 Register rm = operand.GetOffsetRegister(); 12056 if (IsUsingT32()) { 12057 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 12058 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 12059 sign.IsPlus() && operand.IsOffset()) { 12060 EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) | 12061 (rm.GetCode() << 6)); 12062 AdvanceIT(); 12063 return; 12064 } 12065 } else { 12066 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 12067 if (operand.IsOffset() && cond.IsNotNever() && 12068 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12069 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 12070 EmitA32(0x010000b0U | (cond.GetCondition() << 28) | 12071 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12072 (sign_ << 23)); 12073 return; 12074 } 12075 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 12076 if (operand.IsPostIndex() && cond.IsNotNever() && 12077 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12078 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 12079 EmitA32(0x000000b0U | (cond.GetCondition() << 28) | 12080 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12081 (sign_ << 23)); 12082 return; 12083 } 12084 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 12085 if (operand.IsPreIndex() && cond.IsNotNever() && 12086 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12087 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 12088 EmitA32(0x012000b0U | (cond.GetCondition() << 28) | 12089 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12090 (sign_ << 23)); 12091 return; 12092 } 12093 } 12094 } 12095 if (operand.IsShiftedRegister()) { 12096 Register rn = operand.GetBaseRegister(); 12097 Sign sign = operand.GetSign(); 12098 Register rm = operand.GetOffsetRegister(); 12099 Shift shift = operand.GetShift(); 12100 uint32_t amount = operand.GetShiftAmount(); 12101 if (IsUsingT32()) { 12102 // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 12103 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 12104 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 12105 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12106 EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 12107 rm.GetCode() | (amount << 4)); 12108 AdvanceIT(); 12109 return; 12110 } 12111 } 12112 } 12113 Delegate(kStrh, &Assembler::strh, cond, size, rt, operand); 12114 } 12115 12116 void Assembler::sub(Condition cond, 12117 EncodingSize size, 12118 Register rd, 12119 Register rn, 12120 const Operand& operand) { 12121 VIXL_ASSERT(AllowAssembler()); 12122 CheckIT(cond); 12123 if (operand.IsImmediate()) { 12124 uint32_t imm = operand.GetImmediate(); 12125 if (IsUsingT32()) { 12126 ImmediateT32 immediate_t32(imm); 12127 // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1 12128 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 12129 (imm <= 7)) { 12130 EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 12131 AdvanceIT(); 12132 return; 12133 } 12134 // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 12135 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 12136 (imm <= 255)) { 12137 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 12138 AdvanceIT(); 12139 return; 12140 } 12141 // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1 12142 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && 12143 ((imm % 4) == 0)) { 12144 uint32_t imm_ = imm >> 2; 12145 EmitT32_16(0xb080 | imm_); 12146 AdvanceIT(); 12147 return; 12148 } 12149 // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2 12150 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && 12151 (!rd.IsPC() || AllowUnpredictable())) { 12152 EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) | 12153 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12154 AdvanceIT(); 12155 return; 12156 } 12157 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 12158 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 12159 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 12160 EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12161 (immediate_t32.GetEncodingValue() & 0xff) | 12162 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12163 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12164 AdvanceIT(); 12165 return; 12166 } 12167 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 12168 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 12169 (!rd.IsPC() || AllowUnpredictable())) { 12170 EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12171 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12172 AdvanceIT(); 12173 return; 12174 } 12175 // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2 12176 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 12177 (!rd.IsPC() || AllowUnpredictable())) { 12178 EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) | 12179 (immediate_t32.GetEncodingValue() & 0xff) | 12180 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12181 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12182 AdvanceIT(); 12183 return; 12184 } 12185 // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3 12186 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && 12187 (!rd.IsPC() || AllowUnpredictable())) { 12188 EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) | 12189 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12190 AdvanceIT(); 12191 return; 12192 } 12193 } else { 12194 ImmediateA32 immediate_a32(imm); 12195 // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2 12196 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { 12197 EmitA32(0x024f0000U | (cond.GetCondition() << 28) | 12198 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 12199 return; 12200 } 12201 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 12202 if (immediate_a32.IsValid() && cond.IsNotNever() && 12203 ((rn.GetCode() & 0xd) != 0xd)) { 12204 EmitA32(0x02400000U | (cond.GetCondition() << 28) | 12205 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 12206 immediate_a32.GetEncodingValue()); 12207 return; 12208 } 12209 // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 12210 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 12211 EmitA32(0x024d0000U | (cond.GetCondition() << 28) | 12212 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 12213 return; 12214 } 12215 } 12216 } 12217 if (operand.IsImmediateShiftedRegister()) { 12218 Register rm = operand.GetBaseRegister(); 12219 if (operand.IsPlainRegister()) { 12220 if (IsUsingT32()) { 12221 // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 12222 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 12223 rm.IsLow()) { 12224 EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) | 12225 (rm.GetCode() << 6)); 12226 AdvanceIT(); 12227 return; 12228 } 12229 // SUB{<c>} {<Rd>}, SP, <Rm> ; T1 12230 if (rn.Is(sp) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12231 EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode()); 12232 AdvanceIT(); 12233 return; 12234 } 12235 } 12236 } 12237 Shift shift = operand.GetShift(); 12238 uint32_t amount = operand.GetShiftAmount(); 12239 if (IsUsingT32()) { 12240 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 12241 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 12242 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12243 uint32_t amount_ = amount % 32; 12244 EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12245 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 12246 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12247 AdvanceIT(); 12248 return; 12249 } 12250 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 12251 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 12252 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12253 uint32_t amount_ = amount % 32; 12254 EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() | 12255 (operand.GetTypeEncodingValue() << 4) | 12256 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12257 AdvanceIT(); 12258 return; 12259 } 12260 } else { 12261 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 12262 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 12263 uint32_t amount_ = amount % 32; 12264 EmitA32(0x00400000U | (cond.GetCondition() << 28) | 12265 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12266 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12267 return; 12268 } 12269 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 12270 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 12271 uint32_t amount_ = amount % 32; 12272 EmitA32(0x004d0000U | (cond.GetCondition() << 28) | 12273 (rd.GetCode() << 12) | rm.GetCode() | 12274 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12275 return; 12276 } 12277 } 12278 } 12279 if (operand.IsRegisterShiftedRegister()) { 12280 Register rm = operand.GetBaseRegister(); 12281 Shift shift = operand.GetShift(); 12282 Register rs = operand.GetShiftRegister(); 12283 if (IsUsingA32()) { 12284 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 12285 if (cond.IsNotNever() && 12286 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 12287 AllowUnpredictable())) { 12288 EmitA32(0x00400010U | (cond.GetCondition() << 28) | 12289 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12290 (shift.GetType() << 5) | (rs.GetCode() << 8)); 12291 return; 12292 } 12293 } 12294 } 12295 Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand); 12296 } 12297 12298 void Assembler::sub(Condition cond, Register rd, const Operand& operand) { 12299 VIXL_ASSERT(AllowAssembler()); 12300 CheckIT(cond); 12301 if (operand.IsImmediate()) { 12302 uint32_t imm = operand.GetImmediate(); 12303 if (IsUsingT32()) { 12304 // SUB<c>{<q>} <Rdn>, #<imm8> ; T2 12305 if (InITBlock() && rd.IsLow() && (imm <= 255)) { 12306 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 12307 AdvanceIT(); 12308 return; 12309 } 12310 } 12311 } 12312 Delegate(kSub, &Assembler::sub, cond, rd, operand); 12313 } 12314 12315 void Assembler::subs(Condition cond, 12316 EncodingSize size, 12317 Register rd, 12318 Register rn, 12319 const Operand& operand) { 12320 VIXL_ASSERT(AllowAssembler()); 12321 CheckIT(cond); 12322 if (operand.IsImmediate()) { 12323 uint32_t imm = operand.GetImmediate(); 12324 if (IsUsingT32()) { 12325 ImmediateT32 immediate_t32(imm); 12326 // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1 12327 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 12328 (imm <= 7)) { 12329 EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 12330 AdvanceIT(); 12331 return; 12332 } 12333 // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 12334 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 12335 (imm <= 255)) { 12336 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 12337 AdvanceIT(); 12338 return; 12339 } 12340 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 12341 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 12342 !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { 12343 EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12344 (immediate_t32.GetEncodingValue() & 0xff) | 12345 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12346 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12347 AdvanceIT(); 12348 return; 12349 } 12350 // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5 12351 if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255) && 12352 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) { 12353 EmitT32_32(0xf3de8f00U | imm); 12354 AdvanceIT(); 12355 return; 12356 } 12357 // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2 12358 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 12359 !rd.Is(pc)) { 12360 EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) | 12361 (immediate_t32.GetEncodingValue() & 0xff) | 12362 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12363 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12364 AdvanceIT(); 12365 return; 12366 } 12367 } else { 12368 ImmediateA32 immediate_a32(imm); 12369 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 12370 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { 12371 EmitA32(0x02500000U | (cond.GetCondition() << 28) | 12372 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 12373 immediate_a32.GetEncodingValue()); 12374 return; 12375 } 12376 // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 12377 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 12378 EmitA32(0x025d0000U | (cond.GetCondition() << 28) | 12379 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 12380 return; 12381 } 12382 } 12383 } 12384 if (operand.IsImmediateShiftedRegister()) { 12385 Register rm = operand.GetBaseRegister(); 12386 if (operand.IsPlainRegister()) { 12387 if (IsUsingT32()) { 12388 // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12389 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 12390 rm.IsLow()) { 12391 EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) | 12392 (rm.GetCode() << 6)); 12393 AdvanceIT(); 12394 return; 12395 } 12396 } 12397 } 12398 Shift shift = operand.GetShift(); 12399 uint32_t amount = operand.GetShiftAmount(); 12400 if (IsUsingT32()) { 12401 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 12402 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 12403 !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12404 uint32_t amount_ = amount % 32; 12405 EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12406 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 12407 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12408 AdvanceIT(); 12409 return; 12410 } 12411 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 12412 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 12413 !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { 12414 uint32_t amount_ = amount % 32; 12415 EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() | 12416 (operand.GetTypeEncodingValue() << 4) | 12417 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12418 AdvanceIT(); 12419 return; 12420 } 12421 } else { 12422 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 12423 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 12424 uint32_t amount_ = amount % 32; 12425 EmitA32(0x00500000U | (cond.GetCondition() << 28) | 12426 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12427 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12428 return; 12429 } 12430 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 12431 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 12432 uint32_t amount_ = amount % 32; 12433 EmitA32(0x005d0000U | (cond.GetCondition() << 28) | 12434 (rd.GetCode() << 12) | rm.GetCode() | 12435 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12436 return; 12437 } 12438 } 12439 } 12440 if (operand.IsRegisterShiftedRegister()) { 12441 Register rm = operand.GetBaseRegister(); 12442 Shift shift = operand.GetShift(); 12443 Register rs = operand.GetShiftRegister(); 12444 if (IsUsingA32()) { 12445 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 12446 if (cond.IsNotNever() && 12447 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 12448 AllowUnpredictable())) { 12449 EmitA32(0x00500010U | (cond.GetCondition() << 28) | 12450 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12451 (shift.GetType() << 5) | (rs.GetCode() << 8)); 12452 return; 12453 } 12454 } 12455 } 12456 Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand); 12457 } 12458 12459 void Assembler::subs(Register rd, const Operand& operand) { 12460 VIXL_ASSERT(AllowAssembler()); 12461 CheckIT(al); 12462 if (operand.IsImmediate()) { 12463 uint32_t imm = operand.GetImmediate(); 12464 if (IsUsingT32()) { 12465 // SUBS{<q>} <Rdn>, #<imm8> ; T2 12466 if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) { 12467 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 12468 AdvanceIT(); 12469 return; 12470 } 12471 } 12472 } 12473 Delegate(kSubs, &Assembler::subs, rd, operand); 12474 } 12475 12476 void Assembler::subw(Condition cond, 12477 Register rd, 12478 Register rn, 12479 const Operand& operand) { 12480 VIXL_ASSERT(AllowAssembler()); 12481 CheckIT(cond); 12482 if (operand.IsImmediate()) { 12483 uint32_t imm = operand.GetImmediate(); 12484 if (IsUsingT32()) { 12485 // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 12486 if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 12487 (!rd.IsPC() || AllowUnpredictable())) { 12488 EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12489 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12490 AdvanceIT(); 12491 return; 12492 } 12493 // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3 12494 if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 12495 EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) | 12496 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12497 AdvanceIT(); 12498 return; 12499 } 12500 } 12501 } 12502 Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand); 12503 } 12504 12505 void Assembler::svc(Condition cond, uint32_t imm) { 12506 VIXL_ASSERT(AllowAssembler()); 12507 CheckIT(cond); 12508 if (IsUsingT32()) { 12509 // SVC{<c>}{<q>} {#}<imm> ; T1 12510 if ((imm <= 255)) { 12511 EmitT32_16(0xdf00 | imm); 12512 AdvanceIT(); 12513 return; 12514 } 12515 } else { 12516 // SVC{<c>}{<q>} {#}<imm> ; A1 12517 if ((imm <= 16777215) && cond.IsNotNever()) { 12518 EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm); 12519 return; 12520 } 12521 } 12522 Delegate(kSvc, &Assembler::svc, cond, imm); 12523 } 12524 12525 void Assembler::sxtab(Condition cond, 12526 Register rd, 12527 Register rn, 12528 const Operand& operand) { 12529 VIXL_ASSERT(AllowAssembler()); 12530 CheckIT(cond); 12531 if (operand.IsImmediateShiftedRegister()) { 12532 Register rm = operand.GetBaseRegister(); 12533 Shift shift = operand.GetShift(); 12534 uint32_t amount = operand.GetShiftAmount(); 12535 if (IsUsingT32()) { 12536 // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12537 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12538 ((amount % 8) == 0) && !rn.Is(pc) && 12539 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12540 uint32_t amount_ = amount / 8; 12541 EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12542 rm.GetCode() | (amount_ << 4)); 12543 AdvanceIT(); 12544 return; 12545 } 12546 } else { 12547 // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12548 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12549 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 12550 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12551 uint32_t amount_ = amount / 8; 12552 EmitA32(0x06a00070U | (cond.GetCondition() << 28) | 12553 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12554 (amount_ << 10)); 12555 return; 12556 } 12557 } 12558 } 12559 Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand); 12560 } 12561 12562 void Assembler::sxtab16(Condition cond, 12563 Register rd, 12564 Register rn, 12565 const Operand& operand) { 12566 VIXL_ASSERT(AllowAssembler()); 12567 CheckIT(cond); 12568 if (operand.IsImmediateShiftedRegister()) { 12569 Register rm = operand.GetBaseRegister(); 12570 Shift shift = operand.GetShift(); 12571 uint32_t amount = operand.GetShiftAmount(); 12572 if (IsUsingT32()) { 12573 // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12574 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12575 ((amount % 8) == 0) && !rn.Is(pc) && 12576 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12577 uint32_t amount_ = amount / 8; 12578 EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12579 rm.GetCode() | (amount_ << 4)); 12580 AdvanceIT(); 12581 return; 12582 } 12583 } else { 12584 // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12585 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12586 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 12587 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12588 uint32_t amount_ = amount / 8; 12589 EmitA32(0x06800070U | (cond.GetCondition() << 28) | 12590 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12591 (amount_ << 10)); 12592 return; 12593 } 12594 } 12595 } 12596 Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand); 12597 } 12598 12599 void Assembler::sxtah(Condition cond, 12600 Register rd, 12601 Register rn, 12602 const Operand& operand) { 12603 VIXL_ASSERT(AllowAssembler()); 12604 CheckIT(cond); 12605 if (operand.IsImmediateShiftedRegister()) { 12606 Register rm = operand.GetBaseRegister(); 12607 Shift shift = operand.GetShift(); 12608 uint32_t amount = operand.GetShiftAmount(); 12609 if (IsUsingT32()) { 12610 // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12611 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12612 ((amount % 8) == 0) && !rn.Is(pc) && 12613 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12614 uint32_t amount_ = amount / 8; 12615 EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12616 rm.GetCode() | (amount_ << 4)); 12617 AdvanceIT(); 12618 return; 12619 } 12620 } else { 12621 // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12622 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12623 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 12624 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12625 uint32_t amount_ = amount / 8; 12626 EmitA32(0x06b00070U | (cond.GetCondition() << 28) | 12627 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12628 (amount_ << 10)); 12629 return; 12630 } 12631 } 12632 } 12633 Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand); 12634 } 12635 12636 void Assembler::sxtb(Condition cond, 12637 EncodingSize size, 12638 Register rd, 12639 const Operand& operand) { 12640 VIXL_ASSERT(AllowAssembler()); 12641 CheckIT(cond); 12642 if (operand.IsImmediateShiftedRegister()) { 12643 Register rm = operand.GetBaseRegister(); 12644 if (operand.IsPlainRegister()) { 12645 if (IsUsingT32()) { 12646 // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1 12647 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 12648 EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3)); 12649 AdvanceIT(); 12650 return; 12651 } 12652 } 12653 } 12654 Shift shift = operand.GetShift(); 12655 uint32_t amount = operand.GetShiftAmount(); 12656 if (IsUsingT32()) { 12657 // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 12658 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 12659 (amount <= 24) && ((amount % 8) == 0) && 12660 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12661 uint32_t amount_ = amount / 8; 12662 EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12663 (amount_ << 4)); 12664 AdvanceIT(); 12665 return; 12666 } 12667 } else { 12668 // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12669 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12670 ((amount % 8) == 0) && cond.IsNotNever() && 12671 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12672 uint32_t amount_ = amount / 8; 12673 EmitA32(0x06af0070U | (cond.GetCondition() << 28) | 12674 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12675 return; 12676 } 12677 } 12678 } 12679 Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand); 12680 } 12681 12682 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) { 12683 VIXL_ASSERT(AllowAssembler()); 12684 CheckIT(cond); 12685 if (operand.IsImmediateShiftedRegister()) { 12686 Register rm = operand.GetBaseRegister(); 12687 Shift shift = operand.GetShift(); 12688 uint32_t amount = operand.GetShiftAmount(); 12689 if (IsUsingT32()) { 12690 // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1 12691 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12692 ((amount % 8) == 0) && 12693 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12694 uint32_t amount_ = amount / 8; 12695 EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12696 (amount_ << 4)); 12697 AdvanceIT(); 12698 return; 12699 } 12700 } else { 12701 // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12702 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12703 ((amount % 8) == 0) && cond.IsNotNever() && 12704 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12705 uint32_t amount_ = amount / 8; 12706 EmitA32(0x068f0070U | (cond.GetCondition() << 28) | 12707 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12708 return; 12709 } 12710 } 12711 } 12712 Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand); 12713 } 12714 12715 void Assembler::sxth(Condition cond, 12716 EncodingSize size, 12717 Register rd, 12718 const Operand& operand) { 12719 VIXL_ASSERT(AllowAssembler()); 12720 CheckIT(cond); 12721 if (operand.IsImmediateShiftedRegister()) { 12722 Register rm = operand.GetBaseRegister(); 12723 if (operand.IsPlainRegister()) { 12724 if (IsUsingT32()) { 12725 // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1 12726 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 12727 EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3)); 12728 AdvanceIT(); 12729 return; 12730 } 12731 } 12732 } 12733 Shift shift = operand.GetShift(); 12734 uint32_t amount = operand.GetShiftAmount(); 12735 if (IsUsingT32()) { 12736 // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 12737 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 12738 (amount <= 24) && ((amount % 8) == 0) && 12739 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12740 uint32_t amount_ = amount / 8; 12741 EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12742 (amount_ << 4)); 12743 AdvanceIT(); 12744 return; 12745 } 12746 } else { 12747 // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12748 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12749 ((amount % 8) == 0) && cond.IsNotNever() && 12750 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12751 uint32_t amount_ = amount / 8; 12752 EmitA32(0x06bf0070U | (cond.GetCondition() << 28) | 12753 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12754 return; 12755 } 12756 } 12757 } 12758 Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand); 12759 } 12760 12761 void Assembler::tbb(Condition cond, Register rn, Register rm) { 12762 VIXL_ASSERT(AllowAssembler()); 12763 CheckIT(cond); 12764 if (IsUsingT32()) { 12765 // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1 12766 if (OutsideITBlockAndAlOrLast(cond) && 12767 (!rm.IsPC() || AllowUnpredictable())) { 12768 EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode()); 12769 AdvanceIT(); 12770 return; 12771 } 12772 } 12773 Delegate(kTbb, &Assembler::tbb, cond, rn, rm); 12774 } 12775 12776 void Assembler::tbh(Condition cond, Register rn, Register rm) { 12777 VIXL_ASSERT(AllowAssembler()); 12778 CheckIT(cond); 12779 if (IsUsingT32()) { 12780 // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1 12781 if (OutsideITBlockAndAlOrLast(cond) && 12782 (!rm.IsPC() || AllowUnpredictable())) { 12783 EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode()); 12784 AdvanceIT(); 12785 return; 12786 } 12787 } 12788 Delegate(kTbh, &Assembler::tbh, cond, rn, rm); 12789 } 12790 12791 void Assembler::teq(Condition cond, Register rn, const Operand& operand) { 12792 VIXL_ASSERT(AllowAssembler()); 12793 CheckIT(cond); 12794 if (operand.IsImmediate()) { 12795 uint32_t imm = operand.GetImmediate(); 12796 if (IsUsingT32()) { 12797 ImmediateT32 immediate_t32(imm); 12798 // TEQ{<c>}{<q>} <Rn>, #<const> ; T1 12799 if (immediate_t32.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 12800 EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) | 12801 (immediate_t32.GetEncodingValue() & 0xff) | 12802 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12803 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12804 AdvanceIT(); 12805 return; 12806 } 12807 } else { 12808 ImmediateA32 immediate_a32(imm); 12809 // TEQ{<c>}{<q>} <Rn>, #<const> ; A1 12810 if (immediate_a32.IsValid() && cond.IsNotNever()) { 12811 EmitA32(0x03300000U | (cond.GetCondition() << 28) | 12812 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 12813 return; 12814 } 12815 } 12816 } 12817 if (operand.IsImmediateShiftedRegister()) { 12818 Register rm = operand.GetBaseRegister(); 12819 Shift shift = operand.GetShift(); 12820 uint32_t amount = operand.GetShiftAmount(); 12821 if (IsUsingT32()) { 12822 // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1 12823 if (shift.IsValidAmount(amount) && 12824 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12825 uint32_t amount_ = amount % 32; 12826 EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() | 12827 (operand.GetTypeEncodingValue() << 4) | 12828 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12829 AdvanceIT(); 12830 return; 12831 } 12832 } else { 12833 // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 12834 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 12835 uint32_t amount_ = amount % 32; 12836 EmitA32(0x01300000U | (cond.GetCondition() << 28) | 12837 (rn.GetCode() << 16) | rm.GetCode() | 12838 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12839 return; 12840 } 12841 } 12842 } 12843 if (operand.IsRegisterShiftedRegister()) { 12844 Register rm = operand.GetBaseRegister(); 12845 Shift shift = operand.GetShift(); 12846 Register rs = operand.GetShiftRegister(); 12847 if (IsUsingA32()) { 12848 // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 12849 if (cond.IsNotNever() && 12850 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 12851 EmitA32(0x01300010U | (cond.GetCondition() << 28) | 12852 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 12853 (rs.GetCode() << 8)); 12854 return; 12855 } 12856 } 12857 } 12858 Delegate(kTeq, &Assembler::teq, cond, rn, operand); 12859 } 12860 12861 void Assembler::tst(Condition cond, 12862 EncodingSize size, 12863 Register rn, 12864 const Operand& operand) { 12865 VIXL_ASSERT(AllowAssembler()); 12866 CheckIT(cond); 12867 if (operand.IsImmediate()) { 12868 uint32_t imm = operand.GetImmediate(); 12869 if (IsUsingT32()) { 12870 ImmediateT32 immediate_t32(imm); 12871 // TST{<c>}{<q>} <Rn>, #<const> ; T1 12872 if (!size.IsNarrow() && immediate_t32.IsValid() && 12873 (!rn.IsPC() || AllowUnpredictable())) { 12874 EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) | 12875 (immediate_t32.GetEncodingValue() & 0xff) | 12876 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12877 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12878 AdvanceIT(); 12879 return; 12880 } 12881 } else { 12882 ImmediateA32 immediate_a32(imm); 12883 // TST{<c>}{<q>} <Rn>, #<const> ; A1 12884 if (immediate_a32.IsValid() && cond.IsNotNever()) { 12885 EmitA32(0x03100000U | (cond.GetCondition() << 28) | 12886 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 12887 return; 12888 } 12889 } 12890 } 12891 if (operand.IsImmediateShiftedRegister()) { 12892 Register rm = operand.GetBaseRegister(); 12893 if (operand.IsPlainRegister()) { 12894 if (IsUsingT32()) { 12895 // TST{<c>}{<q>} <Rn>, <Rm> ; T1 12896 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 12897 EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3)); 12898 AdvanceIT(); 12899 return; 12900 } 12901 } 12902 } 12903 Shift shift = operand.GetShift(); 12904 uint32_t amount = operand.GetShiftAmount(); 12905 if (IsUsingT32()) { 12906 // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2 12907 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 12908 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12909 uint32_t amount_ = amount % 32; 12910 EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() | 12911 (operand.GetTypeEncodingValue() << 4) | 12912 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12913 AdvanceIT(); 12914 return; 12915 } 12916 } else { 12917 // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 12918 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 12919 uint32_t amount_ = amount % 32; 12920 EmitA32(0x01100000U | (cond.GetCondition() << 28) | 12921 (rn.GetCode() << 16) | rm.GetCode() | 12922 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12923 return; 12924 } 12925 } 12926 } 12927 if (operand.IsRegisterShiftedRegister()) { 12928 Register rm = operand.GetBaseRegister(); 12929 Shift shift = operand.GetShift(); 12930 Register rs = operand.GetShiftRegister(); 12931 if (IsUsingA32()) { 12932 // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 12933 if (cond.IsNotNever() && 12934 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 12935 EmitA32(0x01100010U | (cond.GetCondition() << 28) | 12936 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 12937 (rs.GetCode() << 8)); 12938 return; 12939 } 12940 } 12941 } 12942 Delegate(kTst, &Assembler::tst, cond, size, rn, operand); 12943 } 12944 12945 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) { 12946 VIXL_ASSERT(AllowAssembler()); 12947 CheckIT(cond); 12948 if (IsUsingT32()) { 12949 // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12950 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12951 EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12952 rm.GetCode()); 12953 AdvanceIT(); 12954 return; 12955 } 12956 } else { 12957 // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12958 if (cond.IsNotNever() && 12959 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12960 EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12961 (rn.GetCode() << 16) | rm.GetCode()); 12962 return; 12963 } 12964 } 12965 Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm); 12966 } 12967 12968 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) { 12969 VIXL_ASSERT(AllowAssembler()); 12970 CheckIT(cond); 12971 if (IsUsingT32()) { 12972 // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12973 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12974 EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12975 rm.GetCode()); 12976 AdvanceIT(); 12977 return; 12978 } 12979 } else { 12980 // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12981 if (cond.IsNotNever() && 12982 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12983 EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12984 (rn.GetCode() << 16) | rm.GetCode()); 12985 return; 12986 } 12987 } 12988 Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm); 12989 } 12990 12991 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) { 12992 VIXL_ASSERT(AllowAssembler()); 12993 CheckIT(cond); 12994 if (IsUsingT32()) { 12995 // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12996 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12997 EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12998 rm.GetCode()); 12999 AdvanceIT(); 13000 return; 13001 } 13002 } else { 13003 // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13004 if (cond.IsNotNever() && 13005 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13006 EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13007 (rn.GetCode() << 16) | rm.GetCode()); 13008 return; 13009 } 13010 } 13011 Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm); 13012 } 13013 13014 void Assembler::ubfx( 13015 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) { 13016 VIXL_ASSERT(AllowAssembler()); 13017 CheckIT(cond); 13018 if (IsUsingT32()) { 13019 // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 13020 if ((lsb <= 31) && 13021 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) || 13022 AllowUnpredictable())) { 13023 uint32_t widthm1 = width - 1; 13024 EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13025 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1); 13026 AdvanceIT(); 13027 return; 13028 } 13029 } else { 13030 // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 13031 if ((lsb <= 31) && cond.IsNotNever() && 13032 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) || 13033 AllowUnpredictable())) { 13034 uint32_t widthm1 = width - 1; 13035 EmitA32(0x07e00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13036 rn.GetCode() | (lsb << 7) | (widthm1 << 16)); 13037 return; 13038 } 13039 } 13040 Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, width); 13041 } 13042 13043 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) { 13044 VIXL_ASSERT(AllowAssembler()); 13045 CheckIT(cond); 13046 if (IsUsingT32()) { 13047 // UDF{<c>}{<q>} {#}<imm> ; T1 13048 if (!size.IsWide() && (imm <= 255)) { 13049 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13050 EmitT32_16(0xde00 | imm); 13051 AdvanceIT(); 13052 return; 13053 } 13054 } 13055 // UDF{<c>}{<q>} {#}<imm> ; T2 13056 if (!size.IsNarrow() && (imm <= 65535)) { 13057 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13058 EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4)); 13059 AdvanceIT(); 13060 return; 13061 } 13062 } 13063 } else { 13064 // UDF{<c>}{<q>} {#}<imm> ; A1 13065 if ((imm <= 65535)) { 13066 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13067 EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4)); 13068 return; 13069 } 13070 } 13071 } 13072 Delegate(kUdf, &Assembler::udf, cond, size, imm); 13073 } 13074 13075 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) { 13076 VIXL_ASSERT(AllowAssembler()); 13077 CheckIT(cond); 13078 if (IsUsingT32()) { 13079 // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13080 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13081 EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13082 rm.GetCode()); 13083 AdvanceIT(); 13084 return; 13085 } 13086 } else { 13087 // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13088 if (cond.IsNotNever() && 13089 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13090 EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 13091 rn.GetCode() | (rm.GetCode() << 8)); 13092 return; 13093 } 13094 } 13095 Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm); 13096 } 13097 13098 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) { 13099 VIXL_ASSERT(AllowAssembler()); 13100 CheckIT(cond); 13101 if (IsUsingT32()) { 13102 // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13103 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13104 EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13105 rm.GetCode()); 13106 AdvanceIT(); 13107 return; 13108 } 13109 } else { 13110 // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13111 if (cond.IsNotNever() && 13112 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13113 EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13114 (rn.GetCode() << 16) | rm.GetCode()); 13115 return; 13116 } 13117 } 13118 Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm); 13119 } 13120 13121 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) { 13122 VIXL_ASSERT(AllowAssembler()); 13123 CheckIT(cond); 13124 if (IsUsingT32()) { 13125 // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13126 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13127 EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13128 rm.GetCode()); 13129 AdvanceIT(); 13130 return; 13131 } 13132 } else { 13133 // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13134 if (cond.IsNotNever() && 13135 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13136 EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13137 (rn.GetCode() << 16) | rm.GetCode()); 13138 return; 13139 } 13140 } 13141 Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm); 13142 } 13143 13144 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) { 13145 VIXL_ASSERT(AllowAssembler()); 13146 CheckIT(cond); 13147 if (IsUsingT32()) { 13148 // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13149 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13150 EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13151 rm.GetCode()); 13152 AdvanceIT(); 13153 return; 13154 } 13155 } else { 13156 // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13157 if (cond.IsNotNever() && 13158 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13159 EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13160 (rn.GetCode() << 16) | rm.GetCode()); 13161 return; 13162 } 13163 } 13164 Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm); 13165 } 13166 13167 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) { 13168 VIXL_ASSERT(AllowAssembler()); 13169 CheckIT(cond); 13170 if (IsUsingT32()) { 13171 // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13172 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13173 EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13174 rm.GetCode()); 13175 AdvanceIT(); 13176 return; 13177 } 13178 } else { 13179 // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13180 if (cond.IsNotNever() && 13181 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13182 EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13183 (rn.GetCode() << 16) | rm.GetCode()); 13184 return; 13185 } 13186 } 13187 Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm); 13188 } 13189 13190 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) { 13191 VIXL_ASSERT(AllowAssembler()); 13192 CheckIT(cond); 13193 if (IsUsingT32()) { 13194 // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13195 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13196 EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13197 rm.GetCode()); 13198 AdvanceIT(); 13199 return; 13200 } 13201 } else { 13202 // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13203 if (cond.IsNotNever() && 13204 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13205 EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13206 (rn.GetCode() << 16) | rm.GetCode()); 13207 return; 13208 } 13209 } 13210 Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm); 13211 } 13212 13213 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) { 13214 VIXL_ASSERT(AllowAssembler()); 13215 CheckIT(cond); 13216 if (IsUsingT32()) { 13217 // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13218 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13219 EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13220 rm.GetCode()); 13221 AdvanceIT(); 13222 return; 13223 } 13224 } else { 13225 // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13226 if (cond.IsNotNever() && 13227 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13228 EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13229 (rn.GetCode() << 16) | rm.GetCode()); 13230 return; 13231 } 13232 } 13233 Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm); 13234 } 13235 13236 void Assembler::umaal( 13237 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13238 VIXL_ASSERT(AllowAssembler()); 13239 CheckIT(cond); 13240 if (IsUsingT32()) { 13241 // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 13242 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13243 AllowUnpredictable())) { 13244 EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 13245 (rn.GetCode() << 16) | rm.GetCode()); 13246 AdvanceIT(); 13247 return; 13248 } 13249 } else { 13250 // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13251 if (cond.IsNotNever() && 13252 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13253 AllowUnpredictable())) { 13254 EmitA32(0x00400090U | (cond.GetCondition() << 28) | 13255 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13256 (rm.GetCode() << 8)); 13257 return; 13258 } 13259 } 13260 Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm); 13261 } 13262 13263 void Assembler::umlal( 13264 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13265 VIXL_ASSERT(AllowAssembler()); 13266 CheckIT(cond); 13267 if (IsUsingT32()) { 13268 // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 13269 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13270 AllowUnpredictable())) { 13271 EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 13272 (rn.GetCode() << 16) | rm.GetCode()); 13273 AdvanceIT(); 13274 return; 13275 } 13276 } else { 13277 // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13278 if (cond.IsNotNever() && 13279 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13280 AllowUnpredictable())) { 13281 EmitA32(0x00a00090U | (cond.GetCondition() << 28) | 13282 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13283 (rm.GetCode() << 8)); 13284 return; 13285 } 13286 } 13287 Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm); 13288 } 13289 13290 void Assembler::umlals( 13291 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13292 VIXL_ASSERT(AllowAssembler()); 13293 CheckIT(cond); 13294 if (IsUsingA32()) { 13295 // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13296 if (cond.IsNotNever() && 13297 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13298 AllowUnpredictable())) { 13299 EmitA32(0x00b00090U | (cond.GetCondition() << 28) | 13300 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13301 (rm.GetCode() << 8)); 13302 return; 13303 } 13304 } 13305 Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm); 13306 } 13307 13308 void Assembler::umull( 13309 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13310 VIXL_ASSERT(AllowAssembler()); 13311 CheckIT(cond); 13312 if (IsUsingT32()) { 13313 // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 13314 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13315 AllowUnpredictable())) { 13316 EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 13317 (rn.GetCode() << 16) | rm.GetCode()); 13318 AdvanceIT(); 13319 return; 13320 } 13321 } else { 13322 // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13323 if (cond.IsNotNever() && 13324 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13325 AllowUnpredictable())) { 13326 EmitA32(0x00800090U | (cond.GetCondition() << 28) | 13327 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13328 (rm.GetCode() << 8)); 13329 return; 13330 } 13331 } 13332 Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm); 13333 } 13334 13335 void Assembler::umulls( 13336 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13337 VIXL_ASSERT(AllowAssembler()); 13338 CheckIT(cond); 13339 if (IsUsingA32()) { 13340 // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13341 if (cond.IsNotNever() && 13342 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13343 AllowUnpredictable())) { 13344 EmitA32(0x00900090U | (cond.GetCondition() << 28) | 13345 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13346 (rm.GetCode() << 8)); 13347 return; 13348 } 13349 } 13350 Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm); 13351 } 13352 13353 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) { 13354 VIXL_ASSERT(AllowAssembler()); 13355 CheckIT(cond); 13356 if (IsUsingT32()) { 13357 // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13358 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13359 EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13360 rm.GetCode()); 13361 AdvanceIT(); 13362 return; 13363 } 13364 } else { 13365 // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13366 if (cond.IsNotNever() && 13367 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13368 EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13369 (rn.GetCode() << 16) | rm.GetCode()); 13370 return; 13371 } 13372 } 13373 Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm); 13374 } 13375 13376 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) { 13377 VIXL_ASSERT(AllowAssembler()); 13378 CheckIT(cond); 13379 if (IsUsingT32()) { 13380 // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13381 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13382 EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13383 rm.GetCode()); 13384 AdvanceIT(); 13385 return; 13386 } 13387 } else { 13388 // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13389 if (cond.IsNotNever() && 13390 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13391 EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13392 (rn.GetCode() << 16) | rm.GetCode()); 13393 return; 13394 } 13395 } 13396 Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm); 13397 } 13398 13399 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) { 13400 VIXL_ASSERT(AllowAssembler()); 13401 CheckIT(cond); 13402 if (IsUsingT32()) { 13403 // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13404 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13405 EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13406 rm.GetCode()); 13407 AdvanceIT(); 13408 return; 13409 } 13410 } else { 13411 // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13412 if (cond.IsNotNever() && 13413 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13414 EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13415 (rn.GetCode() << 16) | rm.GetCode()); 13416 return; 13417 } 13418 } 13419 Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm); 13420 } 13421 13422 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) { 13423 VIXL_ASSERT(AllowAssembler()); 13424 CheckIT(cond); 13425 if (IsUsingT32()) { 13426 // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13427 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13428 EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13429 rm.GetCode()); 13430 AdvanceIT(); 13431 return; 13432 } 13433 } else { 13434 // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13435 if (cond.IsNotNever() && 13436 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13437 EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13438 (rn.GetCode() << 16) | rm.GetCode()); 13439 return; 13440 } 13441 } 13442 Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm); 13443 } 13444 13445 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) { 13446 VIXL_ASSERT(AllowAssembler()); 13447 CheckIT(cond); 13448 if (IsUsingT32()) { 13449 // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13450 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13451 EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13452 rm.GetCode()); 13453 AdvanceIT(); 13454 return; 13455 } 13456 } else { 13457 // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13458 if (cond.IsNotNever() && 13459 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13460 EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13461 (rn.GetCode() << 16) | rm.GetCode()); 13462 return; 13463 } 13464 } 13465 Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm); 13466 } 13467 13468 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) { 13469 VIXL_ASSERT(AllowAssembler()); 13470 CheckIT(cond); 13471 if (IsUsingT32()) { 13472 // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13473 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13474 EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13475 rm.GetCode()); 13476 AdvanceIT(); 13477 return; 13478 } 13479 } else { 13480 // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13481 if (cond.IsNotNever() && 13482 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13483 EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13484 (rn.GetCode() << 16) | rm.GetCode()); 13485 return; 13486 } 13487 } 13488 Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm); 13489 } 13490 13491 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) { 13492 VIXL_ASSERT(AllowAssembler()); 13493 CheckIT(cond); 13494 if (IsUsingT32()) { 13495 // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13496 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13497 EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13498 rm.GetCode()); 13499 AdvanceIT(); 13500 return; 13501 } 13502 } else { 13503 // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13504 if (cond.IsNotNever() && 13505 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13506 EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 13507 rn.GetCode() | (rm.GetCode() << 8)); 13508 return; 13509 } 13510 } 13511 Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm); 13512 } 13513 13514 void Assembler::usada8( 13515 Condition cond, Register rd, Register rn, Register rm, Register ra) { 13516 VIXL_ASSERT(AllowAssembler()); 13517 CheckIT(cond); 13518 if (IsUsingT32()) { 13519 // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 13520 if (!ra.Is(pc) && 13521 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13522 EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13523 rm.GetCode() | (ra.GetCode() << 12)); 13524 AdvanceIT(); 13525 return; 13526 } 13527 } else { 13528 // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 13529 if (cond.IsNotNever() && !ra.Is(pc) && 13530 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13531 EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 13532 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 13533 return; 13534 } 13535 } 13536 Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra); 13537 } 13538 13539 void Assembler::usat(Condition cond, 13540 Register rd, 13541 uint32_t imm, 13542 const Operand& operand) { 13543 VIXL_ASSERT(AllowAssembler()); 13544 CheckIT(cond); 13545 if (operand.IsImmediateShiftedRegister()) { 13546 Register rn = operand.GetBaseRegister(); 13547 Shift shift = operand.GetShift(); 13548 uint32_t amount = operand.GetShiftAmount(); 13549 if (IsUsingT32()) { 13550 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1 13551 if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31) && 13552 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13553 EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm | 13554 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 13555 ((amount & 0x1c) << 10)); 13556 AdvanceIT(); 13557 return; 13558 } 13559 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1 13560 if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && 13561 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13562 EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm | 13563 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 13564 ((amount & 0x1c) << 10)); 13565 AdvanceIT(); 13566 return; 13567 } 13568 } else { 13569 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1 13570 if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) && 13571 cond.IsNotNever() && 13572 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13573 uint32_t amount_ = amount % 32; 13574 EmitA32(0x06e00050U | (cond.GetCondition() << 28) | 13575 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() | 13576 (amount_ << 7)); 13577 return; 13578 } 13579 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1 13580 if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever() && 13581 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13582 EmitA32(0x06e00010U | (cond.GetCondition() << 28) | 13583 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() | 13584 (amount << 7)); 13585 return; 13586 } 13587 } 13588 } 13589 Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand); 13590 } 13591 13592 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) { 13593 VIXL_ASSERT(AllowAssembler()); 13594 CheckIT(cond); 13595 if (IsUsingT32()) { 13596 // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1 13597 if ((imm <= 15) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13598 EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm | 13599 (rn.GetCode() << 16)); 13600 AdvanceIT(); 13601 return; 13602 } 13603 } else { 13604 // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1 13605 if ((imm <= 15) && cond.IsNotNever() && 13606 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13607 EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13608 (imm << 16) | rn.GetCode()); 13609 return; 13610 } 13611 } 13612 Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn); 13613 } 13614 13615 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) { 13616 VIXL_ASSERT(AllowAssembler()); 13617 CheckIT(cond); 13618 if (IsUsingT32()) { 13619 // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13620 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13621 EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13622 rm.GetCode()); 13623 AdvanceIT(); 13624 return; 13625 } 13626 } else { 13627 // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13628 if (cond.IsNotNever() && 13629 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13630 EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13631 (rn.GetCode() << 16) | rm.GetCode()); 13632 return; 13633 } 13634 } 13635 Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm); 13636 } 13637 13638 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) { 13639 VIXL_ASSERT(AllowAssembler()); 13640 CheckIT(cond); 13641 if (IsUsingT32()) { 13642 // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13643 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13644 EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13645 rm.GetCode()); 13646 AdvanceIT(); 13647 return; 13648 } 13649 } else { 13650 // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13651 if (cond.IsNotNever() && 13652 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13653 EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13654 (rn.GetCode() << 16) | rm.GetCode()); 13655 return; 13656 } 13657 } 13658 Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm); 13659 } 13660 13661 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) { 13662 VIXL_ASSERT(AllowAssembler()); 13663 CheckIT(cond); 13664 if (IsUsingT32()) { 13665 // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13666 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13667 EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13668 rm.GetCode()); 13669 AdvanceIT(); 13670 return; 13671 } 13672 } else { 13673 // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13674 if (cond.IsNotNever() && 13675 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13676 EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13677 (rn.GetCode() << 16) | rm.GetCode()); 13678 return; 13679 } 13680 } 13681 Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm); 13682 } 13683 13684 void Assembler::uxtab(Condition cond, 13685 Register rd, 13686 Register rn, 13687 const Operand& operand) { 13688 VIXL_ASSERT(AllowAssembler()); 13689 CheckIT(cond); 13690 if (operand.IsImmediateShiftedRegister()) { 13691 Register rm = operand.GetBaseRegister(); 13692 Shift shift = operand.GetShift(); 13693 uint32_t amount = operand.GetShiftAmount(); 13694 if (IsUsingT32()) { 13695 // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 13696 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13697 ((amount % 8) == 0) && !rn.Is(pc) && 13698 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13699 uint32_t amount_ = amount / 8; 13700 EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13701 rm.GetCode() | (amount_ << 4)); 13702 AdvanceIT(); 13703 return; 13704 } 13705 } else { 13706 // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 13707 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13708 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 13709 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13710 uint32_t amount_ = amount / 8; 13711 EmitA32(0x06e00070U | (cond.GetCondition() << 28) | 13712 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 13713 (amount_ << 10)); 13714 return; 13715 } 13716 } 13717 } 13718 Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand); 13719 } 13720 13721 void Assembler::uxtab16(Condition cond, 13722 Register rd, 13723 Register rn, 13724 const Operand& operand) { 13725 VIXL_ASSERT(AllowAssembler()); 13726 CheckIT(cond); 13727 if (operand.IsImmediateShiftedRegister()) { 13728 Register rm = operand.GetBaseRegister(); 13729 Shift shift = operand.GetShift(); 13730 uint32_t amount = operand.GetShiftAmount(); 13731 if (IsUsingT32()) { 13732 // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 13733 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13734 ((amount % 8) == 0) && !rn.Is(pc) && 13735 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13736 uint32_t amount_ = amount / 8; 13737 EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13738 rm.GetCode() | (amount_ << 4)); 13739 AdvanceIT(); 13740 return; 13741 } 13742 } else { 13743 // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 13744 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13745 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 13746 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13747 uint32_t amount_ = amount / 8; 13748 EmitA32(0x06c00070U | (cond.GetCondition() << 28) | 13749 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 13750 (amount_ << 10)); 13751 return; 13752 } 13753 } 13754 } 13755 Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand); 13756 } 13757 13758 void Assembler::uxtah(Condition cond, 13759 Register rd, 13760 Register rn, 13761 const Operand& operand) { 13762 VIXL_ASSERT(AllowAssembler()); 13763 CheckIT(cond); 13764 if (operand.IsImmediateShiftedRegister()) { 13765 Register rm = operand.GetBaseRegister(); 13766 Shift shift = operand.GetShift(); 13767 uint32_t amount = operand.GetShiftAmount(); 13768 if (IsUsingT32()) { 13769 // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 13770 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13771 ((amount % 8) == 0) && !rn.Is(pc) && 13772 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13773 uint32_t amount_ = amount / 8; 13774 EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13775 rm.GetCode() | (amount_ << 4)); 13776 AdvanceIT(); 13777 return; 13778 } 13779 } else { 13780 // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 13781 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13782 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 13783 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13784 uint32_t amount_ = amount / 8; 13785 EmitA32(0x06f00070U | (cond.GetCondition() << 28) | 13786 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 13787 (amount_ << 10)); 13788 return; 13789 } 13790 } 13791 } 13792 Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand); 13793 } 13794 13795 void Assembler::uxtb(Condition cond, 13796 EncodingSize size, 13797 Register rd, 13798 const Operand& operand) { 13799 VIXL_ASSERT(AllowAssembler()); 13800 CheckIT(cond); 13801 if (operand.IsImmediateShiftedRegister()) { 13802 Register rm = operand.GetBaseRegister(); 13803 if (operand.IsPlainRegister()) { 13804 if (IsUsingT32()) { 13805 // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1 13806 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 13807 EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3)); 13808 AdvanceIT(); 13809 return; 13810 } 13811 } 13812 } 13813 Shift shift = operand.GetShift(); 13814 uint32_t amount = operand.GetShiftAmount(); 13815 if (IsUsingT32()) { 13816 // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 13817 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 13818 (amount <= 24) && ((amount % 8) == 0) && 13819 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13820 uint32_t amount_ = amount / 8; 13821 EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() | 13822 (amount_ << 4)); 13823 AdvanceIT(); 13824 return; 13825 } 13826 } else { 13827 // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 13828 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13829 ((amount % 8) == 0) && cond.IsNotNever() && 13830 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13831 uint32_t amount_ = amount / 8; 13832 EmitA32(0x06ef0070U | (cond.GetCondition() << 28) | 13833 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 13834 return; 13835 } 13836 } 13837 } 13838 Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand); 13839 } 13840 13841 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) { 13842 VIXL_ASSERT(AllowAssembler()); 13843 CheckIT(cond); 13844 if (operand.IsImmediateShiftedRegister()) { 13845 Register rm = operand.GetBaseRegister(); 13846 Shift shift = operand.GetShift(); 13847 uint32_t amount = operand.GetShiftAmount(); 13848 if (IsUsingT32()) { 13849 // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1 13850 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13851 ((amount % 8) == 0) && 13852 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13853 uint32_t amount_ = amount / 8; 13854 EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() | 13855 (amount_ << 4)); 13856 AdvanceIT(); 13857 return; 13858 } 13859 } else { 13860 // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 13861 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13862 ((amount % 8) == 0) && cond.IsNotNever() && 13863 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13864 uint32_t amount_ = amount / 8; 13865 EmitA32(0x06cf0070U | (cond.GetCondition() << 28) | 13866 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 13867 return; 13868 } 13869 } 13870 } 13871 Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand); 13872 } 13873 13874 void Assembler::uxth(Condition cond, 13875 EncodingSize size, 13876 Register rd, 13877 const Operand& operand) { 13878 VIXL_ASSERT(AllowAssembler()); 13879 CheckIT(cond); 13880 if (operand.IsImmediateShiftedRegister()) { 13881 Register rm = operand.GetBaseRegister(); 13882 if (operand.IsPlainRegister()) { 13883 if (IsUsingT32()) { 13884 // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1 13885 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 13886 EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3)); 13887 AdvanceIT(); 13888 return; 13889 } 13890 } 13891 } 13892 Shift shift = operand.GetShift(); 13893 uint32_t amount = operand.GetShiftAmount(); 13894 if (IsUsingT32()) { 13895 // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 13896 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 13897 (amount <= 24) && ((amount % 8) == 0) && 13898 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13899 uint32_t amount_ = amount / 8; 13900 EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() | 13901 (amount_ << 4)); 13902 AdvanceIT(); 13903 return; 13904 } 13905 } else { 13906 // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 13907 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13908 ((amount % 8) == 0) && cond.IsNotNever() && 13909 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13910 uint32_t amount_ = amount / 8; 13911 EmitA32(0x06ff0070U | (cond.GetCondition() << 28) | 13912 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 13913 return; 13914 } 13915 } 13916 } 13917 Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand); 13918 } 13919 13920 void Assembler::vaba( 13921 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13922 VIXL_ASSERT(AllowAssembler()); 13923 CheckIT(cond); 13924 Dt_U_size_1 encoded_dt(dt); 13925 if (IsUsingT32()) { 13926 // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1 13927 if (encoded_dt.IsValid()) { 13928 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13929 EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13930 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13931 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13932 AdvanceIT(); 13933 return; 13934 } 13935 } 13936 } else { 13937 // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1 13938 if (encoded_dt.IsValid()) { 13939 if (cond.Is(al)) { 13940 EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13941 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 13942 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13943 return; 13944 } 13945 } 13946 } 13947 Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm); 13948 } 13949 13950 void Assembler::vaba( 13951 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13952 VIXL_ASSERT(AllowAssembler()); 13953 CheckIT(cond); 13954 Dt_U_size_1 encoded_dt(dt); 13955 if (IsUsingT32()) { 13956 // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1 13957 if (encoded_dt.IsValid()) { 13958 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13959 EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13960 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13961 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13962 AdvanceIT(); 13963 return; 13964 } 13965 } 13966 } else { 13967 // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1 13968 if (encoded_dt.IsValid()) { 13969 if (cond.Is(al)) { 13970 EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13971 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 13972 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13973 return; 13974 } 13975 } 13976 } 13977 Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm); 13978 } 13979 13980 void Assembler::vabal( 13981 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 13982 VIXL_ASSERT(AllowAssembler()); 13983 CheckIT(cond); 13984 Dt_U_size_1 encoded_dt(dt); 13985 if (IsUsingT32()) { 13986 // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 13987 if (encoded_dt.IsValid()) { 13988 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13989 EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13990 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13991 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13992 AdvanceIT(); 13993 return; 13994 } 13995 } 13996 } else { 13997 // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 13998 if (encoded_dt.IsValid()) { 13999 if (cond.Is(al)) { 14000 EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14001 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14002 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14003 return; 14004 } 14005 } 14006 } 14007 Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm); 14008 } 14009 14010 void Assembler::vabd( 14011 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14012 VIXL_ASSERT(AllowAssembler()); 14013 CheckIT(cond); 14014 Dt_U_size_1 encoded_dt(dt); 14015 if (IsUsingT32()) { 14016 // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14017 if (dt.Is(F32)) { 14018 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14019 EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14020 rm.Encode(5, 0)); 14021 AdvanceIT(); 14022 return; 14023 } 14024 } 14025 // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 14026 if (encoded_dt.IsValid()) { 14027 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14028 EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14029 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14030 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14031 AdvanceIT(); 14032 return; 14033 } 14034 } 14035 } else { 14036 // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14037 if (dt.Is(F32)) { 14038 if (cond.Is(al)) { 14039 EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14040 rm.Encode(5, 0)); 14041 return; 14042 } 14043 } 14044 // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 14045 if (encoded_dt.IsValid()) { 14046 if (cond.Is(al)) { 14047 EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14048 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14049 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14050 return; 14051 } 14052 } 14053 } 14054 Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm); 14055 } 14056 14057 void Assembler::vabd( 14058 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14059 VIXL_ASSERT(AllowAssembler()); 14060 CheckIT(cond); 14061 Dt_U_size_1 encoded_dt(dt); 14062 if (IsUsingT32()) { 14063 // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14064 if (dt.Is(F32)) { 14065 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14066 EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14067 rm.Encode(5, 0)); 14068 AdvanceIT(); 14069 return; 14070 } 14071 } 14072 // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 14073 if (encoded_dt.IsValid()) { 14074 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14075 EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14076 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14077 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14078 AdvanceIT(); 14079 return; 14080 } 14081 } 14082 } else { 14083 // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14084 if (dt.Is(F32)) { 14085 if (cond.Is(al)) { 14086 EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14087 rm.Encode(5, 0)); 14088 return; 14089 } 14090 } 14091 // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14092 if (encoded_dt.IsValid()) { 14093 if (cond.Is(al)) { 14094 EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14095 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14096 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14097 return; 14098 } 14099 } 14100 } 14101 Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm); 14102 } 14103 14104 void Assembler::vabdl( 14105 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 14106 VIXL_ASSERT(AllowAssembler()); 14107 CheckIT(cond); 14108 Dt_U_size_1 encoded_dt(dt); 14109 if (IsUsingT32()) { 14110 // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 14111 if (encoded_dt.IsValid()) { 14112 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14113 EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14114 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14115 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14116 AdvanceIT(); 14117 return; 14118 } 14119 } 14120 } else { 14121 // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 14122 if (encoded_dt.IsValid()) { 14123 if (cond.Is(al)) { 14124 EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14125 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14126 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14127 return; 14128 } 14129 } 14130 } 14131 Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm); 14132 } 14133 14134 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) { 14135 VIXL_ASSERT(AllowAssembler()); 14136 CheckIT(cond); 14137 Dt_F_size_1 encoded_dt(dt); 14138 if (IsUsingT32()) { 14139 // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 14140 if (encoded_dt.IsValid()) { 14141 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14142 EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14143 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14144 rd.Encode(22, 12) | rm.Encode(5, 0)); 14145 AdvanceIT(); 14146 return; 14147 } 14148 } 14149 // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 14150 if (dt.Is(F64)) { 14151 EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14152 AdvanceIT(); 14153 return; 14154 } 14155 } else { 14156 // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 14157 if (encoded_dt.IsValid()) { 14158 if (cond.Is(al)) { 14159 EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14160 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14161 rd.Encode(22, 12) | rm.Encode(5, 0)); 14162 return; 14163 } 14164 } 14165 // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 14166 if (dt.Is(F64) && cond.IsNotNever()) { 14167 EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14168 rm.Encode(5, 0)); 14169 return; 14170 } 14171 } 14172 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 14173 } 14174 14175 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) { 14176 VIXL_ASSERT(AllowAssembler()); 14177 CheckIT(cond); 14178 Dt_F_size_1 encoded_dt(dt); 14179 if (IsUsingT32()) { 14180 // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 14181 if (encoded_dt.IsValid()) { 14182 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14183 EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14184 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14185 rd.Encode(22, 12) | rm.Encode(5, 0)); 14186 AdvanceIT(); 14187 return; 14188 } 14189 } 14190 } else { 14191 // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 14192 if (encoded_dt.IsValid()) { 14193 if (cond.Is(al)) { 14194 EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14195 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14196 rd.Encode(22, 12) | rm.Encode(5, 0)); 14197 return; 14198 } 14199 } 14200 } 14201 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 14202 } 14203 14204 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) { 14205 VIXL_ASSERT(AllowAssembler()); 14206 CheckIT(cond); 14207 if (IsUsingT32()) { 14208 // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 14209 if (dt.Is(F32)) { 14210 EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14211 AdvanceIT(); 14212 return; 14213 } 14214 } else { 14215 // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 14216 if (dt.Is(F32) && cond.IsNotNever()) { 14217 EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14218 rm.Encode(5, 0)); 14219 return; 14220 } 14221 } 14222 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 14223 } 14224 14225 void Assembler::vacge( 14226 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14227 VIXL_ASSERT(AllowAssembler()); 14228 CheckIT(cond); 14229 if (IsUsingT32()) { 14230 // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14231 if (dt.Is(F32)) { 14232 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14233 EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14234 rm.Encode(5, 0)); 14235 AdvanceIT(); 14236 return; 14237 } 14238 } 14239 } else { 14240 // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14241 if (dt.Is(F32)) { 14242 if (cond.Is(al)) { 14243 EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14244 rm.Encode(5, 0)); 14245 return; 14246 } 14247 } 14248 } 14249 Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm); 14250 } 14251 14252 void Assembler::vacge( 14253 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14254 VIXL_ASSERT(AllowAssembler()); 14255 CheckIT(cond); 14256 if (IsUsingT32()) { 14257 // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14258 if (dt.Is(F32)) { 14259 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14260 EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14261 rm.Encode(5, 0)); 14262 AdvanceIT(); 14263 return; 14264 } 14265 } 14266 } else { 14267 // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14268 if (dt.Is(F32)) { 14269 if (cond.Is(al)) { 14270 EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14271 rm.Encode(5, 0)); 14272 return; 14273 } 14274 } 14275 } 14276 Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm); 14277 } 14278 14279 void Assembler::vacgt( 14280 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14281 VIXL_ASSERT(AllowAssembler()); 14282 CheckIT(cond); 14283 if (IsUsingT32()) { 14284 // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14285 if (dt.Is(F32)) { 14286 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14287 EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14288 rm.Encode(5, 0)); 14289 AdvanceIT(); 14290 return; 14291 } 14292 } 14293 } else { 14294 // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14295 if (dt.Is(F32)) { 14296 if (cond.Is(al)) { 14297 EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14298 rm.Encode(5, 0)); 14299 return; 14300 } 14301 } 14302 } 14303 Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm); 14304 } 14305 14306 void Assembler::vacgt( 14307 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14308 VIXL_ASSERT(AllowAssembler()); 14309 CheckIT(cond); 14310 if (IsUsingT32()) { 14311 // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14312 if (dt.Is(F32)) { 14313 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14314 EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14315 rm.Encode(5, 0)); 14316 AdvanceIT(); 14317 return; 14318 } 14319 } 14320 } else { 14321 // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14322 if (dt.Is(F32)) { 14323 if (cond.Is(al)) { 14324 EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14325 rm.Encode(5, 0)); 14326 return; 14327 } 14328 } 14329 } 14330 Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm); 14331 } 14332 14333 void Assembler::vacle( 14334 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14335 VIXL_ASSERT(AllowAssembler()); 14336 CheckIT(cond); 14337 if (IsUsingT32()) { 14338 // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14339 if (dt.Is(F32)) { 14340 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14341 EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14342 rm.Encode(5, 0)); 14343 AdvanceIT(); 14344 return; 14345 } 14346 } 14347 } else { 14348 // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14349 if (dt.Is(F32)) { 14350 if (cond.Is(al)) { 14351 EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14352 rm.Encode(5, 0)); 14353 return; 14354 } 14355 } 14356 } 14357 Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm); 14358 } 14359 14360 void Assembler::vacle( 14361 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14362 VIXL_ASSERT(AllowAssembler()); 14363 CheckIT(cond); 14364 if (IsUsingT32()) { 14365 // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14366 if (dt.Is(F32)) { 14367 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14368 EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14369 rm.Encode(5, 0)); 14370 AdvanceIT(); 14371 return; 14372 } 14373 } 14374 } else { 14375 // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14376 if (dt.Is(F32)) { 14377 if (cond.Is(al)) { 14378 EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14379 rm.Encode(5, 0)); 14380 return; 14381 } 14382 } 14383 } 14384 Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm); 14385 } 14386 14387 void Assembler::vaclt( 14388 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14389 VIXL_ASSERT(AllowAssembler()); 14390 CheckIT(cond); 14391 if (IsUsingT32()) { 14392 // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14393 if (dt.Is(F32)) { 14394 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14395 EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14396 rm.Encode(5, 0)); 14397 AdvanceIT(); 14398 return; 14399 } 14400 } 14401 } else { 14402 // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14403 if (dt.Is(F32)) { 14404 if (cond.Is(al)) { 14405 EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14406 rm.Encode(5, 0)); 14407 return; 14408 } 14409 } 14410 } 14411 Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm); 14412 } 14413 14414 void Assembler::vaclt( 14415 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14416 VIXL_ASSERT(AllowAssembler()); 14417 CheckIT(cond); 14418 if (IsUsingT32()) { 14419 // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14420 if (dt.Is(F32)) { 14421 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14422 EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14423 rm.Encode(5, 0)); 14424 AdvanceIT(); 14425 return; 14426 } 14427 } 14428 } else { 14429 // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14430 if (dt.Is(F32)) { 14431 if (cond.Is(al)) { 14432 EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14433 rm.Encode(5, 0)); 14434 return; 14435 } 14436 } 14437 } 14438 Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm); 14439 } 14440 14441 void Assembler::vadd( 14442 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14443 VIXL_ASSERT(AllowAssembler()); 14444 CheckIT(cond); 14445 Dt_size_2 encoded_dt(dt); 14446 if (IsUsingT32()) { 14447 // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14448 if (dt.Is(F32)) { 14449 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14450 EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14451 rm.Encode(5, 0)); 14452 AdvanceIT(); 14453 return; 14454 } 14455 } 14456 // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 14457 if (dt.Is(F64)) { 14458 EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14459 rm.Encode(5, 0)); 14460 AdvanceIT(); 14461 return; 14462 } 14463 // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 14464 if (encoded_dt.IsValid()) { 14465 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14466 EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) | 14467 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14468 AdvanceIT(); 14469 return; 14470 } 14471 } 14472 } else { 14473 // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14474 if (dt.Is(F32)) { 14475 if (cond.Is(al)) { 14476 EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14477 rm.Encode(5, 0)); 14478 return; 14479 } 14480 } 14481 // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 14482 if (dt.Is(F64) && cond.IsNotNever()) { 14483 EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14484 rn.Encode(7, 16) | rm.Encode(5, 0)); 14485 return; 14486 } 14487 // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 14488 if (encoded_dt.IsValid()) { 14489 if (cond.Is(al)) { 14490 EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) | 14491 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14492 return; 14493 } 14494 } 14495 } 14496 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 14497 } 14498 14499 void Assembler::vadd( 14500 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14501 VIXL_ASSERT(AllowAssembler()); 14502 CheckIT(cond); 14503 Dt_size_2 encoded_dt(dt); 14504 if (IsUsingT32()) { 14505 // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14506 if (dt.Is(F32)) { 14507 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14508 EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14509 rm.Encode(5, 0)); 14510 AdvanceIT(); 14511 return; 14512 } 14513 } 14514 // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 14515 if (encoded_dt.IsValid()) { 14516 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14517 EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) | 14518 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14519 AdvanceIT(); 14520 return; 14521 } 14522 } 14523 } else { 14524 // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14525 if (dt.Is(F32)) { 14526 if (cond.Is(al)) { 14527 EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14528 rm.Encode(5, 0)); 14529 return; 14530 } 14531 } 14532 // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14533 if (encoded_dt.IsValid()) { 14534 if (cond.Is(al)) { 14535 EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) | 14536 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14537 return; 14538 } 14539 } 14540 } 14541 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 14542 } 14543 14544 void Assembler::vadd( 14545 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 14546 VIXL_ASSERT(AllowAssembler()); 14547 CheckIT(cond); 14548 if (IsUsingT32()) { 14549 // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 14550 if (dt.Is(F32)) { 14551 EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14552 rm.Encode(5, 0)); 14553 AdvanceIT(); 14554 return; 14555 } 14556 } else { 14557 // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 14558 if (dt.Is(F32) && cond.IsNotNever()) { 14559 EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14560 rn.Encode(7, 16) | rm.Encode(5, 0)); 14561 return; 14562 } 14563 } 14564 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 14565 } 14566 14567 void Assembler::vaddhn( 14568 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 14569 VIXL_ASSERT(AllowAssembler()); 14570 CheckIT(cond); 14571 Dt_size_3 encoded_dt(dt); 14572 if (IsUsingT32()) { 14573 // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 14574 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 14575 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14576 EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) | 14577 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14578 AdvanceIT(); 14579 return; 14580 } 14581 } 14582 } else { 14583 // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 14584 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 14585 if (cond.Is(al)) { 14586 EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) | 14587 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14588 return; 14589 } 14590 } 14591 } 14592 Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm); 14593 } 14594 14595 void Assembler::vaddl( 14596 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 14597 VIXL_ASSERT(AllowAssembler()); 14598 CheckIT(cond); 14599 Dt_U_size_1 encoded_dt(dt); 14600 if (IsUsingT32()) { 14601 // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 14602 if (encoded_dt.IsValid()) { 14603 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14604 EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14605 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14606 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14607 AdvanceIT(); 14608 return; 14609 } 14610 } 14611 } else { 14612 // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 14613 if (encoded_dt.IsValid()) { 14614 if (cond.Is(al)) { 14615 EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14616 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14617 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14618 return; 14619 } 14620 } 14621 } 14622 Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm); 14623 } 14624 14625 void Assembler::vaddw( 14626 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) { 14627 VIXL_ASSERT(AllowAssembler()); 14628 CheckIT(cond); 14629 Dt_U_size_1 encoded_dt(dt); 14630 if (IsUsingT32()) { 14631 // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1 14632 if (encoded_dt.IsValid()) { 14633 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14634 EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14635 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14636 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14637 AdvanceIT(); 14638 return; 14639 } 14640 } 14641 } else { 14642 // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1 14643 if (encoded_dt.IsValid()) { 14644 if (cond.Is(al)) { 14645 EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14646 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14647 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14648 return; 14649 } 14650 } 14651 } 14652 Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm); 14653 } 14654 14655 void Assembler::vand(Condition cond, 14656 DataType dt, 14657 DRegister rd, 14658 DRegister rn, 14659 const DOperand& operand) { 14660 VIXL_ASSERT(AllowAssembler()); 14661 CheckIT(cond); 14662 if (operand.IsImmediate()) { 14663 ImmediateVand encoded_dt(dt, operand.GetNeonImmediate()); 14664 if (IsUsingT32()) { 14665 // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 14666 if (encoded_dt.IsValid() && rd.Is(rn)) { 14667 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14668 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 14669 rd.Encode(22, 12) | 14670 (encoded_dt.GetEncodedImmediate() & 0xf) | 14671 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14672 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 14673 AdvanceIT(); 14674 return; 14675 } 14676 } 14677 } else { 14678 // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 14679 if (encoded_dt.IsValid() && rd.Is(rn)) { 14680 if (cond.Is(al)) { 14681 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 14682 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 14683 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14684 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 14685 return; 14686 } 14687 } 14688 } 14689 } 14690 if (operand.IsRegister()) { 14691 DRegister rm = operand.GetRegister(); 14692 USE(dt); 14693 if (IsUsingT32()) { 14694 // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14695 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14696 EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14697 rm.Encode(5, 0)); 14698 AdvanceIT(); 14699 return; 14700 } 14701 } else { 14702 // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14703 if (cond.Is(al)) { 14704 EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14705 rm.Encode(5, 0)); 14706 return; 14707 } 14708 } 14709 } 14710 Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand); 14711 } 14712 14713 void Assembler::vand(Condition cond, 14714 DataType dt, 14715 QRegister rd, 14716 QRegister rn, 14717 const QOperand& operand) { 14718 VIXL_ASSERT(AllowAssembler()); 14719 CheckIT(cond); 14720 if (operand.IsImmediate()) { 14721 ImmediateVand encoded_dt(dt, operand.GetNeonImmediate()); 14722 if (IsUsingT32()) { 14723 // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 14724 if (encoded_dt.IsValid() && rd.Is(rn)) { 14725 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14726 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 14727 rd.Encode(22, 12) | 14728 (encoded_dt.GetEncodedImmediate() & 0xf) | 14729 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14730 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 14731 AdvanceIT(); 14732 return; 14733 } 14734 } 14735 } else { 14736 // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 14737 if (encoded_dt.IsValid() && rd.Is(rn)) { 14738 if (cond.Is(al)) { 14739 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 14740 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 14741 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14742 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 14743 return; 14744 } 14745 } 14746 } 14747 } 14748 if (operand.IsRegister()) { 14749 QRegister rm = operand.GetRegister(); 14750 USE(dt); 14751 if (IsUsingT32()) { 14752 // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14753 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14754 EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14755 rm.Encode(5, 0)); 14756 AdvanceIT(); 14757 return; 14758 } 14759 } else { 14760 // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14761 if (cond.Is(al)) { 14762 EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14763 rm.Encode(5, 0)); 14764 return; 14765 } 14766 } 14767 } 14768 Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand); 14769 } 14770 14771 void Assembler::vbic(Condition cond, 14772 DataType dt, 14773 DRegister rd, 14774 DRegister rn, 14775 const DOperand& operand) { 14776 VIXL_ASSERT(AllowAssembler()); 14777 CheckIT(cond); 14778 if (operand.IsImmediate()) { 14779 ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate()); 14780 if (IsUsingT32()) { 14781 // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 14782 if (encoded_dt.IsValid() && rd.Is(rn)) { 14783 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14784 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 14785 rd.Encode(22, 12) | 14786 (encoded_dt.GetEncodedImmediate() & 0xf) | 14787 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14788 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 14789 AdvanceIT(); 14790 return; 14791 } 14792 } 14793 } else { 14794 // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 14795 if (encoded_dt.IsValid() && rd.Is(rn)) { 14796 if (cond.Is(al)) { 14797 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 14798 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 14799 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14800 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 14801 return; 14802 } 14803 } 14804 } 14805 } 14806 if (operand.IsRegister()) { 14807 DRegister rm = operand.GetRegister(); 14808 USE(dt); 14809 if (IsUsingT32()) { 14810 // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14811 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14812 EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14813 rm.Encode(5, 0)); 14814 AdvanceIT(); 14815 return; 14816 } 14817 } else { 14818 // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14819 if (cond.Is(al)) { 14820 EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14821 rm.Encode(5, 0)); 14822 return; 14823 } 14824 } 14825 } 14826 Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand); 14827 } 14828 14829 void Assembler::vbic(Condition cond, 14830 DataType dt, 14831 QRegister rd, 14832 QRegister rn, 14833 const QOperand& operand) { 14834 VIXL_ASSERT(AllowAssembler()); 14835 CheckIT(cond); 14836 if (operand.IsImmediate()) { 14837 ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate()); 14838 if (IsUsingT32()) { 14839 // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 14840 if (encoded_dt.IsValid() && rd.Is(rn)) { 14841 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14842 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 14843 rd.Encode(22, 12) | 14844 (encoded_dt.GetEncodedImmediate() & 0xf) | 14845 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14846 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 14847 AdvanceIT(); 14848 return; 14849 } 14850 } 14851 } else { 14852 // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 14853 if (encoded_dt.IsValid() && rd.Is(rn)) { 14854 if (cond.Is(al)) { 14855 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 14856 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 14857 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14858 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 14859 return; 14860 } 14861 } 14862 } 14863 } 14864 if (operand.IsRegister()) { 14865 QRegister rm = operand.GetRegister(); 14866 USE(dt); 14867 if (IsUsingT32()) { 14868 // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14869 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14870 EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14871 rm.Encode(5, 0)); 14872 AdvanceIT(); 14873 return; 14874 } 14875 } else { 14876 // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14877 if (cond.Is(al)) { 14878 EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14879 rm.Encode(5, 0)); 14880 return; 14881 } 14882 } 14883 } 14884 Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand); 14885 } 14886 14887 void Assembler::vbif( 14888 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14889 VIXL_ASSERT(AllowAssembler()); 14890 CheckIT(cond); 14891 USE(dt); 14892 if (IsUsingT32()) { 14893 // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14894 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14895 EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14896 rm.Encode(5, 0)); 14897 AdvanceIT(); 14898 return; 14899 } 14900 } else { 14901 // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14902 if (cond.Is(al)) { 14903 EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14904 rm.Encode(5, 0)); 14905 return; 14906 } 14907 } 14908 Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm); 14909 } 14910 14911 void Assembler::vbif( 14912 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14913 VIXL_ASSERT(AllowAssembler()); 14914 CheckIT(cond); 14915 USE(dt); 14916 if (IsUsingT32()) { 14917 // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14918 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14919 EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14920 rm.Encode(5, 0)); 14921 AdvanceIT(); 14922 return; 14923 } 14924 } else { 14925 // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14926 if (cond.Is(al)) { 14927 EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14928 rm.Encode(5, 0)); 14929 return; 14930 } 14931 } 14932 Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm); 14933 } 14934 14935 void Assembler::vbit( 14936 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14937 VIXL_ASSERT(AllowAssembler()); 14938 CheckIT(cond); 14939 USE(dt); 14940 if (IsUsingT32()) { 14941 // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14942 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14943 EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14944 rm.Encode(5, 0)); 14945 AdvanceIT(); 14946 return; 14947 } 14948 } else { 14949 // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14950 if (cond.Is(al)) { 14951 EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14952 rm.Encode(5, 0)); 14953 return; 14954 } 14955 } 14956 Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm); 14957 } 14958 14959 void Assembler::vbit( 14960 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14961 VIXL_ASSERT(AllowAssembler()); 14962 CheckIT(cond); 14963 USE(dt); 14964 if (IsUsingT32()) { 14965 // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14966 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14967 EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14968 rm.Encode(5, 0)); 14969 AdvanceIT(); 14970 return; 14971 } 14972 } else { 14973 // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14974 if (cond.Is(al)) { 14975 EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14976 rm.Encode(5, 0)); 14977 return; 14978 } 14979 } 14980 Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm); 14981 } 14982 14983 void Assembler::vbsl( 14984 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14985 VIXL_ASSERT(AllowAssembler()); 14986 CheckIT(cond); 14987 USE(dt); 14988 if (IsUsingT32()) { 14989 // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14990 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14991 EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14992 rm.Encode(5, 0)); 14993 AdvanceIT(); 14994 return; 14995 } 14996 } else { 14997 // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14998 if (cond.Is(al)) { 14999 EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15000 rm.Encode(5, 0)); 15001 return; 15002 } 15003 } 15004 Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm); 15005 } 15006 15007 void Assembler::vbsl( 15008 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15009 VIXL_ASSERT(AllowAssembler()); 15010 CheckIT(cond); 15011 USE(dt); 15012 if (IsUsingT32()) { 15013 // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 15014 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15015 EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15016 rm.Encode(5, 0)); 15017 AdvanceIT(); 15018 return; 15019 } 15020 } else { 15021 // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 15022 if (cond.Is(al)) { 15023 EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15024 rm.Encode(5, 0)); 15025 return; 15026 } 15027 } 15028 Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm); 15029 } 15030 15031 void Assembler::vceq(Condition cond, 15032 DataType dt, 15033 DRegister rd, 15034 DRegister rm, 15035 const DOperand& operand) { 15036 VIXL_ASSERT(AllowAssembler()); 15037 CheckIT(cond); 15038 if (operand.IsImmediate()) { 15039 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15040 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15041 Dt_F_size_2 encoded_dt(dt); 15042 if (IsUsingT32()) { 15043 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15044 if (encoded_dt.IsValid() && (imm == 0)) { 15045 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15046 EmitT32_32(0xffb10100U | 15047 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15048 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15049 rd.Encode(22, 12) | rm.Encode(5, 0)); 15050 AdvanceIT(); 15051 return; 15052 } 15053 } 15054 } else { 15055 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15056 if (encoded_dt.IsValid() && (imm == 0)) { 15057 if (cond.Is(al)) { 15058 EmitA32(0xf3b10100U | 15059 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15060 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15061 rd.Encode(22, 12) | rm.Encode(5, 0)); 15062 return; 15063 } 15064 } 15065 } 15066 } 15067 } 15068 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand); 15069 } 15070 15071 void Assembler::vceq(Condition cond, 15072 DataType dt, 15073 QRegister rd, 15074 QRegister rm, 15075 const QOperand& operand) { 15076 VIXL_ASSERT(AllowAssembler()); 15077 CheckIT(cond); 15078 if (operand.IsImmediate()) { 15079 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15080 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15081 Dt_F_size_2 encoded_dt(dt); 15082 if (IsUsingT32()) { 15083 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15084 if (encoded_dt.IsValid() && (imm == 0)) { 15085 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15086 EmitT32_32(0xffb10140U | 15087 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15088 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15089 rd.Encode(22, 12) | rm.Encode(5, 0)); 15090 AdvanceIT(); 15091 return; 15092 } 15093 } 15094 } else { 15095 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15096 if (encoded_dt.IsValid() && (imm == 0)) { 15097 if (cond.Is(al)) { 15098 EmitA32(0xf3b10140U | 15099 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15100 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15101 rd.Encode(22, 12) | rm.Encode(5, 0)); 15102 return; 15103 } 15104 } 15105 } 15106 } 15107 } 15108 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand); 15109 } 15110 15111 void Assembler::vceq( 15112 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15113 VIXL_ASSERT(AllowAssembler()); 15114 CheckIT(cond); 15115 Dt_size_4 encoded_dt(dt); 15116 Dt_sz_1 encoded_dt_2(dt); 15117 if (IsUsingT32()) { 15118 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15119 if (encoded_dt.IsValid()) { 15120 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15121 EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) | 15122 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15123 AdvanceIT(); 15124 return; 15125 } 15126 } 15127 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2 15128 if (encoded_dt_2.IsValid()) { 15129 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15130 EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) | 15131 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15132 AdvanceIT(); 15133 return; 15134 } 15135 } 15136 } else { 15137 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15138 if (encoded_dt.IsValid()) { 15139 if (cond.Is(al)) { 15140 EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) | 15141 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15142 return; 15143 } 15144 } 15145 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2 15146 if (encoded_dt_2.IsValid()) { 15147 if (cond.Is(al)) { 15148 EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) | 15149 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15150 return; 15151 } 15152 } 15153 } 15154 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm); 15155 } 15156 15157 void Assembler::vceq( 15158 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15159 VIXL_ASSERT(AllowAssembler()); 15160 CheckIT(cond); 15161 Dt_size_4 encoded_dt(dt); 15162 Dt_sz_1 encoded_dt_2(dt); 15163 if (IsUsingT32()) { 15164 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15165 if (encoded_dt.IsValid()) { 15166 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15167 EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) | 15168 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15169 AdvanceIT(); 15170 return; 15171 } 15172 } 15173 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2 15174 if (encoded_dt_2.IsValid()) { 15175 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15176 EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) | 15177 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15178 AdvanceIT(); 15179 return; 15180 } 15181 } 15182 } else { 15183 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15184 if (encoded_dt.IsValid()) { 15185 if (cond.Is(al)) { 15186 EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) | 15187 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15188 return; 15189 } 15190 } 15191 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2 15192 if (encoded_dt_2.IsValid()) { 15193 if (cond.Is(al)) { 15194 EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) | 15195 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15196 return; 15197 } 15198 } 15199 } 15200 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm); 15201 } 15202 15203 void Assembler::vcge(Condition cond, 15204 DataType dt, 15205 DRegister rd, 15206 DRegister rm, 15207 const DOperand& operand) { 15208 VIXL_ASSERT(AllowAssembler()); 15209 CheckIT(cond); 15210 if (operand.IsImmediate()) { 15211 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15212 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15213 Dt_F_size_1 encoded_dt(dt); 15214 if (IsUsingT32()) { 15215 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15216 if (encoded_dt.IsValid() && (imm == 0)) { 15217 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15218 EmitT32_32(0xffb10080U | 15219 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15220 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15221 rd.Encode(22, 12) | rm.Encode(5, 0)); 15222 AdvanceIT(); 15223 return; 15224 } 15225 } 15226 } else { 15227 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15228 if (encoded_dt.IsValid() && (imm == 0)) { 15229 if (cond.Is(al)) { 15230 EmitA32(0xf3b10080U | 15231 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15232 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15233 rd.Encode(22, 12) | rm.Encode(5, 0)); 15234 return; 15235 } 15236 } 15237 } 15238 } 15239 } 15240 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand); 15241 } 15242 15243 void Assembler::vcge(Condition cond, 15244 DataType dt, 15245 QRegister rd, 15246 QRegister rm, 15247 const QOperand& operand) { 15248 VIXL_ASSERT(AllowAssembler()); 15249 CheckIT(cond); 15250 if (operand.IsImmediate()) { 15251 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15252 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15253 Dt_F_size_1 encoded_dt(dt); 15254 if (IsUsingT32()) { 15255 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15256 if (encoded_dt.IsValid() && (imm == 0)) { 15257 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15258 EmitT32_32(0xffb100c0U | 15259 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15260 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15261 rd.Encode(22, 12) | rm.Encode(5, 0)); 15262 AdvanceIT(); 15263 return; 15264 } 15265 } 15266 } else { 15267 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15268 if (encoded_dt.IsValid() && (imm == 0)) { 15269 if (cond.Is(al)) { 15270 EmitA32(0xf3b100c0U | 15271 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15272 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15273 rd.Encode(22, 12) | rm.Encode(5, 0)); 15274 return; 15275 } 15276 } 15277 } 15278 } 15279 } 15280 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand); 15281 } 15282 15283 void Assembler::vcge( 15284 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15285 VIXL_ASSERT(AllowAssembler()); 15286 CheckIT(cond); 15287 Dt_U_size_1 encoded_dt(dt); 15288 if (IsUsingT32()) { 15289 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15290 if (encoded_dt.IsValid()) { 15291 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15292 EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15293 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15294 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15295 AdvanceIT(); 15296 return; 15297 } 15298 } 15299 // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 15300 if (dt.Is(F32)) { 15301 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15302 EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15303 rm.Encode(5, 0)); 15304 AdvanceIT(); 15305 return; 15306 } 15307 } 15308 } else { 15309 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15310 if (encoded_dt.IsValid()) { 15311 if (cond.Is(al)) { 15312 EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15313 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15314 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15315 return; 15316 } 15317 } 15318 // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 15319 if (dt.Is(F32)) { 15320 if (cond.Is(al)) { 15321 EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15322 rm.Encode(5, 0)); 15323 return; 15324 } 15325 } 15326 } 15327 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm); 15328 } 15329 15330 void Assembler::vcge( 15331 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15332 VIXL_ASSERT(AllowAssembler()); 15333 CheckIT(cond); 15334 Dt_U_size_1 encoded_dt(dt); 15335 if (IsUsingT32()) { 15336 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15337 if (encoded_dt.IsValid()) { 15338 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15339 EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15340 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15341 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15342 AdvanceIT(); 15343 return; 15344 } 15345 } 15346 // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 15347 if (dt.Is(F32)) { 15348 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15349 EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15350 rm.Encode(5, 0)); 15351 AdvanceIT(); 15352 return; 15353 } 15354 } 15355 } else { 15356 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15357 if (encoded_dt.IsValid()) { 15358 if (cond.Is(al)) { 15359 EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15360 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15361 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15362 return; 15363 } 15364 } 15365 // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 15366 if (dt.Is(F32)) { 15367 if (cond.Is(al)) { 15368 EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15369 rm.Encode(5, 0)); 15370 return; 15371 } 15372 } 15373 } 15374 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm); 15375 } 15376 15377 void Assembler::vcgt(Condition cond, 15378 DataType dt, 15379 DRegister rd, 15380 DRegister rm, 15381 const DOperand& operand) { 15382 VIXL_ASSERT(AllowAssembler()); 15383 CheckIT(cond); 15384 if (operand.IsImmediate()) { 15385 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15386 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15387 Dt_F_size_1 encoded_dt(dt); 15388 if (IsUsingT32()) { 15389 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15390 if (encoded_dt.IsValid() && (imm == 0)) { 15391 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15392 EmitT32_32(0xffb10000U | 15393 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15394 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15395 rd.Encode(22, 12) | rm.Encode(5, 0)); 15396 AdvanceIT(); 15397 return; 15398 } 15399 } 15400 } else { 15401 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15402 if (encoded_dt.IsValid() && (imm == 0)) { 15403 if (cond.Is(al)) { 15404 EmitA32(0xf3b10000U | 15405 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15406 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15407 rd.Encode(22, 12) | rm.Encode(5, 0)); 15408 return; 15409 } 15410 } 15411 } 15412 } 15413 } 15414 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand); 15415 } 15416 15417 void Assembler::vcgt(Condition cond, 15418 DataType dt, 15419 QRegister rd, 15420 QRegister rm, 15421 const QOperand& operand) { 15422 VIXL_ASSERT(AllowAssembler()); 15423 CheckIT(cond); 15424 if (operand.IsImmediate()) { 15425 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15426 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15427 Dt_F_size_1 encoded_dt(dt); 15428 if (IsUsingT32()) { 15429 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15430 if (encoded_dt.IsValid() && (imm == 0)) { 15431 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15432 EmitT32_32(0xffb10040U | 15433 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15434 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15435 rd.Encode(22, 12) | rm.Encode(5, 0)); 15436 AdvanceIT(); 15437 return; 15438 } 15439 } 15440 } else { 15441 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15442 if (encoded_dt.IsValid() && (imm == 0)) { 15443 if (cond.Is(al)) { 15444 EmitA32(0xf3b10040U | 15445 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15446 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15447 rd.Encode(22, 12) | rm.Encode(5, 0)); 15448 return; 15449 } 15450 } 15451 } 15452 } 15453 } 15454 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand); 15455 } 15456 15457 void Assembler::vcgt( 15458 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15459 VIXL_ASSERT(AllowAssembler()); 15460 CheckIT(cond); 15461 Dt_U_size_1 encoded_dt(dt); 15462 if (IsUsingT32()) { 15463 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15464 if (encoded_dt.IsValid()) { 15465 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15466 EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15467 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15468 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15469 AdvanceIT(); 15470 return; 15471 } 15472 } 15473 // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 15474 if (dt.Is(F32)) { 15475 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15476 EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15477 rm.Encode(5, 0)); 15478 AdvanceIT(); 15479 return; 15480 } 15481 } 15482 } else { 15483 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15484 if (encoded_dt.IsValid()) { 15485 if (cond.Is(al)) { 15486 EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15487 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15488 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15489 return; 15490 } 15491 } 15492 // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 15493 if (dt.Is(F32)) { 15494 if (cond.Is(al)) { 15495 EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15496 rm.Encode(5, 0)); 15497 return; 15498 } 15499 } 15500 } 15501 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm); 15502 } 15503 15504 void Assembler::vcgt( 15505 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15506 VIXL_ASSERT(AllowAssembler()); 15507 CheckIT(cond); 15508 Dt_U_size_1 encoded_dt(dt); 15509 if (IsUsingT32()) { 15510 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15511 if (encoded_dt.IsValid()) { 15512 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15513 EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15514 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15515 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15516 AdvanceIT(); 15517 return; 15518 } 15519 } 15520 // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 15521 if (dt.Is(F32)) { 15522 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15523 EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15524 rm.Encode(5, 0)); 15525 AdvanceIT(); 15526 return; 15527 } 15528 } 15529 } else { 15530 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15531 if (encoded_dt.IsValid()) { 15532 if (cond.Is(al)) { 15533 EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15534 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15535 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15536 return; 15537 } 15538 } 15539 // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 15540 if (dt.Is(F32)) { 15541 if (cond.Is(al)) { 15542 EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15543 rm.Encode(5, 0)); 15544 return; 15545 } 15546 } 15547 } 15548 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm); 15549 } 15550 15551 void Assembler::vcle(Condition cond, 15552 DataType dt, 15553 DRegister rd, 15554 DRegister rm, 15555 const DOperand& operand) { 15556 VIXL_ASSERT(AllowAssembler()); 15557 CheckIT(cond); 15558 if (operand.IsImmediate()) { 15559 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15560 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15561 Dt_F_size_1 encoded_dt(dt); 15562 if (IsUsingT32()) { 15563 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15564 if (encoded_dt.IsValid() && (imm == 0)) { 15565 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15566 EmitT32_32(0xffb10180U | 15567 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15568 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15569 rd.Encode(22, 12) | rm.Encode(5, 0)); 15570 AdvanceIT(); 15571 return; 15572 } 15573 } 15574 } else { 15575 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15576 if (encoded_dt.IsValid() && (imm == 0)) { 15577 if (cond.Is(al)) { 15578 EmitA32(0xf3b10180U | 15579 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15580 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15581 rd.Encode(22, 12) | rm.Encode(5, 0)); 15582 return; 15583 } 15584 } 15585 } 15586 } 15587 } 15588 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand); 15589 } 15590 15591 void Assembler::vcle(Condition cond, 15592 DataType dt, 15593 QRegister rd, 15594 QRegister rm, 15595 const QOperand& operand) { 15596 VIXL_ASSERT(AllowAssembler()); 15597 CheckIT(cond); 15598 if (operand.IsImmediate()) { 15599 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15600 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15601 Dt_F_size_1 encoded_dt(dt); 15602 if (IsUsingT32()) { 15603 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15604 if (encoded_dt.IsValid() && (imm == 0)) { 15605 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15606 EmitT32_32(0xffb101c0U | 15607 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15608 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15609 rd.Encode(22, 12) | rm.Encode(5, 0)); 15610 AdvanceIT(); 15611 return; 15612 } 15613 } 15614 } else { 15615 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15616 if (encoded_dt.IsValid() && (imm == 0)) { 15617 if (cond.Is(al)) { 15618 EmitA32(0xf3b101c0U | 15619 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15620 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15621 rd.Encode(22, 12) | rm.Encode(5, 0)); 15622 return; 15623 } 15624 } 15625 } 15626 } 15627 } 15628 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand); 15629 } 15630 15631 void Assembler::vcle( 15632 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15633 VIXL_ASSERT(AllowAssembler()); 15634 CheckIT(cond); 15635 Dt_U_size_1 encoded_dt(dt); 15636 if (IsUsingT32()) { 15637 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15638 if (encoded_dt.IsValid()) { 15639 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15640 EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15641 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15642 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15643 AdvanceIT(); 15644 return; 15645 } 15646 } 15647 // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 15648 if (dt.Is(F32)) { 15649 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15650 EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15651 rm.Encode(7, 16)); 15652 AdvanceIT(); 15653 return; 15654 } 15655 } 15656 } else { 15657 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15658 if (encoded_dt.IsValid()) { 15659 if (cond.Is(al)) { 15660 EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15661 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15662 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15663 return; 15664 } 15665 } 15666 // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 15667 if (dt.Is(F32)) { 15668 if (cond.Is(al)) { 15669 EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15670 rm.Encode(7, 16)); 15671 return; 15672 } 15673 } 15674 } 15675 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm); 15676 } 15677 15678 void Assembler::vcle( 15679 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15680 VIXL_ASSERT(AllowAssembler()); 15681 CheckIT(cond); 15682 Dt_U_size_1 encoded_dt(dt); 15683 if (IsUsingT32()) { 15684 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15685 if (encoded_dt.IsValid()) { 15686 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15687 EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15688 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15689 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15690 AdvanceIT(); 15691 return; 15692 } 15693 } 15694 // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 15695 if (dt.Is(F32)) { 15696 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15697 EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15698 rm.Encode(7, 16)); 15699 AdvanceIT(); 15700 return; 15701 } 15702 } 15703 } else { 15704 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15705 if (encoded_dt.IsValid()) { 15706 if (cond.Is(al)) { 15707 EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15708 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15709 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15710 return; 15711 } 15712 } 15713 // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 15714 if (dt.Is(F32)) { 15715 if (cond.Is(al)) { 15716 EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15717 rm.Encode(7, 16)); 15718 return; 15719 } 15720 } 15721 } 15722 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm); 15723 } 15724 15725 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) { 15726 VIXL_ASSERT(AllowAssembler()); 15727 CheckIT(cond); 15728 Dt_size_5 encoded_dt(dt); 15729 if (IsUsingT32()) { 15730 // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 15731 if (encoded_dt.IsValid()) { 15732 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15733 EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) | 15734 rd.Encode(22, 12) | rm.Encode(5, 0)); 15735 AdvanceIT(); 15736 return; 15737 } 15738 } 15739 } else { 15740 // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 15741 if (encoded_dt.IsValid()) { 15742 if (cond.Is(al)) { 15743 EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) | 15744 rd.Encode(22, 12) | rm.Encode(5, 0)); 15745 return; 15746 } 15747 } 15748 } 15749 Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm); 15750 } 15751 15752 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) { 15753 VIXL_ASSERT(AllowAssembler()); 15754 CheckIT(cond); 15755 Dt_size_5 encoded_dt(dt); 15756 if (IsUsingT32()) { 15757 // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 15758 if (encoded_dt.IsValid()) { 15759 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15760 EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) | 15761 rd.Encode(22, 12) | rm.Encode(5, 0)); 15762 AdvanceIT(); 15763 return; 15764 } 15765 } 15766 } else { 15767 // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 15768 if (encoded_dt.IsValid()) { 15769 if (cond.Is(al)) { 15770 EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) | 15771 rd.Encode(22, 12) | rm.Encode(5, 0)); 15772 return; 15773 } 15774 } 15775 } 15776 Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm); 15777 } 15778 15779 void Assembler::vclt(Condition cond, 15780 DataType dt, 15781 DRegister rd, 15782 DRegister rm, 15783 const DOperand& operand) { 15784 VIXL_ASSERT(AllowAssembler()); 15785 CheckIT(cond); 15786 if (operand.IsImmediate()) { 15787 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15788 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15789 Dt_F_size_1 encoded_dt(dt); 15790 if (IsUsingT32()) { 15791 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15792 if (encoded_dt.IsValid() && (imm == 0)) { 15793 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15794 EmitT32_32(0xffb10200U | 15795 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15796 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15797 rd.Encode(22, 12) | rm.Encode(5, 0)); 15798 AdvanceIT(); 15799 return; 15800 } 15801 } 15802 } else { 15803 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15804 if (encoded_dt.IsValid() && (imm == 0)) { 15805 if (cond.Is(al)) { 15806 EmitA32(0xf3b10200U | 15807 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15808 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15809 rd.Encode(22, 12) | rm.Encode(5, 0)); 15810 return; 15811 } 15812 } 15813 } 15814 } 15815 } 15816 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand); 15817 } 15818 15819 void Assembler::vclt(Condition cond, 15820 DataType dt, 15821 QRegister rd, 15822 QRegister rm, 15823 const QOperand& operand) { 15824 VIXL_ASSERT(AllowAssembler()); 15825 CheckIT(cond); 15826 if (operand.IsImmediate()) { 15827 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15828 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15829 Dt_F_size_1 encoded_dt(dt); 15830 if (IsUsingT32()) { 15831 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15832 if (encoded_dt.IsValid() && (imm == 0)) { 15833 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15834 EmitT32_32(0xffb10240U | 15835 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15836 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15837 rd.Encode(22, 12) | rm.Encode(5, 0)); 15838 AdvanceIT(); 15839 return; 15840 } 15841 } 15842 } else { 15843 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15844 if (encoded_dt.IsValid() && (imm == 0)) { 15845 if (cond.Is(al)) { 15846 EmitA32(0xf3b10240U | 15847 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15848 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15849 rd.Encode(22, 12) | rm.Encode(5, 0)); 15850 return; 15851 } 15852 } 15853 } 15854 } 15855 } 15856 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand); 15857 } 15858 15859 void Assembler::vclt( 15860 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15861 VIXL_ASSERT(AllowAssembler()); 15862 CheckIT(cond); 15863 Dt_U_size_1 encoded_dt(dt); 15864 if (IsUsingT32()) { 15865 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15866 if (encoded_dt.IsValid()) { 15867 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15868 EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15869 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15870 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15871 AdvanceIT(); 15872 return; 15873 } 15874 } 15875 // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 15876 if (dt.Is(F32)) { 15877 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15878 EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15879 rm.Encode(7, 16)); 15880 AdvanceIT(); 15881 return; 15882 } 15883 } 15884 } else { 15885 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15886 if (encoded_dt.IsValid()) { 15887 if (cond.Is(al)) { 15888 EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15889 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15890 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15891 return; 15892 } 15893 } 15894 // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 15895 if (dt.Is(F32)) { 15896 if (cond.Is(al)) { 15897 EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15898 rm.Encode(7, 16)); 15899 return; 15900 } 15901 } 15902 } 15903 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm); 15904 } 15905 15906 void Assembler::vclt( 15907 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15908 VIXL_ASSERT(AllowAssembler()); 15909 CheckIT(cond); 15910 Dt_U_size_1 encoded_dt(dt); 15911 if (IsUsingT32()) { 15912 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15913 if (encoded_dt.IsValid()) { 15914 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15915 EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15916 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15917 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15918 AdvanceIT(); 15919 return; 15920 } 15921 } 15922 // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 15923 if (dt.Is(F32)) { 15924 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15925 EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15926 rm.Encode(7, 16)); 15927 AdvanceIT(); 15928 return; 15929 } 15930 } 15931 } else { 15932 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15933 if (encoded_dt.IsValid()) { 15934 if (cond.Is(al)) { 15935 EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15936 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15937 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15938 return; 15939 } 15940 } 15941 // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 15942 if (dt.Is(F32)) { 15943 if (cond.Is(al)) { 15944 EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15945 rm.Encode(7, 16)); 15946 return; 15947 } 15948 } 15949 } 15950 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm); 15951 } 15952 15953 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) { 15954 VIXL_ASSERT(AllowAssembler()); 15955 CheckIT(cond); 15956 Dt_size_4 encoded_dt(dt); 15957 if (IsUsingT32()) { 15958 // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 15959 if (encoded_dt.IsValid()) { 15960 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15961 EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) | 15962 rd.Encode(22, 12) | rm.Encode(5, 0)); 15963 AdvanceIT(); 15964 return; 15965 } 15966 } 15967 } else { 15968 // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 15969 if (encoded_dt.IsValid()) { 15970 if (cond.Is(al)) { 15971 EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) | 15972 rd.Encode(22, 12) | rm.Encode(5, 0)); 15973 return; 15974 } 15975 } 15976 } 15977 Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm); 15978 } 15979 15980 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) { 15981 VIXL_ASSERT(AllowAssembler()); 15982 CheckIT(cond); 15983 Dt_size_4 encoded_dt(dt); 15984 if (IsUsingT32()) { 15985 // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 15986 if (encoded_dt.IsValid()) { 15987 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15988 EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) | 15989 rd.Encode(22, 12) | rm.Encode(5, 0)); 15990 AdvanceIT(); 15991 return; 15992 } 15993 } 15994 } else { 15995 // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 15996 if (encoded_dt.IsValid()) { 15997 if (cond.Is(al)) { 15998 EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) | 15999 rd.Encode(22, 12) | rm.Encode(5, 0)); 16000 return; 16001 } 16002 } 16003 } 16004 Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm); 16005 } 16006 16007 void Assembler::vcmp(Condition cond, 16008 DataType dt, 16009 SRegister rd, 16010 const SOperand& operand) { 16011 VIXL_ASSERT(AllowAssembler()); 16012 CheckIT(cond); 16013 if (operand.IsRegister()) { 16014 SRegister rm = operand.GetRegister(); 16015 if (IsUsingT32()) { 16016 // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 16017 if (dt.Is(F32)) { 16018 EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16019 AdvanceIT(); 16020 return; 16021 } 16022 } else { 16023 // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 16024 if (dt.Is(F32) && cond.IsNotNever()) { 16025 EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16026 rm.Encode(5, 0)); 16027 return; 16028 } 16029 } 16030 } 16031 if (operand.IsImmediate()) { 16032 if (IsUsingT32()) { 16033 // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2 16034 if (dt.Is(F32) && (operand.IsFloatZero())) { 16035 EmitT32_32(0xeeb50a40U | rd.Encode(22, 12)); 16036 AdvanceIT(); 16037 return; 16038 } 16039 } else { 16040 // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2 16041 if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) { 16042 EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 16043 return; 16044 } 16045 } 16046 } 16047 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand); 16048 } 16049 16050 void Assembler::vcmp(Condition cond, 16051 DataType dt, 16052 DRegister rd, 16053 const DOperand& operand) { 16054 VIXL_ASSERT(AllowAssembler()); 16055 CheckIT(cond); 16056 if (operand.IsRegister()) { 16057 DRegister rm = operand.GetRegister(); 16058 if (IsUsingT32()) { 16059 // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 16060 if (dt.Is(F64)) { 16061 EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16062 AdvanceIT(); 16063 return; 16064 } 16065 } else { 16066 // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 16067 if (dt.Is(F64) && cond.IsNotNever()) { 16068 EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16069 rm.Encode(5, 0)); 16070 return; 16071 } 16072 } 16073 } 16074 if (operand.IsImmediate()) { 16075 if (IsUsingT32()) { 16076 // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2 16077 if (dt.Is(F64) && (operand.IsFloatZero())) { 16078 EmitT32_32(0xeeb50b40U | rd.Encode(22, 12)); 16079 AdvanceIT(); 16080 return; 16081 } 16082 } else { 16083 // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2 16084 if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) { 16085 EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 16086 return; 16087 } 16088 } 16089 } 16090 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand); 16091 } 16092 16093 void Assembler::vcmpe(Condition cond, 16094 DataType dt, 16095 SRegister rd, 16096 const SOperand& operand) { 16097 VIXL_ASSERT(AllowAssembler()); 16098 CheckIT(cond); 16099 if (operand.IsRegister()) { 16100 SRegister rm = operand.GetRegister(); 16101 if (IsUsingT32()) { 16102 // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 16103 if (dt.Is(F32)) { 16104 EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16105 AdvanceIT(); 16106 return; 16107 } 16108 } else { 16109 // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 16110 if (dt.Is(F32) && cond.IsNotNever()) { 16111 EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16112 rm.Encode(5, 0)); 16113 return; 16114 } 16115 } 16116 } 16117 if (operand.IsImmediate()) { 16118 if (IsUsingT32()) { 16119 // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2 16120 if (dt.Is(F32) && (operand.IsFloatZero())) { 16121 EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12)); 16122 AdvanceIT(); 16123 return; 16124 } 16125 } else { 16126 // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2 16127 if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) { 16128 EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 16129 return; 16130 } 16131 } 16132 } 16133 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand); 16134 } 16135 16136 void Assembler::vcmpe(Condition cond, 16137 DataType dt, 16138 DRegister rd, 16139 const DOperand& operand) { 16140 VIXL_ASSERT(AllowAssembler()); 16141 CheckIT(cond); 16142 if (operand.IsRegister()) { 16143 DRegister rm = operand.GetRegister(); 16144 if (IsUsingT32()) { 16145 // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 16146 if (dt.Is(F64)) { 16147 EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16148 AdvanceIT(); 16149 return; 16150 } 16151 } else { 16152 // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 16153 if (dt.Is(F64) && cond.IsNotNever()) { 16154 EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16155 rm.Encode(5, 0)); 16156 return; 16157 } 16158 } 16159 } 16160 if (operand.IsImmediate()) { 16161 if (IsUsingT32()) { 16162 // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2 16163 if (dt.Is(F64) && (operand.IsFloatZero())) { 16164 EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12)); 16165 AdvanceIT(); 16166 return; 16167 } 16168 } else { 16169 // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2 16170 if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) { 16171 EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 16172 return; 16173 } 16174 } 16175 } 16176 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand); 16177 } 16178 16179 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) { 16180 VIXL_ASSERT(AllowAssembler()); 16181 CheckIT(cond); 16182 if (IsUsingT32()) { 16183 // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1 16184 if (dt.Is(Untyped8)) { 16185 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16186 EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16187 AdvanceIT(); 16188 return; 16189 } 16190 } 16191 } else { 16192 // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1 16193 if (dt.Is(Untyped8)) { 16194 if (cond.Is(al)) { 16195 EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16196 return; 16197 } 16198 } 16199 } 16200 Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm); 16201 } 16202 16203 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) { 16204 VIXL_ASSERT(AllowAssembler()); 16205 CheckIT(cond); 16206 if (IsUsingT32()) { 16207 // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1 16208 if (dt.Is(Untyped8)) { 16209 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16210 EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16211 AdvanceIT(); 16212 return; 16213 } 16214 } 16215 } else { 16216 // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1 16217 if (dt.Is(Untyped8)) { 16218 if (cond.Is(al)) { 16219 EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16220 return; 16221 } 16222 } 16223 } 16224 Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm); 16225 } 16226 16227 void Assembler::vcvt( 16228 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 16229 VIXL_ASSERT(AllowAssembler()); 16230 CheckIT(cond); 16231 Dt_op_2 encoded_dt(dt2); 16232 if (IsUsingT32()) { 16233 // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1 16234 if (dt1.Is(F64) && dt2.Is(F32)) { 16235 EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16236 AdvanceIT(); 16237 return; 16238 } 16239 // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1 16240 if (dt1.Is(F64) && encoded_dt.IsValid()) { 16241 EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) | 16242 rd.Encode(22, 12) | rm.Encode(5, 0)); 16243 AdvanceIT(); 16244 return; 16245 } 16246 } else { 16247 // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1 16248 if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) { 16249 EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16250 rm.Encode(5, 0)); 16251 return; 16252 } 16253 // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1 16254 if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) { 16255 EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) | 16256 (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) | 16257 rm.Encode(5, 0)); 16258 return; 16259 } 16260 } 16261 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16262 } 16263 16264 void Assembler::vcvt( 16265 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16266 VIXL_ASSERT(AllowAssembler()); 16267 CheckIT(cond); 16268 if (IsUsingT32()) { 16269 // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1 16270 if (dt1.Is(F32) && dt2.Is(F64)) { 16271 EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16272 AdvanceIT(); 16273 return; 16274 } 16275 // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1 16276 if (dt1.Is(U32) && dt2.Is(F64)) { 16277 EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16278 AdvanceIT(); 16279 return; 16280 } 16281 // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1 16282 if (dt1.Is(S32) && dt2.Is(F64)) { 16283 EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16284 AdvanceIT(); 16285 return; 16286 } 16287 } else { 16288 // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1 16289 if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) { 16290 EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16291 rm.Encode(5, 0)); 16292 return; 16293 } 16294 // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1 16295 if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) { 16296 EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16297 rm.Encode(5, 0)); 16298 return; 16299 } 16300 // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1 16301 if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) { 16302 EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16303 rm.Encode(5, 0)); 16304 return; 16305 } 16306 } 16307 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16308 } 16309 16310 void Assembler::vcvt(Condition cond, 16311 DataType dt1, 16312 DataType dt2, 16313 DRegister rd, 16314 DRegister rm, 16315 int32_t fbits) { 16316 VIXL_ASSERT(AllowAssembler()); 16317 CheckIT(cond); 16318 Dt_op_U_1 encoded_dt(dt1, dt2); 16319 Dt_U_sx_1 encoded_dt_2(dt2); 16320 Dt_U_sx_1 encoded_dt_3(dt1); 16321 if (IsUsingT32()) { 16322 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1 16323 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 16324 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16325 uint32_t fbits_ = 64 - fbits; 16326 EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) | 16327 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 16328 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 16329 AdvanceIT(); 16330 return; 16331 } 16332 } 16333 // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1 16334 if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) && 16335 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 16336 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 16337 unsigned offset = 32; 16338 if (dt2.Is(S16) || dt2.Is(U16)) { 16339 offset = 16; 16340 } 16341 uint32_t fbits_ = offset - fbits; 16342 EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 16343 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 16344 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16345 ((fbits_ & 0x1e) >> 1)); 16346 AdvanceIT(); 16347 return; 16348 } 16349 // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1 16350 if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) && 16351 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 16352 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 16353 unsigned offset = 32; 16354 if (dt1.Is(S16) || dt1.Is(U16)) { 16355 offset = 16; 16356 } 16357 uint32_t fbits_ = offset - fbits; 16358 EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) | 16359 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) | 16360 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16361 ((fbits_ & 0x1e) >> 1)); 16362 AdvanceIT(); 16363 return; 16364 } 16365 } else { 16366 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1 16367 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 16368 if (cond.Is(al)) { 16369 uint32_t fbits_ = 64 - fbits; 16370 EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) | 16371 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 16372 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 16373 return; 16374 } 16375 } 16376 // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1 16377 if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) && 16378 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 16379 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 16380 cond.IsNotNever()) { 16381 unsigned offset = 32; 16382 if (dt2.Is(S16) || dt2.Is(U16)) { 16383 offset = 16; 16384 } 16385 uint32_t fbits_ = offset - fbits; 16386 EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) | 16387 ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 16388 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 16389 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16390 ((fbits_ & 0x1e) >> 1)); 16391 return; 16392 } 16393 // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1 16394 if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) && 16395 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 16396 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 16397 cond.IsNotNever()) { 16398 unsigned offset = 32; 16399 if (dt1.Is(S16) || dt1.Is(U16)) { 16400 offset = 16; 16401 } 16402 uint32_t fbits_ = offset - fbits; 16403 EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) | 16404 ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) | 16405 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) | 16406 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16407 ((fbits_ & 0x1e) >> 1)); 16408 return; 16409 } 16410 } 16411 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 16412 } 16413 16414 void Assembler::vcvt(Condition cond, 16415 DataType dt1, 16416 DataType dt2, 16417 QRegister rd, 16418 QRegister rm, 16419 int32_t fbits) { 16420 VIXL_ASSERT(AllowAssembler()); 16421 CheckIT(cond); 16422 Dt_op_U_1 encoded_dt(dt1, dt2); 16423 if (IsUsingT32()) { 16424 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1 16425 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 16426 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16427 uint32_t fbits_ = 64 - fbits; 16428 EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) | 16429 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 16430 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 16431 AdvanceIT(); 16432 return; 16433 } 16434 } 16435 } else { 16436 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1 16437 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 16438 if (cond.Is(al)) { 16439 uint32_t fbits_ = 64 - fbits; 16440 EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) | 16441 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 16442 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 16443 return; 16444 } 16445 } 16446 } 16447 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 16448 } 16449 16450 void Assembler::vcvt(Condition cond, 16451 DataType dt1, 16452 DataType dt2, 16453 SRegister rd, 16454 SRegister rm, 16455 int32_t fbits) { 16456 VIXL_ASSERT(AllowAssembler()); 16457 CheckIT(cond); 16458 Dt_U_sx_1 encoded_dt(dt2); 16459 Dt_U_sx_1 encoded_dt_2(dt1); 16460 if (IsUsingT32()) { 16461 // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1 16462 if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) && 16463 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 16464 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 16465 unsigned offset = 32; 16466 if (dt2.Is(S16) || dt2.Is(U16)) { 16467 offset = 16; 16468 } 16469 uint32_t fbits_ = offset - fbits; 16470 EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) | 16471 ((encoded_dt.GetEncodingValue() & 0x2) << 15) | 16472 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16473 ((fbits_ & 0x1e) >> 1)); 16474 AdvanceIT(); 16475 return; 16476 } 16477 // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1 16478 if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) && 16479 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 16480 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 16481 unsigned offset = 32; 16482 if (dt1.Is(S16) || dt1.Is(U16)) { 16483 offset = 16; 16484 } 16485 uint32_t fbits_ = offset - fbits; 16486 EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 16487 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 16488 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16489 ((fbits_ & 0x1e) >> 1)); 16490 AdvanceIT(); 16491 return; 16492 } 16493 } else { 16494 // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1 16495 if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) && 16496 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 16497 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 16498 cond.IsNotNever()) { 16499 unsigned offset = 32; 16500 if (dt2.Is(S16) || dt2.Is(U16)) { 16501 offset = 16; 16502 } 16503 uint32_t fbits_ = offset - fbits; 16504 EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) | 16505 ((encoded_dt.GetEncodingValue() & 0x1) << 7) | 16506 ((encoded_dt.GetEncodingValue() & 0x2) << 15) | 16507 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16508 ((fbits_ & 0x1e) >> 1)); 16509 return; 16510 } 16511 // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1 16512 if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) && 16513 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 16514 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 16515 cond.IsNotNever()) { 16516 unsigned offset = 32; 16517 if (dt1.Is(S16) || dt1.Is(U16)) { 16518 offset = 16; 16519 } 16520 uint32_t fbits_ = offset - fbits; 16521 EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) | 16522 ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 16523 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 16524 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16525 ((fbits_ & 0x1e) >> 1)); 16526 return; 16527 } 16528 } 16529 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 16530 } 16531 16532 void Assembler::vcvt( 16533 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16534 VIXL_ASSERT(AllowAssembler()); 16535 CheckIT(cond); 16536 Dt_op_1 encoded_dt(dt1, dt2); 16537 if (IsUsingT32()) { 16538 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1 16539 if (encoded_dt.IsValid()) { 16540 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16541 EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) | 16542 rd.Encode(22, 12) | rm.Encode(5, 0)); 16543 AdvanceIT(); 16544 return; 16545 } 16546 } 16547 } else { 16548 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1 16549 if (encoded_dt.IsValid()) { 16550 if (cond.Is(al)) { 16551 EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) | 16552 rd.Encode(22, 12) | rm.Encode(5, 0)); 16553 return; 16554 } 16555 } 16556 } 16557 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16558 } 16559 16560 void Assembler::vcvt( 16561 Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 16562 VIXL_ASSERT(AllowAssembler()); 16563 CheckIT(cond); 16564 Dt_op_1 encoded_dt(dt1, dt2); 16565 if (IsUsingT32()) { 16566 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1 16567 if (encoded_dt.IsValid()) { 16568 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16569 EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) | 16570 rd.Encode(22, 12) | rm.Encode(5, 0)); 16571 AdvanceIT(); 16572 return; 16573 } 16574 } 16575 } else { 16576 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1 16577 if (encoded_dt.IsValid()) { 16578 if (cond.Is(al)) { 16579 EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) | 16580 rd.Encode(22, 12) | rm.Encode(5, 0)); 16581 return; 16582 } 16583 } 16584 } 16585 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16586 } 16587 16588 void Assembler::vcvt( 16589 Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) { 16590 VIXL_ASSERT(AllowAssembler()); 16591 CheckIT(cond); 16592 if (IsUsingT32()) { 16593 // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1 16594 if (dt1.Is(F16) && dt2.Is(F32)) { 16595 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16596 EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16597 AdvanceIT(); 16598 return; 16599 } 16600 } 16601 } else { 16602 // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1 16603 if (dt1.Is(F16) && dt2.Is(F32)) { 16604 if (cond.Is(al)) { 16605 EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16606 return; 16607 } 16608 } 16609 } 16610 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16611 } 16612 16613 void Assembler::vcvt( 16614 Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) { 16615 VIXL_ASSERT(AllowAssembler()); 16616 CheckIT(cond); 16617 if (IsUsingT32()) { 16618 // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1 16619 if (dt1.Is(F32) && dt2.Is(F16)) { 16620 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16621 EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16622 AdvanceIT(); 16623 return; 16624 } 16625 } 16626 } else { 16627 // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1 16628 if (dt1.Is(F32) && dt2.Is(F16)) { 16629 if (cond.Is(al)) { 16630 EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16631 return; 16632 } 16633 } 16634 } 16635 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16636 } 16637 16638 void Assembler::vcvt( 16639 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16640 VIXL_ASSERT(AllowAssembler()); 16641 CheckIT(cond); 16642 Dt_op_2 encoded_dt(dt2); 16643 if (IsUsingT32()) { 16644 // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1 16645 if (dt1.Is(U32) && dt2.Is(F32)) { 16646 EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16647 AdvanceIT(); 16648 return; 16649 } 16650 // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1 16651 if (dt1.Is(S32) && dt2.Is(F32)) { 16652 EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16653 AdvanceIT(); 16654 return; 16655 } 16656 // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1 16657 if (dt1.Is(F32) && encoded_dt.IsValid()) { 16658 EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) | 16659 rd.Encode(22, 12) | rm.Encode(5, 0)); 16660 AdvanceIT(); 16661 return; 16662 } 16663 } else { 16664 // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1 16665 if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) { 16666 EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16667 rm.Encode(5, 0)); 16668 return; 16669 } 16670 // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1 16671 if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) { 16672 EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16673 rm.Encode(5, 0)); 16674 return; 16675 } 16676 // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1 16677 if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) { 16678 EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) | 16679 (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) | 16680 rm.Encode(5, 0)); 16681 return; 16682 } 16683 } 16684 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16685 } 16686 16687 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16688 VIXL_ASSERT(AllowAssembler()); 16689 CheckIT(al); 16690 Dt_op_3 encoded_dt(dt1); 16691 if (IsUsingT32()) { 16692 // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 16693 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16694 EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) | 16695 rd.Encode(22, 12) | rm.Encode(5, 0)); 16696 AdvanceIT(); 16697 return; 16698 } 16699 } else { 16700 // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 16701 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16702 EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) | 16703 rd.Encode(22, 12) | rm.Encode(5, 0)); 16704 return; 16705 } 16706 } 16707 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 16708 } 16709 16710 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 16711 VIXL_ASSERT(AllowAssembler()); 16712 CheckIT(al); 16713 Dt_op_3 encoded_dt(dt1); 16714 if (IsUsingT32()) { 16715 // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 16716 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16717 EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) | 16718 rd.Encode(22, 12) | rm.Encode(5, 0)); 16719 AdvanceIT(); 16720 return; 16721 } 16722 } else { 16723 // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 16724 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16725 EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) | 16726 rd.Encode(22, 12) | rm.Encode(5, 0)); 16727 return; 16728 } 16729 } 16730 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 16731 } 16732 16733 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16734 VIXL_ASSERT(AllowAssembler()); 16735 CheckIT(al); 16736 Dt_op_2 encoded_dt(dt1); 16737 if (IsUsingT32()) { 16738 // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 16739 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16740 EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) | 16741 rd.Encode(22, 12) | rm.Encode(5, 0)); 16742 AdvanceIT(); 16743 return; 16744 } 16745 } else { 16746 // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 16747 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16748 EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) | 16749 rd.Encode(22, 12) | rm.Encode(5, 0)); 16750 return; 16751 } 16752 } 16753 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 16754 } 16755 16756 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16757 VIXL_ASSERT(AllowAssembler()); 16758 CheckIT(al); 16759 Dt_op_2 encoded_dt(dt1); 16760 if (IsUsingT32()) { 16761 // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 16762 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16763 EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) | 16764 rd.Encode(22, 12) | rm.Encode(5, 0)); 16765 AdvanceIT(); 16766 return; 16767 } 16768 } else { 16769 // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 16770 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16771 EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) | 16772 rd.Encode(22, 12) | rm.Encode(5, 0)); 16773 return; 16774 } 16775 } 16776 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 16777 } 16778 16779 void Assembler::vcvtb( 16780 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16781 VIXL_ASSERT(AllowAssembler()); 16782 CheckIT(cond); 16783 if (IsUsingT32()) { 16784 // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1 16785 if (dt1.Is(F32) && dt2.Is(F16)) { 16786 EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16787 AdvanceIT(); 16788 return; 16789 } 16790 // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1 16791 if (dt1.Is(F16) && dt2.Is(F32)) { 16792 EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16793 AdvanceIT(); 16794 return; 16795 } 16796 } else { 16797 // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1 16798 if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) { 16799 EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16800 rm.Encode(5, 0)); 16801 return; 16802 } 16803 // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1 16804 if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) { 16805 EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16806 rm.Encode(5, 0)); 16807 return; 16808 } 16809 } 16810 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 16811 } 16812 16813 void Assembler::vcvtb( 16814 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 16815 VIXL_ASSERT(AllowAssembler()); 16816 CheckIT(cond); 16817 if (IsUsingT32()) { 16818 // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1 16819 if (dt1.Is(F64) && dt2.Is(F16)) { 16820 EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16821 AdvanceIT(); 16822 return; 16823 } 16824 } else { 16825 // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1 16826 if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) { 16827 EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16828 rm.Encode(5, 0)); 16829 return; 16830 } 16831 } 16832 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 16833 } 16834 16835 void Assembler::vcvtb( 16836 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16837 VIXL_ASSERT(AllowAssembler()); 16838 CheckIT(cond); 16839 if (IsUsingT32()) { 16840 // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1 16841 if (dt1.Is(F16) && dt2.Is(F64)) { 16842 EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16843 AdvanceIT(); 16844 return; 16845 } 16846 } else { 16847 // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1 16848 if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) { 16849 EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16850 rm.Encode(5, 0)); 16851 return; 16852 } 16853 } 16854 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 16855 } 16856 16857 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16858 VIXL_ASSERT(AllowAssembler()); 16859 CheckIT(al); 16860 Dt_op_3 encoded_dt(dt1); 16861 if (IsUsingT32()) { 16862 // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 16863 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16864 EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) | 16865 rd.Encode(22, 12) | rm.Encode(5, 0)); 16866 AdvanceIT(); 16867 return; 16868 } 16869 } else { 16870 // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 16871 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16872 EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) | 16873 rd.Encode(22, 12) | rm.Encode(5, 0)); 16874 return; 16875 } 16876 } 16877 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 16878 } 16879 16880 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 16881 VIXL_ASSERT(AllowAssembler()); 16882 CheckIT(al); 16883 Dt_op_3 encoded_dt(dt1); 16884 if (IsUsingT32()) { 16885 // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 16886 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16887 EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) | 16888 rd.Encode(22, 12) | rm.Encode(5, 0)); 16889 AdvanceIT(); 16890 return; 16891 } 16892 } else { 16893 // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 16894 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16895 EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) | 16896 rd.Encode(22, 12) | rm.Encode(5, 0)); 16897 return; 16898 } 16899 } 16900 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 16901 } 16902 16903 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16904 VIXL_ASSERT(AllowAssembler()); 16905 CheckIT(al); 16906 Dt_op_2 encoded_dt(dt1); 16907 if (IsUsingT32()) { 16908 // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 16909 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16910 EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) | 16911 rd.Encode(22, 12) | rm.Encode(5, 0)); 16912 AdvanceIT(); 16913 return; 16914 } 16915 } else { 16916 // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 16917 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16918 EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) | 16919 rd.Encode(22, 12) | rm.Encode(5, 0)); 16920 return; 16921 } 16922 } 16923 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 16924 } 16925 16926 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16927 VIXL_ASSERT(AllowAssembler()); 16928 CheckIT(al); 16929 Dt_op_2 encoded_dt(dt1); 16930 if (IsUsingT32()) { 16931 // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 16932 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16933 EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) | 16934 rd.Encode(22, 12) | rm.Encode(5, 0)); 16935 AdvanceIT(); 16936 return; 16937 } 16938 } else { 16939 // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 16940 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16941 EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) | 16942 rd.Encode(22, 12) | rm.Encode(5, 0)); 16943 return; 16944 } 16945 } 16946 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 16947 } 16948 16949 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16950 VIXL_ASSERT(AllowAssembler()); 16951 CheckIT(al); 16952 Dt_op_3 encoded_dt(dt1); 16953 if (IsUsingT32()) { 16954 // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 16955 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16956 EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) | 16957 rd.Encode(22, 12) | rm.Encode(5, 0)); 16958 AdvanceIT(); 16959 return; 16960 } 16961 } else { 16962 // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 16963 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16964 EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) | 16965 rd.Encode(22, 12) | rm.Encode(5, 0)); 16966 return; 16967 } 16968 } 16969 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 16970 } 16971 16972 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 16973 VIXL_ASSERT(AllowAssembler()); 16974 CheckIT(al); 16975 Dt_op_3 encoded_dt(dt1); 16976 if (IsUsingT32()) { 16977 // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 16978 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16979 EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) | 16980 rd.Encode(22, 12) | rm.Encode(5, 0)); 16981 AdvanceIT(); 16982 return; 16983 } 16984 } else { 16985 // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 16986 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16987 EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) | 16988 rd.Encode(22, 12) | rm.Encode(5, 0)); 16989 return; 16990 } 16991 } 16992 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 16993 } 16994 16995 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16996 VIXL_ASSERT(AllowAssembler()); 16997 CheckIT(al); 16998 Dt_op_2 encoded_dt(dt1); 16999 if (IsUsingT32()) { 17000 // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 17001 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17002 EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) | 17003 rd.Encode(22, 12) | rm.Encode(5, 0)); 17004 AdvanceIT(); 17005 return; 17006 } 17007 } else { 17008 // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 17009 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17010 EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) | 17011 rd.Encode(22, 12) | rm.Encode(5, 0)); 17012 return; 17013 } 17014 } 17015 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 17016 } 17017 17018 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 17019 VIXL_ASSERT(AllowAssembler()); 17020 CheckIT(al); 17021 Dt_op_2 encoded_dt(dt1); 17022 if (IsUsingT32()) { 17023 // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 17024 if (encoded_dt.IsValid() && dt2.Is(F64)) { 17025 EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) | 17026 rd.Encode(22, 12) | rm.Encode(5, 0)); 17027 AdvanceIT(); 17028 return; 17029 } 17030 } else { 17031 // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 17032 if (encoded_dt.IsValid() && dt2.Is(F64)) { 17033 EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) | 17034 rd.Encode(22, 12) | rm.Encode(5, 0)); 17035 return; 17036 } 17037 } 17038 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 17039 } 17040 17041 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 17042 VIXL_ASSERT(AllowAssembler()); 17043 CheckIT(al); 17044 Dt_op_3 encoded_dt(dt1); 17045 if (IsUsingT32()) { 17046 // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 17047 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17048 EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) | 17049 rd.Encode(22, 12) | rm.Encode(5, 0)); 17050 AdvanceIT(); 17051 return; 17052 } 17053 } else { 17054 // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 17055 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17056 EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) | 17057 rd.Encode(22, 12) | rm.Encode(5, 0)); 17058 return; 17059 } 17060 } 17061 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 17062 } 17063 17064 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 17065 VIXL_ASSERT(AllowAssembler()); 17066 CheckIT(al); 17067 Dt_op_3 encoded_dt(dt1); 17068 if (IsUsingT32()) { 17069 // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 17070 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17071 EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) | 17072 rd.Encode(22, 12) | rm.Encode(5, 0)); 17073 AdvanceIT(); 17074 return; 17075 } 17076 } else { 17077 // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 17078 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17079 EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) | 17080 rd.Encode(22, 12) | rm.Encode(5, 0)); 17081 return; 17082 } 17083 } 17084 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 17085 } 17086 17087 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 17088 VIXL_ASSERT(AllowAssembler()); 17089 CheckIT(al); 17090 Dt_op_2 encoded_dt(dt1); 17091 if (IsUsingT32()) { 17092 // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 17093 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17094 EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) | 17095 rd.Encode(22, 12) | rm.Encode(5, 0)); 17096 AdvanceIT(); 17097 return; 17098 } 17099 } else { 17100 // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 17101 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17102 EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) | 17103 rd.Encode(22, 12) | rm.Encode(5, 0)); 17104 return; 17105 } 17106 } 17107 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 17108 } 17109 17110 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 17111 VIXL_ASSERT(AllowAssembler()); 17112 CheckIT(al); 17113 Dt_op_2 encoded_dt(dt1); 17114 if (IsUsingT32()) { 17115 // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 17116 if (encoded_dt.IsValid() && dt2.Is(F64)) { 17117 EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) | 17118 rd.Encode(22, 12) | rm.Encode(5, 0)); 17119 AdvanceIT(); 17120 return; 17121 } 17122 } else { 17123 // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 17124 if (encoded_dt.IsValid() && dt2.Is(F64)) { 17125 EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) | 17126 rd.Encode(22, 12) | rm.Encode(5, 0)); 17127 return; 17128 } 17129 } 17130 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 17131 } 17132 17133 void Assembler::vcvtr( 17134 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 17135 VIXL_ASSERT(AllowAssembler()); 17136 CheckIT(cond); 17137 if (IsUsingT32()) { 17138 // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1 17139 if (dt1.Is(U32) && dt2.Is(F32)) { 17140 EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17141 AdvanceIT(); 17142 return; 17143 } 17144 // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1 17145 if (dt1.Is(S32) && dt2.Is(F32)) { 17146 EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17147 AdvanceIT(); 17148 return; 17149 } 17150 } else { 17151 // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1 17152 if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) { 17153 EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17154 rm.Encode(5, 0)); 17155 return; 17156 } 17157 // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1 17158 if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) { 17159 EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17160 rm.Encode(5, 0)); 17161 return; 17162 } 17163 } 17164 Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm); 17165 } 17166 17167 void Assembler::vcvtr( 17168 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 17169 VIXL_ASSERT(AllowAssembler()); 17170 CheckIT(cond); 17171 if (IsUsingT32()) { 17172 // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1 17173 if (dt1.Is(U32) && dt2.Is(F64)) { 17174 EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17175 AdvanceIT(); 17176 return; 17177 } 17178 // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1 17179 if (dt1.Is(S32) && dt2.Is(F64)) { 17180 EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17181 AdvanceIT(); 17182 return; 17183 } 17184 } else { 17185 // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1 17186 if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) { 17187 EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17188 rm.Encode(5, 0)); 17189 return; 17190 } 17191 // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1 17192 if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) { 17193 EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17194 rm.Encode(5, 0)); 17195 return; 17196 } 17197 } 17198 Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm); 17199 } 17200 17201 void Assembler::vcvtt( 17202 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 17203 VIXL_ASSERT(AllowAssembler()); 17204 CheckIT(cond); 17205 if (IsUsingT32()) { 17206 // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1 17207 if (dt1.Is(F32) && dt2.Is(F16)) { 17208 EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17209 AdvanceIT(); 17210 return; 17211 } 17212 // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1 17213 if (dt1.Is(F16) && dt2.Is(F32)) { 17214 EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17215 AdvanceIT(); 17216 return; 17217 } 17218 } else { 17219 // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1 17220 if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) { 17221 EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17222 rm.Encode(5, 0)); 17223 return; 17224 } 17225 // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1 17226 if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) { 17227 EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17228 rm.Encode(5, 0)); 17229 return; 17230 } 17231 } 17232 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 17233 } 17234 17235 void Assembler::vcvtt( 17236 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 17237 VIXL_ASSERT(AllowAssembler()); 17238 CheckIT(cond); 17239 if (IsUsingT32()) { 17240 // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1 17241 if (dt1.Is(F64) && dt2.Is(F16)) { 17242 EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17243 AdvanceIT(); 17244 return; 17245 } 17246 } else { 17247 // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1 17248 if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) { 17249 EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17250 rm.Encode(5, 0)); 17251 return; 17252 } 17253 } 17254 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 17255 } 17256 17257 void Assembler::vcvtt( 17258 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 17259 VIXL_ASSERT(AllowAssembler()); 17260 CheckIT(cond); 17261 if (IsUsingT32()) { 17262 // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1 17263 if (dt1.Is(F16) && dt2.Is(F64)) { 17264 EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17265 AdvanceIT(); 17266 return; 17267 } 17268 } else { 17269 // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1 17270 if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) { 17271 EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17272 rm.Encode(5, 0)); 17273 return; 17274 } 17275 } 17276 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 17277 } 17278 17279 void Assembler::vdiv( 17280 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17281 VIXL_ASSERT(AllowAssembler()); 17282 CheckIT(cond); 17283 if (IsUsingT32()) { 17284 // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1 17285 if (dt.Is(F32)) { 17286 EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17287 rm.Encode(5, 0)); 17288 AdvanceIT(); 17289 return; 17290 } 17291 } else { 17292 // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1 17293 if (dt.Is(F32) && cond.IsNotNever()) { 17294 EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17295 rn.Encode(7, 16) | rm.Encode(5, 0)); 17296 return; 17297 } 17298 } 17299 Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm); 17300 } 17301 17302 void Assembler::vdiv( 17303 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17304 VIXL_ASSERT(AllowAssembler()); 17305 CheckIT(cond); 17306 if (IsUsingT32()) { 17307 // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1 17308 if (dt.Is(F64)) { 17309 EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17310 rm.Encode(5, 0)); 17311 AdvanceIT(); 17312 return; 17313 } 17314 } else { 17315 // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1 17316 if (dt.Is(F64) && cond.IsNotNever()) { 17317 EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17318 rn.Encode(7, 16) | rm.Encode(5, 0)); 17319 return; 17320 } 17321 } 17322 Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm); 17323 } 17324 17325 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) { 17326 VIXL_ASSERT(AllowAssembler()); 17327 CheckIT(cond); 17328 Dt_B_E_1 encoded_dt(dt); 17329 if (IsUsingT32()) { 17330 // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1 17331 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) { 17332 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17333 EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 17334 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 17335 rd.Encode(7, 16) | (rt.GetCode() << 12)); 17336 AdvanceIT(); 17337 return; 17338 } 17339 } 17340 } else { 17341 // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1 17342 if (encoded_dt.IsValid() && cond.IsNotNever() && 17343 (!rt.IsPC() || AllowUnpredictable())) { 17344 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17345 EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) | 17346 ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 17347 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 17348 rd.Encode(7, 16) | (rt.GetCode() << 12)); 17349 return; 17350 } 17351 } 17352 } 17353 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt); 17354 } 17355 17356 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) { 17357 VIXL_ASSERT(AllowAssembler()); 17358 CheckIT(cond); 17359 Dt_B_E_1 encoded_dt(dt); 17360 if (IsUsingT32()) { 17361 // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1 17362 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) { 17363 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17364 EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 17365 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 17366 rd.Encode(7, 16) | (rt.GetCode() << 12)); 17367 AdvanceIT(); 17368 return; 17369 } 17370 } 17371 } else { 17372 // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1 17373 if (encoded_dt.IsValid() && cond.IsNotNever() && 17374 (!rt.IsPC() || AllowUnpredictable())) { 17375 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17376 EmitA32(0x0e800b10U | (cond.GetCondition() << 28) | 17377 ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 17378 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 17379 rd.Encode(7, 16) | (rt.GetCode() << 12)); 17380 return; 17381 } 17382 } 17383 } 17384 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt); 17385 } 17386 17387 void Assembler::vdup(Condition cond, 17388 DataType dt, 17389 DRegister rd, 17390 DRegisterLane rm) { 17391 VIXL_ASSERT(AllowAssembler()); 17392 CheckIT(cond); 17393 Dt_imm4_1 encoded_dt(dt, rm); 17394 if (IsUsingT32()) { 17395 // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1 17396 if (encoded_dt.IsValid()) { 17397 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17398 EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) | 17399 rd.Encode(22, 12) | rm.Encode(5, 0)); 17400 AdvanceIT(); 17401 return; 17402 } 17403 } 17404 } else { 17405 // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1 17406 if (encoded_dt.IsValid()) { 17407 if (cond.Is(al)) { 17408 EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) | 17409 rd.Encode(22, 12) | rm.Encode(5, 0)); 17410 return; 17411 } 17412 } 17413 } 17414 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm); 17415 } 17416 17417 void Assembler::vdup(Condition cond, 17418 DataType dt, 17419 QRegister rd, 17420 DRegisterLane rm) { 17421 VIXL_ASSERT(AllowAssembler()); 17422 CheckIT(cond); 17423 Dt_imm4_1 encoded_dt(dt, rm); 17424 if (IsUsingT32()) { 17425 // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1 17426 if (encoded_dt.IsValid()) { 17427 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17428 EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) | 17429 rd.Encode(22, 12) | rm.Encode(5, 0)); 17430 AdvanceIT(); 17431 return; 17432 } 17433 } 17434 } else { 17435 // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1 17436 if (encoded_dt.IsValid()) { 17437 if (cond.Is(al)) { 17438 EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) | 17439 rd.Encode(22, 12) | rm.Encode(5, 0)); 17440 return; 17441 } 17442 } 17443 } 17444 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm); 17445 } 17446 17447 void Assembler::veor( 17448 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17449 VIXL_ASSERT(AllowAssembler()); 17450 CheckIT(cond); 17451 USE(dt); 17452 if (IsUsingT32()) { 17453 // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 17454 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17455 EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17456 rm.Encode(5, 0)); 17457 AdvanceIT(); 17458 return; 17459 } 17460 } else { 17461 // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 17462 if (cond.Is(al)) { 17463 EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17464 rm.Encode(5, 0)); 17465 return; 17466 } 17467 } 17468 Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm); 17469 } 17470 17471 void Assembler::veor( 17472 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17473 VIXL_ASSERT(AllowAssembler()); 17474 CheckIT(cond); 17475 USE(dt); 17476 if (IsUsingT32()) { 17477 // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 17478 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17479 EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17480 rm.Encode(5, 0)); 17481 AdvanceIT(); 17482 return; 17483 } 17484 } else { 17485 // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 17486 if (cond.Is(al)) { 17487 EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17488 rm.Encode(5, 0)); 17489 return; 17490 } 17491 } 17492 Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm); 17493 } 17494 17495 void Assembler::vext(Condition cond, 17496 DataType dt, 17497 DRegister rd, 17498 DRegister rn, 17499 DRegister rm, 17500 const DOperand& operand) { 17501 VIXL_ASSERT(AllowAssembler()); 17502 CheckIT(cond); 17503 if (operand.IsImmediate()) { 17504 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 17505 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 17506 if (IsUsingT32()) { 17507 // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1 17508 if (dt.Is(Untyped8) && (imm <= 7)) { 17509 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17510 EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17511 rm.Encode(5, 0) | (imm << 8)); 17512 AdvanceIT(); 17513 return; 17514 } 17515 } 17516 // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1 17517 if ((dt.Is(Untyped16) || dt.Is(Untyped32)) && 17518 (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 17519 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17520 uint32_t imm4 = imm / dt.GetSize(); 17521 EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17522 rm.Encode(5, 0) | (imm4 << 8)); 17523 AdvanceIT(); 17524 return; 17525 } 17526 } 17527 } else { 17528 // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1 17529 if (dt.Is(Untyped8) && (imm <= 7)) { 17530 if (cond.Is(al)) { 17531 EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17532 rm.Encode(5, 0) | (imm << 8)); 17533 return; 17534 } 17535 } 17536 // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1 17537 if ((dt.Is(Untyped16) || dt.Is(Untyped32)) && 17538 (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 17539 if (cond.Is(al)) { 17540 uint32_t imm4 = imm / dt.GetSize(); 17541 EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17542 rm.Encode(5, 0) | (imm4 << 8)); 17543 return; 17544 } 17545 } 17546 } 17547 } 17548 } 17549 Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand); 17550 } 17551 17552 void Assembler::vext(Condition cond, 17553 DataType dt, 17554 QRegister rd, 17555 QRegister rn, 17556 QRegister rm, 17557 const QOperand& operand) { 17558 VIXL_ASSERT(AllowAssembler()); 17559 CheckIT(cond); 17560 if (operand.IsImmediate()) { 17561 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 17562 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 17563 if (IsUsingT32()) { 17564 // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1 17565 if (dt.Is(Untyped8) && (imm <= 15)) { 17566 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17567 EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17568 rm.Encode(5, 0) | (imm << 8)); 17569 AdvanceIT(); 17570 return; 17571 } 17572 } 17573 // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1 17574 if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) && 17575 (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 17576 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17577 uint32_t imm4 = imm / dt.GetSize(); 17578 EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17579 rm.Encode(5, 0) | (imm4 << 8)); 17580 AdvanceIT(); 17581 return; 17582 } 17583 } 17584 } else { 17585 // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1 17586 if (dt.Is(Untyped8) && (imm <= 15)) { 17587 if (cond.Is(al)) { 17588 EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17589 rm.Encode(5, 0) | (imm << 8)); 17590 return; 17591 } 17592 } 17593 // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1 17594 if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) && 17595 (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 17596 if (cond.Is(al)) { 17597 uint32_t imm4 = imm / dt.GetSize(); 17598 EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17599 rm.Encode(5, 0) | (imm4 << 8)); 17600 return; 17601 } 17602 } 17603 } 17604 } 17605 } 17606 Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand); 17607 } 17608 17609 void Assembler::vfma( 17610 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17611 VIXL_ASSERT(AllowAssembler()); 17612 CheckIT(cond); 17613 if (IsUsingT32()) { 17614 // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 17615 if (dt.Is(F32)) { 17616 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17617 EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17618 rm.Encode(5, 0)); 17619 AdvanceIT(); 17620 return; 17621 } 17622 } 17623 // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 17624 if (dt.Is(F64)) { 17625 EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17626 rm.Encode(5, 0)); 17627 AdvanceIT(); 17628 return; 17629 } 17630 } else { 17631 // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 17632 if (dt.Is(F32)) { 17633 if (cond.Is(al)) { 17634 EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17635 rm.Encode(5, 0)); 17636 return; 17637 } 17638 } 17639 // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 17640 if (dt.Is(F64) && cond.IsNotNever()) { 17641 EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17642 rn.Encode(7, 16) | rm.Encode(5, 0)); 17643 return; 17644 } 17645 } 17646 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 17647 } 17648 17649 void Assembler::vfma( 17650 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17651 VIXL_ASSERT(AllowAssembler()); 17652 CheckIT(cond); 17653 if (IsUsingT32()) { 17654 // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 17655 if (dt.Is(F32)) { 17656 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17657 EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17658 rm.Encode(5, 0)); 17659 AdvanceIT(); 17660 return; 17661 } 17662 } 17663 } else { 17664 // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 17665 if (dt.Is(F32)) { 17666 if (cond.Is(al)) { 17667 EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17668 rm.Encode(5, 0)); 17669 return; 17670 } 17671 } 17672 } 17673 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 17674 } 17675 17676 void Assembler::vfma( 17677 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17678 VIXL_ASSERT(AllowAssembler()); 17679 CheckIT(cond); 17680 if (IsUsingT32()) { 17681 // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 17682 if (dt.Is(F32)) { 17683 EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17684 rm.Encode(5, 0)); 17685 AdvanceIT(); 17686 return; 17687 } 17688 } else { 17689 // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 17690 if (dt.Is(F32) && cond.IsNotNever()) { 17691 EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17692 rn.Encode(7, 16) | rm.Encode(5, 0)); 17693 return; 17694 } 17695 } 17696 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 17697 } 17698 17699 void Assembler::vfms( 17700 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17701 VIXL_ASSERT(AllowAssembler()); 17702 CheckIT(cond); 17703 if (IsUsingT32()) { 17704 // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 17705 if (dt.Is(F32)) { 17706 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17707 EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17708 rm.Encode(5, 0)); 17709 AdvanceIT(); 17710 return; 17711 } 17712 } 17713 // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 17714 if (dt.Is(F64)) { 17715 EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17716 rm.Encode(5, 0)); 17717 AdvanceIT(); 17718 return; 17719 } 17720 } else { 17721 // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 17722 if (dt.Is(F32)) { 17723 if (cond.Is(al)) { 17724 EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17725 rm.Encode(5, 0)); 17726 return; 17727 } 17728 } 17729 // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 17730 if (dt.Is(F64) && cond.IsNotNever()) { 17731 EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17732 rn.Encode(7, 16) | rm.Encode(5, 0)); 17733 return; 17734 } 17735 } 17736 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 17737 } 17738 17739 void Assembler::vfms( 17740 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17741 VIXL_ASSERT(AllowAssembler()); 17742 CheckIT(cond); 17743 if (IsUsingT32()) { 17744 // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 17745 if (dt.Is(F32)) { 17746 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17747 EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17748 rm.Encode(5, 0)); 17749 AdvanceIT(); 17750 return; 17751 } 17752 } 17753 } else { 17754 // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 17755 if (dt.Is(F32)) { 17756 if (cond.Is(al)) { 17757 EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17758 rm.Encode(5, 0)); 17759 return; 17760 } 17761 } 17762 } 17763 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 17764 } 17765 17766 void Assembler::vfms( 17767 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17768 VIXL_ASSERT(AllowAssembler()); 17769 CheckIT(cond); 17770 if (IsUsingT32()) { 17771 // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 17772 if (dt.Is(F32)) { 17773 EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17774 rm.Encode(5, 0)); 17775 AdvanceIT(); 17776 return; 17777 } 17778 } else { 17779 // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 17780 if (dt.Is(F32) && cond.IsNotNever()) { 17781 EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17782 rn.Encode(7, 16) | rm.Encode(5, 0)); 17783 return; 17784 } 17785 } 17786 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 17787 } 17788 17789 void Assembler::vfnma( 17790 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17791 VIXL_ASSERT(AllowAssembler()); 17792 CheckIT(cond); 17793 if (IsUsingT32()) { 17794 // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 17795 if (dt.Is(F32)) { 17796 EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17797 rm.Encode(5, 0)); 17798 AdvanceIT(); 17799 return; 17800 } 17801 } else { 17802 // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 17803 if (dt.Is(F32) && cond.IsNotNever()) { 17804 EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17805 rn.Encode(7, 16) | rm.Encode(5, 0)); 17806 return; 17807 } 17808 } 17809 Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm); 17810 } 17811 17812 void Assembler::vfnma( 17813 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17814 VIXL_ASSERT(AllowAssembler()); 17815 CheckIT(cond); 17816 if (IsUsingT32()) { 17817 // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 17818 if (dt.Is(F64)) { 17819 EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17820 rm.Encode(5, 0)); 17821 AdvanceIT(); 17822 return; 17823 } 17824 } else { 17825 // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 17826 if (dt.Is(F64) && cond.IsNotNever()) { 17827 EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17828 rn.Encode(7, 16) | rm.Encode(5, 0)); 17829 return; 17830 } 17831 } 17832 Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm); 17833 } 17834 17835 void Assembler::vfnms( 17836 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17837 VIXL_ASSERT(AllowAssembler()); 17838 CheckIT(cond); 17839 if (IsUsingT32()) { 17840 // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 17841 if (dt.Is(F32)) { 17842 EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17843 rm.Encode(5, 0)); 17844 AdvanceIT(); 17845 return; 17846 } 17847 } else { 17848 // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 17849 if (dt.Is(F32) && cond.IsNotNever()) { 17850 EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17851 rn.Encode(7, 16) | rm.Encode(5, 0)); 17852 return; 17853 } 17854 } 17855 Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm); 17856 } 17857 17858 void Assembler::vfnms( 17859 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17860 VIXL_ASSERT(AllowAssembler()); 17861 CheckIT(cond); 17862 if (IsUsingT32()) { 17863 // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 17864 if (dt.Is(F64)) { 17865 EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17866 rm.Encode(5, 0)); 17867 AdvanceIT(); 17868 return; 17869 } 17870 } else { 17871 // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 17872 if (dt.Is(F64) && cond.IsNotNever()) { 17873 EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17874 rn.Encode(7, 16) | rm.Encode(5, 0)); 17875 return; 17876 } 17877 } 17878 Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm); 17879 } 17880 17881 void Assembler::vhadd( 17882 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17883 VIXL_ASSERT(AllowAssembler()); 17884 CheckIT(cond); 17885 Dt_U_size_1 encoded_dt(dt); 17886 if (IsUsingT32()) { 17887 // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 17888 if (encoded_dt.IsValid()) { 17889 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17890 EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17891 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 17892 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17893 AdvanceIT(); 17894 return; 17895 } 17896 } 17897 } else { 17898 // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 17899 if (encoded_dt.IsValid()) { 17900 if (cond.Is(al)) { 17901 EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17902 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 17903 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17904 return; 17905 } 17906 } 17907 } 17908 Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm); 17909 } 17910 17911 void Assembler::vhadd( 17912 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17913 VIXL_ASSERT(AllowAssembler()); 17914 CheckIT(cond); 17915 Dt_U_size_1 encoded_dt(dt); 17916 if (IsUsingT32()) { 17917 // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 17918 if (encoded_dt.IsValid()) { 17919 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17920 EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17921 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 17922 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17923 AdvanceIT(); 17924 return; 17925 } 17926 } 17927 } else { 17928 // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 17929 if (encoded_dt.IsValid()) { 17930 if (cond.Is(al)) { 17931 EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17932 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 17933 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17934 return; 17935 } 17936 } 17937 } 17938 Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm); 17939 } 17940 17941 void Assembler::vhsub( 17942 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17943 VIXL_ASSERT(AllowAssembler()); 17944 CheckIT(cond); 17945 Dt_U_size_1 encoded_dt(dt); 17946 if (IsUsingT32()) { 17947 // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 17948 if (encoded_dt.IsValid()) { 17949 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17950 EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17951 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 17952 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17953 AdvanceIT(); 17954 return; 17955 } 17956 } 17957 } else { 17958 // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 17959 if (encoded_dt.IsValid()) { 17960 if (cond.Is(al)) { 17961 EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17962 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 17963 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17964 return; 17965 } 17966 } 17967 } 17968 Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm); 17969 } 17970 17971 void Assembler::vhsub( 17972 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17973 VIXL_ASSERT(AllowAssembler()); 17974 CheckIT(cond); 17975 Dt_U_size_1 encoded_dt(dt); 17976 if (IsUsingT32()) { 17977 // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 17978 if (encoded_dt.IsValid()) { 17979 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17980 EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17981 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 17982 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17983 AdvanceIT(); 17984 return; 17985 } 17986 } 17987 } else { 17988 // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 17989 if (encoded_dt.IsValid()) { 17990 if (cond.Is(al)) { 17991 EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17992 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 17993 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17994 return; 17995 } 17996 } 17997 } 17998 Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm); 17999 } 18000 18001 void Assembler::vld1(Condition cond, 18002 DataType dt, 18003 const NeonRegisterList& nreglist, 18004 const AlignedMemOperand& operand) { 18005 VIXL_ASSERT(AllowAssembler()); 18006 CheckIT(cond); 18007 if (operand.IsImmediateZero()) { 18008 Register rn = operand.GetBaseRegister(); 18009 Alignment align = operand.GetAlignment(); 18010 Dt_size_6 encoded_dt(dt); 18011 Dt_size_7 encoded_dt_2(dt); 18012 Align_align_1 encoded_align_1(align, nreglist); 18013 Align_a_1 encoded_align_2(align, dt); 18014 Align_index_align_1 encoded_align_3(align, nreglist, dt); 18015 if (IsUsingT32()) { 18016 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18017 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18018 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18019 operand.IsOffset() && encoded_align_1.IsValid() && 18020 (!rn.IsPC() || AllowUnpredictable())) { 18021 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18022 const DRegister& first = nreglist.GetFirstDRegister(); 18023 uint32_t len_encoding; 18024 switch (nreglist.GetLength()) { 18025 default: 18026 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18027 case 1: 18028 len_encoding = 0x7; 18029 break; 18030 case 2: 18031 len_encoding = 0xa; 18032 break; 18033 case 3: 18034 len_encoding = 0x6; 18035 break; 18036 case 4: 18037 len_encoding = 0x2; 18038 break; 18039 } 18040 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 18041 (encoded_align_1.GetEncodingValue() << 4) | 18042 first.Encode(22, 12) | (len_encoding << 8) | 18043 (rn.GetCode() << 16)); 18044 AdvanceIT(); 18045 return; 18046 } 18047 } 18048 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18049 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18050 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18051 operand.IsPostIndex() && encoded_align_1.IsValid() && 18052 (!rn.IsPC() || AllowUnpredictable())) { 18053 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18054 const DRegister& first = nreglist.GetFirstDRegister(); 18055 uint32_t len_encoding; 18056 switch (nreglist.GetLength()) { 18057 default: 18058 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18059 case 1: 18060 len_encoding = 0x7; 18061 break; 18062 case 2: 18063 len_encoding = 0xa; 18064 break; 18065 case 3: 18066 len_encoding = 0x6; 18067 break; 18068 case 4: 18069 len_encoding = 0x2; 18070 break; 18071 } 18072 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 18073 (encoded_align_1.GetEncodingValue() << 4) | 18074 first.Encode(22, 12) | (len_encoding << 8) | 18075 (rn.GetCode() << 16)); 18076 AdvanceIT(); 18077 return; 18078 } 18079 } 18080 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18081 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18082 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18083 operand.IsOffset() && encoded_align_2.IsValid() && 18084 (!rn.IsPC() || AllowUnpredictable())) { 18085 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18086 const DRegister& first = nreglist.GetFirstDRegister(); 18087 uint32_t len_encoding = nreglist.GetLength() - 1; 18088 EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) | 18089 (encoded_align_2.GetEncodingValue() << 4) | 18090 first.Encode(22, 12) | (len_encoding << 5) | 18091 (rn.GetCode() << 16)); 18092 AdvanceIT(); 18093 return; 18094 } 18095 } 18096 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18097 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18098 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18099 operand.IsPostIndex() && encoded_align_2.IsValid() && 18100 (!rn.IsPC() || AllowUnpredictable())) { 18101 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18102 const DRegister& first = nreglist.GetFirstDRegister(); 18103 uint32_t len_encoding = nreglist.GetLength() - 1; 18104 EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) | 18105 (encoded_align_2.GetEncodingValue() << 4) | 18106 first.Encode(22, 12) | (len_encoding << 5) | 18107 (rn.GetCode() << 16)); 18108 AdvanceIT(); 18109 return; 18110 } 18111 } 18112 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18113 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18114 (nreglist.GetLength() == 1) && operand.IsOffset() && 18115 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 18116 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18117 const DRegister& first = nreglist.GetFirstDRegister(); 18118 EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) | 18119 (encoded_align_3.GetEncodingValue() << 4) | 18120 first.Encode(22, 12) | (rn.GetCode() << 16)); 18121 AdvanceIT(); 18122 return; 18123 } 18124 } 18125 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18126 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18127 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 18128 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 18129 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18130 const DRegister& first = nreglist.GetFirstDRegister(); 18131 EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) | 18132 (encoded_align_3.GetEncodingValue() << 4) | 18133 first.Encode(22, 12) | (rn.GetCode() << 16)); 18134 AdvanceIT(); 18135 return; 18136 } 18137 } 18138 } else { 18139 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18140 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18141 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18142 operand.IsOffset() && encoded_align_1.IsValid() && 18143 (!rn.IsPC() || AllowUnpredictable())) { 18144 if (cond.Is(al)) { 18145 const DRegister& first = nreglist.GetFirstDRegister(); 18146 uint32_t len_encoding; 18147 switch (nreglist.GetLength()) { 18148 default: 18149 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18150 case 1: 18151 len_encoding = 0x7; 18152 break; 18153 case 2: 18154 len_encoding = 0xa; 18155 break; 18156 case 3: 18157 len_encoding = 0x6; 18158 break; 18159 case 4: 18160 len_encoding = 0x2; 18161 break; 18162 } 18163 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 18164 (encoded_align_1.GetEncodingValue() << 4) | 18165 first.Encode(22, 12) | (len_encoding << 8) | 18166 (rn.GetCode() << 16)); 18167 return; 18168 } 18169 } 18170 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18171 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18172 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18173 operand.IsPostIndex() && encoded_align_1.IsValid() && 18174 (!rn.IsPC() || AllowUnpredictable())) { 18175 if (cond.Is(al)) { 18176 const DRegister& first = nreglist.GetFirstDRegister(); 18177 uint32_t len_encoding; 18178 switch (nreglist.GetLength()) { 18179 default: 18180 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18181 case 1: 18182 len_encoding = 0x7; 18183 break; 18184 case 2: 18185 len_encoding = 0xa; 18186 break; 18187 case 3: 18188 len_encoding = 0x6; 18189 break; 18190 case 4: 18191 len_encoding = 0x2; 18192 break; 18193 } 18194 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 18195 (encoded_align_1.GetEncodingValue() << 4) | 18196 first.Encode(22, 12) | (len_encoding << 8) | 18197 (rn.GetCode() << 16)); 18198 return; 18199 } 18200 } 18201 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18202 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18203 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18204 operand.IsOffset() && encoded_align_2.IsValid() && 18205 (!rn.IsPC() || AllowUnpredictable())) { 18206 if (cond.Is(al)) { 18207 const DRegister& first = nreglist.GetFirstDRegister(); 18208 uint32_t len_encoding = nreglist.GetLength() - 1; 18209 EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) | 18210 (encoded_align_2.GetEncodingValue() << 4) | 18211 first.Encode(22, 12) | (len_encoding << 5) | 18212 (rn.GetCode() << 16)); 18213 return; 18214 } 18215 } 18216 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18217 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18218 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18219 operand.IsPostIndex() && encoded_align_2.IsValid() && 18220 (!rn.IsPC() || AllowUnpredictable())) { 18221 if (cond.Is(al)) { 18222 const DRegister& first = nreglist.GetFirstDRegister(); 18223 uint32_t len_encoding = nreglist.GetLength() - 1; 18224 EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) | 18225 (encoded_align_2.GetEncodingValue() << 4) | 18226 first.Encode(22, 12) | (len_encoding << 5) | 18227 (rn.GetCode() << 16)); 18228 return; 18229 } 18230 } 18231 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18232 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18233 (nreglist.GetLength() == 1) && operand.IsOffset() && 18234 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 18235 if (cond.Is(al)) { 18236 const DRegister& first = nreglist.GetFirstDRegister(); 18237 EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) | 18238 (encoded_align_3.GetEncodingValue() << 4) | 18239 first.Encode(22, 12) | (rn.GetCode() << 16)); 18240 return; 18241 } 18242 } 18243 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18244 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18245 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 18246 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 18247 if (cond.Is(al)) { 18248 const DRegister& first = nreglist.GetFirstDRegister(); 18249 EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) | 18250 (encoded_align_3.GetEncodingValue() << 4) | 18251 first.Encode(22, 12) | (rn.GetCode() << 16)); 18252 return; 18253 } 18254 } 18255 } 18256 } 18257 if (operand.IsPlainRegister()) { 18258 Register rn = operand.GetBaseRegister(); 18259 Alignment align = operand.GetAlignment(); 18260 Register rm = operand.GetOffsetRegister(); 18261 Dt_size_6 encoded_dt(dt); 18262 Dt_size_7 encoded_dt_2(dt); 18263 Align_align_1 encoded_align_1(align, nreglist); 18264 Align_a_1 encoded_align_2(align, dt); 18265 Align_index_align_1 encoded_align_3(align, nreglist, dt); 18266 if (IsUsingT32()) { 18267 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18268 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18269 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18270 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18271 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18272 const DRegister& first = nreglist.GetFirstDRegister(); 18273 uint32_t len_encoding; 18274 switch (nreglist.GetLength()) { 18275 default: 18276 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18277 case 1: 18278 len_encoding = 0x7; 18279 break; 18280 case 2: 18281 len_encoding = 0xa; 18282 break; 18283 case 3: 18284 len_encoding = 0x6; 18285 break; 18286 case 4: 18287 len_encoding = 0x2; 18288 break; 18289 } 18290 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 18291 (encoded_align_1.GetEncodingValue() << 4) | 18292 first.Encode(22, 12) | (len_encoding << 8) | 18293 (rn.GetCode() << 16) | rm.GetCode()); 18294 AdvanceIT(); 18295 return; 18296 } 18297 } 18298 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18299 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18300 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18301 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18302 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18303 const DRegister& first = nreglist.GetFirstDRegister(); 18304 uint32_t len_encoding = nreglist.GetLength() - 1; 18305 EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) | 18306 (encoded_align_2.GetEncodingValue() << 4) | 18307 first.Encode(22, 12) | (len_encoding << 5) | 18308 (rn.GetCode() << 16) | rm.GetCode()); 18309 AdvanceIT(); 18310 return; 18311 } 18312 } 18313 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18314 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18315 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() && 18316 (!rn.IsPC() || AllowUnpredictable())) { 18317 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18318 const DRegister& first = nreglist.GetFirstDRegister(); 18319 EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) | 18320 (encoded_align_3.GetEncodingValue() << 4) | 18321 first.Encode(22, 12) | (rn.GetCode() << 16) | 18322 rm.GetCode()); 18323 AdvanceIT(); 18324 return; 18325 } 18326 } 18327 } else { 18328 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18329 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18330 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18331 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18332 if (cond.Is(al)) { 18333 const DRegister& first = nreglist.GetFirstDRegister(); 18334 uint32_t len_encoding; 18335 switch (nreglist.GetLength()) { 18336 default: 18337 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18338 case 1: 18339 len_encoding = 0x7; 18340 break; 18341 case 2: 18342 len_encoding = 0xa; 18343 break; 18344 case 3: 18345 len_encoding = 0x6; 18346 break; 18347 case 4: 18348 len_encoding = 0x2; 18349 break; 18350 } 18351 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 18352 (encoded_align_1.GetEncodingValue() << 4) | 18353 first.Encode(22, 12) | (len_encoding << 8) | 18354 (rn.GetCode() << 16) | rm.GetCode()); 18355 return; 18356 } 18357 } 18358 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18359 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18360 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18361 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18362 if (cond.Is(al)) { 18363 const DRegister& first = nreglist.GetFirstDRegister(); 18364 uint32_t len_encoding = nreglist.GetLength() - 1; 18365 EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) | 18366 (encoded_align_2.GetEncodingValue() << 4) | 18367 first.Encode(22, 12) | (len_encoding << 5) | 18368 (rn.GetCode() << 16) | rm.GetCode()); 18369 return; 18370 } 18371 } 18372 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18373 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18374 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() && 18375 (!rn.IsPC() || AllowUnpredictable())) { 18376 if (cond.Is(al)) { 18377 const DRegister& first = nreglist.GetFirstDRegister(); 18378 EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) | 18379 (encoded_align_3.GetEncodingValue() << 4) | 18380 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 18381 return; 18382 } 18383 } 18384 } 18385 } 18386 Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand); 18387 } 18388 18389 void Assembler::vld2(Condition cond, 18390 DataType dt, 18391 const NeonRegisterList& nreglist, 18392 const AlignedMemOperand& operand) { 18393 VIXL_ASSERT(AllowAssembler()); 18394 CheckIT(cond); 18395 if (operand.IsImmediateZero()) { 18396 Register rn = operand.GetBaseRegister(); 18397 Alignment align = operand.GetAlignment(); 18398 Dt_size_7 encoded_dt(dt); 18399 Align_align_2 encoded_align_1(align, nreglist); 18400 Align_a_2 encoded_align_2(align, dt); 18401 Align_index_align_2 encoded_align_3(align, nreglist, dt); 18402 if (IsUsingT32()) { 18403 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18404 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18405 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18406 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18407 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18408 operand.IsOffset() && encoded_align_1.IsValid() && 18409 (!rn.IsPC() || AllowUnpredictable())) { 18410 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18411 const DRegister& first = nreglist.GetFirstDRegister(); 18412 uint32_t len_encoding; 18413 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18414 len_encoding = 0x8; 18415 } 18416 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18417 len_encoding = 0x9; 18418 } 18419 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18420 len_encoding = 0x3; 18421 } 18422 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 18423 (encoded_align_1.GetEncodingValue() << 4) | 18424 first.Encode(22, 12) | (len_encoding << 8) | 18425 (rn.GetCode() << 16)); 18426 AdvanceIT(); 18427 return; 18428 } 18429 } 18430 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18431 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18432 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18433 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18434 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18435 operand.IsPostIndex() && encoded_align_1.IsValid() && 18436 (!rn.IsPC() || AllowUnpredictable())) { 18437 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18438 const DRegister& first = nreglist.GetFirstDRegister(); 18439 uint32_t len_encoding; 18440 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18441 len_encoding = 0x8; 18442 } 18443 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18444 len_encoding = 0x9; 18445 } 18446 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18447 len_encoding = 0x3; 18448 } 18449 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 18450 (encoded_align_1.GetEncodingValue() << 4) | 18451 first.Encode(22, 12) | (len_encoding << 8) | 18452 (rn.GetCode() << 16)); 18453 AdvanceIT(); 18454 return; 18455 } 18456 } 18457 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18458 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18459 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18460 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18461 operand.IsOffset() && encoded_align_2.IsValid() && 18462 (!rn.IsPC() || AllowUnpredictable())) { 18463 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18464 const DRegister& first = nreglist.GetFirstDRegister(); 18465 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18466 EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) | 18467 (encoded_align_2.GetEncodingValue() << 4) | 18468 first.Encode(22, 12) | (len_encoding << 5) | 18469 (rn.GetCode() << 16)); 18470 AdvanceIT(); 18471 return; 18472 } 18473 } 18474 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18475 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18476 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18477 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18478 operand.IsPostIndex() && encoded_align_2.IsValid() && 18479 (!rn.IsPC() || AllowUnpredictable())) { 18480 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18481 const DRegister& first = nreglist.GetFirstDRegister(); 18482 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18483 EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) | 18484 (encoded_align_2.GetEncodingValue() << 4) | 18485 first.Encode(22, 12) | (len_encoding << 5) | 18486 (rn.GetCode() << 16)); 18487 AdvanceIT(); 18488 return; 18489 } 18490 } 18491 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18492 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18493 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18494 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18495 operand.IsOffset() && encoded_align_3.IsValid() && 18496 (!rn.IsPC() || AllowUnpredictable())) { 18497 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18498 const DRegister& first = nreglist.GetFirstDRegister(); 18499 EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) | 18500 (encoded_align_3.GetEncodingValue() << 4) | 18501 first.Encode(22, 12) | (rn.GetCode() << 16)); 18502 AdvanceIT(); 18503 return; 18504 } 18505 } 18506 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18507 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18508 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18509 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18510 operand.IsPostIndex() && encoded_align_3.IsValid() && 18511 (!rn.IsPC() || AllowUnpredictable())) { 18512 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18513 const DRegister& first = nreglist.GetFirstDRegister(); 18514 EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) | 18515 (encoded_align_3.GetEncodingValue() << 4) | 18516 first.Encode(22, 12) | (rn.GetCode() << 16)); 18517 AdvanceIT(); 18518 return; 18519 } 18520 } 18521 } else { 18522 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18523 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18524 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18525 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18526 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18527 operand.IsOffset() && encoded_align_1.IsValid() && 18528 (!rn.IsPC() || AllowUnpredictable())) { 18529 if (cond.Is(al)) { 18530 const DRegister& first = nreglist.GetFirstDRegister(); 18531 uint32_t len_encoding; 18532 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18533 len_encoding = 0x8; 18534 } 18535 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18536 len_encoding = 0x9; 18537 } 18538 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18539 len_encoding = 0x3; 18540 } 18541 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 18542 (encoded_align_1.GetEncodingValue() << 4) | 18543 first.Encode(22, 12) | (len_encoding << 8) | 18544 (rn.GetCode() << 16)); 18545 return; 18546 } 18547 } 18548 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18549 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18550 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18551 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18552 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18553 operand.IsPostIndex() && encoded_align_1.IsValid() && 18554 (!rn.IsPC() || AllowUnpredictable())) { 18555 if (cond.Is(al)) { 18556 const DRegister& first = nreglist.GetFirstDRegister(); 18557 uint32_t len_encoding; 18558 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18559 len_encoding = 0x8; 18560 } 18561 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18562 len_encoding = 0x9; 18563 } 18564 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18565 len_encoding = 0x3; 18566 } 18567 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 18568 (encoded_align_1.GetEncodingValue() << 4) | 18569 first.Encode(22, 12) | (len_encoding << 8) | 18570 (rn.GetCode() << 16)); 18571 return; 18572 } 18573 } 18574 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18575 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18576 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18577 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18578 operand.IsOffset() && encoded_align_2.IsValid() && 18579 (!rn.IsPC() || AllowUnpredictable())) { 18580 if (cond.Is(al)) { 18581 const DRegister& first = nreglist.GetFirstDRegister(); 18582 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18583 EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) | 18584 (encoded_align_2.GetEncodingValue() << 4) | 18585 first.Encode(22, 12) | (len_encoding << 5) | 18586 (rn.GetCode() << 16)); 18587 return; 18588 } 18589 } 18590 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18591 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18592 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18593 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18594 operand.IsPostIndex() && encoded_align_2.IsValid() && 18595 (!rn.IsPC() || AllowUnpredictable())) { 18596 if (cond.Is(al)) { 18597 const DRegister& first = nreglist.GetFirstDRegister(); 18598 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18599 EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) | 18600 (encoded_align_2.GetEncodingValue() << 4) | 18601 first.Encode(22, 12) | (len_encoding << 5) | 18602 (rn.GetCode() << 16)); 18603 return; 18604 } 18605 } 18606 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18607 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18608 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18609 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18610 operand.IsOffset() && encoded_align_3.IsValid() && 18611 (!rn.IsPC() || AllowUnpredictable())) { 18612 if (cond.Is(al)) { 18613 const DRegister& first = nreglist.GetFirstDRegister(); 18614 EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) | 18615 (encoded_align_3.GetEncodingValue() << 4) | 18616 first.Encode(22, 12) | (rn.GetCode() << 16)); 18617 return; 18618 } 18619 } 18620 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18621 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18622 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18623 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18624 operand.IsPostIndex() && encoded_align_3.IsValid() && 18625 (!rn.IsPC() || AllowUnpredictable())) { 18626 if (cond.Is(al)) { 18627 const DRegister& first = nreglist.GetFirstDRegister(); 18628 EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) | 18629 (encoded_align_3.GetEncodingValue() << 4) | 18630 first.Encode(22, 12) | (rn.GetCode() << 16)); 18631 return; 18632 } 18633 } 18634 } 18635 } 18636 if (operand.IsPlainRegister()) { 18637 Register rn = operand.GetBaseRegister(); 18638 Alignment align = operand.GetAlignment(); 18639 Register rm = operand.GetOffsetRegister(); 18640 Dt_size_7 encoded_dt(dt); 18641 Align_align_2 encoded_align_1(align, nreglist); 18642 Align_a_2 encoded_align_2(align, dt); 18643 Align_index_align_2 encoded_align_3(align, nreglist, dt); 18644 if (IsUsingT32()) { 18645 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18646 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18647 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18648 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18649 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18650 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18651 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18652 const DRegister& first = nreglist.GetFirstDRegister(); 18653 uint32_t len_encoding; 18654 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18655 len_encoding = 0x8; 18656 } 18657 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18658 len_encoding = 0x9; 18659 } 18660 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18661 len_encoding = 0x3; 18662 } 18663 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 18664 (encoded_align_1.GetEncodingValue() << 4) | 18665 first.Encode(22, 12) | (len_encoding << 8) | 18666 (rn.GetCode() << 16) | rm.GetCode()); 18667 AdvanceIT(); 18668 return; 18669 } 18670 } 18671 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18672 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18673 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18674 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18675 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18676 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18677 const DRegister& first = nreglist.GetFirstDRegister(); 18678 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18679 EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) | 18680 (encoded_align_2.GetEncodingValue() << 4) | 18681 first.Encode(22, 12) | (len_encoding << 5) | 18682 (rn.GetCode() << 16) | rm.GetCode()); 18683 AdvanceIT(); 18684 return; 18685 } 18686 } 18687 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18688 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18689 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18690 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18691 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18692 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18693 const DRegister& first = nreglist.GetFirstDRegister(); 18694 EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) | 18695 (encoded_align_3.GetEncodingValue() << 4) | 18696 first.Encode(22, 12) | (rn.GetCode() << 16) | 18697 rm.GetCode()); 18698 AdvanceIT(); 18699 return; 18700 } 18701 } 18702 } else { 18703 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18704 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18705 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18706 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18707 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18708 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18709 if (cond.Is(al)) { 18710 const DRegister& first = nreglist.GetFirstDRegister(); 18711 uint32_t len_encoding; 18712 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18713 len_encoding = 0x8; 18714 } 18715 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18716 len_encoding = 0x9; 18717 } 18718 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18719 len_encoding = 0x3; 18720 } 18721 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 18722 (encoded_align_1.GetEncodingValue() << 4) | 18723 first.Encode(22, 12) | (len_encoding << 8) | 18724 (rn.GetCode() << 16) | rm.GetCode()); 18725 return; 18726 } 18727 } 18728 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18729 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18730 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18731 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18732 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18733 if (cond.Is(al)) { 18734 const DRegister& first = nreglist.GetFirstDRegister(); 18735 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18736 EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) | 18737 (encoded_align_2.GetEncodingValue() << 4) | 18738 first.Encode(22, 12) | (len_encoding << 5) | 18739 (rn.GetCode() << 16) | rm.GetCode()); 18740 return; 18741 } 18742 } 18743 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18744 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18745 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18746 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18747 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18748 if (cond.Is(al)) { 18749 const DRegister& first = nreglist.GetFirstDRegister(); 18750 EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) | 18751 (encoded_align_3.GetEncodingValue() << 4) | 18752 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 18753 return; 18754 } 18755 } 18756 } 18757 } 18758 Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand); 18759 } 18760 18761 void Assembler::vld3(Condition cond, 18762 DataType dt, 18763 const NeonRegisterList& nreglist, 18764 const AlignedMemOperand& operand) { 18765 VIXL_ASSERT(AllowAssembler()); 18766 CheckIT(cond); 18767 if (operand.IsImmediateZero()) { 18768 Register rn = operand.GetBaseRegister(); 18769 Alignment align = operand.GetAlignment(); 18770 Dt_size_7 encoded_dt(dt); 18771 Align_align_3 encoded_align_1(align); 18772 if (IsUsingT32()) { 18773 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18774 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18775 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18776 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18777 operand.IsOffset() && encoded_align_1.IsValid() && 18778 (!rn.IsPC() || AllowUnpredictable())) { 18779 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18780 const DRegister& first = nreglist.GetFirstDRegister(); 18781 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18782 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 18783 (encoded_align_1.GetEncodingValue() << 4) | 18784 first.Encode(22, 12) | (len_encoding << 8) | 18785 (rn.GetCode() << 16)); 18786 AdvanceIT(); 18787 return; 18788 } 18789 } 18790 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18791 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18792 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18793 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18794 operand.IsPostIndex() && encoded_align_1.IsValid() && 18795 (!rn.IsPC() || AllowUnpredictable())) { 18796 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18797 const DRegister& first = nreglist.GetFirstDRegister(); 18798 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18799 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 18800 (encoded_align_1.GetEncodingValue() << 4) | 18801 first.Encode(22, 12) | (len_encoding << 8) | 18802 (rn.GetCode() << 16)); 18803 AdvanceIT(); 18804 return; 18805 } 18806 } 18807 } else { 18808 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18809 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18810 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18811 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18812 operand.IsOffset() && encoded_align_1.IsValid() && 18813 (!rn.IsPC() || AllowUnpredictable())) { 18814 if (cond.Is(al)) { 18815 const DRegister& first = nreglist.GetFirstDRegister(); 18816 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18817 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 18818 (encoded_align_1.GetEncodingValue() << 4) | 18819 first.Encode(22, 12) | (len_encoding << 8) | 18820 (rn.GetCode() << 16)); 18821 return; 18822 } 18823 } 18824 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18825 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18826 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18827 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18828 operand.IsPostIndex() && encoded_align_1.IsValid() && 18829 (!rn.IsPC() || AllowUnpredictable())) { 18830 if (cond.Is(al)) { 18831 const DRegister& first = nreglist.GetFirstDRegister(); 18832 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18833 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 18834 (encoded_align_1.GetEncodingValue() << 4) | 18835 first.Encode(22, 12) | (len_encoding << 8) | 18836 (rn.GetCode() << 16)); 18837 return; 18838 } 18839 } 18840 } 18841 } 18842 if (operand.IsPlainRegister()) { 18843 Register rn = operand.GetBaseRegister(); 18844 Alignment align = operand.GetAlignment(); 18845 Register rm = operand.GetOffsetRegister(); 18846 Dt_size_7 encoded_dt(dt); 18847 Align_align_3 encoded_align_1(align); 18848 if (IsUsingT32()) { 18849 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18850 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18851 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18852 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18853 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18854 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18855 const DRegister& first = nreglist.GetFirstDRegister(); 18856 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18857 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 18858 (encoded_align_1.GetEncodingValue() << 4) | 18859 first.Encode(22, 12) | (len_encoding << 8) | 18860 (rn.GetCode() << 16) | rm.GetCode()); 18861 AdvanceIT(); 18862 return; 18863 } 18864 } 18865 } else { 18866 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18867 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18868 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18869 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18870 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18871 if (cond.Is(al)) { 18872 const DRegister& first = nreglist.GetFirstDRegister(); 18873 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18874 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 18875 (encoded_align_1.GetEncodingValue() << 4) | 18876 first.Encode(22, 12) | (len_encoding << 8) | 18877 (rn.GetCode() << 16) | rm.GetCode()); 18878 return; 18879 } 18880 } 18881 } 18882 } 18883 Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand); 18884 } 18885 18886 void Assembler::vld3(Condition cond, 18887 DataType dt, 18888 const NeonRegisterList& nreglist, 18889 const MemOperand& operand) { 18890 VIXL_ASSERT(AllowAssembler()); 18891 CheckIT(cond); 18892 if (operand.IsImmediateZero()) { 18893 Register rn = operand.GetBaseRegister(); 18894 Dt_size_7 encoded_dt(dt); 18895 Index_1 encoded_align_1(nreglist, dt); 18896 if (IsUsingT32()) { 18897 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 18898 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18899 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18900 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18901 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 18902 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18903 const DRegister& first = nreglist.GetFirstDRegister(); 18904 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18905 EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) | 18906 first.Encode(22, 12) | (len_encoding << 5) | 18907 (rn.GetCode() << 16)); 18908 AdvanceIT(); 18909 return; 18910 } 18911 } 18912 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 18913 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18914 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18915 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18916 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 18917 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18918 const DRegister& first = nreglist.GetFirstDRegister(); 18919 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18920 EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) | 18921 first.Encode(22, 12) | (len_encoding << 5) | 18922 (rn.GetCode() << 16)); 18923 AdvanceIT(); 18924 return; 18925 } 18926 } 18927 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 18928 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18929 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18930 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18931 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 18932 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18933 const DRegister& first = nreglist.GetFirstDRegister(); 18934 EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) | 18935 (encoded_align_1.GetEncodingValue() << 4) | 18936 first.Encode(22, 12) | (rn.GetCode() << 16)); 18937 AdvanceIT(); 18938 return; 18939 } 18940 } 18941 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 18942 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18943 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18944 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18945 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 18946 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18947 const DRegister& first = nreglist.GetFirstDRegister(); 18948 EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) | 18949 (encoded_align_1.GetEncodingValue() << 4) | 18950 first.Encode(22, 12) | (rn.GetCode() << 16)); 18951 AdvanceIT(); 18952 return; 18953 } 18954 } 18955 } else { 18956 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 18957 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18958 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18959 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18960 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 18961 if (cond.Is(al)) { 18962 const DRegister& first = nreglist.GetFirstDRegister(); 18963 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18964 EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) | 18965 first.Encode(22, 12) | (len_encoding << 5) | 18966 (rn.GetCode() << 16)); 18967 return; 18968 } 18969 } 18970 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 18971 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18972 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18973 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18974 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 18975 if (cond.Is(al)) { 18976 const DRegister& first = nreglist.GetFirstDRegister(); 18977 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18978 EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) | 18979 first.Encode(22, 12) | (len_encoding << 5) | 18980 (rn.GetCode() << 16)); 18981 return; 18982 } 18983 } 18984 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 18985 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18986 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18987 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18988 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 18989 if (cond.Is(al)) { 18990 const DRegister& first = nreglist.GetFirstDRegister(); 18991 EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) | 18992 (encoded_align_1.GetEncodingValue() << 4) | 18993 first.Encode(22, 12) | (rn.GetCode() << 16)); 18994 return; 18995 } 18996 } 18997 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 18998 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18999 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 19000 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 19001 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 19002 if (cond.Is(al)) { 19003 const DRegister& first = nreglist.GetFirstDRegister(); 19004 EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) | 19005 (encoded_align_1.GetEncodingValue() << 4) | 19006 first.Encode(22, 12) | (rn.GetCode() << 16)); 19007 return; 19008 } 19009 } 19010 } 19011 } 19012 if (operand.IsPlainRegister()) { 19013 Register rn = operand.GetBaseRegister(); 19014 Sign sign = operand.GetSign(); 19015 Register rm = operand.GetOffsetRegister(); 19016 Dt_size_7 encoded_dt(dt); 19017 Index_1 encoded_align_1(nreglist, dt); 19018 if (IsUsingT32()) { 19019 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 19020 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 19021 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 19022 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 19023 sign.IsPlus() && operand.IsPostIndex() && 19024 (!rn.IsPC() || AllowUnpredictable())) { 19025 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19026 const DRegister& first = nreglist.GetFirstDRegister(); 19027 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19028 EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) | 19029 first.Encode(22, 12) | (len_encoding << 5) | 19030 (rn.GetCode() << 16) | rm.GetCode()); 19031 AdvanceIT(); 19032 return; 19033 } 19034 } 19035 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 19036 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19037 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 19038 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 19039 sign.IsPlus() && operand.IsPostIndex() && 19040 (!rn.IsPC() || AllowUnpredictable())) { 19041 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19042 const DRegister& first = nreglist.GetFirstDRegister(); 19043 EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) | 19044 (encoded_align_1.GetEncodingValue() << 4) | 19045 first.Encode(22, 12) | (rn.GetCode() << 16) | 19046 rm.GetCode()); 19047 AdvanceIT(); 19048 return; 19049 } 19050 } 19051 } else { 19052 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 19053 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 19054 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 19055 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 19056 sign.IsPlus() && operand.IsPostIndex() && 19057 (!rn.IsPC() || AllowUnpredictable())) { 19058 if (cond.Is(al)) { 19059 const DRegister& first = nreglist.GetFirstDRegister(); 19060 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19061 EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) | 19062 first.Encode(22, 12) | (len_encoding << 5) | 19063 (rn.GetCode() << 16) | rm.GetCode()); 19064 return; 19065 } 19066 } 19067 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 19068 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19069 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 19070 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 19071 sign.IsPlus() && operand.IsPostIndex() && 19072 (!rn.IsPC() || AllowUnpredictable())) { 19073 if (cond.Is(al)) { 19074 const DRegister& first = nreglist.GetFirstDRegister(); 19075 EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) | 19076 (encoded_align_1.GetEncodingValue() << 4) | 19077 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 19078 return; 19079 } 19080 } 19081 } 19082 } 19083 Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand); 19084 } 19085 19086 void Assembler::vld4(Condition cond, 19087 DataType dt, 19088 const NeonRegisterList& nreglist, 19089 const AlignedMemOperand& operand) { 19090 VIXL_ASSERT(AllowAssembler()); 19091 CheckIT(cond); 19092 if (operand.IsImmediateZero()) { 19093 Register rn = operand.GetBaseRegister(); 19094 Alignment align = operand.GetAlignment(); 19095 Dt_size_7 encoded_dt(dt); 19096 Dt_size_8 encoded_dt_2(dt, align); 19097 Align_align_4 encoded_align_1(align); 19098 Align_a_3 encoded_align_2(align, dt); 19099 Align_index_align_3 encoded_align_3(align, nreglist, dt); 19100 if (IsUsingT32()) { 19101 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 19102 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19103 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19104 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19105 operand.IsOffset() && encoded_align_1.IsValid() && 19106 (!rn.IsPC() || AllowUnpredictable())) { 19107 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19108 const DRegister& first = nreglist.GetFirstDRegister(); 19109 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19110 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 19111 (encoded_align_1.GetEncodingValue() << 4) | 19112 first.Encode(22, 12) | (len_encoding << 8) | 19113 (rn.GetCode() << 16)); 19114 AdvanceIT(); 19115 return; 19116 } 19117 } 19118 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 19119 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19120 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19121 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19122 operand.IsPostIndex() && encoded_align_1.IsValid() && 19123 (!rn.IsPC() || AllowUnpredictable())) { 19124 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19125 const DRegister& first = nreglist.GetFirstDRegister(); 19126 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19127 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 19128 (encoded_align_1.GetEncodingValue() << 4) | 19129 first.Encode(22, 12) | (len_encoding << 8) | 19130 (rn.GetCode() << 16)); 19131 AdvanceIT(); 19132 return; 19133 } 19134 } 19135 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 19136 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19137 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19138 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19139 operand.IsOffset() && encoded_align_2.IsValid() && 19140 (!rn.IsPC() || AllowUnpredictable())) { 19141 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19142 const DRegister& first = nreglist.GetFirstDRegister(); 19143 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19144 EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) | 19145 (encoded_align_2.GetEncodingValue() << 4) | 19146 first.Encode(22, 12) | (len_encoding << 5) | 19147 (rn.GetCode() << 16)); 19148 AdvanceIT(); 19149 return; 19150 } 19151 } 19152 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 19153 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19154 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19155 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19156 operand.IsPostIndex() && encoded_align_2.IsValid() && 19157 (!rn.IsPC() || AllowUnpredictable())) { 19158 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19159 const DRegister& first = nreglist.GetFirstDRegister(); 19160 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19161 EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) | 19162 (encoded_align_2.GetEncodingValue() << 4) | 19163 first.Encode(22, 12) | (len_encoding << 5) | 19164 (rn.GetCode() << 16)); 19165 AdvanceIT(); 19166 return; 19167 } 19168 } 19169 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 19170 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19171 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19172 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19173 operand.IsOffset() && encoded_align_3.IsValid() && 19174 (!rn.IsPC() || AllowUnpredictable())) { 19175 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19176 const DRegister& first = nreglist.GetFirstDRegister(); 19177 EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) | 19178 (encoded_align_3.GetEncodingValue() << 4) | 19179 first.Encode(22, 12) | (rn.GetCode() << 16)); 19180 AdvanceIT(); 19181 return; 19182 } 19183 } 19184 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 19185 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19186 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19187 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19188 operand.IsPostIndex() && encoded_align_3.IsValid() && 19189 (!rn.IsPC() || AllowUnpredictable())) { 19190 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19191 const DRegister& first = nreglist.GetFirstDRegister(); 19192 EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) | 19193 (encoded_align_3.GetEncodingValue() << 4) | 19194 first.Encode(22, 12) | (rn.GetCode() << 16)); 19195 AdvanceIT(); 19196 return; 19197 } 19198 } 19199 } else { 19200 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 19201 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19202 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19203 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19204 operand.IsOffset() && encoded_align_1.IsValid() && 19205 (!rn.IsPC() || AllowUnpredictable())) { 19206 if (cond.Is(al)) { 19207 const DRegister& first = nreglist.GetFirstDRegister(); 19208 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19209 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 19210 (encoded_align_1.GetEncodingValue() << 4) | 19211 first.Encode(22, 12) | (len_encoding << 8) | 19212 (rn.GetCode() << 16)); 19213 return; 19214 } 19215 } 19216 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 19217 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19218 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19219 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19220 operand.IsPostIndex() && encoded_align_1.IsValid() && 19221 (!rn.IsPC() || AllowUnpredictable())) { 19222 if (cond.Is(al)) { 19223 const DRegister& first = nreglist.GetFirstDRegister(); 19224 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19225 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 19226 (encoded_align_1.GetEncodingValue() << 4) | 19227 first.Encode(22, 12) | (len_encoding << 8) | 19228 (rn.GetCode() << 16)); 19229 return; 19230 } 19231 } 19232 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 19233 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19234 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19235 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19236 operand.IsOffset() && encoded_align_2.IsValid() && 19237 (!rn.IsPC() || AllowUnpredictable())) { 19238 if (cond.Is(al)) { 19239 const DRegister& first = nreglist.GetFirstDRegister(); 19240 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19241 EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) | 19242 (encoded_align_2.GetEncodingValue() << 4) | 19243 first.Encode(22, 12) | (len_encoding << 5) | 19244 (rn.GetCode() << 16)); 19245 return; 19246 } 19247 } 19248 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 19249 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19250 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19251 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19252 operand.IsPostIndex() && encoded_align_2.IsValid() && 19253 (!rn.IsPC() || AllowUnpredictable())) { 19254 if (cond.Is(al)) { 19255 const DRegister& first = nreglist.GetFirstDRegister(); 19256 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19257 EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) | 19258 (encoded_align_2.GetEncodingValue() << 4) | 19259 first.Encode(22, 12) | (len_encoding << 5) | 19260 (rn.GetCode() << 16)); 19261 return; 19262 } 19263 } 19264 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 19265 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19266 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19267 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19268 operand.IsOffset() && encoded_align_3.IsValid() && 19269 (!rn.IsPC() || AllowUnpredictable())) { 19270 if (cond.Is(al)) { 19271 const DRegister& first = nreglist.GetFirstDRegister(); 19272 EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) | 19273 (encoded_align_3.GetEncodingValue() << 4) | 19274 first.Encode(22, 12) | (rn.GetCode() << 16)); 19275 return; 19276 } 19277 } 19278 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 19279 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19280 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19281 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19282 operand.IsPostIndex() && encoded_align_3.IsValid() && 19283 (!rn.IsPC() || AllowUnpredictable())) { 19284 if (cond.Is(al)) { 19285 const DRegister& first = nreglist.GetFirstDRegister(); 19286 EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) | 19287 (encoded_align_3.GetEncodingValue() << 4) | 19288 first.Encode(22, 12) | (rn.GetCode() << 16)); 19289 return; 19290 } 19291 } 19292 } 19293 } 19294 if (operand.IsPlainRegister()) { 19295 Register rn = operand.GetBaseRegister(); 19296 Alignment align = operand.GetAlignment(); 19297 Register rm = operand.GetOffsetRegister(); 19298 Dt_size_7 encoded_dt(dt); 19299 Dt_size_8 encoded_dt_2(dt, align); 19300 Align_align_4 encoded_align_1(align); 19301 Align_a_3 encoded_align_2(align, dt); 19302 Align_index_align_3 encoded_align_3(align, nreglist, dt); 19303 if (IsUsingT32()) { 19304 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 19305 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19306 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19307 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19308 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19309 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19310 const DRegister& first = nreglist.GetFirstDRegister(); 19311 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19312 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 19313 (encoded_align_1.GetEncodingValue() << 4) | 19314 first.Encode(22, 12) | (len_encoding << 8) | 19315 (rn.GetCode() << 16) | rm.GetCode()); 19316 AdvanceIT(); 19317 return; 19318 } 19319 } 19320 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 19321 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19322 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19323 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19324 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19325 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19326 const DRegister& first = nreglist.GetFirstDRegister(); 19327 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19328 EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) | 19329 (encoded_align_2.GetEncodingValue() << 4) | 19330 first.Encode(22, 12) | (len_encoding << 5) | 19331 (rn.GetCode() << 16) | rm.GetCode()); 19332 AdvanceIT(); 19333 return; 19334 } 19335 } 19336 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 19337 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19338 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19339 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19340 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19341 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19342 const DRegister& first = nreglist.GetFirstDRegister(); 19343 EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) | 19344 (encoded_align_3.GetEncodingValue() << 4) | 19345 first.Encode(22, 12) | (rn.GetCode() << 16) | 19346 rm.GetCode()); 19347 AdvanceIT(); 19348 return; 19349 } 19350 } 19351 } else { 19352 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 19353 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19354 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19355 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19356 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19357 if (cond.Is(al)) { 19358 const DRegister& first = nreglist.GetFirstDRegister(); 19359 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19360 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 19361 (encoded_align_1.GetEncodingValue() << 4) | 19362 first.Encode(22, 12) | (len_encoding << 8) | 19363 (rn.GetCode() << 16) | rm.GetCode()); 19364 return; 19365 } 19366 } 19367 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 19368 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19369 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19370 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19371 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19372 if (cond.Is(al)) { 19373 const DRegister& first = nreglist.GetFirstDRegister(); 19374 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19375 EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) | 19376 (encoded_align_2.GetEncodingValue() << 4) | 19377 first.Encode(22, 12) | (len_encoding << 5) | 19378 (rn.GetCode() << 16) | rm.GetCode()); 19379 return; 19380 } 19381 } 19382 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 19383 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19384 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19385 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19386 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19387 if (cond.Is(al)) { 19388 const DRegister& first = nreglist.GetFirstDRegister(); 19389 EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) | 19390 (encoded_align_3.GetEncodingValue() << 4) | 19391 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 19392 return; 19393 } 19394 } 19395 } 19396 } 19397 Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand); 19398 } 19399 19400 void Assembler::vldm(Condition cond, 19401 DataType dt, 19402 Register rn, 19403 WriteBack write_back, 19404 DRegisterList dreglist) { 19405 VIXL_ASSERT(AllowAssembler()); 19406 CheckIT(cond); 19407 USE(dt); 19408 if (IsUsingT32()) { 19409 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 19410 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) || 19411 AllowUnpredictable())) { 19412 const DRegister& dreg = dreglist.GetFirstDRegister(); 19413 unsigned len = dreglist.GetLength() * 2; 19414 EmitT32_32(0xec900b00U | (rn.GetCode() << 16) | 19415 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 19416 (len & 0xff)); 19417 AdvanceIT(); 19418 return; 19419 } 19420 } else { 19421 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 19422 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 19423 (!rn.IsPC() || !write_back.DoesWriteBack())) || 19424 AllowUnpredictable())) { 19425 const DRegister& dreg = dreglist.GetFirstDRegister(); 19426 unsigned len = dreglist.GetLength() * 2; 19427 EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19428 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 19429 (len & 0xff)); 19430 return; 19431 } 19432 } 19433 Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist); 19434 } 19435 19436 void Assembler::vldm(Condition cond, 19437 DataType dt, 19438 Register rn, 19439 WriteBack write_back, 19440 SRegisterList sreglist) { 19441 VIXL_ASSERT(AllowAssembler()); 19442 CheckIT(cond); 19443 USE(dt); 19444 if (IsUsingT32()) { 19445 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 19446 if ((!rn.IsPC() || AllowUnpredictable())) { 19447 const SRegister& sreg = sreglist.GetFirstSRegister(); 19448 unsigned len = sreglist.GetLength(); 19449 EmitT32_32(0xec900a00U | (rn.GetCode() << 16) | 19450 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 19451 (len & 0xff)); 19452 AdvanceIT(); 19453 return; 19454 } 19455 } else { 19456 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 19457 if (cond.IsNotNever() && 19458 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) { 19459 const SRegister& sreg = sreglist.GetFirstSRegister(); 19460 unsigned len = sreglist.GetLength(); 19461 EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19462 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 19463 (len & 0xff)); 19464 return; 19465 } 19466 } 19467 Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist); 19468 } 19469 19470 void Assembler::vldmdb(Condition cond, 19471 DataType dt, 19472 Register rn, 19473 WriteBack write_back, 19474 DRegisterList dreglist) { 19475 VIXL_ASSERT(AllowAssembler()); 19476 CheckIT(cond); 19477 USE(dt); 19478 if (IsUsingT32()) { 19479 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1 19480 if (write_back.DoesWriteBack() && 19481 (((dreglist.GetLength() <= 16) && !rn.IsPC()) || 19482 AllowUnpredictable())) { 19483 const DRegister& dreg = dreglist.GetFirstDRegister(); 19484 unsigned len = dreglist.GetLength() * 2; 19485 EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 19486 (len & 0xff)); 19487 AdvanceIT(); 19488 return; 19489 } 19490 } else { 19491 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1 19492 if (write_back.DoesWriteBack() && cond.IsNotNever() && 19493 (((dreglist.GetLength() <= 16) && !rn.IsPC()) || 19494 AllowUnpredictable())) { 19495 const DRegister& dreg = dreglist.GetFirstDRegister(); 19496 unsigned len = dreglist.GetLength() * 2; 19497 EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19498 dreg.Encode(22, 12) | (len & 0xff)); 19499 return; 19500 } 19501 } 19502 Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist); 19503 } 19504 19505 void Assembler::vldmdb(Condition cond, 19506 DataType dt, 19507 Register rn, 19508 WriteBack write_back, 19509 SRegisterList sreglist) { 19510 VIXL_ASSERT(AllowAssembler()); 19511 CheckIT(cond); 19512 USE(dt); 19513 if (IsUsingT32()) { 19514 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2 19515 if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) { 19516 const SRegister& sreg = sreglist.GetFirstSRegister(); 19517 unsigned len = sreglist.GetLength(); 19518 EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) | 19519 (len & 0xff)); 19520 AdvanceIT(); 19521 return; 19522 } 19523 } else { 19524 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2 19525 if (write_back.DoesWriteBack() && cond.IsNotNever() && 19526 (!rn.IsPC() || AllowUnpredictable())) { 19527 const SRegister& sreg = sreglist.GetFirstSRegister(); 19528 unsigned len = sreglist.GetLength(); 19529 EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19530 sreg.Encode(22, 12) | (len & 0xff)); 19531 return; 19532 } 19533 } 19534 Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist); 19535 } 19536 19537 void Assembler::vldmia(Condition cond, 19538 DataType dt, 19539 Register rn, 19540 WriteBack write_back, 19541 DRegisterList dreglist) { 19542 VIXL_ASSERT(AllowAssembler()); 19543 CheckIT(cond); 19544 USE(dt); 19545 if (IsUsingT32()) { 19546 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 19547 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) || 19548 AllowUnpredictable())) { 19549 const DRegister& dreg = dreglist.GetFirstDRegister(); 19550 unsigned len = dreglist.GetLength() * 2; 19551 EmitT32_32(0xec900b00U | (rn.GetCode() << 16) | 19552 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 19553 (len & 0xff)); 19554 AdvanceIT(); 19555 return; 19556 } 19557 } else { 19558 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 19559 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 19560 (!rn.IsPC() || !write_back.DoesWriteBack())) || 19561 AllowUnpredictable())) { 19562 const DRegister& dreg = dreglist.GetFirstDRegister(); 19563 unsigned len = dreglist.GetLength() * 2; 19564 EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19565 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 19566 (len & 0xff)); 19567 return; 19568 } 19569 } 19570 Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist); 19571 } 19572 19573 void Assembler::vldmia(Condition cond, 19574 DataType dt, 19575 Register rn, 19576 WriteBack write_back, 19577 SRegisterList sreglist) { 19578 VIXL_ASSERT(AllowAssembler()); 19579 CheckIT(cond); 19580 USE(dt); 19581 if (IsUsingT32()) { 19582 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 19583 if ((!rn.IsPC() || AllowUnpredictable())) { 19584 const SRegister& sreg = sreglist.GetFirstSRegister(); 19585 unsigned len = sreglist.GetLength(); 19586 EmitT32_32(0xec900a00U | (rn.GetCode() << 16) | 19587 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 19588 (len & 0xff)); 19589 AdvanceIT(); 19590 return; 19591 } 19592 } else { 19593 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 19594 if (cond.IsNotNever() && 19595 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) { 19596 const SRegister& sreg = sreglist.GetFirstSRegister(); 19597 unsigned len = sreglist.GetLength(); 19598 EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19599 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 19600 (len & 0xff)); 19601 return; 19602 } 19603 } 19604 Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist); 19605 } 19606 19607 void Assembler::vldr(Condition cond, 19608 DataType dt, 19609 DRegister rd, 19610 Location* location) { 19611 VIXL_ASSERT(AllowAssembler()); 19612 CheckIT(cond); 19613 Location::Offset offset = 19614 location->IsBound() 19615 ? location->GetLocation() - 19616 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 19617 : 0; 19618 if (IsUsingT32()) { 19619 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1 19620 if (dt.IsNoneOr(Untyped64) && 19621 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 19622 ((offset & 0x3) == 0)) || 19623 !location->IsBound())) { 19624 static class EmitOp : public Location::EmitOperator { 19625 public: 19626 EmitOp() : Location::EmitOperator(T32) {} 19627 virtual uint32_t Encode(uint32_t instr, 19628 Location::Offset program_counter, 19629 const Location* loc) const VIXL_OVERRIDE { 19630 program_counter += kT32PcDelta; 19631 Location::Offset off = 19632 loc->GetLocation() - AlignDown(program_counter, 4); 19633 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0)); 19634 int32_t target = off >> 2; 19635 uint32_t U = (target >= 0); 19636 target = abs(target) | (U << 8); 19637 return instr | (target & 0xff) | ((target & 0x100) << 15); 19638 } 19639 } immop; 19640 EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12), 19641 location, 19642 immop, 19643 &kT32DataInfo)); 19644 AdvanceIT(); 19645 return; 19646 } 19647 } else { 19648 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1 19649 if (dt.IsNoneOr(Untyped64) && 19650 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 19651 ((offset & 0x3) == 0)) || 19652 !location->IsBound()) && 19653 cond.IsNotNever()) { 19654 static class EmitOp : public Location::EmitOperator { 19655 public: 19656 EmitOp() : Location::EmitOperator(A32) {} 19657 virtual uint32_t Encode(uint32_t instr, 19658 Location::Offset program_counter, 19659 const Location* loc) const VIXL_OVERRIDE { 19660 program_counter += kA32PcDelta; 19661 Location::Offset off = 19662 loc->GetLocation() - AlignDown(program_counter, 4); 19663 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0)); 19664 int32_t target = off >> 2; 19665 uint32_t U = (target >= 0); 19666 target = abs(target) | (U << 8); 19667 return instr | (target & 0xff) | ((target & 0x100) << 15); 19668 } 19669 } immop; 19670 EmitA32( 19671 Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12), 19672 location, 19673 immop, 19674 &kA32DataInfo)); 19675 return; 19676 } 19677 } 19678 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location); 19679 } 19680 19681 bool Assembler::vldr_info(Condition cond, 19682 DataType dt, 19683 DRegister rd, 19684 Location* location, 19685 const struct ReferenceInfo** info) { 19686 VIXL_ASSERT(!location->IsBound()); 19687 USE(location); 19688 USE(rd); 19689 if (IsUsingT32()) { 19690 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1 19691 if (dt.IsNoneOr(Untyped64)) { 19692 *info = &kT32DataInfo; 19693 return true; 19694 } 19695 } else { 19696 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1 19697 if (dt.IsNoneOr(Untyped64) && cond.IsNotNever()) { 19698 *info = &kA32DataInfo; 19699 return true; 19700 } 19701 } 19702 return false; 19703 } 19704 19705 void Assembler::vldr(Condition cond, 19706 DataType dt, 19707 DRegister rd, 19708 const MemOperand& operand) { 19709 VIXL_ASSERT(AllowAssembler()); 19710 CheckIT(cond); 19711 if (operand.IsImmediate()) { 19712 Register rn = operand.GetBaseRegister(); 19713 int32_t offset = operand.GetOffsetImmediate(); 19714 if (IsUsingT32()) { 19715 // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1 19716 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 19717 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) { 19718 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19719 uint32_t offset_ = abs(offset) >> 2; 19720 EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23)); 19721 AdvanceIT(); 19722 return; 19723 } 19724 // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1 19725 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 19726 ((offset % 4) == 0) && operand.IsOffset() && 19727 ((rn.GetCode() & 0xf) != 0xf)) { 19728 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19729 uint32_t offset_ = abs(offset) >> 2; 19730 EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 19731 offset_ | (sign << 23)); 19732 AdvanceIT(); 19733 return; 19734 } 19735 } else { 19736 // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1 19737 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 19738 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() && 19739 cond.IsNotNever()) { 19740 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19741 uint32_t offset_ = abs(offset) >> 2; 19742 EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19743 offset_ | (sign << 23)); 19744 return; 19745 } 19746 // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1 19747 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 19748 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() && 19749 ((rn.GetCode() & 0xf) != 0xf)) { 19750 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19751 uint32_t offset_ = abs(offset) >> 2; 19752 EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19753 (rn.GetCode() << 16) | offset_ | (sign << 23)); 19754 return; 19755 } 19756 } 19757 } 19758 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand); 19759 } 19760 19761 void Assembler::vldr(Condition cond, 19762 DataType dt, 19763 SRegister rd, 19764 Location* location) { 19765 VIXL_ASSERT(AllowAssembler()); 19766 CheckIT(cond); 19767 Location::Offset offset = 19768 location->IsBound() 19769 ? location->GetLocation() - 19770 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 19771 : 0; 19772 if (IsUsingT32()) { 19773 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2 19774 if (dt.IsNoneOr(Untyped32) && 19775 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 19776 ((offset & 0x3) == 0)) || 19777 !location->IsBound())) { 19778 static class EmitOp : public Location::EmitOperator { 19779 public: 19780 EmitOp() : Location::EmitOperator(T32) {} 19781 virtual uint32_t Encode(uint32_t instr, 19782 Location::Offset program_counter, 19783 const Location* loc) const VIXL_OVERRIDE { 19784 program_counter += kT32PcDelta; 19785 Location::Offset off = 19786 loc->GetLocation() - AlignDown(program_counter, 4); 19787 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0)); 19788 int32_t target = off >> 2; 19789 uint32_t U = (target >= 0); 19790 target = abs(target) | (U << 8); 19791 return instr | (target & 0xff) | ((target & 0x100) << 15); 19792 } 19793 } immop; 19794 EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12), 19795 location, 19796 immop, 19797 &kT32DataInfo)); 19798 AdvanceIT(); 19799 return; 19800 } 19801 } else { 19802 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2 19803 if (dt.IsNoneOr(Untyped32) && 19804 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 19805 ((offset & 0x3) == 0)) || 19806 !location->IsBound()) && 19807 cond.IsNotNever()) { 19808 static class EmitOp : public Location::EmitOperator { 19809 public: 19810 EmitOp() : Location::EmitOperator(A32) {} 19811 virtual uint32_t Encode(uint32_t instr, 19812 Location::Offset program_counter, 19813 const Location* loc) const VIXL_OVERRIDE { 19814 program_counter += kA32PcDelta; 19815 Location::Offset off = 19816 loc->GetLocation() - AlignDown(program_counter, 4); 19817 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0)); 19818 int32_t target = off >> 2; 19819 uint32_t U = (target >= 0); 19820 target = abs(target) | (U << 8); 19821 return instr | (target & 0xff) | ((target & 0x100) << 15); 19822 } 19823 } immop; 19824 EmitA32( 19825 Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12), 19826 location, 19827 immop, 19828 &kA32DataInfo)); 19829 return; 19830 } 19831 } 19832 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location); 19833 } 19834 19835 bool Assembler::vldr_info(Condition cond, 19836 DataType dt, 19837 SRegister rd, 19838 Location* location, 19839 const struct ReferenceInfo** info) { 19840 VIXL_ASSERT(!location->IsBound()); 19841 USE(location); 19842 USE(rd); 19843 if (IsUsingT32()) { 19844 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2 19845 if (dt.IsNoneOr(Untyped32)) { 19846 *info = &kT32DataInfo; 19847 return true; 19848 } 19849 } else { 19850 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2 19851 if (dt.IsNoneOr(Untyped32) && cond.IsNotNever()) { 19852 *info = &kA32DataInfo; 19853 return true; 19854 } 19855 } 19856 return false; 19857 } 19858 19859 void Assembler::vldr(Condition cond, 19860 DataType dt, 19861 SRegister rd, 19862 const MemOperand& operand) { 19863 VIXL_ASSERT(AllowAssembler()); 19864 CheckIT(cond); 19865 if (operand.IsImmediate()) { 19866 Register rn = operand.GetBaseRegister(); 19867 int32_t offset = operand.GetOffsetImmediate(); 19868 if (IsUsingT32()) { 19869 // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2 19870 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 19871 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) { 19872 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19873 uint32_t offset_ = abs(offset) >> 2; 19874 EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23)); 19875 AdvanceIT(); 19876 return; 19877 } 19878 // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2 19879 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 19880 ((offset % 4) == 0) && operand.IsOffset() && 19881 ((rn.GetCode() & 0xf) != 0xf)) { 19882 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19883 uint32_t offset_ = abs(offset) >> 2; 19884 EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 19885 offset_ | (sign << 23)); 19886 AdvanceIT(); 19887 return; 19888 } 19889 } else { 19890 // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2 19891 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 19892 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() && 19893 cond.IsNotNever()) { 19894 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19895 uint32_t offset_ = abs(offset) >> 2; 19896 EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19897 offset_ | (sign << 23)); 19898 return; 19899 } 19900 // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2 19901 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 19902 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() && 19903 ((rn.GetCode() & 0xf) != 0xf)) { 19904 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19905 uint32_t offset_ = abs(offset) >> 2; 19906 EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19907 (rn.GetCode() << 16) | offset_ | (sign << 23)); 19908 return; 19909 } 19910 } 19911 } 19912 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand); 19913 } 19914 19915 void Assembler::vmax( 19916 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 19917 VIXL_ASSERT(AllowAssembler()); 19918 CheckIT(cond); 19919 Dt_U_size_1 encoded_dt(dt); 19920 if (IsUsingT32()) { 19921 // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 19922 if (dt.Is(F32)) { 19923 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19924 EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19925 rm.Encode(5, 0)); 19926 AdvanceIT(); 19927 return; 19928 } 19929 } 19930 // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 19931 if (encoded_dt.IsValid()) { 19932 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19933 EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 19934 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 19935 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19936 AdvanceIT(); 19937 return; 19938 } 19939 } 19940 } else { 19941 // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 19942 if (dt.Is(F32)) { 19943 if (cond.Is(al)) { 19944 EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19945 rm.Encode(5, 0)); 19946 return; 19947 } 19948 } 19949 // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 19950 if (encoded_dt.IsValid()) { 19951 if (cond.Is(al)) { 19952 EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 19953 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 19954 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19955 return; 19956 } 19957 } 19958 } 19959 Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm); 19960 } 19961 19962 void Assembler::vmax( 19963 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 19964 VIXL_ASSERT(AllowAssembler()); 19965 CheckIT(cond); 19966 Dt_U_size_1 encoded_dt(dt); 19967 if (IsUsingT32()) { 19968 // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 19969 if (dt.Is(F32)) { 19970 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19971 EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19972 rm.Encode(5, 0)); 19973 AdvanceIT(); 19974 return; 19975 } 19976 } 19977 // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 19978 if (encoded_dt.IsValid()) { 19979 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19980 EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 19981 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 19982 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19983 AdvanceIT(); 19984 return; 19985 } 19986 } 19987 } else { 19988 // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 19989 if (dt.Is(F32)) { 19990 if (cond.Is(al)) { 19991 EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19992 rm.Encode(5, 0)); 19993 return; 19994 } 19995 } 19996 // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 19997 if (encoded_dt.IsValid()) { 19998 if (cond.Is(al)) { 19999 EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20000 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20001 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20002 return; 20003 } 20004 } 20005 } 20006 Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm); 20007 } 20008 20009 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20010 VIXL_ASSERT(AllowAssembler()); 20011 CheckIT(al); 20012 if (IsUsingT32()) { 20013 // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 20014 if (OutsideITBlock() && dt.Is(F32)) { 20015 EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20016 rm.Encode(5, 0)); 20017 AdvanceIT(); 20018 return; 20019 } 20020 // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 20021 if (OutsideITBlock() && dt.Is(F64)) { 20022 EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20023 rm.Encode(5, 0)); 20024 AdvanceIT(); 20025 return; 20026 } 20027 } else { 20028 // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 20029 if (dt.Is(F32)) { 20030 EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20031 rm.Encode(5, 0)); 20032 return; 20033 } 20034 // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 20035 if (dt.Is(F64)) { 20036 EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20037 rm.Encode(5, 0)); 20038 return; 20039 } 20040 } 20041 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 20042 } 20043 20044 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20045 VIXL_ASSERT(AllowAssembler()); 20046 CheckIT(al); 20047 if (IsUsingT32()) { 20048 // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 20049 if (OutsideITBlock() && dt.Is(F32)) { 20050 EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20051 rm.Encode(5, 0)); 20052 AdvanceIT(); 20053 return; 20054 } 20055 } else { 20056 // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 20057 if (dt.Is(F32)) { 20058 EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20059 rm.Encode(5, 0)); 20060 return; 20061 } 20062 } 20063 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 20064 } 20065 20066 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20067 VIXL_ASSERT(AllowAssembler()); 20068 CheckIT(al); 20069 if (IsUsingT32()) { 20070 // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 20071 if (OutsideITBlock() && dt.Is(F32)) { 20072 EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20073 rm.Encode(5, 0)); 20074 AdvanceIT(); 20075 return; 20076 } 20077 } else { 20078 // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 20079 if (dt.Is(F32)) { 20080 EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20081 rm.Encode(5, 0)); 20082 return; 20083 } 20084 } 20085 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 20086 } 20087 20088 void Assembler::vmin( 20089 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20090 VIXL_ASSERT(AllowAssembler()); 20091 CheckIT(cond); 20092 Dt_U_size_1 encoded_dt(dt); 20093 if (IsUsingT32()) { 20094 // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 20095 if (dt.Is(F32)) { 20096 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20097 EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20098 rm.Encode(5, 0)); 20099 AdvanceIT(); 20100 return; 20101 } 20102 } 20103 // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 20104 if (encoded_dt.IsValid()) { 20105 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20106 EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20107 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 20108 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20109 AdvanceIT(); 20110 return; 20111 } 20112 } 20113 } else { 20114 // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 20115 if (dt.Is(F32)) { 20116 if (cond.Is(al)) { 20117 EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20118 rm.Encode(5, 0)); 20119 return; 20120 } 20121 } 20122 // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 20123 if (encoded_dt.IsValid()) { 20124 if (cond.Is(al)) { 20125 EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20126 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20127 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20128 return; 20129 } 20130 } 20131 } 20132 Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm); 20133 } 20134 20135 void Assembler::vmin( 20136 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20137 VIXL_ASSERT(AllowAssembler()); 20138 CheckIT(cond); 20139 Dt_U_size_1 encoded_dt(dt); 20140 if (IsUsingT32()) { 20141 // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 20142 if (dt.Is(F32)) { 20143 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20144 EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20145 rm.Encode(5, 0)); 20146 AdvanceIT(); 20147 return; 20148 } 20149 } 20150 // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 20151 if (encoded_dt.IsValid()) { 20152 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20153 EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20154 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 20155 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20156 AdvanceIT(); 20157 return; 20158 } 20159 } 20160 } else { 20161 // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 20162 if (dt.Is(F32)) { 20163 if (cond.Is(al)) { 20164 EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20165 rm.Encode(5, 0)); 20166 return; 20167 } 20168 } 20169 // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 20170 if (encoded_dt.IsValid()) { 20171 if (cond.Is(al)) { 20172 EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20173 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20174 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20175 return; 20176 } 20177 } 20178 } 20179 Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm); 20180 } 20181 20182 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20183 VIXL_ASSERT(AllowAssembler()); 20184 CheckIT(al); 20185 if (IsUsingT32()) { 20186 // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 20187 if (OutsideITBlock() && dt.Is(F32)) { 20188 EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20189 rm.Encode(5, 0)); 20190 AdvanceIT(); 20191 return; 20192 } 20193 // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 20194 if (OutsideITBlock() && dt.Is(F64)) { 20195 EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20196 rm.Encode(5, 0)); 20197 AdvanceIT(); 20198 return; 20199 } 20200 } else { 20201 // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 20202 if (dt.Is(F32)) { 20203 EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20204 rm.Encode(5, 0)); 20205 return; 20206 } 20207 // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 20208 if (dt.Is(F64)) { 20209 EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20210 rm.Encode(5, 0)); 20211 return; 20212 } 20213 } 20214 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 20215 } 20216 20217 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20218 VIXL_ASSERT(AllowAssembler()); 20219 CheckIT(al); 20220 if (IsUsingT32()) { 20221 // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 20222 if (OutsideITBlock() && dt.Is(F32)) { 20223 EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20224 rm.Encode(5, 0)); 20225 AdvanceIT(); 20226 return; 20227 } 20228 } else { 20229 // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 20230 if (dt.Is(F32)) { 20231 EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20232 rm.Encode(5, 0)); 20233 return; 20234 } 20235 } 20236 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 20237 } 20238 20239 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20240 VIXL_ASSERT(AllowAssembler()); 20241 CheckIT(al); 20242 if (IsUsingT32()) { 20243 // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 20244 if (OutsideITBlock() && dt.Is(F32)) { 20245 EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20246 rm.Encode(5, 0)); 20247 AdvanceIT(); 20248 return; 20249 } 20250 } else { 20251 // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 20252 if (dt.Is(F32)) { 20253 EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20254 rm.Encode(5, 0)); 20255 return; 20256 } 20257 } 20258 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 20259 } 20260 20261 void Assembler::vmla( 20262 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 20263 VIXL_ASSERT(AllowAssembler()); 20264 CheckIT(cond); 20265 Dt_size_9 encoded_dt(dt); 20266 if (IsUsingT32()) { 20267 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1 20268 if (encoded_dt.IsValid() && 20269 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20270 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20271 (rm.GetLane() <= 1)))) { 20272 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20273 EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 20274 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20275 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20276 AdvanceIT(); 20277 return; 20278 } 20279 } 20280 } else { 20281 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1 20282 if (encoded_dt.IsValid() && 20283 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20284 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20285 (rm.GetLane() <= 1)))) { 20286 if (cond.Is(al)) { 20287 EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 20288 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20289 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20290 return; 20291 } 20292 } 20293 } 20294 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20295 } 20296 20297 void Assembler::vmla( 20298 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 20299 VIXL_ASSERT(AllowAssembler()); 20300 CheckIT(cond); 20301 Dt_size_9 encoded_dt(dt); 20302 if (IsUsingT32()) { 20303 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1 20304 if (encoded_dt.IsValid() && 20305 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20306 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20307 (rm.GetLane() <= 1)))) { 20308 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20309 EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 20310 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20311 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20312 AdvanceIT(); 20313 return; 20314 } 20315 } 20316 } else { 20317 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1 20318 if (encoded_dt.IsValid() && 20319 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20320 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20321 (rm.GetLane() <= 1)))) { 20322 if (cond.Is(al)) { 20323 EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 20324 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20325 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20326 return; 20327 } 20328 } 20329 } 20330 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20331 } 20332 20333 void Assembler::vmla( 20334 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20335 VIXL_ASSERT(AllowAssembler()); 20336 CheckIT(cond); 20337 Dt_size_10 encoded_dt(dt); 20338 if (IsUsingT32()) { 20339 // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 20340 if (dt.Is(F32)) { 20341 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20342 EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20343 rm.Encode(5, 0)); 20344 AdvanceIT(); 20345 return; 20346 } 20347 } 20348 // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 20349 if (dt.Is(F64)) { 20350 EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20351 rm.Encode(5, 0)); 20352 AdvanceIT(); 20353 return; 20354 } 20355 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1 20356 if (encoded_dt.IsValid()) { 20357 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20358 EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) | 20359 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20360 AdvanceIT(); 20361 return; 20362 } 20363 } 20364 } else { 20365 // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 20366 if (dt.Is(F32)) { 20367 if (cond.Is(al)) { 20368 EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20369 rm.Encode(5, 0)); 20370 return; 20371 } 20372 } 20373 // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 20374 if (dt.Is(F64) && cond.IsNotNever()) { 20375 EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20376 rn.Encode(7, 16) | rm.Encode(5, 0)); 20377 return; 20378 } 20379 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1 20380 if (encoded_dt.IsValid()) { 20381 if (cond.Is(al)) { 20382 EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) | 20383 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20384 return; 20385 } 20386 } 20387 } 20388 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20389 } 20390 20391 void Assembler::vmla( 20392 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20393 VIXL_ASSERT(AllowAssembler()); 20394 CheckIT(cond); 20395 Dt_size_10 encoded_dt(dt); 20396 if (IsUsingT32()) { 20397 // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 20398 if (dt.Is(F32)) { 20399 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20400 EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20401 rm.Encode(5, 0)); 20402 AdvanceIT(); 20403 return; 20404 } 20405 } 20406 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1 20407 if (encoded_dt.IsValid()) { 20408 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20409 EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) | 20410 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20411 AdvanceIT(); 20412 return; 20413 } 20414 } 20415 } else { 20416 // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 20417 if (dt.Is(F32)) { 20418 if (cond.Is(al)) { 20419 EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20420 rm.Encode(5, 0)); 20421 return; 20422 } 20423 } 20424 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1 20425 if (encoded_dt.IsValid()) { 20426 if (cond.Is(al)) { 20427 EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) | 20428 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20429 return; 20430 } 20431 } 20432 } 20433 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20434 } 20435 20436 void Assembler::vmla( 20437 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20438 VIXL_ASSERT(AllowAssembler()); 20439 CheckIT(cond); 20440 if (IsUsingT32()) { 20441 // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 20442 if (dt.Is(F32)) { 20443 EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20444 rm.Encode(5, 0)); 20445 AdvanceIT(); 20446 return; 20447 } 20448 } else { 20449 // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 20450 if (dt.Is(F32) && cond.IsNotNever()) { 20451 EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20452 rn.Encode(7, 16) | rm.Encode(5, 0)); 20453 return; 20454 } 20455 } 20456 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20457 } 20458 20459 void Assembler::vmlal( 20460 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 20461 VIXL_ASSERT(AllowAssembler()); 20462 CheckIT(cond); 20463 Dt_size_11 encoded_dt(dt); 20464 if (IsUsingT32()) { 20465 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1 20466 if (encoded_dt.IsValid() && 20467 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20468 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20469 (rm.GetLane() <= 1)))) { 20470 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20471 EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) | 20472 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20473 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20474 AdvanceIT(); 20475 return; 20476 } 20477 } 20478 } else { 20479 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1 20480 if (encoded_dt.IsValid() && 20481 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20482 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20483 (rm.GetLane() <= 1)))) { 20484 if (cond.Is(al)) { 20485 EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) | 20486 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20487 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20488 return; 20489 } 20490 } 20491 } 20492 Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm); 20493 } 20494 20495 void Assembler::vmlal( 20496 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 20497 VIXL_ASSERT(AllowAssembler()); 20498 CheckIT(cond); 20499 Dt_size_12 encoded_dt(dt); 20500 if (IsUsingT32()) { 20501 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1 20502 if (encoded_dt.IsValid()) { 20503 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20504 EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) | 20505 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20506 rn.Encode(7, 16) | rm.Encode(5, 0)); 20507 AdvanceIT(); 20508 return; 20509 } 20510 } 20511 } else { 20512 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1 20513 if (encoded_dt.IsValid()) { 20514 if (cond.Is(al)) { 20515 EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) | 20516 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20517 rn.Encode(7, 16) | rm.Encode(5, 0)); 20518 return; 20519 } 20520 } 20521 } 20522 Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm); 20523 } 20524 20525 void Assembler::vmls( 20526 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 20527 VIXL_ASSERT(AllowAssembler()); 20528 CheckIT(cond); 20529 Dt_size_9 encoded_dt(dt); 20530 if (IsUsingT32()) { 20531 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1 20532 if (encoded_dt.IsValid() && 20533 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20534 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20535 (rm.GetLane() <= 1)))) { 20536 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20537 EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 20538 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20539 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20540 AdvanceIT(); 20541 return; 20542 } 20543 } 20544 } else { 20545 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1 20546 if (encoded_dt.IsValid() && 20547 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20548 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20549 (rm.GetLane() <= 1)))) { 20550 if (cond.Is(al)) { 20551 EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 20552 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20553 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20554 return; 20555 } 20556 } 20557 } 20558 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20559 } 20560 20561 void Assembler::vmls( 20562 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 20563 VIXL_ASSERT(AllowAssembler()); 20564 CheckIT(cond); 20565 Dt_size_9 encoded_dt(dt); 20566 if (IsUsingT32()) { 20567 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1 20568 if (encoded_dt.IsValid() && 20569 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20570 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20571 (rm.GetLane() <= 1)))) { 20572 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20573 EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 20574 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20575 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20576 AdvanceIT(); 20577 return; 20578 } 20579 } 20580 } else { 20581 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1 20582 if (encoded_dt.IsValid() && 20583 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20584 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20585 (rm.GetLane() <= 1)))) { 20586 if (cond.Is(al)) { 20587 EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 20588 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20589 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20590 return; 20591 } 20592 } 20593 } 20594 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20595 } 20596 20597 void Assembler::vmls( 20598 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20599 VIXL_ASSERT(AllowAssembler()); 20600 CheckIT(cond); 20601 Dt_size_10 encoded_dt(dt); 20602 if (IsUsingT32()) { 20603 // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 20604 if (dt.Is(F32)) { 20605 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20606 EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20607 rm.Encode(5, 0)); 20608 AdvanceIT(); 20609 return; 20610 } 20611 } 20612 // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 20613 if (dt.Is(F64)) { 20614 EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20615 rm.Encode(5, 0)); 20616 AdvanceIT(); 20617 return; 20618 } 20619 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1 20620 if (encoded_dt.IsValid()) { 20621 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20622 EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) | 20623 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20624 AdvanceIT(); 20625 return; 20626 } 20627 } 20628 } else { 20629 // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 20630 if (dt.Is(F32)) { 20631 if (cond.Is(al)) { 20632 EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20633 rm.Encode(5, 0)); 20634 return; 20635 } 20636 } 20637 // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 20638 if (dt.Is(F64) && cond.IsNotNever()) { 20639 EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20640 rn.Encode(7, 16) | rm.Encode(5, 0)); 20641 return; 20642 } 20643 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1 20644 if (encoded_dt.IsValid()) { 20645 if (cond.Is(al)) { 20646 EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) | 20647 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20648 return; 20649 } 20650 } 20651 } 20652 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20653 } 20654 20655 void Assembler::vmls( 20656 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20657 VIXL_ASSERT(AllowAssembler()); 20658 CheckIT(cond); 20659 Dt_size_10 encoded_dt(dt); 20660 if (IsUsingT32()) { 20661 // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 20662 if (dt.Is(F32)) { 20663 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20664 EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20665 rm.Encode(5, 0)); 20666 AdvanceIT(); 20667 return; 20668 } 20669 } 20670 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1 20671 if (encoded_dt.IsValid()) { 20672 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20673 EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) | 20674 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20675 AdvanceIT(); 20676 return; 20677 } 20678 } 20679 } else { 20680 // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 20681 if (dt.Is(F32)) { 20682 if (cond.Is(al)) { 20683 EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20684 rm.Encode(5, 0)); 20685 return; 20686 } 20687 } 20688 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1 20689 if (encoded_dt.IsValid()) { 20690 if (cond.Is(al)) { 20691 EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) | 20692 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20693 return; 20694 } 20695 } 20696 } 20697 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20698 } 20699 20700 void Assembler::vmls( 20701 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20702 VIXL_ASSERT(AllowAssembler()); 20703 CheckIT(cond); 20704 if (IsUsingT32()) { 20705 // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 20706 if (dt.Is(F32)) { 20707 EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20708 rm.Encode(5, 0)); 20709 AdvanceIT(); 20710 return; 20711 } 20712 } else { 20713 // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 20714 if (dt.Is(F32) && cond.IsNotNever()) { 20715 EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20716 rn.Encode(7, 16) | rm.Encode(5, 0)); 20717 return; 20718 } 20719 } 20720 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20721 } 20722 20723 void Assembler::vmlsl( 20724 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 20725 VIXL_ASSERT(AllowAssembler()); 20726 CheckIT(cond); 20727 Dt_size_11 encoded_dt(dt); 20728 if (IsUsingT32()) { 20729 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1 20730 if (encoded_dt.IsValid() && 20731 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20732 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20733 (rm.GetLane() <= 1)))) { 20734 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20735 EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) | 20736 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20737 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20738 AdvanceIT(); 20739 return; 20740 } 20741 } 20742 } else { 20743 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1 20744 if (encoded_dt.IsValid() && 20745 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20746 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20747 (rm.GetLane() <= 1)))) { 20748 if (cond.Is(al)) { 20749 EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) | 20750 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20751 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20752 return; 20753 } 20754 } 20755 } 20756 Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm); 20757 } 20758 20759 void Assembler::vmlsl( 20760 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 20761 VIXL_ASSERT(AllowAssembler()); 20762 CheckIT(cond); 20763 Dt_size_12 encoded_dt(dt); 20764 if (IsUsingT32()) { 20765 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1 20766 if (encoded_dt.IsValid()) { 20767 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20768 EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) | 20769 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20770 rn.Encode(7, 16) | rm.Encode(5, 0)); 20771 AdvanceIT(); 20772 return; 20773 } 20774 } 20775 } else { 20776 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1 20777 if (encoded_dt.IsValid()) { 20778 if (cond.Is(al)) { 20779 EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) | 20780 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20781 rn.Encode(7, 16) | rm.Encode(5, 0)); 20782 return; 20783 } 20784 } 20785 } 20786 Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm); 20787 } 20788 20789 void Assembler::vmov(Condition cond, Register rt, SRegister rn) { 20790 VIXL_ASSERT(AllowAssembler()); 20791 CheckIT(cond); 20792 if (IsUsingT32()) { 20793 // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1 20794 if ((!rt.IsPC() || AllowUnpredictable())) { 20795 EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16)); 20796 AdvanceIT(); 20797 return; 20798 } 20799 } else { 20800 // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1 20801 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 20802 EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 20803 rn.Encode(7, 16)); 20804 return; 20805 } 20806 } 20807 Delegate(kVmov, &Assembler::vmov, cond, rt, rn); 20808 } 20809 20810 void Assembler::vmov(Condition cond, SRegister rn, Register rt) { 20811 VIXL_ASSERT(AllowAssembler()); 20812 CheckIT(cond); 20813 if (IsUsingT32()) { 20814 // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1 20815 if ((!rt.IsPC() || AllowUnpredictable())) { 20816 EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12)); 20817 AdvanceIT(); 20818 return; 20819 } 20820 } else { 20821 // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1 20822 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 20823 EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) | 20824 (rt.GetCode() << 12)); 20825 return; 20826 } 20827 } 20828 Delegate(kVmov, &Assembler::vmov, cond, rn, rt); 20829 } 20830 20831 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) { 20832 VIXL_ASSERT(AllowAssembler()); 20833 CheckIT(cond); 20834 if (IsUsingT32()) { 20835 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1 20836 if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20837 EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) | 20838 rm.Encode(5, 0)); 20839 AdvanceIT(); 20840 return; 20841 } 20842 } else { 20843 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1 20844 if (cond.IsNotNever() && 20845 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20846 EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 20847 (rt2.GetCode() << 16) | rm.Encode(5, 0)); 20848 return; 20849 } 20850 } 20851 Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm); 20852 } 20853 20854 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) { 20855 VIXL_ASSERT(AllowAssembler()); 20856 CheckIT(cond); 20857 if (IsUsingT32()) { 20858 // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1 20859 if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20860 EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) | 20861 (rt2.GetCode() << 16)); 20862 AdvanceIT(); 20863 return; 20864 } 20865 } else { 20866 // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1 20867 if (cond.IsNotNever() && 20868 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20869 EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) | 20870 (rt.GetCode() << 12) | (rt2.GetCode() << 16)); 20871 return; 20872 } 20873 } 20874 Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2); 20875 } 20876 20877 void Assembler::vmov( 20878 Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) { 20879 VIXL_ASSERT(AllowAssembler()); 20880 CheckIT(cond); 20881 if (IsUsingT32()) { 20882 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1 20883 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 20884 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20885 EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) | 20886 rm.Encode(5, 0)); 20887 AdvanceIT(); 20888 return; 20889 } 20890 } else { 20891 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1 20892 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 20893 cond.IsNotNever() && 20894 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20895 EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 20896 (rt2.GetCode() << 16) | rm.Encode(5, 0)); 20897 return; 20898 } 20899 } 20900 Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1); 20901 } 20902 20903 void Assembler::vmov( 20904 Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) { 20905 VIXL_ASSERT(AllowAssembler()); 20906 CheckIT(cond); 20907 if (IsUsingT32()) { 20908 // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1 20909 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 20910 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20911 EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) | 20912 (rt2.GetCode() << 16)); 20913 AdvanceIT(); 20914 return; 20915 } 20916 } else { 20917 // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1 20918 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 20919 cond.IsNotNever() && 20920 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20921 EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) | 20922 (rt.GetCode() << 12) | (rt2.GetCode() << 16)); 20923 return; 20924 } 20925 } 20926 Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2); 20927 } 20928 20929 void Assembler::vmov(Condition cond, 20930 DataType dt, 20931 DRegisterLane rd, 20932 Register rt) { 20933 VIXL_ASSERT(AllowAssembler()); 20934 CheckIT(cond); 20935 Dt_opc1_opc2_1 encoded_dt(dt, rd); 20936 if (IsUsingT32()) { 20937 // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1 20938 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) { 20939 EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 20940 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 20941 rd.Encode(7, 16) | (rt.GetCode() << 12)); 20942 AdvanceIT(); 20943 return; 20944 } 20945 } else { 20946 // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1 20947 if (encoded_dt.IsValid() && cond.IsNotNever() && 20948 (!rt.IsPC() || AllowUnpredictable())) { 20949 EmitA32(0x0e000b10U | (cond.GetCondition() << 28) | 20950 ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 20951 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) | 20952 (rt.GetCode() << 12)); 20953 return; 20954 } 20955 } 20956 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt); 20957 } 20958 20959 void Assembler::vmov(Condition cond, 20960 DataType dt, 20961 DRegister rd, 20962 const DOperand& operand) { 20963 VIXL_ASSERT(AllowAssembler()); 20964 CheckIT(cond); 20965 if (operand.IsImmediate()) { 20966 ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate()); 20967 if (IsUsingT32()) { 20968 // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 20969 if (encoded_dt.IsValid()) { 20970 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20971 EmitT32_32( 20972 0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 20973 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 20974 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20975 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20976 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 20977 AdvanceIT(); 20978 return; 20979 } 20980 } 20981 } else { 20982 // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 20983 if (encoded_dt.IsValid()) { 20984 if (cond.Is(al)) { 20985 EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 20986 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 20987 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20988 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20989 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 20990 return; 20991 } 20992 } 20993 } 20994 } 20995 if (operand.IsImmediate()) { 20996 ImmediateVFP vfp(operand.GetNeonImmediate()); 20997 if (IsUsingT32()) { 20998 // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2 20999 if (dt.Is(F64) && vfp.IsValid()) { 21000 EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) | 21001 (vfp.GetEncodingValue() & 0xf) | 21002 ((vfp.GetEncodingValue() & 0xf0) << 12)); 21003 AdvanceIT(); 21004 return; 21005 } 21006 } else { 21007 // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2 21008 if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) { 21009 EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21010 (vfp.GetEncodingValue() & 0xf) | 21011 ((vfp.GetEncodingValue() & 0xf0) << 12)); 21012 return; 21013 } 21014 } 21015 } 21016 if (operand.IsRegister()) { 21017 DRegister rm = operand.GetRegister(); 21018 if (IsUsingT32()) { 21019 // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 21020 if (dt.Is(F64)) { 21021 EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21022 AdvanceIT(); 21023 return; 21024 } 21025 // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 21026 if (!dt.Is(F64)) { 21027 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21028 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 21029 rm.Encode(5, 0)); 21030 AdvanceIT(); 21031 return; 21032 } 21033 } 21034 } else { 21035 // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 21036 if (dt.Is(F64) && cond.IsNotNever()) { 21037 EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21038 rm.Encode(5, 0)); 21039 return; 21040 } 21041 // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 21042 if (!dt.Is(F64)) { 21043 if (cond.Is(al)) { 21044 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 21045 rm.Encode(5, 0)); 21046 return; 21047 } 21048 } 21049 } 21050 } 21051 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 21052 } 21053 21054 void Assembler::vmov(Condition cond, 21055 DataType dt, 21056 QRegister rd, 21057 const QOperand& operand) { 21058 VIXL_ASSERT(AllowAssembler()); 21059 CheckIT(cond); 21060 if (operand.IsImmediate()) { 21061 ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate()); 21062 if (IsUsingT32()) { 21063 // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 21064 if (encoded_dt.IsValid()) { 21065 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21066 EmitT32_32( 21067 0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 21068 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 21069 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21070 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21071 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21072 AdvanceIT(); 21073 return; 21074 } 21075 } 21076 } else { 21077 // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 21078 if (encoded_dt.IsValid()) { 21079 if (cond.Is(al)) { 21080 EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 21081 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 21082 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21083 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21084 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21085 return; 21086 } 21087 } 21088 } 21089 } 21090 if (operand.IsRegister()) { 21091 QRegister rm = operand.GetRegister(); 21092 if (IsUsingT32()) { 21093 // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 21094 if (!dt.Is(F64)) { 21095 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21096 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 21097 rm.Encode(5, 0)); 21098 AdvanceIT(); 21099 return; 21100 } 21101 } 21102 } else { 21103 // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 21104 if (!dt.Is(F64)) { 21105 if (cond.Is(al)) { 21106 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 21107 rm.Encode(5, 0)); 21108 return; 21109 } 21110 } 21111 } 21112 } 21113 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 21114 } 21115 21116 void Assembler::vmov(Condition cond, 21117 DataType dt, 21118 SRegister rd, 21119 const SOperand& operand) { 21120 VIXL_ASSERT(AllowAssembler()); 21121 CheckIT(cond); 21122 if (operand.IsImmediate()) { 21123 ImmediateVFP vfp(operand.GetNeonImmediate()); 21124 if (IsUsingT32()) { 21125 // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2 21126 if (dt.Is(F32) && vfp.IsValid()) { 21127 EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) | 21128 (vfp.GetEncodingValue() & 0xf) | 21129 ((vfp.GetEncodingValue() & 0xf0) << 12)); 21130 AdvanceIT(); 21131 return; 21132 } 21133 } else { 21134 // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2 21135 if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) { 21136 EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21137 (vfp.GetEncodingValue() & 0xf) | 21138 ((vfp.GetEncodingValue() & 0xf0) << 12)); 21139 return; 21140 } 21141 } 21142 } 21143 if (operand.IsRegister()) { 21144 SRegister rm = operand.GetRegister(); 21145 if (IsUsingT32()) { 21146 // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 21147 if (dt.Is(F32)) { 21148 EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21149 AdvanceIT(); 21150 return; 21151 } 21152 } else { 21153 // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 21154 if (dt.Is(F32) && cond.IsNotNever()) { 21155 EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21156 rm.Encode(5, 0)); 21157 return; 21158 } 21159 } 21160 } 21161 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 21162 } 21163 21164 void Assembler::vmov(Condition cond, 21165 DataType dt, 21166 Register rt, 21167 DRegisterLane rn) { 21168 VIXL_ASSERT(AllowAssembler()); 21169 CheckIT(cond); 21170 Dt_U_opc1_opc2_1 encoded_dt(dt, rn); 21171 if (IsUsingT32()) { 21172 // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1 21173 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) { 21174 EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 21175 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 21176 ((encoded_dt.GetEncodingValue() & 0x10) << 19) | 21177 (rt.GetCode() << 12) | rn.Encode(7, 16)); 21178 AdvanceIT(); 21179 return; 21180 } 21181 } else { 21182 // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1 21183 if (encoded_dt.IsValid() && cond.IsNotNever() && 21184 (!rt.IsPC() || AllowUnpredictable())) { 21185 EmitA32(0x0e100b10U | (cond.GetCondition() << 28) | 21186 ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 21187 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 21188 ((encoded_dt.GetEncodingValue() & 0x10) << 19) | 21189 (rt.GetCode() << 12) | rn.Encode(7, 16)); 21190 return; 21191 } 21192 } 21193 Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn); 21194 } 21195 21196 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) { 21197 VIXL_ASSERT(AllowAssembler()); 21198 CheckIT(cond); 21199 Dt_U_imm3H_1 encoded_dt(dt); 21200 if (IsUsingT32()) { 21201 // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1 21202 if (encoded_dt.IsValid()) { 21203 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21204 EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 21205 ((encoded_dt.GetEncodingValue() & 0x8) << 25) | 21206 rd.Encode(22, 12) | rm.Encode(5, 0)); 21207 AdvanceIT(); 21208 return; 21209 } 21210 } 21211 } else { 21212 // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1 21213 if (encoded_dt.IsValid()) { 21214 if (cond.Is(al)) { 21215 EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 21216 ((encoded_dt.GetEncodingValue() & 0x8) << 21) | 21217 rd.Encode(22, 12) | rm.Encode(5, 0)); 21218 return; 21219 } 21220 } 21221 } 21222 Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm); 21223 } 21224 21225 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) { 21226 VIXL_ASSERT(AllowAssembler()); 21227 CheckIT(cond); 21228 Dt_size_3 encoded_dt(dt); 21229 if (IsUsingT32()) { 21230 // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 21231 if (encoded_dt.IsValid()) { 21232 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21233 EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) | 21234 rd.Encode(22, 12) | rm.Encode(5, 0)); 21235 AdvanceIT(); 21236 return; 21237 } 21238 } 21239 } else { 21240 // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 21241 if (encoded_dt.IsValid()) { 21242 if (cond.Is(al)) { 21243 EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) | 21244 rd.Encode(22, 12) | rm.Encode(5, 0)); 21245 return; 21246 } 21247 } 21248 } 21249 Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm); 21250 } 21251 21252 void Assembler::vmrs(Condition cond, 21253 RegisterOrAPSR_nzcv rt, 21254 SpecialFPRegister spec_reg) { 21255 VIXL_ASSERT(AllowAssembler()); 21256 CheckIT(cond); 21257 if (IsUsingT32()) { 21258 // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1 21259 EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16)); 21260 AdvanceIT(); 21261 return; 21262 } else { 21263 // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1 21264 if (cond.IsNotNever()) { 21265 EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 21266 (spec_reg.GetReg() << 16)); 21267 return; 21268 } 21269 } 21270 Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg); 21271 } 21272 21273 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) { 21274 VIXL_ASSERT(AllowAssembler()); 21275 CheckIT(cond); 21276 if (IsUsingT32()) { 21277 // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1 21278 if ((!rt.IsPC() || AllowUnpredictable())) { 21279 EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) | 21280 (rt.GetCode() << 12)); 21281 AdvanceIT(); 21282 return; 21283 } 21284 } else { 21285 // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1 21286 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 21287 EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) | 21288 (spec_reg.GetReg() << 16) | (rt.GetCode() << 12)); 21289 return; 21290 } 21291 } 21292 Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt); 21293 } 21294 21295 void Assembler::vmul(Condition cond, 21296 DataType dt, 21297 DRegister rd, 21298 DRegister rn, 21299 DRegister dm, 21300 unsigned index) { 21301 VIXL_ASSERT(AllowAssembler()); 21302 CheckIT(cond); 21303 Dt_F_size_3 encoded_dt(dt); 21304 if (IsUsingT32()) { 21305 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1 21306 if (encoded_dt.IsValid() && 21307 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 21308 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) { 21309 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21310 uint32_t shift = 4; 21311 if (dt.Is(I16)) { 21312 shift = 3; 21313 } 21314 uint32_t mvm = dm.GetCode() | index << shift; 21315 EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21316 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 21317 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21318 ((mvm & 0x10) << 1)); 21319 AdvanceIT(); 21320 return; 21321 } 21322 } 21323 } else { 21324 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1 21325 if (encoded_dt.IsValid() && 21326 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 21327 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) { 21328 if (cond.Is(al)) { 21329 uint32_t shift = 4; 21330 if (dt.Is(I16)) { 21331 shift = 3; 21332 } 21333 uint32_t mvm = dm.GetCode() | index << shift; 21334 EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21335 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 21336 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21337 ((mvm & 0x10) << 1)); 21338 return; 21339 } 21340 } 21341 } 21342 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index); 21343 } 21344 21345 void Assembler::vmul(Condition cond, 21346 DataType dt, 21347 QRegister rd, 21348 QRegister rn, 21349 DRegister dm, 21350 unsigned index) { 21351 VIXL_ASSERT(AllowAssembler()); 21352 CheckIT(cond); 21353 Dt_F_size_3 encoded_dt(dt); 21354 if (IsUsingT32()) { 21355 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1 21356 if (encoded_dt.IsValid() && 21357 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 21358 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) { 21359 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21360 uint32_t shift = 4; 21361 if (dt.Is(I16)) { 21362 shift = 3; 21363 } 21364 uint32_t mvm = dm.GetCode() | index << shift; 21365 EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21366 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 21367 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21368 ((mvm & 0x10) << 1)); 21369 AdvanceIT(); 21370 return; 21371 } 21372 } 21373 } else { 21374 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1 21375 if (encoded_dt.IsValid() && 21376 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 21377 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) { 21378 if (cond.Is(al)) { 21379 uint32_t shift = 4; 21380 if (dt.Is(I16)) { 21381 shift = 3; 21382 } 21383 uint32_t mvm = dm.GetCode() | index << shift; 21384 EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21385 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 21386 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21387 ((mvm & 0x10) << 1)); 21388 return; 21389 } 21390 } 21391 } 21392 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index); 21393 } 21394 21395 void Assembler::vmul( 21396 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21397 VIXL_ASSERT(AllowAssembler()); 21398 CheckIT(cond); 21399 Dt_op_size_1 encoded_dt(dt); 21400 if (IsUsingT32()) { 21401 // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 21402 if (dt.Is(F32)) { 21403 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21404 EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21405 rm.Encode(5, 0)); 21406 AdvanceIT(); 21407 return; 21408 } 21409 } 21410 // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 21411 if (dt.Is(F64)) { 21412 EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21413 rm.Encode(5, 0)); 21414 AdvanceIT(); 21415 return; 21416 } 21417 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 21418 if (encoded_dt.IsValid()) { 21419 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21420 EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21421 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21422 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21423 AdvanceIT(); 21424 return; 21425 } 21426 } 21427 } else { 21428 // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 21429 if (dt.Is(F32)) { 21430 if (cond.Is(al)) { 21431 EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21432 rm.Encode(5, 0)); 21433 return; 21434 } 21435 } 21436 // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 21437 if (dt.Is(F64) && cond.IsNotNever()) { 21438 EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21439 rn.Encode(7, 16) | rm.Encode(5, 0)); 21440 return; 21441 } 21442 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 21443 if (encoded_dt.IsValid()) { 21444 if (cond.Is(al)) { 21445 EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21446 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21447 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21448 return; 21449 } 21450 } 21451 } 21452 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 21453 } 21454 21455 void Assembler::vmul( 21456 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 21457 VIXL_ASSERT(AllowAssembler()); 21458 CheckIT(cond); 21459 Dt_op_size_1 encoded_dt(dt); 21460 if (IsUsingT32()) { 21461 // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 21462 if (dt.Is(F32)) { 21463 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21464 EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21465 rm.Encode(5, 0)); 21466 AdvanceIT(); 21467 return; 21468 } 21469 } 21470 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 21471 if (encoded_dt.IsValid()) { 21472 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21473 EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21474 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21475 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21476 AdvanceIT(); 21477 return; 21478 } 21479 } 21480 } else { 21481 // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 21482 if (dt.Is(F32)) { 21483 if (cond.Is(al)) { 21484 EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21485 rm.Encode(5, 0)); 21486 return; 21487 } 21488 } 21489 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 21490 if (encoded_dt.IsValid()) { 21491 if (cond.Is(al)) { 21492 EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21493 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21494 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21495 return; 21496 } 21497 } 21498 } 21499 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 21500 } 21501 21502 void Assembler::vmul( 21503 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 21504 VIXL_ASSERT(AllowAssembler()); 21505 CheckIT(cond); 21506 if (IsUsingT32()) { 21507 // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 21508 if (dt.Is(F32)) { 21509 EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21510 rm.Encode(5, 0)); 21511 AdvanceIT(); 21512 return; 21513 } 21514 } else { 21515 // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 21516 if (dt.Is(F32) && cond.IsNotNever()) { 21517 EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21518 rn.Encode(7, 16) | rm.Encode(5, 0)); 21519 return; 21520 } 21521 } 21522 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 21523 } 21524 21525 void Assembler::vmull(Condition cond, 21526 DataType dt, 21527 QRegister rd, 21528 DRegister rn, 21529 DRegister dm, 21530 unsigned index) { 21531 VIXL_ASSERT(AllowAssembler()); 21532 CheckIT(cond); 21533 Dt_U_size_2 encoded_dt(dt); 21534 if (IsUsingT32()) { 21535 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1 21536 if (encoded_dt.IsValid() && 21537 (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) || 21538 (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) && 21539 (dm.GetCode() <= 15)))) { 21540 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21541 uint32_t shift = 4; 21542 if (dt.Is(S16) || dt.Is(U16)) { 21543 shift = 3; 21544 } 21545 uint32_t mvm = dm.GetCode() | index << shift; 21546 EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21547 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21548 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21549 ((mvm & 0x10) << 1)); 21550 AdvanceIT(); 21551 return; 21552 } 21553 } 21554 } else { 21555 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1 21556 if (encoded_dt.IsValid() && 21557 (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) || 21558 (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) && 21559 (dm.GetCode() <= 15)))) { 21560 if (cond.Is(al)) { 21561 uint32_t shift = 4; 21562 if (dt.Is(S16) || dt.Is(U16)) { 21563 shift = 3; 21564 } 21565 uint32_t mvm = dm.GetCode() | index << shift; 21566 EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21567 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21568 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21569 ((mvm & 0x10) << 1)); 21570 return; 21571 } 21572 } 21573 } 21574 Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index); 21575 } 21576 21577 void Assembler::vmull( 21578 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 21579 VIXL_ASSERT(AllowAssembler()); 21580 CheckIT(cond); 21581 Dt_op_U_size_1 encoded_dt(dt); 21582 if (IsUsingT32()) { 21583 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 21584 if (encoded_dt.IsValid()) { 21585 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21586 EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21587 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21588 ((encoded_dt.GetEncodingValue() & 0x8) << 6) | 21589 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21590 AdvanceIT(); 21591 return; 21592 } 21593 } 21594 } else { 21595 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 21596 if (encoded_dt.IsValid()) { 21597 if (cond.Is(al)) { 21598 EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21599 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21600 ((encoded_dt.GetEncodingValue() & 0x8) << 6) | 21601 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21602 return; 21603 } 21604 } 21605 } 21606 Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm); 21607 } 21608 21609 void Assembler::vmvn(Condition cond, 21610 DataType dt, 21611 DRegister rd, 21612 const DOperand& operand) { 21613 VIXL_ASSERT(AllowAssembler()); 21614 CheckIT(cond); 21615 if (operand.IsImmediate()) { 21616 ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate()); 21617 if (IsUsingT32()) { 21618 // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 21619 if (encoded_dt.IsValid()) { 21620 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21621 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 21622 rd.Encode(22, 12) | 21623 (encoded_dt.GetEncodedImmediate() & 0xf) | 21624 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21625 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21626 AdvanceIT(); 21627 return; 21628 } 21629 } 21630 } else { 21631 // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 21632 if (encoded_dt.IsValid()) { 21633 if (cond.Is(al)) { 21634 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 21635 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21636 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21637 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21638 return; 21639 } 21640 } 21641 } 21642 } 21643 if (operand.IsRegister()) { 21644 DRegister rm = operand.GetRegister(); 21645 USE(dt); 21646 if (IsUsingT32()) { 21647 // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 21648 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21649 EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21650 AdvanceIT(); 21651 return; 21652 } 21653 } else { 21654 // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 21655 if (cond.Is(al)) { 21656 EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21657 return; 21658 } 21659 } 21660 } 21661 Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand); 21662 } 21663 21664 void Assembler::vmvn(Condition cond, 21665 DataType dt, 21666 QRegister rd, 21667 const QOperand& operand) { 21668 VIXL_ASSERT(AllowAssembler()); 21669 CheckIT(cond); 21670 if (operand.IsImmediate()) { 21671 ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate()); 21672 if (IsUsingT32()) { 21673 // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 21674 if (encoded_dt.IsValid()) { 21675 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21676 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 21677 rd.Encode(22, 12) | 21678 (encoded_dt.GetEncodedImmediate() & 0xf) | 21679 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21680 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21681 AdvanceIT(); 21682 return; 21683 } 21684 } 21685 } else { 21686 // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 21687 if (encoded_dt.IsValid()) { 21688 if (cond.Is(al)) { 21689 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 21690 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21691 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21692 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21693 return; 21694 } 21695 } 21696 } 21697 } 21698 if (operand.IsRegister()) { 21699 QRegister rm = operand.GetRegister(); 21700 USE(dt); 21701 if (IsUsingT32()) { 21702 // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 21703 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21704 EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21705 AdvanceIT(); 21706 return; 21707 } 21708 } else { 21709 // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 21710 if (cond.Is(al)) { 21711 EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21712 return; 21713 } 21714 } 21715 } 21716 Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand); 21717 } 21718 21719 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) { 21720 VIXL_ASSERT(AllowAssembler()); 21721 CheckIT(cond); 21722 Dt_F_size_1 encoded_dt(dt); 21723 if (IsUsingT32()) { 21724 // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 21725 if (encoded_dt.IsValid()) { 21726 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21727 EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21728 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 21729 rd.Encode(22, 12) | rm.Encode(5, 0)); 21730 AdvanceIT(); 21731 return; 21732 } 21733 } 21734 // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 21735 if (dt.Is(F64)) { 21736 EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21737 AdvanceIT(); 21738 return; 21739 } 21740 } else { 21741 // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 21742 if (encoded_dt.IsValid()) { 21743 if (cond.Is(al)) { 21744 EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21745 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 21746 rd.Encode(22, 12) | rm.Encode(5, 0)); 21747 return; 21748 } 21749 } 21750 // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 21751 if (dt.Is(F64) && cond.IsNotNever()) { 21752 EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21753 rm.Encode(5, 0)); 21754 return; 21755 } 21756 } 21757 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 21758 } 21759 21760 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) { 21761 VIXL_ASSERT(AllowAssembler()); 21762 CheckIT(cond); 21763 Dt_F_size_1 encoded_dt(dt); 21764 if (IsUsingT32()) { 21765 // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 21766 if (encoded_dt.IsValid()) { 21767 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21768 EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21769 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 21770 rd.Encode(22, 12) | rm.Encode(5, 0)); 21771 AdvanceIT(); 21772 return; 21773 } 21774 } 21775 } else { 21776 // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 21777 if (encoded_dt.IsValid()) { 21778 if (cond.Is(al)) { 21779 EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21780 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 21781 rd.Encode(22, 12) | rm.Encode(5, 0)); 21782 return; 21783 } 21784 } 21785 } 21786 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 21787 } 21788 21789 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) { 21790 VIXL_ASSERT(AllowAssembler()); 21791 CheckIT(cond); 21792 if (IsUsingT32()) { 21793 // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 21794 if (dt.Is(F32)) { 21795 EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21796 AdvanceIT(); 21797 return; 21798 } 21799 } else { 21800 // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 21801 if (dt.Is(F32) && cond.IsNotNever()) { 21802 EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21803 rm.Encode(5, 0)); 21804 return; 21805 } 21806 } 21807 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 21808 } 21809 21810 void Assembler::vnmla( 21811 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 21812 VIXL_ASSERT(AllowAssembler()); 21813 CheckIT(cond); 21814 if (IsUsingT32()) { 21815 // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 21816 if (dt.Is(F32)) { 21817 EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21818 rm.Encode(5, 0)); 21819 AdvanceIT(); 21820 return; 21821 } 21822 } else { 21823 // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 21824 if (dt.Is(F32) && cond.IsNotNever()) { 21825 EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21826 rn.Encode(7, 16) | rm.Encode(5, 0)); 21827 return; 21828 } 21829 } 21830 Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm); 21831 } 21832 21833 void Assembler::vnmla( 21834 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21835 VIXL_ASSERT(AllowAssembler()); 21836 CheckIT(cond); 21837 if (IsUsingT32()) { 21838 // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 21839 if (dt.Is(F64)) { 21840 EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21841 rm.Encode(5, 0)); 21842 AdvanceIT(); 21843 return; 21844 } 21845 } else { 21846 // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 21847 if (dt.Is(F64) && cond.IsNotNever()) { 21848 EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21849 rn.Encode(7, 16) | rm.Encode(5, 0)); 21850 return; 21851 } 21852 } 21853 Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm); 21854 } 21855 21856 void Assembler::vnmls( 21857 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 21858 VIXL_ASSERT(AllowAssembler()); 21859 CheckIT(cond); 21860 if (IsUsingT32()) { 21861 // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 21862 if (dt.Is(F32)) { 21863 EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21864 rm.Encode(5, 0)); 21865 AdvanceIT(); 21866 return; 21867 } 21868 } else { 21869 // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 21870 if (dt.Is(F32) && cond.IsNotNever()) { 21871 EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21872 rn.Encode(7, 16) | rm.Encode(5, 0)); 21873 return; 21874 } 21875 } 21876 Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm); 21877 } 21878 21879 void Assembler::vnmls( 21880 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21881 VIXL_ASSERT(AllowAssembler()); 21882 CheckIT(cond); 21883 if (IsUsingT32()) { 21884 // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 21885 if (dt.Is(F64)) { 21886 EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21887 rm.Encode(5, 0)); 21888 AdvanceIT(); 21889 return; 21890 } 21891 } else { 21892 // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 21893 if (dt.Is(F64) && cond.IsNotNever()) { 21894 EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21895 rn.Encode(7, 16) | rm.Encode(5, 0)); 21896 return; 21897 } 21898 } 21899 Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm); 21900 } 21901 21902 void Assembler::vnmul( 21903 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 21904 VIXL_ASSERT(AllowAssembler()); 21905 CheckIT(cond); 21906 if (IsUsingT32()) { 21907 // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1 21908 if (dt.Is(F32)) { 21909 EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21910 rm.Encode(5, 0)); 21911 AdvanceIT(); 21912 return; 21913 } 21914 } else { 21915 // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1 21916 if (dt.Is(F32) && cond.IsNotNever()) { 21917 EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21918 rn.Encode(7, 16) | rm.Encode(5, 0)); 21919 return; 21920 } 21921 } 21922 Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm); 21923 } 21924 21925 void Assembler::vnmul( 21926 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21927 VIXL_ASSERT(AllowAssembler()); 21928 CheckIT(cond); 21929 if (IsUsingT32()) { 21930 // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1 21931 if (dt.Is(F64)) { 21932 EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21933 rm.Encode(5, 0)); 21934 AdvanceIT(); 21935 return; 21936 } 21937 } else { 21938 // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1 21939 if (dt.Is(F64) && cond.IsNotNever()) { 21940 EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21941 rn.Encode(7, 16) | rm.Encode(5, 0)); 21942 return; 21943 } 21944 } 21945 Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm); 21946 } 21947 21948 void Assembler::vorn(Condition cond, 21949 DataType dt, 21950 DRegister rd, 21951 DRegister rn, 21952 const DOperand& operand) { 21953 VIXL_ASSERT(AllowAssembler()); 21954 CheckIT(cond); 21955 if (operand.IsImmediate()) { 21956 ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate()); 21957 if (IsUsingT32()) { 21958 // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 21959 if (encoded_dt.IsValid() && rd.Is(rn)) { 21960 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21961 EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) | 21962 rd.Encode(22, 12) | 21963 (encoded_dt.GetEncodedImmediate() & 0xf) | 21964 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21965 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21966 AdvanceIT(); 21967 return; 21968 } 21969 } 21970 } else { 21971 // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 21972 if (encoded_dt.IsValid() && rd.Is(rn)) { 21973 if (cond.Is(al)) { 21974 EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) | 21975 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21976 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21977 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21978 return; 21979 } 21980 } 21981 } 21982 } 21983 if (operand.IsRegister()) { 21984 DRegister rm = operand.GetRegister(); 21985 USE(dt); 21986 if (IsUsingT32()) { 21987 // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 21988 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21989 EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21990 rm.Encode(5, 0)); 21991 AdvanceIT(); 21992 return; 21993 } 21994 } else { 21995 // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 21996 if (cond.Is(al)) { 21997 EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21998 rm.Encode(5, 0)); 21999 return; 22000 } 22001 } 22002 } 22003 Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand); 22004 } 22005 22006 void Assembler::vorn(Condition cond, 22007 DataType dt, 22008 QRegister rd, 22009 QRegister rn, 22010 const QOperand& operand) { 22011 VIXL_ASSERT(AllowAssembler()); 22012 CheckIT(cond); 22013 if (operand.IsImmediate()) { 22014 ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate()); 22015 if (IsUsingT32()) { 22016 // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 22017 if (encoded_dt.IsValid() && rd.Is(rn)) { 22018 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22019 EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) | 22020 rd.Encode(22, 12) | 22021 (encoded_dt.GetEncodedImmediate() & 0xf) | 22022 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22023 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 22024 AdvanceIT(); 22025 return; 22026 } 22027 } 22028 } else { 22029 // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 22030 if (encoded_dt.IsValid() && rd.Is(rn)) { 22031 if (cond.Is(al)) { 22032 EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) | 22033 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 22034 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22035 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 22036 return; 22037 } 22038 } 22039 } 22040 } 22041 if (operand.IsRegister()) { 22042 QRegister rm = operand.GetRegister(); 22043 USE(dt); 22044 if (IsUsingT32()) { 22045 // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 22046 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22047 EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22048 rm.Encode(5, 0)); 22049 AdvanceIT(); 22050 return; 22051 } 22052 } else { 22053 // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 22054 if (cond.Is(al)) { 22055 EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22056 rm.Encode(5, 0)); 22057 return; 22058 } 22059 } 22060 } 22061 Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand); 22062 } 22063 22064 void Assembler::vorr(Condition cond, 22065 DataType dt, 22066 DRegister rd, 22067 DRegister rn, 22068 const DOperand& operand) { 22069 VIXL_ASSERT(AllowAssembler()); 22070 CheckIT(cond); 22071 if (operand.IsRegister()) { 22072 DRegister rm = operand.GetRegister(); 22073 USE(dt); 22074 if (IsUsingT32()) { 22075 // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 22076 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22077 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22078 rm.Encode(5, 0)); 22079 AdvanceIT(); 22080 return; 22081 } 22082 } else { 22083 // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 22084 if (cond.Is(al)) { 22085 EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22086 rm.Encode(5, 0)); 22087 return; 22088 } 22089 } 22090 } 22091 if (operand.IsImmediate()) { 22092 ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate()); 22093 if (IsUsingT32()) { 22094 // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 22095 if (encoded_dt.IsValid() && rd.Is(rn)) { 22096 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22097 EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) | 22098 rd.Encode(22, 12) | 22099 (encoded_dt.GetEncodedImmediate() & 0xf) | 22100 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22101 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 22102 AdvanceIT(); 22103 return; 22104 } 22105 } 22106 } else { 22107 // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 22108 if (encoded_dt.IsValid() && rd.Is(rn)) { 22109 if (cond.Is(al)) { 22110 EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) | 22111 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 22112 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22113 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 22114 return; 22115 } 22116 } 22117 } 22118 } 22119 Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand); 22120 } 22121 22122 void Assembler::vorr(Condition cond, 22123 DataType dt, 22124 QRegister rd, 22125 QRegister rn, 22126 const QOperand& operand) { 22127 VIXL_ASSERT(AllowAssembler()); 22128 CheckIT(cond); 22129 if (operand.IsRegister()) { 22130 QRegister rm = operand.GetRegister(); 22131 USE(dt); 22132 if (IsUsingT32()) { 22133 // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 22134 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22135 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22136 rm.Encode(5, 0)); 22137 AdvanceIT(); 22138 return; 22139 } 22140 } else { 22141 // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 22142 if (cond.Is(al)) { 22143 EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22144 rm.Encode(5, 0)); 22145 return; 22146 } 22147 } 22148 } 22149 if (operand.IsImmediate()) { 22150 ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate()); 22151 if (IsUsingT32()) { 22152 // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 22153 if (encoded_dt.IsValid() && rd.Is(rn)) { 22154 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22155 EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) | 22156 rd.Encode(22, 12) | 22157 (encoded_dt.GetEncodedImmediate() & 0xf) | 22158 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22159 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 22160 AdvanceIT(); 22161 return; 22162 } 22163 } 22164 } else { 22165 // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 22166 if (encoded_dt.IsValid() && rd.Is(rn)) { 22167 if (cond.Is(al)) { 22168 EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) | 22169 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 22170 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22171 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 22172 return; 22173 } 22174 } 22175 } 22176 } 22177 Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand); 22178 } 22179 22180 void Assembler::vpadal(Condition cond, 22181 DataType dt, 22182 DRegister rd, 22183 DRegister rm) { 22184 VIXL_ASSERT(AllowAssembler()); 22185 CheckIT(cond); 22186 Dt_op_size_2 encoded_dt(dt); 22187 if (IsUsingT32()) { 22188 // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22189 if (encoded_dt.IsValid()) { 22190 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22191 EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22192 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22193 rd.Encode(22, 12) | rm.Encode(5, 0)); 22194 AdvanceIT(); 22195 return; 22196 } 22197 } 22198 } else { 22199 // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22200 if (encoded_dt.IsValid()) { 22201 if (cond.Is(al)) { 22202 EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22203 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22204 rd.Encode(22, 12) | rm.Encode(5, 0)); 22205 return; 22206 } 22207 } 22208 } 22209 Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm); 22210 } 22211 22212 void Assembler::vpadal(Condition cond, 22213 DataType dt, 22214 QRegister rd, 22215 QRegister rm) { 22216 VIXL_ASSERT(AllowAssembler()); 22217 CheckIT(cond); 22218 Dt_op_size_2 encoded_dt(dt); 22219 if (IsUsingT32()) { 22220 // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22221 if (encoded_dt.IsValid()) { 22222 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22223 EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22224 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22225 rd.Encode(22, 12) | rm.Encode(5, 0)); 22226 AdvanceIT(); 22227 return; 22228 } 22229 } 22230 } else { 22231 // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22232 if (encoded_dt.IsValid()) { 22233 if (cond.Is(al)) { 22234 EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22235 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22236 rd.Encode(22, 12) | rm.Encode(5, 0)); 22237 return; 22238 } 22239 } 22240 } 22241 Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm); 22242 } 22243 22244 void Assembler::vpadd( 22245 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22246 VIXL_ASSERT(AllowAssembler()); 22247 CheckIT(cond); 22248 Dt_size_4 encoded_dt(dt); 22249 if (IsUsingT32()) { 22250 // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 22251 if (dt.Is(F32)) { 22252 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22253 EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22254 rm.Encode(5, 0)); 22255 AdvanceIT(); 22256 return; 22257 } 22258 } 22259 // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22260 if (encoded_dt.IsValid()) { 22261 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22262 EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) | 22263 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22264 AdvanceIT(); 22265 return; 22266 } 22267 } 22268 } else { 22269 // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 22270 if (dt.Is(F32)) { 22271 if (cond.Is(al)) { 22272 EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22273 rm.Encode(5, 0)); 22274 return; 22275 } 22276 } 22277 // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22278 if (encoded_dt.IsValid()) { 22279 if (cond.Is(al)) { 22280 EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) | 22281 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22282 return; 22283 } 22284 } 22285 } 22286 Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm); 22287 } 22288 22289 void Assembler::vpaddl(Condition cond, 22290 DataType dt, 22291 DRegister rd, 22292 DRegister rm) { 22293 VIXL_ASSERT(AllowAssembler()); 22294 CheckIT(cond); 22295 Dt_op_size_2 encoded_dt(dt); 22296 if (IsUsingT32()) { 22297 // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22298 if (encoded_dt.IsValid()) { 22299 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22300 EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22301 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22302 rd.Encode(22, 12) | rm.Encode(5, 0)); 22303 AdvanceIT(); 22304 return; 22305 } 22306 } 22307 } else { 22308 // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22309 if (encoded_dt.IsValid()) { 22310 if (cond.Is(al)) { 22311 EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22312 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22313 rd.Encode(22, 12) | rm.Encode(5, 0)); 22314 return; 22315 } 22316 } 22317 } 22318 Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm); 22319 } 22320 22321 void Assembler::vpaddl(Condition cond, 22322 DataType dt, 22323 QRegister rd, 22324 QRegister rm) { 22325 VIXL_ASSERT(AllowAssembler()); 22326 CheckIT(cond); 22327 Dt_op_size_2 encoded_dt(dt); 22328 if (IsUsingT32()) { 22329 // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22330 if (encoded_dt.IsValid()) { 22331 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22332 EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22333 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22334 rd.Encode(22, 12) | rm.Encode(5, 0)); 22335 AdvanceIT(); 22336 return; 22337 } 22338 } 22339 } else { 22340 // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22341 if (encoded_dt.IsValid()) { 22342 if (cond.Is(al)) { 22343 EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22344 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22345 rd.Encode(22, 12) | rm.Encode(5, 0)); 22346 return; 22347 } 22348 } 22349 } 22350 Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm); 22351 } 22352 22353 void Assembler::vpmax( 22354 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22355 VIXL_ASSERT(AllowAssembler()); 22356 CheckIT(cond); 22357 Dt_U_size_1 encoded_dt(dt); 22358 if (IsUsingT32()) { 22359 // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 22360 if (dt.Is(F32)) { 22361 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22362 EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22363 rm.Encode(5, 0)); 22364 AdvanceIT(); 22365 return; 22366 } 22367 } 22368 // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22369 if (encoded_dt.IsValid()) { 22370 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22371 EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22372 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22373 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22374 AdvanceIT(); 22375 return; 22376 } 22377 } 22378 } else { 22379 // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 22380 if (dt.Is(F32)) { 22381 if (cond.Is(al)) { 22382 EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22383 rm.Encode(5, 0)); 22384 return; 22385 } 22386 } 22387 // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22388 if (encoded_dt.IsValid()) { 22389 if (cond.Is(al)) { 22390 EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22391 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22392 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22393 return; 22394 } 22395 } 22396 } 22397 Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm); 22398 } 22399 22400 void Assembler::vpmin( 22401 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22402 VIXL_ASSERT(AllowAssembler()); 22403 CheckIT(cond); 22404 Dt_U_size_1 encoded_dt(dt); 22405 if (IsUsingT32()) { 22406 // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 22407 if (dt.Is(F32)) { 22408 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22409 EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22410 rm.Encode(5, 0)); 22411 AdvanceIT(); 22412 return; 22413 } 22414 } 22415 // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22416 if (encoded_dt.IsValid()) { 22417 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22418 EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22419 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22420 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22421 AdvanceIT(); 22422 return; 22423 } 22424 } 22425 } else { 22426 // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 22427 if (dt.Is(F32)) { 22428 if (cond.Is(al)) { 22429 EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22430 rm.Encode(5, 0)); 22431 return; 22432 } 22433 } 22434 // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22435 if (encoded_dt.IsValid()) { 22436 if (cond.Is(al)) { 22437 EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22438 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22439 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22440 return; 22441 } 22442 } 22443 } 22444 Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm); 22445 } 22446 22447 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) { 22448 VIXL_ASSERT(AllowAssembler()); 22449 CheckIT(cond); 22450 USE(dt); 22451 if (IsUsingT32()) { 22452 // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1 22453 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 22454 const DRegister& dreg = dreglist.GetFirstDRegister(); 22455 unsigned len = dreglist.GetLength() * 2; 22456 EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff)); 22457 AdvanceIT(); 22458 return; 22459 } 22460 } else { 22461 // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1 22462 if (cond.IsNotNever() && 22463 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 22464 const DRegister& dreg = dreglist.GetFirstDRegister(); 22465 unsigned len = dreglist.GetLength() * 2; 22466 EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) | 22467 (len & 0xff)); 22468 return; 22469 } 22470 } 22471 Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist); 22472 } 22473 22474 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) { 22475 VIXL_ASSERT(AllowAssembler()); 22476 CheckIT(cond); 22477 USE(dt); 22478 if (IsUsingT32()) { 22479 // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2 22480 const SRegister& sreg = sreglist.GetFirstSRegister(); 22481 unsigned len = sreglist.GetLength(); 22482 EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff)); 22483 AdvanceIT(); 22484 return; 22485 } else { 22486 // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2 22487 if (cond.IsNotNever()) { 22488 const SRegister& sreg = sreglist.GetFirstSRegister(); 22489 unsigned len = sreglist.GetLength(); 22490 EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) | 22491 (len & 0xff)); 22492 return; 22493 } 22494 } 22495 Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist); 22496 } 22497 22498 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) { 22499 VIXL_ASSERT(AllowAssembler()); 22500 CheckIT(cond); 22501 USE(dt); 22502 if (IsUsingT32()) { 22503 // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1 22504 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 22505 const DRegister& dreg = dreglist.GetFirstDRegister(); 22506 unsigned len = dreglist.GetLength() * 2; 22507 EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff)); 22508 AdvanceIT(); 22509 return; 22510 } 22511 } else { 22512 // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1 22513 if (cond.IsNotNever() && 22514 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 22515 const DRegister& dreg = dreglist.GetFirstDRegister(); 22516 unsigned len = dreglist.GetLength() * 2; 22517 EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) | 22518 (len & 0xff)); 22519 return; 22520 } 22521 } 22522 Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist); 22523 } 22524 22525 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) { 22526 VIXL_ASSERT(AllowAssembler()); 22527 CheckIT(cond); 22528 USE(dt); 22529 if (IsUsingT32()) { 22530 // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2 22531 const SRegister& sreg = sreglist.GetFirstSRegister(); 22532 unsigned len = sreglist.GetLength(); 22533 EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff)); 22534 AdvanceIT(); 22535 return; 22536 } else { 22537 // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2 22538 if (cond.IsNotNever()) { 22539 const SRegister& sreg = sreglist.GetFirstSRegister(); 22540 unsigned len = sreglist.GetLength(); 22541 EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) | 22542 (len & 0xff)); 22543 return; 22544 } 22545 } 22546 Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist); 22547 } 22548 22549 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) { 22550 VIXL_ASSERT(AllowAssembler()); 22551 CheckIT(cond); 22552 Dt_size_5 encoded_dt(dt); 22553 if (IsUsingT32()) { 22554 // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22555 if (encoded_dt.IsValid()) { 22556 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22557 EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) | 22558 rd.Encode(22, 12) | rm.Encode(5, 0)); 22559 AdvanceIT(); 22560 return; 22561 } 22562 } 22563 } else { 22564 // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22565 if (encoded_dt.IsValid()) { 22566 if (cond.Is(al)) { 22567 EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) | 22568 rd.Encode(22, 12) | rm.Encode(5, 0)); 22569 return; 22570 } 22571 } 22572 } 22573 Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm); 22574 } 22575 22576 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) { 22577 VIXL_ASSERT(AllowAssembler()); 22578 CheckIT(cond); 22579 Dt_size_5 encoded_dt(dt); 22580 if (IsUsingT32()) { 22581 // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22582 if (encoded_dt.IsValid()) { 22583 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22584 EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) | 22585 rd.Encode(22, 12) | rm.Encode(5, 0)); 22586 AdvanceIT(); 22587 return; 22588 } 22589 } 22590 } else { 22591 // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22592 if (encoded_dt.IsValid()) { 22593 if (cond.Is(al)) { 22594 EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) | 22595 rd.Encode(22, 12) | rm.Encode(5, 0)); 22596 return; 22597 } 22598 } 22599 } 22600 Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm); 22601 } 22602 22603 void Assembler::vqadd( 22604 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22605 VIXL_ASSERT(AllowAssembler()); 22606 CheckIT(cond); 22607 Dt_U_size_3 encoded_dt(dt); 22608 if (IsUsingT32()) { 22609 // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22610 if (encoded_dt.IsValid()) { 22611 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22612 EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22613 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22614 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22615 AdvanceIT(); 22616 return; 22617 } 22618 } 22619 } else { 22620 // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22621 if (encoded_dt.IsValid()) { 22622 if (cond.Is(al)) { 22623 EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22624 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22625 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22626 return; 22627 } 22628 } 22629 } 22630 Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm); 22631 } 22632 22633 void Assembler::vqadd( 22634 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 22635 VIXL_ASSERT(AllowAssembler()); 22636 CheckIT(cond); 22637 Dt_U_size_3 encoded_dt(dt); 22638 if (IsUsingT32()) { 22639 // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 22640 if (encoded_dt.IsValid()) { 22641 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22642 EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22643 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22644 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22645 AdvanceIT(); 22646 return; 22647 } 22648 } 22649 } else { 22650 // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 22651 if (encoded_dt.IsValid()) { 22652 if (cond.Is(al)) { 22653 EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22654 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22655 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22656 return; 22657 } 22658 } 22659 } 22660 Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm); 22661 } 22662 22663 void Assembler::vqdmlal( 22664 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 22665 VIXL_ASSERT(AllowAssembler()); 22666 CheckIT(cond); 22667 Dt_size_13 encoded_dt(dt); 22668 if (IsUsingT32()) { 22669 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 22670 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22671 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22672 EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) | 22673 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22674 AdvanceIT(); 22675 return; 22676 } 22677 } 22678 } else { 22679 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 22680 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22681 if (cond.Is(al)) { 22682 EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) | 22683 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22684 return; 22685 } 22686 } 22687 } 22688 Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm); 22689 } 22690 22691 void Assembler::vqdmlal(Condition cond, 22692 DataType dt, 22693 QRegister rd, 22694 DRegister rn, 22695 DRegister dm, 22696 unsigned index) { 22697 VIXL_ASSERT(AllowAssembler()); 22698 CheckIT(cond); 22699 Dt_size_13 encoded_dt(dt); 22700 if (IsUsingT32()) { 22701 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2 22702 if (encoded_dt.IsValid() && 22703 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 22704 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) && 22705 (dt.Is(S16) || dt.Is(S32))) { 22706 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22707 uint32_t shift = 4; 22708 if (dt.Is(S16)) { 22709 shift = 3; 22710 } 22711 uint32_t mvm = dm.GetCode() | index << shift; 22712 EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) | 22713 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 22714 ((mvm & 0x10) << 1)); 22715 AdvanceIT(); 22716 return; 22717 } 22718 } 22719 } else { 22720 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2 22721 if (encoded_dt.IsValid() && 22722 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 22723 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) && 22724 (dt.Is(S16) || dt.Is(S32))) { 22725 if (cond.Is(al)) { 22726 uint32_t shift = 4; 22727 if (dt.Is(S16)) { 22728 shift = 3; 22729 } 22730 uint32_t mvm = dm.GetCode() | index << shift; 22731 EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) | 22732 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 22733 ((mvm & 0x10) << 1)); 22734 return; 22735 } 22736 } 22737 } 22738 Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index); 22739 } 22740 22741 void Assembler::vqdmlsl( 22742 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 22743 VIXL_ASSERT(AllowAssembler()); 22744 CheckIT(cond); 22745 Dt_size_13 encoded_dt(dt); 22746 if (IsUsingT32()) { 22747 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 22748 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22749 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22750 EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) | 22751 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22752 AdvanceIT(); 22753 return; 22754 } 22755 } 22756 } else { 22757 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 22758 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22759 if (cond.Is(al)) { 22760 EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) | 22761 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22762 return; 22763 } 22764 } 22765 } 22766 Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm); 22767 } 22768 22769 void Assembler::vqdmlsl(Condition cond, 22770 DataType dt, 22771 QRegister rd, 22772 DRegister rn, 22773 DRegister dm, 22774 unsigned index) { 22775 VIXL_ASSERT(AllowAssembler()); 22776 CheckIT(cond); 22777 Dt_size_13 encoded_dt(dt); 22778 if (IsUsingT32()) { 22779 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2 22780 if (encoded_dt.IsValid() && 22781 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 22782 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) && 22783 (dt.Is(S16) || dt.Is(S32))) { 22784 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22785 uint32_t shift = 4; 22786 if (dt.Is(S16)) { 22787 shift = 3; 22788 } 22789 uint32_t mvm = dm.GetCode() | index << shift; 22790 EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) | 22791 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 22792 ((mvm & 0x10) << 1)); 22793 AdvanceIT(); 22794 return; 22795 } 22796 } 22797 } else { 22798 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2 22799 if (encoded_dt.IsValid() && 22800 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 22801 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) && 22802 (dt.Is(S16) || dt.Is(S32))) { 22803 if (cond.Is(al)) { 22804 uint32_t shift = 4; 22805 if (dt.Is(S16)) { 22806 shift = 3; 22807 } 22808 uint32_t mvm = dm.GetCode() | index << shift; 22809 EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) | 22810 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 22811 ((mvm & 0x10) << 1)); 22812 return; 22813 } 22814 } 22815 } 22816 Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index); 22817 } 22818 22819 void Assembler::vqdmulh( 22820 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22821 VIXL_ASSERT(AllowAssembler()); 22822 CheckIT(cond); 22823 Dt_size_13 encoded_dt(dt); 22824 if (IsUsingT32()) { 22825 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22826 if (encoded_dt.IsValid()) { 22827 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22828 EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) | 22829 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22830 AdvanceIT(); 22831 return; 22832 } 22833 } 22834 } else { 22835 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22836 if (encoded_dt.IsValid()) { 22837 if (cond.Is(al)) { 22838 EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) | 22839 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22840 return; 22841 } 22842 } 22843 } 22844 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 22845 } 22846 22847 void Assembler::vqdmulh( 22848 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 22849 VIXL_ASSERT(AllowAssembler()); 22850 CheckIT(cond); 22851 Dt_size_13 encoded_dt(dt); 22852 if (IsUsingT32()) { 22853 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 22854 if (encoded_dt.IsValid()) { 22855 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22856 EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) | 22857 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22858 AdvanceIT(); 22859 return; 22860 } 22861 } 22862 } else { 22863 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 22864 if (encoded_dt.IsValid()) { 22865 if (cond.Is(al)) { 22866 EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) | 22867 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22868 return; 22869 } 22870 } 22871 } 22872 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 22873 } 22874 22875 void Assembler::vqdmulh( 22876 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 22877 VIXL_ASSERT(AllowAssembler()); 22878 CheckIT(cond); 22879 Dt_size_13 encoded_dt(dt); 22880 if (IsUsingT32()) { 22881 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2 22882 if (encoded_dt.IsValid() && 22883 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22884 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22885 (rm.GetLane() <= 1))) && 22886 (dt.Is(S16) || dt.Is(S32))) { 22887 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22888 EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) | 22889 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22890 AdvanceIT(); 22891 return; 22892 } 22893 } 22894 } else { 22895 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2 22896 if (encoded_dt.IsValid() && 22897 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22898 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22899 (rm.GetLane() <= 1))) && 22900 (dt.Is(S16) || dt.Is(S32))) { 22901 if (cond.Is(al)) { 22902 EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) | 22903 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22904 return; 22905 } 22906 } 22907 } 22908 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 22909 } 22910 22911 void Assembler::vqdmulh( 22912 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 22913 VIXL_ASSERT(AllowAssembler()); 22914 CheckIT(cond); 22915 Dt_size_13 encoded_dt(dt); 22916 if (IsUsingT32()) { 22917 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2 22918 if (encoded_dt.IsValid() && 22919 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22920 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22921 (rm.GetLane() <= 1))) && 22922 (dt.Is(S16) || dt.Is(S32))) { 22923 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22924 EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) | 22925 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22926 AdvanceIT(); 22927 return; 22928 } 22929 } 22930 } else { 22931 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2 22932 if (encoded_dt.IsValid() && 22933 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22934 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22935 (rm.GetLane() <= 1))) && 22936 (dt.Is(S16) || dt.Is(S32))) { 22937 if (cond.Is(al)) { 22938 EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) | 22939 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22940 return; 22941 } 22942 } 22943 } 22944 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 22945 } 22946 22947 void Assembler::vqdmull( 22948 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 22949 VIXL_ASSERT(AllowAssembler()); 22950 CheckIT(cond); 22951 Dt_size_13 encoded_dt(dt); 22952 if (IsUsingT32()) { 22953 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 22954 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22955 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22956 EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) | 22957 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22958 AdvanceIT(); 22959 return; 22960 } 22961 } 22962 } else { 22963 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 22964 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22965 if (cond.Is(al)) { 22966 EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) | 22967 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22968 return; 22969 } 22970 } 22971 } 22972 Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm); 22973 } 22974 22975 void Assembler::vqdmull( 22976 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 22977 VIXL_ASSERT(AllowAssembler()); 22978 CheckIT(cond); 22979 Dt_size_13 encoded_dt(dt); 22980 if (IsUsingT32()) { 22981 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2 22982 if (encoded_dt.IsValid() && 22983 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22984 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22985 (rm.GetLane() <= 1))) && 22986 (dt.Is(S16) || dt.Is(S32))) { 22987 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22988 EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) | 22989 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22990 AdvanceIT(); 22991 return; 22992 } 22993 } 22994 } else { 22995 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2 22996 if (encoded_dt.IsValid() && 22997 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22998 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22999 (rm.GetLane() <= 1))) && 23000 (dt.Is(S16) || dt.Is(S32))) { 23001 if (cond.Is(al)) { 23002 EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) | 23003 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23004 return; 23005 } 23006 } 23007 } 23008 Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm); 23009 } 23010 23011 void Assembler::vqmovn(Condition cond, 23012 DataType dt, 23013 DRegister rd, 23014 QRegister rm) { 23015 VIXL_ASSERT(AllowAssembler()); 23016 CheckIT(cond); 23017 Dt_op_size_3 encoded_dt(dt); 23018 if (IsUsingT32()) { 23019 // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 23020 if (encoded_dt.IsValid()) { 23021 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23022 EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23023 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23024 rd.Encode(22, 12) | rm.Encode(5, 0)); 23025 AdvanceIT(); 23026 return; 23027 } 23028 } 23029 } else { 23030 // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 23031 if (encoded_dt.IsValid()) { 23032 if (cond.Is(al)) { 23033 EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23034 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23035 rd.Encode(22, 12) | rm.Encode(5, 0)); 23036 return; 23037 } 23038 } 23039 } 23040 Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm); 23041 } 23042 23043 void Assembler::vqmovun(Condition cond, 23044 DataType dt, 23045 DRegister rd, 23046 QRegister rm) { 23047 VIXL_ASSERT(AllowAssembler()); 23048 CheckIT(cond); 23049 Dt_size_14 encoded_dt(dt); 23050 if (IsUsingT32()) { 23051 // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 23052 if (encoded_dt.IsValid()) { 23053 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23054 EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) | 23055 rd.Encode(22, 12) | rm.Encode(5, 0)); 23056 AdvanceIT(); 23057 return; 23058 } 23059 } 23060 } else { 23061 // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 23062 if (encoded_dt.IsValid()) { 23063 if (cond.Is(al)) { 23064 EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) | 23065 rd.Encode(22, 12) | rm.Encode(5, 0)); 23066 return; 23067 } 23068 } 23069 } 23070 Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm); 23071 } 23072 23073 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) { 23074 VIXL_ASSERT(AllowAssembler()); 23075 CheckIT(cond); 23076 Dt_size_5 encoded_dt(dt); 23077 if (IsUsingT32()) { 23078 // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 23079 if (encoded_dt.IsValid()) { 23080 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23081 EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) | 23082 rd.Encode(22, 12) | rm.Encode(5, 0)); 23083 AdvanceIT(); 23084 return; 23085 } 23086 } 23087 } else { 23088 // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 23089 if (encoded_dt.IsValid()) { 23090 if (cond.Is(al)) { 23091 EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) | 23092 rd.Encode(22, 12) | rm.Encode(5, 0)); 23093 return; 23094 } 23095 } 23096 } 23097 Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm); 23098 } 23099 23100 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) { 23101 VIXL_ASSERT(AllowAssembler()); 23102 CheckIT(cond); 23103 Dt_size_5 encoded_dt(dt); 23104 if (IsUsingT32()) { 23105 // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 23106 if (encoded_dt.IsValid()) { 23107 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23108 EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) | 23109 rd.Encode(22, 12) | rm.Encode(5, 0)); 23110 AdvanceIT(); 23111 return; 23112 } 23113 } 23114 } else { 23115 // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 23116 if (encoded_dt.IsValid()) { 23117 if (cond.Is(al)) { 23118 EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) | 23119 rd.Encode(22, 12) | rm.Encode(5, 0)); 23120 return; 23121 } 23122 } 23123 } 23124 Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm); 23125 } 23126 23127 void Assembler::vqrdmulh( 23128 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23129 VIXL_ASSERT(AllowAssembler()); 23130 CheckIT(cond); 23131 Dt_size_13 encoded_dt(dt); 23132 if (IsUsingT32()) { 23133 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 23134 if (encoded_dt.IsValid()) { 23135 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23136 EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) | 23137 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23138 AdvanceIT(); 23139 return; 23140 } 23141 } 23142 } else { 23143 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 23144 if (encoded_dt.IsValid()) { 23145 if (cond.Is(al)) { 23146 EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) | 23147 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23148 return; 23149 } 23150 } 23151 } 23152 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 23153 } 23154 23155 void Assembler::vqrdmulh( 23156 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 23157 VIXL_ASSERT(AllowAssembler()); 23158 CheckIT(cond); 23159 Dt_size_13 encoded_dt(dt); 23160 if (IsUsingT32()) { 23161 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 23162 if (encoded_dt.IsValid()) { 23163 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23164 EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) | 23165 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23166 AdvanceIT(); 23167 return; 23168 } 23169 } 23170 } else { 23171 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 23172 if (encoded_dt.IsValid()) { 23173 if (cond.Is(al)) { 23174 EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) | 23175 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23176 return; 23177 } 23178 } 23179 } 23180 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 23181 } 23182 23183 void Assembler::vqrdmulh( 23184 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 23185 VIXL_ASSERT(AllowAssembler()); 23186 CheckIT(cond); 23187 Dt_size_13 encoded_dt(dt); 23188 if (IsUsingT32()) { 23189 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2 23190 if (encoded_dt.IsValid() && 23191 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 23192 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 23193 (rm.GetLane() <= 1))) && 23194 (dt.Is(S16) || dt.Is(S32))) { 23195 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23196 EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) | 23197 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23198 AdvanceIT(); 23199 return; 23200 } 23201 } 23202 } else { 23203 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2 23204 if (encoded_dt.IsValid() && 23205 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 23206 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 23207 (rm.GetLane() <= 1))) && 23208 (dt.Is(S16) || dt.Is(S32))) { 23209 if (cond.Is(al)) { 23210 EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) | 23211 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23212 return; 23213 } 23214 } 23215 } 23216 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 23217 } 23218 23219 void Assembler::vqrdmulh( 23220 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 23221 VIXL_ASSERT(AllowAssembler()); 23222 CheckIT(cond); 23223 Dt_size_13 encoded_dt(dt); 23224 if (IsUsingT32()) { 23225 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2 23226 if (encoded_dt.IsValid() && 23227 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 23228 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 23229 (rm.GetLane() <= 1))) && 23230 (dt.Is(S16) || dt.Is(S32))) { 23231 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23232 EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) | 23233 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23234 AdvanceIT(); 23235 return; 23236 } 23237 } 23238 } else { 23239 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2 23240 if (encoded_dt.IsValid() && 23241 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 23242 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 23243 (rm.GetLane() <= 1))) && 23244 (dt.Is(S16) || dt.Is(S32))) { 23245 if (cond.Is(al)) { 23246 EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) | 23247 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23248 return; 23249 } 23250 } 23251 } 23252 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 23253 } 23254 23255 void Assembler::vqrshl( 23256 Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) { 23257 VIXL_ASSERT(AllowAssembler()); 23258 CheckIT(cond); 23259 Dt_U_size_3 encoded_dt(dt); 23260 if (IsUsingT32()) { 23261 // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 23262 if (encoded_dt.IsValid()) { 23263 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23264 EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23265 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23266 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23267 AdvanceIT(); 23268 return; 23269 } 23270 } 23271 } else { 23272 // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 23273 if (encoded_dt.IsValid()) { 23274 if (cond.Is(al)) { 23275 EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23276 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23277 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23278 return; 23279 } 23280 } 23281 } 23282 Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn); 23283 } 23284 23285 void Assembler::vqrshl( 23286 Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) { 23287 VIXL_ASSERT(AllowAssembler()); 23288 CheckIT(cond); 23289 Dt_U_size_3 encoded_dt(dt); 23290 if (IsUsingT32()) { 23291 // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 23292 if (encoded_dt.IsValid()) { 23293 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23294 EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23295 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23296 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23297 AdvanceIT(); 23298 return; 23299 } 23300 } 23301 } else { 23302 // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 23303 if (encoded_dt.IsValid()) { 23304 if (cond.Is(al)) { 23305 EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23306 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23307 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23308 return; 23309 } 23310 } 23311 } 23312 Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn); 23313 } 23314 23315 void Assembler::vqrshrn(Condition cond, 23316 DataType dt, 23317 DRegister rd, 23318 QRegister rm, 23319 const QOperand& operand) { 23320 VIXL_ASSERT(AllowAssembler()); 23321 CheckIT(cond); 23322 if (operand.IsImmediate()) { 23323 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23324 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23325 Dt_op_size_3 encoded_dt(dt); 23326 Dt_imm6_1 encoded_dt_2(dt); 23327 if (IsUsingT32()) { 23328 // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23329 if (encoded_dt.IsValid() && (imm == 0)) { 23330 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23331 EmitT32_32(0xffb20280U | 23332 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23333 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23334 rd.Encode(22, 12) | rm.Encode(5, 0)); 23335 AdvanceIT(); 23336 return; 23337 } 23338 } 23339 // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 23340 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23341 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23342 uint32_t imm6 = dt.GetSize() / 2 - imm; 23343 EmitT32_32(0xef800950U | 23344 (encoded_dt_2.GetTypeEncodingValue() << 28) | 23345 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 23346 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23347 AdvanceIT(); 23348 return; 23349 } 23350 } 23351 } else { 23352 // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23353 if (encoded_dt.IsValid() && (imm == 0)) { 23354 if (cond.Is(al)) { 23355 EmitA32(0xf3b20280U | 23356 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23357 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23358 rd.Encode(22, 12) | rm.Encode(5, 0)); 23359 return; 23360 } 23361 } 23362 // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 23363 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23364 if (cond.Is(al)) { 23365 uint32_t imm6 = dt.GetSize() / 2 - imm; 23366 EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) | 23367 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 23368 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23369 return; 23370 } 23371 } 23372 } 23373 } 23374 } 23375 Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand); 23376 } 23377 23378 void Assembler::vqrshrun(Condition cond, 23379 DataType dt, 23380 DRegister rd, 23381 QRegister rm, 23382 const QOperand& operand) { 23383 VIXL_ASSERT(AllowAssembler()); 23384 CheckIT(cond); 23385 if (operand.IsImmediate()) { 23386 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23387 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23388 Dt_imm6_2 encoded_dt(dt); 23389 Dt_size_14 encoded_dt_2(dt); 23390 if (IsUsingT32()) { 23391 // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 23392 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23393 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23394 uint32_t imm6 = dt.GetSize() / 2 - imm; 23395 EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) | 23396 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23397 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23398 AdvanceIT(); 23399 return; 23400 } 23401 } 23402 // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23403 if (encoded_dt_2.IsValid() && (imm == 0)) { 23404 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23405 EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) | 23406 rd.Encode(22, 12) | rm.Encode(5, 0)); 23407 AdvanceIT(); 23408 return; 23409 } 23410 } 23411 } else { 23412 // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 23413 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23414 if (cond.Is(al)) { 23415 uint32_t imm6 = dt.GetSize() / 2 - imm; 23416 EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) | 23417 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23418 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23419 return; 23420 } 23421 } 23422 // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23423 if (encoded_dt_2.IsValid() && (imm == 0)) { 23424 if (cond.Is(al)) { 23425 EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) | 23426 rd.Encode(22, 12) | rm.Encode(5, 0)); 23427 return; 23428 } 23429 } 23430 } 23431 } 23432 } 23433 Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand); 23434 } 23435 23436 void Assembler::vqshl(Condition cond, 23437 DataType dt, 23438 DRegister rd, 23439 DRegister rm, 23440 const DOperand& operand) { 23441 VIXL_ASSERT(AllowAssembler()); 23442 CheckIT(cond); 23443 if (operand.IsRegister()) { 23444 DRegister rn = operand.GetRegister(); 23445 Dt_U_size_3 encoded_dt(dt); 23446 if (IsUsingT32()) { 23447 // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 23448 if (encoded_dt.IsValid()) { 23449 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23450 EmitT32_32(0xef000410U | 23451 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23452 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23453 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23454 AdvanceIT(); 23455 return; 23456 } 23457 } 23458 } else { 23459 // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 23460 if (encoded_dt.IsValid()) { 23461 if (cond.Is(al)) { 23462 EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23463 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23464 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23465 return; 23466 } 23467 } 23468 } 23469 } 23470 if (operand.IsImmediate()) { 23471 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23472 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23473 Dt_L_imm6_1 encoded_dt(dt); 23474 if (IsUsingT32()) { 23475 // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 23476 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23477 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23478 uint32_t imm6 = imm; 23479 EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) | 23480 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23481 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23482 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23483 AdvanceIT(); 23484 return; 23485 } 23486 } 23487 } else { 23488 // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 23489 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23490 if (cond.Is(al)) { 23491 uint32_t imm6 = imm; 23492 EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) | 23493 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23494 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23495 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23496 return; 23497 } 23498 } 23499 } 23500 } 23501 } 23502 Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand); 23503 } 23504 23505 void Assembler::vqshl(Condition cond, 23506 DataType dt, 23507 QRegister rd, 23508 QRegister rm, 23509 const QOperand& operand) { 23510 VIXL_ASSERT(AllowAssembler()); 23511 CheckIT(cond); 23512 if (operand.IsRegister()) { 23513 QRegister rn = operand.GetRegister(); 23514 Dt_U_size_3 encoded_dt(dt); 23515 if (IsUsingT32()) { 23516 // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 23517 if (encoded_dt.IsValid()) { 23518 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23519 EmitT32_32(0xef000450U | 23520 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23521 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23522 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23523 AdvanceIT(); 23524 return; 23525 } 23526 } 23527 } else { 23528 // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 23529 if (encoded_dt.IsValid()) { 23530 if (cond.Is(al)) { 23531 EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23532 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23533 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23534 return; 23535 } 23536 } 23537 } 23538 } 23539 if (operand.IsImmediate()) { 23540 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23541 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23542 Dt_L_imm6_1 encoded_dt(dt); 23543 if (IsUsingT32()) { 23544 // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 23545 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23546 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23547 uint32_t imm6 = imm; 23548 EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) | 23549 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23550 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23551 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23552 AdvanceIT(); 23553 return; 23554 } 23555 } 23556 } else { 23557 // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 23558 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23559 if (cond.Is(al)) { 23560 uint32_t imm6 = imm; 23561 EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) | 23562 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23563 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23564 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23565 return; 23566 } 23567 } 23568 } 23569 } 23570 } 23571 Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand); 23572 } 23573 23574 void Assembler::vqshlu(Condition cond, 23575 DataType dt, 23576 DRegister rd, 23577 DRegister rm, 23578 const DOperand& operand) { 23579 VIXL_ASSERT(AllowAssembler()); 23580 CheckIT(cond); 23581 if (operand.IsImmediate()) { 23582 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23583 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23584 Dt_L_imm6_2 encoded_dt(dt); 23585 if (IsUsingT32()) { 23586 // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 23587 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23588 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23589 uint32_t imm6 = imm; 23590 EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) | 23591 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23592 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23593 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23594 AdvanceIT(); 23595 return; 23596 } 23597 } 23598 } else { 23599 // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 23600 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23601 if (cond.Is(al)) { 23602 uint32_t imm6 = imm; 23603 EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) | 23604 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23605 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23606 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23607 return; 23608 } 23609 } 23610 } 23611 } 23612 } 23613 Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand); 23614 } 23615 23616 void Assembler::vqshlu(Condition cond, 23617 DataType dt, 23618 QRegister rd, 23619 QRegister rm, 23620 const QOperand& operand) { 23621 VIXL_ASSERT(AllowAssembler()); 23622 CheckIT(cond); 23623 if (operand.IsImmediate()) { 23624 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23625 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23626 Dt_L_imm6_2 encoded_dt(dt); 23627 if (IsUsingT32()) { 23628 // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 23629 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23630 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23631 uint32_t imm6 = imm; 23632 EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) | 23633 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23634 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23635 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23636 AdvanceIT(); 23637 return; 23638 } 23639 } 23640 } else { 23641 // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 23642 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23643 if (cond.Is(al)) { 23644 uint32_t imm6 = imm; 23645 EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) | 23646 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23647 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23648 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23649 return; 23650 } 23651 } 23652 } 23653 } 23654 } 23655 Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand); 23656 } 23657 23658 void Assembler::vqshrn(Condition cond, 23659 DataType dt, 23660 DRegister rd, 23661 QRegister rm, 23662 const QOperand& operand) { 23663 VIXL_ASSERT(AllowAssembler()); 23664 CheckIT(cond); 23665 if (operand.IsImmediate()) { 23666 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23667 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23668 Dt_op_size_3 encoded_dt(dt); 23669 Dt_imm6_1 encoded_dt_2(dt); 23670 if (IsUsingT32()) { 23671 // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23672 if (encoded_dt.IsValid() && (imm == 0)) { 23673 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23674 EmitT32_32(0xffb20280U | 23675 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23676 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23677 rd.Encode(22, 12) | rm.Encode(5, 0)); 23678 AdvanceIT(); 23679 return; 23680 } 23681 } 23682 // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 23683 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23684 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23685 uint32_t imm6 = dt.GetSize() / 2 - imm; 23686 EmitT32_32(0xef800910U | 23687 (encoded_dt_2.GetTypeEncodingValue() << 28) | 23688 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 23689 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23690 AdvanceIT(); 23691 return; 23692 } 23693 } 23694 } else { 23695 // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23696 if (encoded_dt.IsValid() && (imm == 0)) { 23697 if (cond.Is(al)) { 23698 EmitA32(0xf3b20280U | 23699 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23700 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23701 rd.Encode(22, 12) | rm.Encode(5, 0)); 23702 return; 23703 } 23704 } 23705 // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 23706 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23707 if (cond.Is(al)) { 23708 uint32_t imm6 = dt.GetSize() / 2 - imm; 23709 EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) | 23710 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 23711 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23712 return; 23713 } 23714 } 23715 } 23716 } 23717 } 23718 Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand); 23719 } 23720 23721 void Assembler::vqshrun(Condition cond, 23722 DataType dt, 23723 DRegister rd, 23724 QRegister rm, 23725 const QOperand& operand) { 23726 VIXL_ASSERT(AllowAssembler()); 23727 CheckIT(cond); 23728 if (operand.IsImmediate()) { 23729 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23730 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23731 Dt_imm6_2 encoded_dt(dt); 23732 Dt_size_14 encoded_dt_2(dt); 23733 if (IsUsingT32()) { 23734 // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 23735 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23736 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23737 uint32_t imm6 = dt.GetSize() / 2 - imm; 23738 EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) | 23739 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23740 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23741 AdvanceIT(); 23742 return; 23743 } 23744 } 23745 // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23746 if (encoded_dt_2.IsValid() && (imm == 0)) { 23747 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23748 EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) | 23749 rd.Encode(22, 12) | rm.Encode(5, 0)); 23750 AdvanceIT(); 23751 return; 23752 } 23753 } 23754 } else { 23755 // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 23756 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23757 if (cond.Is(al)) { 23758 uint32_t imm6 = dt.GetSize() / 2 - imm; 23759 EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) | 23760 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23761 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23762 return; 23763 } 23764 } 23765 // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23766 if (encoded_dt_2.IsValid() && (imm == 0)) { 23767 if (cond.Is(al)) { 23768 EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) | 23769 rd.Encode(22, 12) | rm.Encode(5, 0)); 23770 return; 23771 } 23772 } 23773 } 23774 } 23775 } 23776 Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand); 23777 } 23778 23779 void Assembler::vqsub( 23780 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23781 VIXL_ASSERT(AllowAssembler()); 23782 CheckIT(cond); 23783 Dt_U_size_3 encoded_dt(dt); 23784 if (IsUsingT32()) { 23785 // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 23786 if (encoded_dt.IsValid()) { 23787 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23788 EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23789 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23790 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23791 AdvanceIT(); 23792 return; 23793 } 23794 } 23795 } else { 23796 // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 23797 if (encoded_dt.IsValid()) { 23798 if (cond.Is(al)) { 23799 EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23800 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23801 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23802 return; 23803 } 23804 } 23805 } 23806 Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm); 23807 } 23808 23809 void Assembler::vqsub( 23810 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 23811 VIXL_ASSERT(AllowAssembler()); 23812 CheckIT(cond); 23813 Dt_U_size_3 encoded_dt(dt); 23814 if (IsUsingT32()) { 23815 // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 23816 if (encoded_dt.IsValid()) { 23817 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23818 EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23819 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23820 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23821 AdvanceIT(); 23822 return; 23823 } 23824 } 23825 } else { 23826 // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 23827 if (encoded_dt.IsValid()) { 23828 if (cond.Is(al)) { 23829 EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23830 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23831 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23832 return; 23833 } 23834 } 23835 } 23836 Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm); 23837 } 23838 23839 void Assembler::vraddhn( 23840 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 23841 VIXL_ASSERT(AllowAssembler()); 23842 CheckIT(cond); 23843 Dt_size_3 encoded_dt(dt); 23844 if (IsUsingT32()) { 23845 // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 23846 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 23847 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23848 EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) | 23849 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23850 AdvanceIT(); 23851 return; 23852 } 23853 } 23854 } else { 23855 // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 23856 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 23857 if (cond.Is(al)) { 23858 EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) | 23859 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23860 return; 23861 } 23862 } 23863 } 23864 Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm); 23865 } 23866 23867 void Assembler::vrecpe(Condition cond, 23868 DataType dt, 23869 DRegister rd, 23870 DRegister rm) { 23871 VIXL_ASSERT(AllowAssembler()); 23872 CheckIT(cond); 23873 Dt_F_size_4 encoded_dt(dt); 23874 if (IsUsingT32()) { 23875 // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 23876 if (encoded_dt.IsValid()) { 23877 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23878 EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23879 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23880 rd.Encode(22, 12) | rm.Encode(5, 0)); 23881 AdvanceIT(); 23882 return; 23883 } 23884 } 23885 } else { 23886 // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 23887 if (encoded_dt.IsValid()) { 23888 if (cond.Is(al)) { 23889 EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23890 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23891 rd.Encode(22, 12) | rm.Encode(5, 0)); 23892 return; 23893 } 23894 } 23895 } 23896 Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm); 23897 } 23898 23899 void Assembler::vrecpe(Condition cond, 23900 DataType dt, 23901 QRegister rd, 23902 QRegister rm) { 23903 VIXL_ASSERT(AllowAssembler()); 23904 CheckIT(cond); 23905 Dt_F_size_4 encoded_dt(dt); 23906 if (IsUsingT32()) { 23907 // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 23908 if (encoded_dt.IsValid()) { 23909 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23910 EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23911 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23912 rd.Encode(22, 12) | rm.Encode(5, 0)); 23913 AdvanceIT(); 23914 return; 23915 } 23916 } 23917 } else { 23918 // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 23919 if (encoded_dt.IsValid()) { 23920 if (cond.Is(al)) { 23921 EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23922 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23923 rd.Encode(22, 12) | rm.Encode(5, 0)); 23924 return; 23925 } 23926 } 23927 } 23928 Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm); 23929 } 23930 23931 void Assembler::vrecps( 23932 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23933 VIXL_ASSERT(AllowAssembler()); 23934 CheckIT(cond); 23935 if (IsUsingT32()) { 23936 // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 23937 if (dt.Is(F32)) { 23938 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23939 EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23940 rm.Encode(5, 0)); 23941 AdvanceIT(); 23942 return; 23943 } 23944 } 23945 } else { 23946 // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 23947 if (dt.Is(F32)) { 23948 if (cond.Is(al)) { 23949 EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23950 rm.Encode(5, 0)); 23951 return; 23952 } 23953 } 23954 } 23955 Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm); 23956 } 23957 23958 void Assembler::vrecps( 23959 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 23960 VIXL_ASSERT(AllowAssembler()); 23961 CheckIT(cond); 23962 if (IsUsingT32()) { 23963 // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 23964 if (dt.Is(F32)) { 23965 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23966 EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23967 rm.Encode(5, 0)); 23968 AdvanceIT(); 23969 return; 23970 } 23971 } 23972 } else { 23973 // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 23974 if (dt.Is(F32)) { 23975 if (cond.Is(al)) { 23976 EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23977 rm.Encode(5, 0)); 23978 return; 23979 } 23980 } 23981 } 23982 Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm); 23983 } 23984 23985 void Assembler::vrev16(Condition cond, 23986 DataType dt, 23987 DRegister rd, 23988 DRegister rm) { 23989 VIXL_ASSERT(AllowAssembler()); 23990 CheckIT(cond); 23991 Dt_size_1 encoded_dt(dt); 23992 if (IsUsingT32()) { 23993 // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 23994 if (encoded_dt.IsValid()) { 23995 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23996 EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) | 23997 rd.Encode(22, 12) | rm.Encode(5, 0)); 23998 AdvanceIT(); 23999 return; 24000 } 24001 } 24002 } else { 24003 // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 24004 if (encoded_dt.IsValid()) { 24005 if (cond.Is(al)) { 24006 EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) | 24007 rd.Encode(22, 12) | rm.Encode(5, 0)); 24008 return; 24009 } 24010 } 24011 } 24012 Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm); 24013 } 24014 24015 void Assembler::vrev16(Condition cond, 24016 DataType dt, 24017 QRegister rd, 24018 QRegister rm) { 24019 VIXL_ASSERT(AllowAssembler()); 24020 CheckIT(cond); 24021 Dt_size_1 encoded_dt(dt); 24022 if (IsUsingT32()) { 24023 // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 24024 if (encoded_dt.IsValid()) { 24025 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24026 EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) | 24027 rd.Encode(22, 12) | rm.Encode(5, 0)); 24028 AdvanceIT(); 24029 return; 24030 } 24031 } 24032 } else { 24033 // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 24034 if (encoded_dt.IsValid()) { 24035 if (cond.Is(al)) { 24036 EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) | 24037 rd.Encode(22, 12) | rm.Encode(5, 0)); 24038 return; 24039 } 24040 } 24041 } 24042 Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm); 24043 } 24044 24045 void Assembler::vrev32(Condition cond, 24046 DataType dt, 24047 DRegister rd, 24048 DRegister rm) { 24049 VIXL_ASSERT(AllowAssembler()); 24050 CheckIT(cond); 24051 Dt_size_15 encoded_dt(dt); 24052 if (IsUsingT32()) { 24053 // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 24054 if (encoded_dt.IsValid()) { 24055 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24056 EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) | 24057 rd.Encode(22, 12) | rm.Encode(5, 0)); 24058 AdvanceIT(); 24059 return; 24060 } 24061 } 24062 } else { 24063 // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 24064 if (encoded_dt.IsValid()) { 24065 if (cond.Is(al)) { 24066 EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) | 24067 rd.Encode(22, 12) | rm.Encode(5, 0)); 24068 return; 24069 } 24070 } 24071 } 24072 Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm); 24073 } 24074 24075 void Assembler::vrev32(Condition cond, 24076 DataType dt, 24077 QRegister rd, 24078 QRegister rm) { 24079 VIXL_ASSERT(AllowAssembler()); 24080 CheckIT(cond); 24081 Dt_size_15 encoded_dt(dt); 24082 if (IsUsingT32()) { 24083 // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 24084 if (encoded_dt.IsValid()) { 24085 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24086 EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) | 24087 rd.Encode(22, 12) | rm.Encode(5, 0)); 24088 AdvanceIT(); 24089 return; 24090 } 24091 } 24092 } else { 24093 // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 24094 if (encoded_dt.IsValid()) { 24095 if (cond.Is(al)) { 24096 EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) | 24097 rd.Encode(22, 12) | rm.Encode(5, 0)); 24098 return; 24099 } 24100 } 24101 } 24102 Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm); 24103 } 24104 24105 void Assembler::vrev64(Condition cond, 24106 DataType dt, 24107 DRegister rd, 24108 DRegister rm) { 24109 VIXL_ASSERT(AllowAssembler()); 24110 CheckIT(cond); 24111 Dt_size_7 encoded_dt(dt); 24112 if (IsUsingT32()) { 24113 // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 24114 if (encoded_dt.IsValid()) { 24115 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24116 EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) | 24117 rd.Encode(22, 12) | rm.Encode(5, 0)); 24118 AdvanceIT(); 24119 return; 24120 } 24121 } 24122 } else { 24123 // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 24124 if (encoded_dt.IsValid()) { 24125 if (cond.Is(al)) { 24126 EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) | 24127 rd.Encode(22, 12) | rm.Encode(5, 0)); 24128 return; 24129 } 24130 } 24131 } 24132 Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm); 24133 } 24134 24135 void Assembler::vrev64(Condition cond, 24136 DataType dt, 24137 QRegister rd, 24138 QRegister rm) { 24139 VIXL_ASSERT(AllowAssembler()); 24140 CheckIT(cond); 24141 Dt_size_7 encoded_dt(dt); 24142 if (IsUsingT32()) { 24143 // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 24144 if (encoded_dt.IsValid()) { 24145 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24146 EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) | 24147 rd.Encode(22, 12) | rm.Encode(5, 0)); 24148 AdvanceIT(); 24149 return; 24150 } 24151 } 24152 } else { 24153 // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 24154 if (encoded_dt.IsValid()) { 24155 if (cond.Is(al)) { 24156 EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) | 24157 rd.Encode(22, 12) | rm.Encode(5, 0)); 24158 return; 24159 } 24160 } 24161 } 24162 Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm); 24163 } 24164 24165 void Assembler::vrhadd( 24166 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 24167 VIXL_ASSERT(AllowAssembler()); 24168 CheckIT(cond); 24169 Dt_U_size_1 encoded_dt(dt); 24170 if (IsUsingT32()) { 24171 // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 24172 if (encoded_dt.IsValid()) { 24173 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24174 EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24175 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24176 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 24177 AdvanceIT(); 24178 return; 24179 } 24180 } 24181 } else { 24182 // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 24183 if (encoded_dt.IsValid()) { 24184 if (cond.Is(al)) { 24185 EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24186 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24187 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 24188 return; 24189 } 24190 } 24191 } 24192 Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm); 24193 } 24194 24195 void Assembler::vrhadd( 24196 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 24197 VIXL_ASSERT(AllowAssembler()); 24198 CheckIT(cond); 24199 Dt_U_size_1 encoded_dt(dt); 24200 if (IsUsingT32()) { 24201 // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 24202 if (encoded_dt.IsValid()) { 24203 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24204 EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24205 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24206 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 24207 AdvanceIT(); 24208 return; 24209 } 24210 } 24211 } else { 24212 // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 24213 if (encoded_dt.IsValid()) { 24214 if (cond.Is(al)) { 24215 EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24216 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24217 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 24218 return; 24219 } 24220 } 24221 } 24222 Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm); 24223 } 24224 24225 void Assembler::vrinta(DataType dt, DRegister rd, DRegister rm) { 24226 VIXL_ASSERT(AllowAssembler()); 24227 CheckIT(al); 24228 Dt_size_16 encoded_dt(dt); 24229 if (IsUsingT32()) { 24230 // VRINTA{<q>}.<dt> <Dd>, <Dm> ; T1 24231 if (encoded_dt.IsValid()) { 24232 EmitT32_32(0xffb20500U | (encoded_dt.GetEncodingValue() << 18) | 24233 rd.Encode(22, 12) | rm.Encode(5, 0)); 24234 AdvanceIT(); 24235 return; 24236 } 24237 // VRINTA{<q>}.F64 <Dd>, <Dm> ; T1 24238 if (dt.Is(F64)) { 24239 EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24240 AdvanceIT(); 24241 return; 24242 } 24243 } else { 24244 // VRINTA{<q>}.<dt> <Dd>, <Dm> ; A1 24245 if (encoded_dt.IsValid()) { 24246 EmitA32(0xf3b20500U | (encoded_dt.GetEncodingValue() << 18) | 24247 rd.Encode(22, 12) | rm.Encode(5, 0)); 24248 return; 24249 } 24250 // VRINTA{<q>}.F64 <Dd>, <Dm> ; A1 24251 if (dt.Is(F64)) { 24252 EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24253 return; 24254 } 24255 } 24256 Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm); 24257 } 24258 24259 void Assembler::vrinta(DataType dt, QRegister rd, QRegister rm) { 24260 VIXL_ASSERT(AllowAssembler()); 24261 CheckIT(al); 24262 Dt_size_16 encoded_dt(dt); 24263 if (IsUsingT32()) { 24264 // VRINTA{<q>}.<dt> <Qd>, <Qm> ; T1 24265 if (encoded_dt.IsValid()) { 24266 EmitT32_32(0xffb20540U | (encoded_dt.GetEncodingValue() << 18) | 24267 rd.Encode(22, 12) | rm.Encode(5, 0)); 24268 AdvanceIT(); 24269 return; 24270 } 24271 } else { 24272 // VRINTA{<q>}.<dt> <Qd>, <Qm> ; A1 24273 if (encoded_dt.IsValid()) { 24274 EmitA32(0xf3b20540U | (encoded_dt.GetEncodingValue() << 18) | 24275 rd.Encode(22, 12) | rm.Encode(5, 0)); 24276 return; 24277 } 24278 } 24279 Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm); 24280 } 24281 24282 void Assembler::vrinta(DataType dt, SRegister rd, SRegister rm) { 24283 VIXL_ASSERT(AllowAssembler()); 24284 CheckIT(al); 24285 if (IsUsingT32()) { 24286 // VRINTA{<q>}.F32 <Sd>, <Sm> ; T1 24287 if (dt.Is(F32)) { 24288 EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24289 AdvanceIT(); 24290 return; 24291 } 24292 } else { 24293 // VRINTA{<q>}.F32 <Sd>, <Sm> ; A1 24294 if (dt.Is(F32)) { 24295 EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24296 return; 24297 } 24298 } 24299 Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm); 24300 } 24301 24302 void Assembler::vrintm(DataType dt, DRegister rd, DRegister rm) { 24303 VIXL_ASSERT(AllowAssembler()); 24304 CheckIT(al); 24305 Dt_size_16 encoded_dt(dt); 24306 if (IsUsingT32()) { 24307 // VRINTM{<q>}.<dt> <Dd>, <Dm> ; T1 24308 if (encoded_dt.IsValid()) { 24309 EmitT32_32(0xffb20680U | (encoded_dt.GetEncodingValue() << 18) | 24310 rd.Encode(22, 12) | rm.Encode(5, 0)); 24311 AdvanceIT(); 24312 return; 24313 } 24314 // VRINTM{<q>}.F64 <Dd>, <Dm> ; T1 24315 if (dt.Is(F64)) { 24316 EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24317 AdvanceIT(); 24318 return; 24319 } 24320 } else { 24321 // VRINTM{<q>}.<dt> <Dd>, <Dm> ; A1 24322 if (encoded_dt.IsValid()) { 24323 EmitA32(0xf3b20680U | (encoded_dt.GetEncodingValue() << 18) | 24324 rd.Encode(22, 12) | rm.Encode(5, 0)); 24325 return; 24326 } 24327 // VRINTM{<q>}.F64 <Dd>, <Dm> ; A1 24328 if (dt.Is(F64)) { 24329 EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24330 return; 24331 } 24332 } 24333 Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm); 24334 } 24335 24336 void Assembler::vrintm(DataType dt, QRegister rd, QRegister rm) { 24337 VIXL_ASSERT(AllowAssembler()); 24338 CheckIT(al); 24339 Dt_size_16 encoded_dt(dt); 24340 if (IsUsingT32()) { 24341 // VRINTM{<q>}.<dt> <Qd>, <Qm> ; T1 24342 if (encoded_dt.IsValid()) { 24343 EmitT32_32(0xffb206c0U | (encoded_dt.GetEncodingValue() << 18) | 24344 rd.Encode(22, 12) | rm.Encode(5, 0)); 24345 AdvanceIT(); 24346 return; 24347 } 24348 } else { 24349 // VRINTM{<q>}.<dt> <Qd>, <Qm> ; A1 24350 if (encoded_dt.IsValid()) { 24351 EmitA32(0xf3b206c0U | (encoded_dt.GetEncodingValue() << 18) | 24352 rd.Encode(22, 12) | rm.Encode(5, 0)); 24353 return; 24354 } 24355 } 24356 Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm); 24357 } 24358 24359 void Assembler::vrintm(DataType dt, SRegister rd, SRegister rm) { 24360 VIXL_ASSERT(AllowAssembler()); 24361 CheckIT(al); 24362 if (IsUsingT32()) { 24363 // VRINTM{<q>}.F32 <Sd>, <Sm> ; T1 24364 if (dt.Is(F32)) { 24365 EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24366 AdvanceIT(); 24367 return; 24368 } 24369 } else { 24370 // VRINTM{<q>}.F32 <Sd>, <Sm> ; A1 24371 if (dt.Is(F32)) { 24372 EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24373 return; 24374 } 24375 } 24376 Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm); 24377 } 24378 24379 void Assembler::vrintn(DataType dt, DRegister rd, DRegister rm) { 24380 VIXL_ASSERT(AllowAssembler()); 24381 CheckIT(al); 24382 Dt_size_16 encoded_dt(dt); 24383 if (IsUsingT32()) { 24384 // VRINTN{<q>}.<dt> <Dd>, <Dm> ; T1 24385 if (encoded_dt.IsValid()) { 24386 EmitT32_32(0xffb20400U | (encoded_dt.GetEncodingValue() << 18) | 24387 rd.Encode(22, 12) | rm.Encode(5, 0)); 24388 AdvanceIT(); 24389 return; 24390 } 24391 // VRINTN{<q>}.F64 <Dd>, <Dm> ; T1 24392 if (dt.Is(F64)) { 24393 EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24394 AdvanceIT(); 24395 return; 24396 } 24397 } else { 24398 // VRINTN{<q>}.<dt> <Dd>, <Dm> ; A1 24399 if (encoded_dt.IsValid()) { 24400 EmitA32(0xf3b20400U | (encoded_dt.GetEncodingValue() << 18) | 24401 rd.Encode(22, 12) | rm.Encode(5, 0)); 24402 return; 24403 } 24404 // VRINTN{<q>}.F64 <Dd>, <Dm> ; A1 24405 if (dt.Is(F64)) { 24406 EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24407 return; 24408 } 24409 } 24410 Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm); 24411 } 24412 24413 void Assembler::vrintn(DataType dt, QRegister rd, QRegister rm) { 24414 VIXL_ASSERT(AllowAssembler()); 24415 CheckIT(al); 24416 Dt_size_16 encoded_dt(dt); 24417 if (IsUsingT32()) { 24418 // VRINTN{<q>}.<dt> <Qd>, <Qm> ; T1 24419 if (encoded_dt.IsValid()) { 24420 EmitT32_32(0xffb20440U | (encoded_dt.GetEncodingValue() << 18) | 24421 rd.Encode(22, 12) | rm.Encode(5, 0)); 24422 AdvanceIT(); 24423 return; 24424 } 24425 } else { 24426 // VRINTN{<q>}.<dt> <Qd>, <Qm> ; A1 24427 if (encoded_dt.IsValid()) { 24428 EmitA32(0xf3b20440U | (encoded_dt.GetEncodingValue() << 18) | 24429 rd.Encode(22, 12) | rm.Encode(5, 0)); 24430 return; 24431 } 24432 } 24433 Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm); 24434 } 24435 24436 void Assembler::vrintn(DataType dt, SRegister rd, SRegister rm) { 24437 VIXL_ASSERT(AllowAssembler()); 24438 CheckIT(al); 24439 if (IsUsingT32()) { 24440 // VRINTN{<q>}.F32 <Sd>, <Sm> ; T1 24441 if (dt.Is(F32)) { 24442 EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24443 AdvanceIT(); 24444 return; 24445 } 24446 } else { 24447 // VRINTN{<q>}.F32 <Sd>, <Sm> ; A1 24448 if (dt.Is(F32)) { 24449 EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24450 return; 24451 } 24452 } 24453 Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm); 24454 } 24455 24456 void Assembler::vrintp(DataType dt, DRegister rd, DRegister rm) { 24457 VIXL_ASSERT(AllowAssembler()); 24458 CheckIT(al); 24459 Dt_size_16 encoded_dt(dt); 24460 if (IsUsingT32()) { 24461 // VRINTP{<q>}.<dt> <Dd>, <Dm> ; T1 24462 if (encoded_dt.IsValid()) { 24463 EmitT32_32(0xffb20780U | (encoded_dt.GetEncodingValue() << 18) | 24464 rd.Encode(22, 12) | rm.Encode(5, 0)); 24465 AdvanceIT(); 24466 return; 24467 } 24468 // VRINTP{<q>}.F64 <Dd>, <Dm> ; T1 24469 if (dt.Is(F64)) { 24470 EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24471 AdvanceIT(); 24472 return; 24473 } 24474 } else { 24475 // VRINTP{<q>}.<dt> <Dd>, <Dm> ; A1 24476 if (encoded_dt.IsValid()) { 24477 EmitA32(0xf3b20780U | (encoded_dt.GetEncodingValue() << 18) | 24478 rd.Encode(22, 12) | rm.Encode(5, 0)); 24479 return; 24480 } 24481 // VRINTP{<q>}.F64 <Dd>, <Dm> ; A1 24482 if (dt.Is(F64)) { 24483 EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24484 return; 24485 } 24486 } 24487 Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm); 24488 } 24489 24490 void Assembler::vrintp(DataType dt, QRegister rd, QRegister rm) { 24491 VIXL_ASSERT(AllowAssembler()); 24492 CheckIT(al); 24493 Dt_size_16 encoded_dt(dt); 24494 if (IsUsingT32()) { 24495 // VRINTP{<q>}.<dt> <Qd>, <Qm> ; T1 24496 if (encoded_dt.IsValid()) { 24497 EmitT32_32(0xffb207c0U | (encoded_dt.GetEncodingValue() << 18) | 24498 rd.Encode(22, 12) | rm.Encode(5, 0)); 24499 AdvanceIT(); 24500 return; 24501 } 24502 } else { 24503 // VRINTP{<q>}.<dt> <Qd>, <Qm> ; A1 24504 if (encoded_dt.IsValid()) { 24505 EmitA32(0xf3b207c0U | (encoded_dt.GetEncodingValue() << 18) | 24506 rd.Encode(22, 12) | rm.Encode(5, 0)); 24507 return; 24508 } 24509 } 24510 Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm); 24511 } 24512 24513 void Assembler::vrintp(DataType dt, SRegister rd, SRegister rm) { 24514 VIXL_ASSERT(AllowAssembler()); 24515 CheckIT(al); 24516 if (IsUsingT32()) { 24517 // VRINTP{<q>}.F32 <Sd>, <Sm> ; T1 24518 if (dt.Is(F32)) { 24519 EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24520 AdvanceIT(); 24521 return; 24522 } 24523 } else { 24524 // VRINTP{<q>}.F32 <Sd>, <Sm> ; A1 24525 if (dt.Is(F32)) { 24526 EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24527 return; 24528 } 24529 } 24530 Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm); 24531 } 24532 24533 void Assembler::vrintr(Condition cond, 24534 DataType dt, 24535 SRegister rd, 24536 SRegister rm) { 24537 VIXL_ASSERT(AllowAssembler()); 24538 CheckIT(cond); 24539 if (IsUsingT32()) { 24540 // VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 24541 if (dt.Is(F32)) { 24542 EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24543 AdvanceIT(); 24544 return; 24545 } 24546 } else { 24547 // VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 24548 if (dt.Is(F32) && cond.IsNotNever()) { 24549 EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24550 rm.Encode(5, 0)); 24551 return; 24552 } 24553 } 24554 Delegate(kVrintr, &Assembler::vrintr, cond, dt, rd, rm); 24555 } 24556 24557 void Assembler::vrintr(Condition cond, 24558 DataType dt, 24559 DRegister rd, 24560 DRegister rm) { 24561 VIXL_ASSERT(AllowAssembler()); 24562 CheckIT(cond); 24563 if (IsUsingT32()) { 24564 // VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 24565 if (dt.Is(F64)) { 24566 EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24567 AdvanceIT(); 24568 return; 24569 } 24570 } else { 24571 // VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 24572 if (dt.Is(F64) && cond.IsNotNever()) { 24573 EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24574 rm.Encode(5, 0)); 24575 return; 24576 } 24577 } 24578 Delegate(kVrintr, &Assembler::vrintr, cond, dt, rd, rm); 24579 } 24580 24581 void Assembler::vrintx(Condition cond, 24582 DataType dt, 24583 DRegister rd, 24584 DRegister rm) { 24585 VIXL_ASSERT(AllowAssembler()); 24586 CheckIT(cond); 24587 Dt_size_16 encoded_dt(dt); 24588 if (IsUsingT32()) { 24589 // VRINTX{<q>}.<dt> <Dd>, <Dm> ; T1 24590 if (encoded_dt.IsValid()) { 24591 EmitT32_32(0xffb20480U | (encoded_dt.GetEncodingValue() << 18) | 24592 rd.Encode(22, 12) | rm.Encode(5, 0)); 24593 AdvanceIT(); 24594 return; 24595 } 24596 // VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 24597 if (dt.Is(F64)) { 24598 EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24599 AdvanceIT(); 24600 return; 24601 } 24602 } else { 24603 // VRINTX{<q>}.<dt> <Dd>, <Dm> ; A1 24604 if (encoded_dt.IsValid()) { 24605 EmitA32(0xf3b20480U | (encoded_dt.GetEncodingValue() << 18) | 24606 rd.Encode(22, 12) | rm.Encode(5, 0)); 24607 return; 24608 } 24609 // VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 24610 if (dt.Is(F64) && cond.IsNotNever()) { 24611 EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24612 rm.Encode(5, 0)); 24613 return; 24614 } 24615 } 24616 Delegate(kVrintx, &Assembler::vrintx, cond, dt, rd, rm); 24617 } 24618 24619 void Assembler::vrintx(DataType dt, QRegister rd, QRegister rm) { 24620 VIXL_ASSERT(AllowAssembler()); 24621 CheckIT(al); 24622 Dt_size_16 encoded_dt(dt); 24623 if (IsUsingT32()) { 24624 // VRINTX{<q>}.<dt> <Qd>, <Qm> ; T1 24625 if (encoded_dt.IsValid()) { 24626 EmitT32_32(0xffb204c0U | (encoded_dt.GetEncodingValue() << 18) | 24627 rd.Encode(22, 12) | rm.Encode(5, 0)); 24628 AdvanceIT(); 24629 return; 24630 } 24631 } else { 24632 // VRINTX{<q>}.<dt> <Qd>, <Qm> ; A1 24633 if (encoded_dt.IsValid()) { 24634 EmitA32(0xf3b204c0U | (encoded_dt.GetEncodingValue() << 18) | 24635 rd.Encode(22, 12) | rm.Encode(5, 0)); 24636 return; 24637 } 24638 } 24639 Delegate(kVrintx, &Assembler::vrintx, dt, rd, rm); 24640 } 24641 24642 void Assembler::vrintx(Condition cond, 24643 DataType dt, 24644 SRegister rd, 24645 SRegister rm) { 24646 VIXL_ASSERT(AllowAssembler()); 24647 CheckIT(cond); 24648 if (IsUsingT32()) { 24649 // VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 24650 if (dt.Is(F32)) { 24651 EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24652 AdvanceIT(); 24653 return; 24654 } 24655 } else { 24656 // VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 24657 if (dt.Is(F32) && cond.IsNotNever()) { 24658 EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24659 rm.Encode(5, 0)); 24660 return; 24661 } 24662 } 24663 Delegate(kVrintx, &Assembler::vrintx, cond, dt, rd, rm); 24664 } 24665 24666 void Assembler::vrintz(Condition cond, 24667 DataType dt, 24668 DRegister rd, 24669 DRegister rm) { 24670 VIXL_ASSERT(AllowAssembler()); 24671 CheckIT(cond); 24672 Dt_size_16 encoded_dt(dt); 24673 if (IsUsingT32()) { 24674 // VRINTZ{<q>}.<dt> <Dd>, <Dm> ; T1 24675 if (encoded_dt.IsValid()) { 24676 EmitT32_32(0xffb20580U | (encoded_dt.GetEncodingValue() << 18) | 24677 rd.Encode(22, 12) | rm.Encode(5, 0)); 24678 AdvanceIT(); 24679 return; 24680 } 24681 // VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 24682 if (dt.Is(F64)) { 24683 EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24684 AdvanceIT(); 24685 return; 24686 } 24687 } else { 24688 // VRINTZ{<q>}.<dt> <Dd>, <Dm> ; A1 24689 if (encoded_dt.IsValid()) { 24690 EmitA32(0xf3b20580U | (encoded_dt.GetEncodingValue() << 18) | 24691 rd.Encode(22, 12) | rm.Encode(5, 0)); 24692 return; 24693 } 24694 // VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 24695 if (dt.Is(F64) && cond.IsNotNever()) { 24696 EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24697 rm.Encode(5, 0)); 24698 return; 24699 } 24700 } 24701 Delegate(kVrintz, &Assembler::vrintz, cond, dt, rd, rm); 24702 } 24703 24704 void Assembler::vrintz(DataType dt, QRegister rd, QRegister rm) { 24705 VIXL_ASSERT(AllowAssembler()); 24706 CheckIT(al); 24707 Dt_size_16 encoded_dt(dt); 24708 if (IsUsingT32()) { 24709 // VRINTZ{<q>}.<dt> <Qd>, <Qm> ; T1 24710 if (encoded_dt.IsValid()) { 24711 EmitT32_32(0xffb205c0U | (encoded_dt.GetEncodingValue() << 18) | 24712 rd.Encode(22, 12) | rm.Encode(5, 0)); 24713 AdvanceIT(); 24714 return; 24715 } 24716 } else { 24717 // VRINTZ{<q>}.<dt> <Qd>, <Qm> ; A1 24718 if (encoded_dt.IsValid()) { 24719 EmitA32(0xf3b205c0U | (encoded_dt.GetEncodingValue() << 18) | 24720 rd.Encode(22, 12) | rm.Encode(5, 0)); 24721 return; 24722 } 24723 } 24724 Delegate(kVrintz, &Assembler::vrintz, dt, rd, rm); 24725 } 24726 24727 void Assembler::vrintz(Condition cond, 24728 DataType dt, 24729 SRegister rd, 24730 SRegister rm) { 24731 VIXL_ASSERT(AllowAssembler()); 24732 CheckIT(cond); 24733 if (IsUsingT32()) { 24734 // VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 24735 if (dt.Is(F32)) { 24736 EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24737 AdvanceIT(); 24738 return; 24739 } 24740 } else { 24741 // VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 24742 if (dt.Is(F32) && cond.IsNotNever()) { 24743 EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24744 rm.Encode(5, 0)); 24745 return; 24746 } 24747 } 24748 Delegate(kVrintz, &Assembler::vrintz, cond, dt, rd, rm); 24749 } 24750 24751 void Assembler::vrshl( 24752 Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) { 24753 VIXL_ASSERT(AllowAssembler()); 24754 CheckIT(cond); 24755 Dt_U_size_3 encoded_dt(dt); 24756 if (IsUsingT32()) { 24757 // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 24758 if (encoded_dt.IsValid()) { 24759 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24760 EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24761 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24762 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24763 AdvanceIT(); 24764 return; 24765 } 24766 } 24767 } else { 24768 // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 24769 if (encoded_dt.IsValid()) { 24770 if (cond.Is(al)) { 24771 EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24772 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24773 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24774 return; 24775 } 24776 } 24777 } 24778 Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn); 24779 } 24780 24781 void Assembler::vrshl( 24782 Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) { 24783 VIXL_ASSERT(AllowAssembler()); 24784 CheckIT(cond); 24785 Dt_U_size_3 encoded_dt(dt); 24786 if (IsUsingT32()) { 24787 // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 24788 if (encoded_dt.IsValid()) { 24789 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24790 EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24791 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24792 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24793 AdvanceIT(); 24794 return; 24795 } 24796 } 24797 } else { 24798 // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 24799 if (encoded_dt.IsValid()) { 24800 if (cond.Is(al)) { 24801 EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24802 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24803 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24804 return; 24805 } 24806 } 24807 } 24808 Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn); 24809 } 24810 24811 void Assembler::vrshr(Condition cond, 24812 DataType dt, 24813 DRegister rd, 24814 DRegister rm, 24815 const DOperand& operand) { 24816 VIXL_ASSERT(AllowAssembler()); 24817 CheckIT(cond); 24818 if (operand.IsImmediate()) { 24819 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24820 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24821 Dt_L_imm6_1 encoded_dt(dt); 24822 if (IsUsingT32()) { 24823 // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 24824 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24825 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24826 uint32_t imm6 = dt.GetSize() - imm; 24827 EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) | 24828 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24829 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24830 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24831 AdvanceIT(); 24832 return; 24833 } 24834 } 24835 // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1 24836 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24837 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24838 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24839 rm.Encode(5, 0)); 24840 AdvanceIT(); 24841 return; 24842 } 24843 } 24844 } else { 24845 // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 24846 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24847 if (cond.Is(al)) { 24848 uint32_t imm6 = dt.GetSize() - imm; 24849 EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) | 24850 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24851 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24852 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24853 return; 24854 } 24855 } 24856 // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1 24857 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24858 if (cond.Is(al)) { 24859 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24860 rm.Encode(5, 0)); 24861 return; 24862 } 24863 } 24864 } 24865 } 24866 } 24867 Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand); 24868 } 24869 24870 void Assembler::vrshr(Condition cond, 24871 DataType dt, 24872 QRegister rd, 24873 QRegister rm, 24874 const QOperand& operand) { 24875 VIXL_ASSERT(AllowAssembler()); 24876 CheckIT(cond); 24877 if (operand.IsImmediate()) { 24878 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24879 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24880 Dt_L_imm6_1 encoded_dt(dt); 24881 if (IsUsingT32()) { 24882 // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 24883 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24884 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24885 uint32_t imm6 = dt.GetSize() - imm; 24886 EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) | 24887 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24888 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24889 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24890 AdvanceIT(); 24891 return; 24892 } 24893 } 24894 // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1 24895 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24896 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24897 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24898 rm.Encode(5, 0)); 24899 AdvanceIT(); 24900 return; 24901 } 24902 } 24903 } else { 24904 // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 24905 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24906 if (cond.Is(al)) { 24907 uint32_t imm6 = dt.GetSize() - imm; 24908 EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) | 24909 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24910 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24911 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24912 return; 24913 } 24914 } 24915 // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1 24916 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24917 if (cond.Is(al)) { 24918 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24919 rm.Encode(5, 0)); 24920 return; 24921 } 24922 } 24923 } 24924 } 24925 } 24926 Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand); 24927 } 24928 24929 void Assembler::vrshrn(Condition cond, 24930 DataType dt, 24931 DRegister rd, 24932 QRegister rm, 24933 const QOperand& operand) { 24934 VIXL_ASSERT(AllowAssembler()); 24935 CheckIT(cond); 24936 if (operand.IsImmediate()) { 24937 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24938 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24939 Dt_imm6_3 encoded_dt(dt); 24940 Dt_size_3 encoded_dt_2(dt); 24941 if (IsUsingT32()) { 24942 // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 24943 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 24944 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24945 uint32_t imm6 = dt.GetSize() / 2 - imm; 24946 EmitT32_32(0xef800850U | 24947 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24948 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24949 AdvanceIT(); 24950 return; 24951 } 24952 } 24953 // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 24954 if (encoded_dt_2.IsValid() && (imm == 0)) { 24955 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24956 EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) | 24957 rd.Encode(22, 12) | rm.Encode(5, 0)); 24958 AdvanceIT(); 24959 return; 24960 } 24961 } 24962 } else { 24963 // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 24964 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 24965 if (cond.Is(al)) { 24966 uint32_t imm6 = dt.GetSize() / 2 - imm; 24967 EmitA32(0xf2800850U | 24968 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24969 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24970 return; 24971 } 24972 } 24973 // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 24974 if (encoded_dt_2.IsValid() && (imm == 0)) { 24975 if (cond.Is(al)) { 24976 EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) | 24977 rd.Encode(22, 12) | rm.Encode(5, 0)); 24978 return; 24979 } 24980 } 24981 } 24982 } 24983 } 24984 Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand); 24985 } 24986 24987 void Assembler::vrsqrte(Condition cond, 24988 DataType dt, 24989 DRegister rd, 24990 DRegister rm) { 24991 VIXL_ASSERT(AllowAssembler()); 24992 CheckIT(cond); 24993 Dt_F_size_4 encoded_dt(dt); 24994 if (IsUsingT32()) { 24995 // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 24996 if (encoded_dt.IsValid()) { 24997 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24998 EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 24999 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 25000 rd.Encode(22, 12) | rm.Encode(5, 0)); 25001 AdvanceIT(); 25002 return; 25003 } 25004 } 25005 } else { 25006 // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 25007 if (encoded_dt.IsValid()) { 25008 if (cond.Is(al)) { 25009 EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 25010 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 25011 rd.Encode(22, 12) | rm.Encode(5, 0)); 25012 return; 25013 } 25014 } 25015 } 25016 Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm); 25017 } 25018 25019 void Assembler::vrsqrte(Condition cond, 25020 DataType dt, 25021 QRegister rd, 25022 QRegister rm) { 25023 VIXL_ASSERT(AllowAssembler()); 25024 CheckIT(cond); 25025 Dt_F_size_4 encoded_dt(dt); 25026 if (IsUsingT32()) { 25027 // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 25028 if (encoded_dt.IsValid()) { 25029 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25030 EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 25031 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 25032 rd.Encode(22, 12) | rm.Encode(5, 0)); 25033 AdvanceIT(); 25034 return; 25035 } 25036 } 25037 } else { 25038 // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 25039 if (encoded_dt.IsValid()) { 25040 if (cond.Is(al)) { 25041 EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 25042 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 25043 rd.Encode(22, 12) | rm.Encode(5, 0)); 25044 return; 25045 } 25046 } 25047 } 25048 Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm); 25049 } 25050 25051 void Assembler::vrsqrts( 25052 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25053 VIXL_ASSERT(AllowAssembler()); 25054 CheckIT(cond); 25055 if (IsUsingT32()) { 25056 // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 25057 if (dt.Is(F32)) { 25058 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25059 EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25060 rm.Encode(5, 0)); 25061 AdvanceIT(); 25062 return; 25063 } 25064 } 25065 } else { 25066 // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 25067 if (dt.Is(F32)) { 25068 if (cond.Is(al)) { 25069 EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25070 rm.Encode(5, 0)); 25071 return; 25072 } 25073 } 25074 } 25075 Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm); 25076 } 25077 25078 void Assembler::vrsqrts( 25079 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 25080 VIXL_ASSERT(AllowAssembler()); 25081 CheckIT(cond); 25082 if (IsUsingT32()) { 25083 // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 25084 if (dt.Is(F32)) { 25085 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25086 EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25087 rm.Encode(5, 0)); 25088 AdvanceIT(); 25089 return; 25090 } 25091 } 25092 } else { 25093 // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 25094 if (dt.Is(F32)) { 25095 if (cond.Is(al)) { 25096 EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25097 rm.Encode(5, 0)); 25098 return; 25099 } 25100 } 25101 } 25102 Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm); 25103 } 25104 25105 void Assembler::vrsra(Condition cond, 25106 DataType dt, 25107 DRegister rd, 25108 DRegister rm, 25109 const DOperand& operand) { 25110 VIXL_ASSERT(AllowAssembler()); 25111 CheckIT(cond); 25112 if (operand.IsImmediate()) { 25113 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25114 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25115 Dt_L_imm6_1 encoded_dt(dt); 25116 if (IsUsingT32()) { 25117 // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 25118 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25119 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25120 uint32_t imm6 = dt.GetSize() - imm; 25121 EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) | 25122 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25123 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25124 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25125 AdvanceIT(); 25126 return; 25127 } 25128 } 25129 } else { 25130 // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 25131 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25132 if (cond.Is(al)) { 25133 uint32_t imm6 = dt.GetSize() - imm; 25134 EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) | 25135 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25136 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25137 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25138 return; 25139 } 25140 } 25141 } 25142 } 25143 } 25144 Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand); 25145 } 25146 25147 void Assembler::vrsra(Condition cond, 25148 DataType dt, 25149 QRegister rd, 25150 QRegister rm, 25151 const QOperand& operand) { 25152 VIXL_ASSERT(AllowAssembler()); 25153 CheckIT(cond); 25154 if (operand.IsImmediate()) { 25155 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25156 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25157 Dt_L_imm6_1 encoded_dt(dt); 25158 if (IsUsingT32()) { 25159 // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 25160 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25161 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25162 uint32_t imm6 = dt.GetSize() - imm; 25163 EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) | 25164 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25165 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25166 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25167 AdvanceIT(); 25168 return; 25169 } 25170 } 25171 } else { 25172 // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 25173 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25174 if (cond.Is(al)) { 25175 uint32_t imm6 = dt.GetSize() - imm; 25176 EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) | 25177 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25178 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25179 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25180 return; 25181 } 25182 } 25183 } 25184 } 25185 } 25186 Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand); 25187 } 25188 25189 void Assembler::vrsubhn( 25190 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 25191 VIXL_ASSERT(AllowAssembler()); 25192 CheckIT(cond); 25193 Dt_size_3 encoded_dt(dt); 25194 if (IsUsingT32()) { 25195 // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 25196 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 25197 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25198 EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) | 25199 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 25200 AdvanceIT(); 25201 return; 25202 } 25203 } 25204 } else { 25205 // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 25206 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 25207 if (cond.Is(al)) { 25208 EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) | 25209 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 25210 return; 25211 } 25212 } 25213 } 25214 Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm); 25215 } 25216 25217 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25218 VIXL_ASSERT(AllowAssembler()); 25219 CheckIT(al); 25220 if (IsUsingT32()) { 25221 // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1 25222 if (OutsideITBlock() && dt.Is(F64)) { 25223 EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25224 rm.Encode(5, 0)); 25225 AdvanceIT(); 25226 return; 25227 } 25228 } else { 25229 // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1 25230 if (dt.Is(F64)) { 25231 EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25232 rm.Encode(5, 0)); 25233 return; 25234 } 25235 } 25236 Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm); 25237 } 25238 25239 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 25240 VIXL_ASSERT(AllowAssembler()); 25241 CheckIT(al); 25242 if (IsUsingT32()) { 25243 // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1 25244 if (OutsideITBlock() && dt.Is(F32)) { 25245 EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25246 rm.Encode(5, 0)); 25247 AdvanceIT(); 25248 return; 25249 } 25250 } else { 25251 // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1 25252 if (dt.Is(F32)) { 25253 EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25254 rm.Encode(5, 0)); 25255 return; 25256 } 25257 } 25258 Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm); 25259 } 25260 25261 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25262 VIXL_ASSERT(AllowAssembler()); 25263 CheckIT(al); 25264 if (IsUsingT32()) { 25265 // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1 25266 if (OutsideITBlock() && dt.Is(F64)) { 25267 EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25268 rm.Encode(5, 0)); 25269 AdvanceIT(); 25270 return; 25271 } 25272 } else { 25273 // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1 25274 if (dt.Is(F64)) { 25275 EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25276 rm.Encode(5, 0)); 25277 return; 25278 } 25279 } 25280 Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm); 25281 } 25282 25283 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 25284 VIXL_ASSERT(AllowAssembler()); 25285 CheckIT(al); 25286 if (IsUsingT32()) { 25287 // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1 25288 if (OutsideITBlock() && dt.Is(F32)) { 25289 EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25290 rm.Encode(5, 0)); 25291 AdvanceIT(); 25292 return; 25293 } 25294 } else { 25295 // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1 25296 if (dt.Is(F32)) { 25297 EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25298 rm.Encode(5, 0)); 25299 return; 25300 } 25301 } 25302 Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm); 25303 } 25304 25305 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25306 VIXL_ASSERT(AllowAssembler()); 25307 CheckIT(al); 25308 if (IsUsingT32()) { 25309 // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1 25310 if (OutsideITBlock() && dt.Is(F64)) { 25311 EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25312 rm.Encode(5, 0)); 25313 AdvanceIT(); 25314 return; 25315 } 25316 } else { 25317 // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1 25318 if (dt.Is(F64)) { 25319 EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25320 rm.Encode(5, 0)); 25321 return; 25322 } 25323 } 25324 Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm); 25325 } 25326 25327 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 25328 VIXL_ASSERT(AllowAssembler()); 25329 CheckIT(al); 25330 if (IsUsingT32()) { 25331 // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1 25332 if (OutsideITBlock() && dt.Is(F32)) { 25333 EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25334 rm.Encode(5, 0)); 25335 AdvanceIT(); 25336 return; 25337 } 25338 } else { 25339 // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1 25340 if (dt.Is(F32)) { 25341 EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25342 rm.Encode(5, 0)); 25343 return; 25344 } 25345 } 25346 Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm); 25347 } 25348 25349 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25350 VIXL_ASSERT(AllowAssembler()); 25351 CheckIT(al); 25352 if (IsUsingT32()) { 25353 // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1 25354 if (OutsideITBlock() && dt.Is(F64)) { 25355 EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25356 rm.Encode(5, 0)); 25357 AdvanceIT(); 25358 return; 25359 } 25360 } else { 25361 // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1 25362 if (dt.Is(F64)) { 25363 EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25364 rm.Encode(5, 0)); 25365 return; 25366 } 25367 } 25368 Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm); 25369 } 25370 25371 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 25372 VIXL_ASSERT(AllowAssembler()); 25373 CheckIT(al); 25374 if (IsUsingT32()) { 25375 // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1 25376 if (OutsideITBlock() && dt.Is(F32)) { 25377 EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25378 rm.Encode(5, 0)); 25379 AdvanceIT(); 25380 return; 25381 } 25382 } else { 25383 // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1 25384 if (dt.Is(F32)) { 25385 EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25386 rm.Encode(5, 0)); 25387 return; 25388 } 25389 } 25390 Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm); 25391 } 25392 25393 void Assembler::vshl(Condition cond, 25394 DataType dt, 25395 DRegister rd, 25396 DRegister rm, 25397 const DOperand& operand) { 25398 VIXL_ASSERT(AllowAssembler()); 25399 CheckIT(cond); 25400 if (operand.IsImmediate()) { 25401 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25402 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25403 Dt_L_imm6_3 encoded_dt(dt); 25404 if (IsUsingT32()) { 25405 // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1 25406 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25407 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25408 uint32_t imm6 = imm; 25409 EmitT32_32(0xef800510U | 25410 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25411 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25412 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25413 AdvanceIT(); 25414 return; 25415 } 25416 } 25417 } else { 25418 // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1 25419 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25420 if (cond.Is(al)) { 25421 uint32_t imm6 = imm; 25422 EmitA32(0xf2800510U | 25423 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25424 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25425 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25426 return; 25427 } 25428 } 25429 } 25430 } 25431 } 25432 if (operand.IsRegister()) { 25433 DRegister rn = operand.GetRegister(); 25434 Dt_U_size_3 encoded_dt(dt); 25435 if (IsUsingT32()) { 25436 // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 25437 if (encoded_dt.IsValid()) { 25438 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25439 EmitT32_32(0xef000400U | 25440 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 25441 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 25442 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 25443 AdvanceIT(); 25444 return; 25445 } 25446 } 25447 } else { 25448 // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 25449 if (encoded_dt.IsValid()) { 25450 if (cond.Is(al)) { 25451 EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 25452 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 25453 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 25454 return; 25455 } 25456 } 25457 } 25458 } 25459 Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand); 25460 } 25461 25462 void Assembler::vshl(Condition cond, 25463 DataType dt, 25464 QRegister rd, 25465 QRegister rm, 25466 const QOperand& operand) { 25467 VIXL_ASSERT(AllowAssembler()); 25468 CheckIT(cond); 25469 if (operand.IsImmediate()) { 25470 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25471 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25472 Dt_L_imm6_3 encoded_dt(dt); 25473 if (IsUsingT32()) { 25474 // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1 25475 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25476 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25477 uint32_t imm6 = imm; 25478 EmitT32_32(0xef800550U | 25479 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25480 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25481 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25482 AdvanceIT(); 25483 return; 25484 } 25485 } 25486 } else { 25487 // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1 25488 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25489 if (cond.Is(al)) { 25490 uint32_t imm6 = imm; 25491 EmitA32(0xf2800550U | 25492 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25493 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25494 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25495 return; 25496 } 25497 } 25498 } 25499 } 25500 } 25501 if (operand.IsRegister()) { 25502 QRegister rn = operand.GetRegister(); 25503 Dt_U_size_3 encoded_dt(dt); 25504 if (IsUsingT32()) { 25505 // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 25506 if (encoded_dt.IsValid()) { 25507 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25508 EmitT32_32(0xef000440U | 25509 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 25510 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 25511 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 25512 AdvanceIT(); 25513 return; 25514 } 25515 } 25516 } else { 25517 // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 25518 if (encoded_dt.IsValid()) { 25519 if (cond.Is(al)) { 25520 EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 25521 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 25522 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 25523 return; 25524 } 25525 } 25526 } 25527 } 25528 Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand); 25529 } 25530 25531 void Assembler::vshll(Condition cond, 25532 DataType dt, 25533 QRegister rd, 25534 DRegister rm, 25535 const DOperand& operand) { 25536 VIXL_ASSERT(AllowAssembler()); 25537 CheckIT(cond); 25538 if (operand.IsImmediate()) { 25539 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25540 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25541 Dt_imm6_4 encoded_dt(dt); 25542 Dt_size_17 encoded_dt_2(dt); 25543 if (IsUsingT32()) { 25544 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 25545 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) { 25546 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25547 uint32_t imm6 = dt.GetSize() + imm; 25548 EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) | 25549 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25550 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25551 AdvanceIT(); 25552 return; 25553 } 25554 } 25555 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2 25556 if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) { 25557 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25558 EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) | 25559 rd.Encode(22, 12) | rm.Encode(5, 0)); 25560 AdvanceIT(); 25561 return; 25562 } 25563 } 25564 } else { 25565 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 25566 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) { 25567 if (cond.Is(al)) { 25568 uint32_t imm6 = dt.GetSize() + imm; 25569 EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) | 25570 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25571 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25572 return; 25573 } 25574 } 25575 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2 25576 if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) { 25577 if (cond.Is(al)) { 25578 EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) | 25579 rd.Encode(22, 12) | rm.Encode(5, 0)); 25580 return; 25581 } 25582 } 25583 } 25584 } 25585 } 25586 Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand); 25587 } 25588 25589 void Assembler::vshr(Condition cond, 25590 DataType dt, 25591 DRegister rd, 25592 DRegister rm, 25593 const DOperand& operand) { 25594 VIXL_ASSERT(AllowAssembler()); 25595 CheckIT(cond); 25596 if (operand.IsImmediate()) { 25597 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25598 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25599 Dt_L_imm6_1 encoded_dt(dt); 25600 if (IsUsingT32()) { 25601 // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 25602 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25603 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25604 uint32_t imm6 = dt.GetSize() - imm; 25605 EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) | 25606 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25607 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25608 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25609 AdvanceIT(); 25610 return; 25611 } 25612 } 25613 // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1 25614 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 25615 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25616 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 25617 rm.Encode(5, 0)); 25618 AdvanceIT(); 25619 return; 25620 } 25621 } 25622 } else { 25623 // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 25624 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25625 if (cond.Is(al)) { 25626 uint32_t imm6 = dt.GetSize() - imm; 25627 EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) | 25628 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25629 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25630 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25631 return; 25632 } 25633 } 25634 // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1 25635 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 25636 if (cond.Is(al)) { 25637 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 25638 rm.Encode(5, 0)); 25639 return; 25640 } 25641 } 25642 } 25643 } 25644 } 25645 Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand); 25646 } 25647 25648 void Assembler::vshr(Condition cond, 25649 DataType dt, 25650 QRegister rd, 25651 QRegister rm, 25652 const QOperand& operand) { 25653 VIXL_ASSERT(AllowAssembler()); 25654 CheckIT(cond); 25655 if (operand.IsImmediate()) { 25656 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25657 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25658 Dt_L_imm6_1 encoded_dt(dt); 25659 if (IsUsingT32()) { 25660 // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 25661 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25662 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25663 uint32_t imm6 = dt.GetSize() - imm; 25664 EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) | 25665 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25666 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25667 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25668 AdvanceIT(); 25669 return; 25670 } 25671 } 25672 // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1 25673 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 25674 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25675 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 25676 rm.Encode(5, 0)); 25677 AdvanceIT(); 25678 return; 25679 } 25680 } 25681 } else { 25682 // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 25683 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25684 if (cond.Is(al)) { 25685 uint32_t imm6 = dt.GetSize() - imm; 25686 EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) | 25687 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25688 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25689 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25690 return; 25691 } 25692 } 25693 // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1 25694 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 25695 if (cond.Is(al)) { 25696 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 25697 rm.Encode(5, 0)); 25698 return; 25699 } 25700 } 25701 } 25702 } 25703 } 25704 Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand); 25705 } 25706 25707 void Assembler::vshrn(Condition cond, 25708 DataType dt, 25709 DRegister rd, 25710 QRegister rm, 25711 const QOperand& operand) { 25712 VIXL_ASSERT(AllowAssembler()); 25713 CheckIT(cond); 25714 if (operand.IsImmediate()) { 25715 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25716 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25717 Dt_imm6_3 encoded_dt(dt); 25718 Dt_size_3 encoded_dt_2(dt); 25719 if (IsUsingT32()) { 25720 // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 25721 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 25722 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25723 uint32_t imm6 = dt.GetSize() / 2 - imm; 25724 EmitT32_32(0xef800810U | 25725 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25726 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25727 AdvanceIT(); 25728 return; 25729 } 25730 } 25731 // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 25732 if (encoded_dt_2.IsValid() && (imm == 0)) { 25733 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25734 EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) | 25735 rd.Encode(22, 12) | rm.Encode(5, 0)); 25736 AdvanceIT(); 25737 return; 25738 } 25739 } 25740 } else { 25741 // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 25742 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 25743 if (cond.Is(al)) { 25744 uint32_t imm6 = dt.GetSize() / 2 - imm; 25745 EmitA32(0xf2800810U | 25746 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25747 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25748 return; 25749 } 25750 } 25751 // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 25752 if (encoded_dt_2.IsValid() && (imm == 0)) { 25753 if (cond.Is(al)) { 25754 EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) | 25755 rd.Encode(22, 12) | rm.Encode(5, 0)); 25756 return; 25757 } 25758 } 25759 } 25760 } 25761 } 25762 Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand); 25763 } 25764 25765 void Assembler::vsli(Condition cond, 25766 DataType dt, 25767 DRegister rd, 25768 DRegister rm, 25769 const DOperand& operand) { 25770 VIXL_ASSERT(AllowAssembler()); 25771 CheckIT(cond); 25772 if (operand.IsImmediate()) { 25773 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25774 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25775 Dt_L_imm6_4 encoded_dt(dt); 25776 if (IsUsingT32()) { 25777 // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1 25778 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25779 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25780 uint32_t imm6 = imm; 25781 EmitT32_32(0xff800510U | 25782 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25783 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25784 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25785 AdvanceIT(); 25786 return; 25787 } 25788 } 25789 } else { 25790 // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1 25791 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25792 if (cond.Is(al)) { 25793 uint32_t imm6 = imm; 25794 EmitA32(0xf3800510U | 25795 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25796 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25797 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25798 return; 25799 } 25800 } 25801 } 25802 } 25803 } 25804 Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand); 25805 } 25806 25807 void Assembler::vsli(Condition cond, 25808 DataType dt, 25809 QRegister rd, 25810 QRegister rm, 25811 const QOperand& operand) { 25812 VIXL_ASSERT(AllowAssembler()); 25813 CheckIT(cond); 25814 if (operand.IsImmediate()) { 25815 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25816 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25817 Dt_L_imm6_4 encoded_dt(dt); 25818 if (IsUsingT32()) { 25819 // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1 25820 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25821 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25822 uint32_t imm6 = imm; 25823 EmitT32_32(0xff800550U | 25824 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25825 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25826 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25827 AdvanceIT(); 25828 return; 25829 } 25830 } 25831 } else { 25832 // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1 25833 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25834 if (cond.Is(al)) { 25835 uint32_t imm6 = imm; 25836 EmitA32(0xf3800550U | 25837 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25838 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25839 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25840 return; 25841 } 25842 } 25843 } 25844 } 25845 } 25846 Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand); 25847 } 25848 25849 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) { 25850 VIXL_ASSERT(AllowAssembler()); 25851 CheckIT(cond); 25852 if (IsUsingT32()) { 25853 // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 25854 if (dt.Is(F32)) { 25855 EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 25856 AdvanceIT(); 25857 return; 25858 } 25859 } else { 25860 // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 25861 if (dt.Is(F32) && cond.IsNotNever()) { 25862 EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 25863 rm.Encode(5, 0)); 25864 return; 25865 } 25866 } 25867 Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm); 25868 } 25869 25870 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) { 25871 VIXL_ASSERT(AllowAssembler()); 25872 CheckIT(cond); 25873 if (IsUsingT32()) { 25874 // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 25875 if (dt.Is(F64)) { 25876 EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 25877 AdvanceIT(); 25878 return; 25879 } 25880 } else { 25881 // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 25882 if (dt.Is(F64) && cond.IsNotNever()) { 25883 EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 25884 rm.Encode(5, 0)); 25885 return; 25886 } 25887 } 25888 Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm); 25889 } 25890 25891 void Assembler::vsra(Condition cond, 25892 DataType dt, 25893 DRegister rd, 25894 DRegister rm, 25895 const DOperand& operand) { 25896 VIXL_ASSERT(AllowAssembler()); 25897 CheckIT(cond); 25898 if (operand.IsImmediate()) { 25899 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25900 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25901 Dt_L_imm6_1 encoded_dt(dt); 25902 if (IsUsingT32()) { 25903 // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 25904 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25905 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25906 uint32_t imm6 = dt.GetSize() - imm; 25907 EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) | 25908 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25909 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25910 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25911 AdvanceIT(); 25912 return; 25913 } 25914 } 25915 } else { 25916 // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 25917 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25918 if (cond.Is(al)) { 25919 uint32_t imm6 = dt.GetSize() - imm; 25920 EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) | 25921 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25922 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25923 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25924 return; 25925 } 25926 } 25927 } 25928 } 25929 } 25930 Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand); 25931 } 25932 25933 void Assembler::vsra(Condition cond, 25934 DataType dt, 25935 QRegister rd, 25936 QRegister rm, 25937 const QOperand& operand) { 25938 VIXL_ASSERT(AllowAssembler()); 25939 CheckIT(cond); 25940 if (operand.IsImmediate()) { 25941 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25942 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25943 Dt_L_imm6_1 encoded_dt(dt); 25944 if (IsUsingT32()) { 25945 // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 25946 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25947 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25948 uint32_t imm6 = dt.GetSize() - imm; 25949 EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) | 25950 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25951 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25952 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25953 AdvanceIT(); 25954 return; 25955 } 25956 } 25957 } else { 25958 // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 25959 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25960 if (cond.Is(al)) { 25961 uint32_t imm6 = dt.GetSize() - imm; 25962 EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) | 25963 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25964 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25965 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25966 return; 25967 } 25968 } 25969 } 25970 } 25971 } 25972 Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand); 25973 } 25974 25975 void Assembler::vsri(Condition cond, 25976 DataType dt, 25977 DRegister rd, 25978 DRegister rm, 25979 const DOperand& operand) { 25980 VIXL_ASSERT(AllowAssembler()); 25981 CheckIT(cond); 25982 if (operand.IsImmediate()) { 25983 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25984 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25985 Dt_L_imm6_4 encoded_dt(dt); 25986 if (IsUsingT32()) { 25987 // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1 25988 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25989 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25990 uint32_t imm6 = dt.GetSize() - imm; 25991 EmitT32_32(0xff800410U | 25992 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25993 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25994 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25995 AdvanceIT(); 25996 return; 25997 } 25998 } 25999 } else { 26000 // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1 26001 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 26002 if (cond.Is(al)) { 26003 uint32_t imm6 = dt.GetSize() - imm; 26004 EmitA32(0xf3800410U | 26005 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 26006 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 26007 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 26008 return; 26009 } 26010 } 26011 } 26012 } 26013 } 26014 Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand); 26015 } 26016 26017 void Assembler::vsri(Condition cond, 26018 DataType dt, 26019 QRegister rd, 26020 QRegister rm, 26021 const QOperand& operand) { 26022 VIXL_ASSERT(AllowAssembler()); 26023 CheckIT(cond); 26024 if (operand.IsImmediate()) { 26025 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 26026 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 26027 Dt_L_imm6_4 encoded_dt(dt); 26028 if (IsUsingT32()) { 26029 // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1 26030 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 26031 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26032 uint32_t imm6 = dt.GetSize() - imm; 26033 EmitT32_32(0xff800450U | 26034 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 26035 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 26036 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 26037 AdvanceIT(); 26038 return; 26039 } 26040 } 26041 } else { 26042 // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1 26043 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 26044 if (cond.Is(al)) { 26045 uint32_t imm6 = dt.GetSize() - imm; 26046 EmitA32(0xf3800450U | 26047 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 26048 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 26049 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 26050 return; 26051 } 26052 } 26053 } 26054 } 26055 } 26056 Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand); 26057 } 26058 26059 void Assembler::vst1(Condition cond, 26060 DataType dt, 26061 const NeonRegisterList& nreglist, 26062 const AlignedMemOperand& operand) { 26063 VIXL_ASSERT(AllowAssembler()); 26064 CheckIT(cond); 26065 if (operand.IsImmediateZero()) { 26066 Register rn = operand.GetBaseRegister(); 26067 Alignment align = operand.GetAlignment(); 26068 Dt_size_6 encoded_dt(dt); 26069 Dt_size_7 encoded_dt_2(dt); 26070 Align_align_5 encoded_align_1(align, nreglist); 26071 Align_index_align_1 encoded_align_2(align, nreglist, dt); 26072 if (IsUsingT32()) { 26073 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26074 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26075 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26076 operand.IsOffset() && encoded_align_1.IsValid() && 26077 (!rn.IsPC() || AllowUnpredictable())) { 26078 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26079 const DRegister& first = nreglist.GetFirstDRegister(); 26080 uint32_t len_encoding; 26081 switch (nreglist.GetLength()) { 26082 default: 26083 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26084 case 1: 26085 len_encoding = 0x7; 26086 break; 26087 case 2: 26088 len_encoding = 0xa; 26089 break; 26090 case 3: 26091 len_encoding = 0x6; 26092 break; 26093 case 4: 26094 len_encoding = 0x2; 26095 break; 26096 } 26097 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 26098 (encoded_align_1.GetEncodingValue() << 4) | 26099 first.Encode(22, 12) | (len_encoding << 8) | 26100 (rn.GetCode() << 16)); 26101 AdvanceIT(); 26102 return; 26103 } 26104 } 26105 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26106 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26107 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26108 operand.IsPostIndex() && encoded_align_1.IsValid() && 26109 (!rn.IsPC() || AllowUnpredictable())) { 26110 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26111 const DRegister& first = nreglist.GetFirstDRegister(); 26112 uint32_t len_encoding; 26113 switch (nreglist.GetLength()) { 26114 default: 26115 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26116 case 1: 26117 len_encoding = 0x7; 26118 break; 26119 case 2: 26120 len_encoding = 0xa; 26121 break; 26122 case 3: 26123 len_encoding = 0x6; 26124 break; 26125 case 4: 26126 len_encoding = 0x2; 26127 break; 26128 } 26129 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 26130 (encoded_align_1.GetEncodingValue() << 4) | 26131 first.Encode(22, 12) | (len_encoding << 8) | 26132 (rn.GetCode() << 16)); 26133 AdvanceIT(); 26134 return; 26135 } 26136 } 26137 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26138 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26139 (nreglist.GetLength() == 1) && operand.IsOffset() && 26140 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 26141 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26142 const DRegister& first = nreglist.GetFirstDRegister(); 26143 EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) | 26144 (encoded_align_2.GetEncodingValue() << 4) | 26145 first.Encode(22, 12) | (rn.GetCode() << 16)); 26146 AdvanceIT(); 26147 return; 26148 } 26149 } 26150 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26151 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26152 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 26153 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 26154 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26155 const DRegister& first = nreglist.GetFirstDRegister(); 26156 EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) | 26157 (encoded_align_2.GetEncodingValue() << 4) | 26158 first.Encode(22, 12) | (rn.GetCode() << 16)); 26159 AdvanceIT(); 26160 return; 26161 } 26162 } 26163 } else { 26164 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26165 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26166 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26167 operand.IsOffset() && encoded_align_1.IsValid() && 26168 (!rn.IsPC() || AllowUnpredictable())) { 26169 if (cond.Is(al)) { 26170 const DRegister& first = nreglist.GetFirstDRegister(); 26171 uint32_t len_encoding; 26172 switch (nreglist.GetLength()) { 26173 default: 26174 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26175 case 1: 26176 len_encoding = 0x7; 26177 break; 26178 case 2: 26179 len_encoding = 0xa; 26180 break; 26181 case 3: 26182 len_encoding = 0x6; 26183 break; 26184 case 4: 26185 len_encoding = 0x2; 26186 break; 26187 } 26188 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 26189 (encoded_align_1.GetEncodingValue() << 4) | 26190 first.Encode(22, 12) | (len_encoding << 8) | 26191 (rn.GetCode() << 16)); 26192 return; 26193 } 26194 } 26195 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26196 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26197 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26198 operand.IsPostIndex() && encoded_align_1.IsValid() && 26199 (!rn.IsPC() || AllowUnpredictable())) { 26200 if (cond.Is(al)) { 26201 const DRegister& first = nreglist.GetFirstDRegister(); 26202 uint32_t len_encoding; 26203 switch (nreglist.GetLength()) { 26204 default: 26205 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26206 case 1: 26207 len_encoding = 0x7; 26208 break; 26209 case 2: 26210 len_encoding = 0xa; 26211 break; 26212 case 3: 26213 len_encoding = 0x6; 26214 break; 26215 case 4: 26216 len_encoding = 0x2; 26217 break; 26218 } 26219 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 26220 (encoded_align_1.GetEncodingValue() << 4) | 26221 first.Encode(22, 12) | (len_encoding << 8) | 26222 (rn.GetCode() << 16)); 26223 return; 26224 } 26225 } 26226 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26227 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26228 (nreglist.GetLength() == 1) && operand.IsOffset() && 26229 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 26230 if (cond.Is(al)) { 26231 const DRegister& first = nreglist.GetFirstDRegister(); 26232 EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) | 26233 (encoded_align_2.GetEncodingValue() << 4) | 26234 first.Encode(22, 12) | (rn.GetCode() << 16)); 26235 return; 26236 } 26237 } 26238 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26239 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26240 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 26241 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 26242 if (cond.Is(al)) { 26243 const DRegister& first = nreglist.GetFirstDRegister(); 26244 EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) | 26245 (encoded_align_2.GetEncodingValue() << 4) | 26246 first.Encode(22, 12) | (rn.GetCode() << 16)); 26247 return; 26248 } 26249 } 26250 } 26251 } 26252 if (operand.IsPlainRegister()) { 26253 Register rn = operand.GetBaseRegister(); 26254 Alignment align = operand.GetAlignment(); 26255 Register rm = operand.GetOffsetRegister(); 26256 Dt_size_6 encoded_dt(dt); 26257 Dt_size_7 encoded_dt_2(dt); 26258 Align_align_5 encoded_align_1(align, nreglist); 26259 Align_index_align_1 encoded_align_2(align, nreglist, dt); 26260 if (IsUsingT32()) { 26261 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26262 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26263 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26264 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26265 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26266 const DRegister& first = nreglist.GetFirstDRegister(); 26267 uint32_t len_encoding; 26268 switch (nreglist.GetLength()) { 26269 default: 26270 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26271 case 1: 26272 len_encoding = 0x7; 26273 break; 26274 case 2: 26275 len_encoding = 0xa; 26276 break; 26277 case 3: 26278 len_encoding = 0x6; 26279 break; 26280 case 4: 26281 len_encoding = 0x2; 26282 break; 26283 } 26284 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 26285 (encoded_align_1.GetEncodingValue() << 4) | 26286 first.Encode(22, 12) | (len_encoding << 8) | 26287 (rn.GetCode() << 16) | rm.GetCode()); 26288 AdvanceIT(); 26289 return; 26290 } 26291 } 26292 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26293 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26294 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() && 26295 (!rn.IsPC() || AllowUnpredictable())) { 26296 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26297 const DRegister& first = nreglist.GetFirstDRegister(); 26298 EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) | 26299 (encoded_align_2.GetEncodingValue() << 4) | 26300 first.Encode(22, 12) | (rn.GetCode() << 16) | 26301 rm.GetCode()); 26302 AdvanceIT(); 26303 return; 26304 } 26305 } 26306 } else { 26307 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26308 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26309 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26310 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26311 if (cond.Is(al)) { 26312 const DRegister& first = nreglist.GetFirstDRegister(); 26313 uint32_t len_encoding; 26314 switch (nreglist.GetLength()) { 26315 default: 26316 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26317 case 1: 26318 len_encoding = 0x7; 26319 break; 26320 case 2: 26321 len_encoding = 0xa; 26322 break; 26323 case 3: 26324 len_encoding = 0x6; 26325 break; 26326 case 4: 26327 len_encoding = 0x2; 26328 break; 26329 } 26330 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 26331 (encoded_align_1.GetEncodingValue() << 4) | 26332 first.Encode(22, 12) | (len_encoding << 8) | 26333 (rn.GetCode() << 16) | rm.GetCode()); 26334 return; 26335 } 26336 } 26337 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26338 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26339 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() && 26340 (!rn.IsPC() || AllowUnpredictable())) { 26341 if (cond.Is(al)) { 26342 const DRegister& first = nreglist.GetFirstDRegister(); 26343 EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) | 26344 (encoded_align_2.GetEncodingValue() << 4) | 26345 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 26346 return; 26347 } 26348 } 26349 } 26350 } 26351 Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand); 26352 } 26353 26354 void Assembler::vst2(Condition cond, 26355 DataType dt, 26356 const NeonRegisterList& nreglist, 26357 const AlignedMemOperand& operand) { 26358 VIXL_ASSERT(AllowAssembler()); 26359 CheckIT(cond); 26360 if (operand.IsImmediateZero()) { 26361 Register rn = operand.GetBaseRegister(); 26362 Alignment align = operand.GetAlignment(); 26363 Dt_size_7 encoded_dt(dt); 26364 Align_align_2 encoded_align_1(align, nreglist); 26365 Align_index_align_2 encoded_align_2(align, nreglist, dt); 26366 if (IsUsingT32()) { 26367 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26368 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26369 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26370 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26371 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26372 operand.IsOffset() && encoded_align_1.IsValid() && 26373 (!rn.IsPC() || AllowUnpredictable())) { 26374 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26375 const DRegister& first = nreglist.GetFirstDRegister(); 26376 uint32_t len_encoding; 26377 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26378 len_encoding = 0x8; 26379 } 26380 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26381 len_encoding = 0x9; 26382 } 26383 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26384 len_encoding = 0x3; 26385 } 26386 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 26387 (encoded_align_1.GetEncodingValue() << 4) | 26388 first.Encode(22, 12) | (len_encoding << 8) | 26389 (rn.GetCode() << 16)); 26390 AdvanceIT(); 26391 return; 26392 } 26393 } 26394 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26395 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26396 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26397 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26398 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26399 operand.IsPostIndex() && encoded_align_1.IsValid() && 26400 (!rn.IsPC() || AllowUnpredictable())) { 26401 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26402 const DRegister& first = nreglist.GetFirstDRegister(); 26403 uint32_t len_encoding; 26404 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26405 len_encoding = 0x8; 26406 } 26407 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26408 len_encoding = 0x9; 26409 } 26410 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26411 len_encoding = 0x3; 26412 } 26413 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 26414 (encoded_align_1.GetEncodingValue() << 4) | 26415 first.Encode(22, 12) | (len_encoding << 8) | 26416 (rn.GetCode() << 16)); 26417 AdvanceIT(); 26418 return; 26419 } 26420 } 26421 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26422 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26423 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26424 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26425 operand.IsOffset() && encoded_align_2.IsValid() && 26426 (!rn.IsPC() || AllowUnpredictable())) { 26427 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26428 const DRegister& first = nreglist.GetFirstDRegister(); 26429 EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) | 26430 (encoded_align_2.GetEncodingValue() << 4) | 26431 first.Encode(22, 12) | (rn.GetCode() << 16)); 26432 AdvanceIT(); 26433 return; 26434 } 26435 } 26436 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26437 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26438 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26439 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26440 operand.IsPostIndex() && encoded_align_2.IsValid() && 26441 (!rn.IsPC() || AllowUnpredictable())) { 26442 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26443 const DRegister& first = nreglist.GetFirstDRegister(); 26444 EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) | 26445 (encoded_align_2.GetEncodingValue() << 4) | 26446 first.Encode(22, 12) | (rn.GetCode() << 16)); 26447 AdvanceIT(); 26448 return; 26449 } 26450 } 26451 } else { 26452 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26453 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26454 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26455 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26456 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26457 operand.IsOffset() && encoded_align_1.IsValid() && 26458 (!rn.IsPC() || AllowUnpredictable())) { 26459 if (cond.Is(al)) { 26460 const DRegister& first = nreglist.GetFirstDRegister(); 26461 uint32_t len_encoding; 26462 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26463 len_encoding = 0x8; 26464 } 26465 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26466 len_encoding = 0x9; 26467 } 26468 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26469 len_encoding = 0x3; 26470 } 26471 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 26472 (encoded_align_1.GetEncodingValue() << 4) | 26473 first.Encode(22, 12) | (len_encoding << 8) | 26474 (rn.GetCode() << 16)); 26475 return; 26476 } 26477 } 26478 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26479 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26480 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26481 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26482 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26483 operand.IsPostIndex() && encoded_align_1.IsValid() && 26484 (!rn.IsPC() || AllowUnpredictable())) { 26485 if (cond.Is(al)) { 26486 const DRegister& first = nreglist.GetFirstDRegister(); 26487 uint32_t len_encoding; 26488 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26489 len_encoding = 0x8; 26490 } 26491 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26492 len_encoding = 0x9; 26493 } 26494 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26495 len_encoding = 0x3; 26496 } 26497 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 26498 (encoded_align_1.GetEncodingValue() << 4) | 26499 first.Encode(22, 12) | (len_encoding << 8) | 26500 (rn.GetCode() << 16)); 26501 return; 26502 } 26503 } 26504 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26505 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26506 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26507 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26508 operand.IsOffset() && encoded_align_2.IsValid() && 26509 (!rn.IsPC() || AllowUnpredictable())) { 26510 if (cond.Is(al)) { 26511 const DRegister& first = nreglist.GetFirstDRegister(); 26512 EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) | 26513 (encoded_align_2.GetEncodingValue() << 4) | 26514 first.Encode(22, 12) | (rn.GetCode() << 16)); 26515 return; 26516 } 26517 } 26518 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26519 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26520 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26521 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26522 operand.IsPostIndex() && encoded_align_2.IsValid() && 26523 (!rn.IsPC() || AllowUnpredictable())) { 26524 if (cond.Is(al)) { 26525 const DRegister& first = nreglist.GetFirstDRegister(); 26526 EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) | 26527 (encoded_align_2.GetEncodingValue() << 4) | 26528 first.Encode(22, 12) | (rn.GetCode() << 16)); 26529 return; 26530 } 26531 } 26532 } 26533 } 26534 if (operand.IsPlainRegister()) { 26535 Register rn = operand.GetBaseRegister(); 26536 Alignment align = operand.GetAlignment(); 26537 Register rm = operand.GetOffsetRegister(); 26538 Dt_size_7 encoded_dt(dt); 26539 Align_align_2 encoded_align_1(align, nreglist); 26540 Align_index_align_2 encoded_align_2(align, nreglist, dt); 26541 if (IsUsingT32()) { 26542 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26543 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26544 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26545 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26546 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26547 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26548 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26549 const DRegister& first = nreglist.GetFirstDRegister(); 26550 uint32_t len_encoding; 26551 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26552 len_encoding = 0x8; 26553 } 26554 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26555 len_encoding = 0x9; 26556 } 26557 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26558 len_encoding = 0x3; 26559 } 26560 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 26561 (encoded_align_1.GetEncodingValue() << 4) | 26562 first.Encode(22, 12) | (len_encoding << 8) | 26563 (rn.GetCode() << 16) | rm.GetCode()); 26564 AdvanceIT(); 26565 return; 26566 } 26567 } 26568 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26569 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26570 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26571 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26572 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26573 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26574 const DRegister& first = nreglist.GetFirstDRegister(); 26575 EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) | 26576 (encoded_align_2.GetEncodingValue() << 4) | 26577 first.Encode(22, 12) | (rn.GetCode() << 16) | 26578 rm.GetCode()); 26579 AdvanceIT(); 26580 return; 26581 } 26582 } 26583 } else { 26584 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26585 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26586 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26587 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26588 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26589 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26590 if (cond.Is(al)) { 26591 const DRegister& first = nreglist.GetFirstDRegister(); 26592 uint32_t len_encoding; 26593 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26594 len_encoding = 0x8; 26595 } 26596 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26597 len_encoding = 0x9; 26598 } 26599 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26600 len_encoding = 0x3; 26601 } 26602 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 26603 (encoded_align_1.GetEncodingValue() << 4) | 26604 first.Encode(22, 12) | (len_encoding << 8) | 26605 (rn.GetCode() << 16) | rm.GetCode()); 26606 return; 26607 } 26608 } 26609 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26610 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26611 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26612 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26613 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26614 if (cond.Is(al)) { 26615 const DRegister& first = nreglist.GetFirstDRegister(); 26616 EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) | 26617 (encoded_align_2.GetEncodingValue() << 4) | 26618 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 26619 return; 26620 } 26621 } 26622 } 26623 } 26624 Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand); 26625 } 26626 26627 void Assembler::vst3(Condition cond, 26628 DataType dt, 26629 const NeonRegisterList& nreglist, 26630 const AlignedMemOperand& operand) { 26631 VIXL_ASSERT(AllowAssembler()); 26632 CheckIT(cond); 26633 if (operand.IsImmediateZero()) { 26634 Register rn = operand.GetBaseRegister(); 26635 Alignment align = operand.GetAlignment(); 26636 Dt_size_7 encoded_dt(dt); 26637 Align_align_3 encoded_align_1(align); 26638 if (IsUsingT32()) { 26639 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26640 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26641 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26642 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26643 operand.IsOffset() && encoded_align_1.IsValid() && 26644 (!rn.IsPC() || AllowUnpredictable())) { 26645 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26646 const DRegister& first = nreglist.GetFirstDRegister(); 26647 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26648 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 26649 (encoded_align_1.GetEncodingValue() << 4) | 26650 first.Encode(22, 12) | (len_encoding << 8) | 26651 (rn.GetCode() << 16)); 26652 AdvanceIT(); 26653 return; 26654 } 26655 } 26656 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26657 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26658 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26659 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26660 operand.IsPostIndex() && encoded_align_1.IsValid() && 26661 (!rn.IsPC() || AllowUnpredictable())) { 26662 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26663 const DRegister& first = nreglist.GetFirstDRegister(); 26664 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26665 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 26666 (encoded_align_1.GetEncodingValue() << 4) | 26667 first.Encode(22, 12) | (len_encoding << 8) | 26668 (rn.GetCode() << 16)); 26669 AdvanceIT(); 26670 return; 26671 } 26672 } 26673 } else { 26674 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26675 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26676 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26677 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26678 operand.IsOffset() && encoded_align_1.IsValid() && 26679 (!rn.IsPC() || AllowUnpredictable())) { 26680 if (cond.Is(al)) { 26681 const DRegister& first = nreglist.GetFirstDRegister(); 26682 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26683 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 26684 (encoded_align_1.GetEncodingValue() << 4) | 26685 first.Encode(22, 12) | (len_encoding << 8) | 26686 (rn.GetCode() << 16)); 26687 return; 26688 } 26689 } 26690 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26691 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26692 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26693 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26694 operand.IsPostIndex() && encoded_align_1.IsValid() && 26695 (!rn.IsPC() || AllowUnpredictable())) { 26696 if (cond.Is(al)) { 26697 const DRegister& first = nreglist.GetFirstDRegister(); 26698 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26699 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 26700 (encoded_align_1.GetEncodingValue() << 4) | 26701 first.Encode(22, 12) | (len_encoding << 8) | 26702 (rn.GetCode() << 16)); 26703 return; 26704 } 26705 } 26706 } 26707 } 26708 if (operand.IsPlainRegister()) { 26709 Register rn = operand.GetBaseRegister(); 26710 Alignment align = operand.GetAlignment(); 26711 Register rm = operand.GetOffsetRegister(); 26712 Dt_size_7 encoded_dt(dt); 26713 Align_align_3 encoded_align_1(align); 26714 if (IsUsingT32()) { 26715 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26716 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26717 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26718 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26719 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26720 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26721 const DRegister& first = nreglist.GetFirstDRegister(); 26722 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26723 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 26724 (encoded_align_1.GetEncodingValue() << 4) | 26725 first.Encode(22, 12) | (len_encoding << 8) | 26726 (rn.GetCode() << 16) | rm.GetCode()); 26727 AdvanceIT(); 26728 return; 26729 } 26730 } 26731 } else { 26732 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26733 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26734 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26735 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26736 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26737 if (cond.Is(al)) { 26738 const DRegister& first = nreglist.GetFirstDRegister(); 26739 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26740 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 26741 (encoded_align_1.GetEncodingValue() << 4) | 26742 first.Encode(22, 12) | (len_encoding << 8) | 26743 (rn.GetCode() << 16) | rm.GetCode()); 26744 return; 26745 } 26746 } 26747 } 26748 } 26749 Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand); 26750 } 26751 26752 void Assembler::vst3(Condition cond, 26753 DataType dt, 26754 const NeonRegisterList& nreglist, 26755 const MemOperand& operand) { 26756 VIXL_ASSERT(AllowAssembler()); 26757 CheckIT(cond); 26758 if (operand.IsImmediateZero()) { 26759 Register rn = operand.GetBaseRegister(); 26760 Dt_size_7 encoded_dt(dt); 26761 Index_1 encoded_align_1(nreglist, dt); 26762 if (IsUsingT32()) { 26763 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 26764 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26765 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26766 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26767 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 26768 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26769 const DRegister& first = nreglist.GetFirstDRegister(); 26770 EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) | 26771 (encoded_align_1.GetEncodingValue() << 4) | 26772 first.Encode(22, 12) | (rn.GetCode() << 16)); 26773 AdvanceIT(); 26774 return; 26775 } 26776 } 26777 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 26778 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26779 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26780 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26781 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 26782 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26783 const DRegister& first = nreglist.GetFirstDRegister(); 26784 EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) | 26785 (encoded_align_1.GetEncodingValue() << 4) | 26786 first.Encode(22, 12) | (rn.GetCode() << 16)); 26787 AdvanceIT(); 26788 return; 26789 } 26790 } 26791 } else { 26792 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 26793 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26794 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26795 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26796 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 26797 if (cond.Is(al)) { 26798 const DRegister& first = nreglist.GetFirstDRegister(); 26799 EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) | 26800 (encoded_align_1.GetEncodingValue() << 4) | 26801 first.Encode(22, 12) | (rn.GetCode() << 16)); 26802 return; 26803 } 26804 } 26805 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 26806 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26807 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26808 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26809 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 26810 if (cond.Is(al)) { 26811 const DRegister& first = nreglist.GetFirstDRegister(); 26812 EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) | 26813 (encoded_align_1.GetEncodingValue() << 4) | 26814 first.Encode(22, 12) | (rn.GetCode() << 16)); 26815 return; 26816 } 26817 } 26818 } 26819 } 26820 if (operand.IsPlainRegister()) { 26821 Register rn = operand.GetBaseRegister(); 26822 Sign sign = operand.GetSign(); 26823 Register rm = operand.GetOffsetRegister(); 26824 Dt_size_7 encoded_dt(dt); 26825 Index_1 encoded_align_1(nreglist, dt); 26826 if (IsUsingT32()) { 26827 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 26828 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26829 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26830 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26831 sign.IsPlus() && operand.IsPostIndex() && 26832 (!rn.IsPC() || AllowUnpredictable())) { 26833 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26834 const DRegister& first = nreglist.GetFirstDRegister(); 26835 EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) | 26836 (encoded_align_1.GetEncodingValue() << 4) | 26837 first.Encode(22, 12) | (rn.GetCode() << 16) | 26838 rm.GetCode()); 26839 AdvanceIT(); 26840 return; 26841 } 26842 } 26843 } else { 26844 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 26845 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26846 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26847 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26848 sign.IsPlus() && operand.IsPostIndex() && 26849 (!rn.IsPC() || AllowUnpredictable())) { 26850 if (cond.Is(al)) { 26851 const DRegister& first = nreglist.GetFirstDRegister(); 26852 EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) | 26853 (encoded_align_1.GetEncodingValue() << 4) | 26854 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 26855 return; 26856 } 26857 } 26858 } 26859 } 26860 Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand); 26861 } 26862 26863 void Assembler::vst4(Condition cond, 26864 DataType dt, 26865 const NeonRegisterList& nreglist, 26866 const AlignedMemOperand& operand) { 26867 VIXL_ASSERT(AllowAssembler()); 26868 CheckIT(cond); 26869 if (operand.IsImmediateZero()) { 26870 Register rn = operand.GetBaseRegister(); 26871 Alignment align = operand.GetAlignment(); 26872 Dt_size_7 encoded_dt(dt); 26873 Align_align_4 encoded_align_1(align); 26874 Align_index_align_3 encoded_align_2(align, nreglist, dt); 26875 if (IsUsingT32()) { 26876 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26877 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26878 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26879 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26880 operand.IsOffset() && encoded_align_1.IsValid() && 26881 (!rn.IsPC() || AllowUnpredictable())) { 26882 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26883 const DRegister& first = nreglist.GetFirstDRegister(); 26884 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26885 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 26886 (encoded_align_1.GetEncodingValue() << 4) | 26887 first.Encode(22, 12) | (len_encoding << 8) | 26888 (rn.GetCode() << 16)); 26889 AdvanceIT(); 26890 return; 26891 } 26892 } 26893 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26894 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26895 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26896 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26897 operand.IsPostIndex() && encoded_align_1.IsValid() && 26898 (!rn.IsPC() || AllowUnpredictable())) { 26899 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26900 const DRegister& first = nreglist.GetFirstDRegister(); 26901 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26902 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 26903 (encoded_align_1.GetEncodingValue() << 4) | 26904 first.Encode(22, 12) | (len_encoding << 8) | 26905 (rn.GetCode() << 16)); 26906 AdvanceIT(); 26907 return; 26908 } 26909 } 26910 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26911 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26912 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26913 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26914 operand.IsOffset() && encoded_align_2.IsValid() && 26915 (!rn.IsPC() || AllowUnpredictable())) { 26916 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26917 const DRegister& first = nreglist.GetFirstDRegister(); 26918 EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) | 26919 (encoded_align_2.GetEncodingValue() << 4) | 26920 first.Encode(22, 12) | (rn.GetCode() << 16)); 26921 AdvanceIT(); 26922 return; 26923 } 26924 } 26925 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26926 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26927 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26928 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26929 operand.IsPostIndex() && encoded_align_2.IsValid() && 26930 (!rn.IsPC() || AllowUnpredictable())) { 26931 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26932 const DRegister& first = nreglist.GetFirstDRegister(); 26933 EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) | 26934 (encoded_align_2.GetEncodingValue() << 4) | 26935 first.Encode(22, 12) | (rn.GetCode() << 16)); 26936 AdvanceIT(); 26937 return; 26938 } 26939 } 26940 } else { 26941 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26942 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26943 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26944 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26945 operand.IsOffset() && encoded_align_1.IsValid() && 26946 (!rn.IsPC() || AllowUnpredictable())) { 26947 if (cond.Is(al)) { 26948 const DRegister& first = nreglist.GetFirstDRegister(); 26949 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26950 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 26951 (encoded_align_1.GetEncodingValue() << 4) | 26952 first.Encode(22, 12) | (len_encoding << 8) | 26953 (rn.GetCode() << 16)); 26954 return; 26955 } 26956 } 26957 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26958 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26959 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26960 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26961 operand.IsPostIndex() && encoded_align_1.IsValid() && 26962 (!rn.IsPC() || AllowUnpredictable())) { 26963 if (cond.Is(al)) { 26964 const DRegister& first = nreglist.GetFirstDRegister(); 26965 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26966 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 26967 (encoded_align_1.GetEncodingValue() << 4) | 26968 first.Encode(22, 12) | (len_encoding << 8) | 26969 (rn.GetCode() << 16)); 26970 return; 26971 } 26972 } 26973 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26974 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26975 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26976 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26977 operand.IsOffset() && encoded_align_2.IsValid() && 26978 (!rn.IsPC() || AllowUnpredictable())) { 26979 if (cond.Is(al)) { 26980 const DRegister& first = nreglist.GetFirstDRegister(); 26981 EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) | 26982 (encoded_align_2.GetEncodingValue() << 4) | 26983 first.Encode(22, 12) | (rn.GetCode() << 16)); 26984 return; 26985 } 26986 } 26987 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26988 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26989 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26990 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26991 operand.IsPostIndex() && encoded_align_2.IsValid() && 26992 (!rn.IsPC() || AllowUnpredictable())) { 26993 if (cond.Is(al)) { 26994 const DRegister& first = nreglist.GetFirstDRegister(); 26995 EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) | 26996 (encoded_align_2.GetEncodingValue() << 4) | 26997 first.Encode(22, 12) | (rn.GetCode() << 16)); 26998 return; 26999 } 27000 } 27001 } 27002 } 27003 if (operand.IsPlainRegister()) { 27004 Register rn = operand.GetBaseRegister(); 27005 Alignment align = operand.GetAlignment(); 27006 Register rm = operand.GetOffsetRegister(); 27007 Dt_size_7 encoded_dt(dt); 27008 Align_align_4 encoded_align_1(align); 27009 Align_index_align_3 encoded_align_2(align, nreglist, dt); 27010 if (IsUsingT32()) { 27011 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 27012 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 27013 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 27014 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 27015 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 27016 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27017 const DRegister& first = nreglist.GetFirstDRegister(); 27018 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 27019 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 27020 (encoded_align_1.GetEncodingValue() << 4) | 27021 first.Encode(22, 12) | (len_encoding << 8) | 27022 (rn.GetCode() << 16) | rm.GetCode()); 27023 AdvanceIT(); 27024 return; 27025 } 27026 } 27027 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 27028 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 27029 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 27030 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 27031 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 27032 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27033 const DRegister& first = nreglist.GetFirstDRegister(); 27034 EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) | 27035 (encoded_align_2.GetEncodingValue() << 4) | 27036 first.Encode(22, 12) | (rn.GetCode() << 16) | 27037 rm.GetCode()); 27038 AdvanceIT(); 27039 return; 27040 } 27041 } 27042 } else { 27043 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 27044 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 27045 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 27046 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 27047 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 27048 if (cond.Is(al)) { 27049 const DRegister& first = nreglist.GetFirstDRegister(); 27050 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 27051 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 27052 (encoded_align_1.GetEncodingValue() << 4) | 27053 first.Encode(22, 12) | (len_encoding << 8) | 27054 (rn.GetCode() << 16) | rm.GetCode()); 27055 return; 27056 } 27057 } 27058 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 27059 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 27060 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 27061 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 27062 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 27063 if (cond.Is(al)) { 27064 const DRegister& first = nreglist.GetFirstDRegister(); 27065 EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) | 27066 (encoded_align_2.GetEncodingValue() << 4) | 27067 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 27068 return; 27069 } 27070 } 27071 } 27072 } 27073 Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand); 27074 } 27075 27076 void Assembler::vstm(Condition cond, 27077 DataType dt, 27078 Register rn, 27079 WriteBack write_back, 27080 DRegisterList dreglist) { 27081 VIXL_ASSERT(AllowAssembler()); 27082 CheckIT(cond); 27083 USE(dt); 27084 if (IsUsingT32()) { 27085 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 27086 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) || 27087 AllowUnpredictable())) { 27088 const DRegister& dreg = dreglist.GetFirstDRegister(); 27089 unsigned len = dreglist.GetLength() * 2; 27090 EmitT32_32(0xec800b00U | (rn.GetCode() << 16) | 27091 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 27092 (len & 0xff)); 27093 AdvanceIT(); 27094 return; 27095 } 27096 } else { 27097 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 27098 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 27099 (!rn.IsPC() || !write_back.DoesWriteBack())) || 27100 AllowUnpredictable())) { 27101 const DRegister& dreg = dreglist.GetFirstDRegister(); 27102 unsigned len = dreglist.GetLength() * 2; 27103 EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27104 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 27105 (len & 0xff)); 27106 return; 27107 } 27108 } 27109 Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist); 27110 } 27111 27112 void Assembler::vstm(Condition cond, 27113 DataType dt, 27114 Register rn, 27115 WriteBack write_back, 27116 SRegisterList sreglist) { 27117 VIXL_ASSERT(AllowAssembler()); 27118 CheckIT(cond); 27119 USE(dt); 27120 if (IsUsingT32()) { 27121 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 27122 if ((!rn.IsPC() || AllowUnpredictable())) { 27123 const SRegister& sreg = sreglist.GetFirstSRegister(); 27124 unsigned len = sreglist.GetLength(); 27125 EmitT32_32(0xec800a00U | (rn.GetCode() << 16) | 27126 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 27127 (len & 0xff)); 27128 AdvanceIT(); 27129 return; 27130 } 27131 } else { 27132 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 27133 if (cond.IsNotNever() && 27134 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) { 27135 const SRegister& sreg = sreglist.GetFirstSRegister(); 27136 unsigned len = sreglist.GetLength(); 27137 EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27138 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 27139 (len & 0xff)); 27140 return; 27141 } 27142 } 27143 Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist); 27144 } 27145 27146 void Assembler::vstmdb(Condition cond, 27147 DataType dt, 27148 Register rn, 27149 WriteBack write_back, 27150 DRegisterList dreglist) { 27151 VIXL_ASSERT(AllowAssembler()); 27152 CheckIT(cond); 27153 USE(dt); 27154 if (IsUsingT32()) { 27155 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1 27156 if (write_back.DoesWriteBack() && 27157 (((dreglist.GetLength() <= 16) && !rn.IsPC()) || 27158 AllowUnpredictable())) { 27159 const DRegister& dreg = dreglist.GetFirstDRegister(); 27160 unsigned len = dreglist.GetLength() * 2; 27161 EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 27162 (len & 0xff)); 27163 AdvanceIT(); 27164 return; 27165 } 27166 } else { 27167 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1 27168 if (write_back.DoesWriteBack() && cond.IsNotNever() && 27169 (((dreglist.GetLength() <= 16) && !rn.IsPC()) || 27170 AllowUnpredictable())) { 27171 const DRegister& dreg = dreglist.GetFirstDRegister(); 27172 unsigned len = dreglist.GetLength() * 2; 27173 EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27174 dreg.Encode(22, 12) | (len & 0xff)); 27175 return; 27176 } 27177 } 27178 Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist); 27179 } 27180 27181 void Assembler::vstmdb(Condition cond, 27182 DataType dt, 27183 Register rn, 27184 WriteBack write_back, 27185 SRegisterList sreglist) { 27186 VIXL_ASSERT(AllowAssembler()); 27187 CheckIT(cond); 27188 USE(dt); 27189 if (IsUsingT32()) { 27190 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2 27191 if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) { 27192 const SRegister& sreg = sreglist.GetFirstSRegister(); 27193 unsigned len = sreglist.GetLength(); 27194 EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) | 27195 (len & 0xff)); 27196 AdvanceIT(); 27197 return; 27198 } 27199 } else { 27200 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2 27201 if (write_back.DoesWriteBack() && cond.IsNotNever() && 27202 (!rn.IsPC() || AllowUnpredictable())) { 27203 const SRegister& sreg = sreglist.GetFirstSRegister(); 27204 unsigned len = sreglist.GetLength(); 27205 EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27206 sreg.Encode(22, 12) | (len & 0xff)); 27207 return; 27208 } 27209 } 27210 Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist); 27211 } 27212 27213 void Assembler::vstmia(Condition cond, 27214 DataType dt, 27215 Register rn, 27216 WriteBack write_back, 27217 DRegisterList dreglist) { 27218 VIXL_ASSERT(AllowAssembler()); 27219 CheckIT(cond); 27220 USE(dt); 27221 if (IsUsingT32()) { 27222 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 27223 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) || 27224 AllowUnpredictable())) { 27225 const DRegister& dreg = dreglist.GetFirstDRegister(); 27226 unsigned len = dreglist.GetLength() * 2; 27227 EmitT32_32(0xec800b00U | (rn.GetCode() << 16) | 27228 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 27229 (len & 0xff)); 27230 AdvanceIT(); 27231 return; 27232 } 27233 } else { 27234 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 27235 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 27236 (!rn.IsPC() || !write_back.DoesWriteBack())) || 27237 AllowUnpredictable())) { 27238 const DRegister& dreg = dreglist.GetFirstDRegister(); 27239 unsigned len = dreglist.GetLength() * 2; 27240 EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27241 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 27242 (len & 0xff)); 27243 return; 27244 } 27245 } 27246 Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist); 27247 } 27248 27249 void Assembler::vstmia(Condition cond, 27250 DataType dt, 27251 Register rn, 27252 WriteBack write_back, 27253 SRegisterList sreglist) { 27254 VIXL_ASSERT(AllowAssembler()); 27255 CheckIT(cond); 27256 USE(dt); 27257 if (IsUsingT32()) { 27258 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 27259 if ((!rn.IsPC() || AllowUnpredictable())) { 27260 const SRegister& sreg = sreglist.GetFirstSRegister(); 27261 unsigned len = sreglist.GetLength(); 27262 EmitT32_32(0xec800a00U | (rn.GetCode() << 16) | 27263 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 27264 (len & 0xff)); 27265 AdvanceIT(); 27266 return; 27267 } 27268 } else { 27269 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 27270 if (cond.IsNotNever() && 27271 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) { 27272 const SRegister& sreg = sreglist.GetFirstSRegister(); 27273 unsigned len = sreglist.GetLength(); 27274 EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27275 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 27276 (len & 0xff)); 27277 return; 27278 } 27279 } 27280 Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist); 27281 } 27282 27283 void Assembler::vstr(Condition cond, 27284 DataType dt, 27285 DRegister rd, 27286 const MemOperand& operand) { 27287 VIXL_ASSERT(AllowAssembler()); 27288 CheckIT(cond); 27289 if (operand.IsImmediate()) { 27290 Register rn = operand.GetBaseRegister(); 27291 int32_t offset = operand.GetOffsetImmediate(); 27292 if (IsUsingT32()) { 27293 // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1 27294 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 27295 ((offset % 4) == 0) && operand.IsOffset() && 27296 (!rn.IsPC() || AllowUnpredictable())) { 27297 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 27298 uint32_t offset_ = abs(offset) >> 2; 27299 EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 27300 offset_ | (sign << 23)); 27301 AdvanceIT(); 27302 return; 27303 } 27304 } else { 27305 // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1 27306 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 27307 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) { 27308 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 27309 uint32_t offset_ = abs(offset) >> 2; 27310 EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 27311 (rn.GetCode() << 16) | offset_ | (sign << 23)); 27312 return; 27313 } 27314 } 27315 } 27316 Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand); 27317 } 27318 27319 void Assembler::vstr(Condition cond, 27320 DataType dt, 27321 SRegister rd, 27322 const MemOperand& operand) { 27323 VIXL_ASSERT(AllowAssembler()); 27324 CheckIT(cond); 27325 if (operand.IsImmediate()) { 27326 Register rn = operand.GetBaseRegister(); 27327 int32_t offset = operand.GetOffsetImmediate(); 27328 if (IsUsingT32()) { 27329 // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2 27330 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 27331 ((offset % 4) == 0) && operand.IsOffset() && 27332 (!rn.IsPC() || AllowUnpredictable())) { 27333 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 27334 uint32_t offset_ = abs(offset) >> 2; 27335 EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 27336 offset_ | (sign << 23)); 27337 AdvanceIT(); 27338 return; 27339 } 27340 } else { 27341 // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2 27342 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 27343 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) { 27344 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 27345 uint32_t offset_ = abs(offset) >> 2; 27346 EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 27347 (rn.GetCode() << 16) | offset_ | (sign << 23)); 27348 return; 27349 } 27350 } 27351 } 27352 Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand); 27353 } 27354 27355 void Assembler::vsub( 27356 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 27357 VIXL_ASSERT(AllowAssembler()); 27358 CheckIT(cond); 27359 Dt_size_2 encoded_dt(dt); 27360 if (IsUsingT32()) { 27361 // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 27362 if (dt.Is(F32)) { 27363 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27364 EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27365 rm.Encode(5, 0)); 27366 AdvanceIT(); 27367 return; 27368 } 27369 } 27370 // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 27371 if (dt.Is(F64)) { 27372 EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27373 rm.Encode(5, 0)); 27374 AdvanceIT(); 27375 return; 27376 } 27377 // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 27378 if (encoded_dt.IsValid()) { 27379 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27380 EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) | 27381 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27382 AdvanceIT(); 27383 return; 27384 } 27385 } 27386 } else { 27387 // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 27388 if (dt.Is(F32)) { 27389 if (cond.Is(al)) { 27390 EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27391 rm.Encode(5, 0)); 27392 return; 27393 } 27394 } 27395 // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 27396 if (dt.Is(F64) && cond.IsNotNever()) { 27397 EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 27398 rn.Encode(7, 16) | rm.Encode(5, 0)); 27399 return; 27400 } 27401 // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 27402 if (encoded_dt.IsValid()) { 27403 if (cond.Is(al)) { 27404 EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) | 27405 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27406 return; 27407 } 27408 } 27409 } 27410 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 27411 } 27412 27413 void Assembler::vsub( 27414 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 27415 VIXL_ASSERT(AllowAssembler()); 27416 CheckIT(cond); 27417 Dt_size_2 encoded_dt(dt); 27418 if (IsUsingT32()) { 27419 // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 27420 if (dt.Is(F32)) { 27421 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27422 EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27423 rm.Encode(5, 0)); 27424 AdvanceIT(); 27425 return; 27426 } 27427 } 27428 // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 27429 if (encoded_dt.IsValid()) { 27430 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27431 EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) | 27432 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27433 AdvanceIT(); 27434 return; 27435 } 27436 } 27437 } else { 27438 // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 27439 if (dt.Is(F32)) { 27440 if (cond.Is(al)) { 27441 EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27442 rm.Encode(5, 0)); 27443 return; 27444 } 27445 } 27446 // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 27447 if (encoded_dt.IsValid()) { 27448 if (cond.Is(al)) { 27449 EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) | 27450 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27451 return; 27452 } 27453 } 27454 } 27455 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 27456 } 27457 27458 void Assembler::vsub( 27459 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 27460 VIXL_ASSERT(AllowAssembler()); 27461 CheckIT(cond); 27462 if (IsUsingT32()) { 27463 // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 27464 if (dt.Is(F32)) { 27465 EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27466 rm.Encode(5, 0)); 27467 AdvanceIT(); 27468 return; 27469 } 27470 } else { 27471 // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 27472 if (dt.Is(F32) && cond.IsNotNever()) { 27473 EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 27474 rn.Encode(7, 16) | rm.Encode(5, 0)); 27475 return; 27476 } 27477 } 27478 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 27479 } 27480 27481 void Assembler::vsubhn( 27482 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 27483 VIXL_ASSERT(AllowAssembler()); 27484 CheckIT(cond); 27485 Dt_size_3 encoded_dt(dt); 27486 if (IsUsingT32()) { 27487 // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 27488 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 27489 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27490 EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) | 27491 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27492 AdvanceIT(); 27493 return; 27494 } 27495 } 27496 } else { 27497 // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 27498 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 27499 if (cond.Is(al)) { 27500 EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) | 27501 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27502 return; 27503 } 27504 } 27505 } 27506 Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm); 27507 } 27508 27509 void Assembler::vsubl( 27510 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 27511 VIXL_ASSERT(AllowAssembler()); 27512 CheckIT(cond); 27513 Dt_U_size_1 encoded_dt(dt); 27514 if (IsUsingT32()) { 27515 // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 27516 if (encoded_dt.IsValid()) { 27517 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27518 EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 27519 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 27520 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27521 AdvanceIT(); 27522 return; 27523 } 27524 } 27525 } else { 27526 // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 27527 if (encoded_dt.IsValid()) { 27528 if (cond.Is(al)) { 27529 EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 27530 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 27531 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27532 return; 27533 } 27534 } 27535 } 27536 Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm); 27537 } 27538 27539 void Assembler::vsubw( 27540 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) { 27541 VIXL_ASSERT(AllowAssembler()); 27542 CheckIT(cond); 27543 Dt_U_size_1 encoded_dt(dt); 27544 if (IsUsingT32()) { 27545 // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1 27546 if (encoded_dt.IsValid()) { 27547 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27548 EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 27549 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 27550 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27551 AdvanceIT(); 27552 return; 27553 } 27554 } 27555 } else { 27556 // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1 27557 if (encoded_dt.IsValid()) { 27558 if (cond.Is(al)) { 27559 EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 27560 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 27561 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27562 return; 27563 } 27564 } 27565 } 27566 Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm); 27567 } 27568 27569 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) { 27570 VIXL_ASSERT(AllowAssembler()); 27571 CheckIT(cond); 27572 USE(dt); 27573 if (IsUsingT32()) { 27574 // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 27575 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27576 EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27577 AdvanceIT(); 27578 return; 27579 } 27580 } else { 27581 // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 27582 if (cond.Is(al)) { 27583 EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27584 return; 27585 } 27586 } 27587 Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm); 27588 } 27589 27590 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) { 27591 VIXL_ASSERT(AllowAssembler()); 27592 CheckIT(cond); 27593 USE(dt); 27594 if (IsUsingT32()) { 27595 // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 27596 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27597 EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27598 AdvanceIT(); 27599 return; 27600 } 27601 } else { 27602 // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 27603 if (cond.Is(al)) { 27604 EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27605 return; 27606 } 27607 } 27608 Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm); 27609 } 27610 27611 void Assembler::vtbl(Condition cond, 27612 DataType dt, 27613 DRegister rd, 27614 const NeonRegisterList& nreglist, 27615 DRegister rm) { 27616 VIXL_ASSERT(AllowAssembler()); 27617 CheckIT(cond); 27618 if (IsUsingT32()) { 27619 // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1 27620 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 27621 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 27622 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27623 const DRegister& first = nreglist.GetFirstDRegister(); 27624 uint32_t len_encoding = nreglist.GetLength() - 1; 27625 EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) | 27626 (len_encoding << 8) | rm.Encode(5, 0)); 27627 AdvanceIT(); 27628 return; 27629 } 27630 } 27631 } else { 27632 // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1 27633 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 27634 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 27635 if (cond.Is(al)) { 27636 const DRegister& first = nreglist.GetFirstDRegister(); 27637 uint32_t len_encoding = nreglist.GetLength() - 1; 27638 EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) | 27639 (len_encoding << 8) | rm.Encode(5, 0)); 27640 return; 27641 } 27642 } 27643 } 27644 Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm); 27645 } 27646 27647 void Assembler::vtbx(Condition cond, 27648 DataType dt, 27649 DRegister rd, 27650 const NeonRegisterList& nreglist, 27651 DRegister rm) { 27652 VIXL_ASSERT(AllowAssembler()); 27653 CheckIT(cond); 27654 if (IsUsingT32()) { 27655 // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1 27656 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 27657 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 27658 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27659 const DRegister& first = nreglist.GetFirstDRegister(); 27660 uint32_t len_encoding = nreglist.GetLength() - 1; 27661 EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) | 27662 (len_encoding << 8) | rm.Encode(5, 0)); 27663 AdvanceIT(); 27664 return; 27665 } 27666 } 27667 } else { 27668 // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1 27669 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 27670 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 27671 if (cond.Is(al)) { 27672 const DRegister& first = nreglist.GetFirstDRegister(); 27673 uint32_t len_encoding = nreglist.GetLength() - 1; 27674 EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) | 27675 (len_encoding << 8) | rm.Encode(5, 0)); 27676 return; 27677 } 27678 } 27679 } 27680 Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm); 27681 } 27682 27683 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) { 27684 VIXL_ASSERT(AllowAssembler()); 27685 CheckIT(cond); 27686 Dt_size_7 encoded_dt(dt); 27687 if (IsUsingT32()) { 27688 // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 27689 if (encoded_dt.IsValid()) { 27690 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27691 EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) | 27692 rd.Encode(22, 12) | rm.Encode(5, 0)); 27693 AdvanceIT(); 27694 return; 27695 } 27696 } 27697 } else { 27698 // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 27699 if (encoded_dt.IsValid()) { 27700 if (cond.Is(al)) { 27701 EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) | 27702 rd.Encode(22, 12) | rm.Encode(5, 0)); 27703 return; 27704 } 27705 } 27706 } 27707 Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm); 27708 } 27709 27710 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) { 27711 VIXL_ASSERT(AllowAssembler()); 27712 CheckIT(cond); 27713 Dt_size_7 encoded_dt(dt); 27714 if (IsUsingT32()) { 27715 // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 27716 if (encoded_dt.IsValid()) { 27717 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27718 EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) | 27719 rd.Encode(22, 12) | rm.Encode(5, 0)); 27720 AdvanceIT(); 27721 return; 27722 } 27723 } 27724 } else { 27725 // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 27726 if (encoded_dt.IsValid()) { 27727 if (cond.Is(al)) { 27728 EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) | 27729 rd.Encode(22, 12) | rm.Encode(5, 0)); 27730 return; 27731 } 27732 } 27733 } 27734 Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm); 27735 } 27736 27737 void Assembler::vtst( 27738 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 27739 VIXL_ASSERT(AllowAssembler()); 27740 CheckIT(cond); 27741 Dt_size_7 encoded_dt(dt); 27742 if (IsUsingT32()) { 27743 // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 27744 if (encoded_dt.IsValid()) { 27745 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27746 EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) | 27747 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27748 AdvanceIT(); 27749 return; 27750 } 27751 } 27752 } else { 27753 // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 27754 if (encoded_dt.IsValid()) { 27755 if (cond.Is(al)) { 27756 EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) | 27757 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27758 return; 27759 } 27760 } 27761 } 27762 Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm); 27763 } 27764 27765 void Assembler::vtst( 27766 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 27767 VIXL_ASSERT(AllowAssembler()); 27768 CheckIT(cond); 27769 Dt_size_7 encoded_dt(dt); 27770 if (IsUsingT32()) { 27771 // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 27772 if (encoded_dt.IsValid()) { 27773 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27774 EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) | 27775 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27776 AdvanceIT(); 27777 return; 27778 } 27779 } 27780 } else { 27781 // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 27782 if (encoded_dt.IsValid()) { 27783 if (cond.Is(al)) { 27784 EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) | 27785 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27786 return; 27787 } 27788 } 27789 } 27790 Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm); 27791 } 27792 27793 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) { 27794 VIXL_ASSERT(AllowAssembler()); 27795 CheckIT(cond); 27796 Dt_size_15 encoded_dt(dt); 27797 if (IsUsingT32()) { 27798 // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 27799 if (encoded_dt.IsValid()) { 27800 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27801 EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) | 27802 rd.Encode(22, 12) | rm.Encode(5, 0)); 27803 AdvanceIT(); 27804 return; 27805 } 27806 } 27807 // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1 27808 if (dt.Is(Untyped32)) { 27809 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27810 EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27811 AdvanceIT(); 27812 return; 27813 } 27814 } 27815 } else { 27816 // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 27817 if (encoded_dt.IsValid()) { 27818 if (cond.Is(al)) { 27819 EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) | 27820 rd.Encode(22, 12) | rm.Encode(5, 0)); 27821 return; 27822 } 27823 } 27824 // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1 27825 if (dt.Is(Untyped32)) { 27826 if (cond.Is(al)) { 27827 EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27828 return; 27829 } 27830 } 27831 } 27832 Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm); 27833 } 27834 27835 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) { 27836 VIXL_ASSERT(AllowAssembler()); 27837 CheckIT(cond); 27838 Dt_size_7 encoded_dt(dt); 27839 if (IsUsingT32()) { 27840 // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 27841 if (encoded_dt.IsValid()) { 27842 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27843 EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) | 27844 rd.Encode(22, 12) | rm.Encode(5, 0)); 27845 AdvanceIT(); 27846 return; 27847 } 27848 } 27849 } else { 27850 // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 27851 if (encoded_dt.IsValid()) { 27852 if (cond.Is(al)) { 27853 EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) | 27854 rd.Encode(22, 12) | rm.Encode(5, 0)); 27855 return; 27856 } 27857 } 27858 } 27859 Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm); 27860 } 27861 27862 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) { 27863 VIXL_ASSERT(AllowAssembler()); 27864 CheckIT(cond); 27865 Dt_size_15 encoded_dt(dt); 27866 if (IsUsingT32()) { 27867 // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 27868 if (encoded_dt.IsValid()) { 27869 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27870 EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) | 27871 rd.Encode(22, 12) | rm.Encode(5, 0)); 27872 AdvanceIT(); 27873 return; 27874 } 27875 } 27876 // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1 27877 if (dt.Is(Untyped32)) { 27878 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27879 EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27880 AdvanceIT(); 27881 return; 27882 } 27883 } 27884 } else { 27885 // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 27886 if (encoded_dt.IsValid()) { 27887 if (cond.Is(al)) { 27888 EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) | 27889 rd.Encode(22, 12) | rm.Encode(5, 0)); 27890 return; 27891 } 27892 } 27893 // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1 27894 if (dt.Is(Untyped32)) { 27895 if (cond.Is(al)) { 27896 EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27897 return; 27898 } 27899 } 27900 } 27901 Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm); 27902 } 27903 27904 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) { 27905 VIXL_ASSERT(AllowAssembler()); 27906 CheckIT(cond); 27907 Dt_size_7 encoded_dt(dt); 27908 if (IsUsingT32()) { 27909 // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 27910 if (encoded_dt.IsValid()) { 27911 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27912 EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) | 27913 rd.Encode(22, 12) | rm.Encode(5, 0)); 27914 AdvanceIT(); 27915 return; 27916 } 27917 } 27918 } else { 27919 // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 27920 if (encoded_dt.IsValid()) { 27921 if (cond.Is(al)) { 27922 EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) | 27923 rd.Encode(22, 12) | rm.Encode(5, 0)); 27924 return; 27925 } 27926 } 27927 } 27928 Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm); 27929 } 27930 27931 void Assembler::yield(Condition cond, EncodingSize size) { 27932 VIXL_ASSERT(AllowAssembler()); 27933 CheckIT(cond); 27934 if (IsUsingT32()) { 27935 // YIELD{<c>}{<q>} ; T1 27936 if (!size.IsWide()) { 27937 EmitT32_16(0xbf10); 27938 AdvanceIT(); 27939 return; 27940 } 27941 // YIELD{<c>}.W ; T2 27942 if (!size.IsNarrow()) { 27943 EmitT32_32(0xf3af8001U); 27944 AdvanceIT(); 27945 return; 27946 } 27947 } else { 27948 // YIELD{<c>}{<q>} ; A1 27949 if (cond.IsNotNever()) { 27950 EmitA32(0x0320f001U | (cond.GetCondition() << 28)); 27951 return; 27952 } 27953 } 27954 Delegate(kYield, &Assembler::yield, cond, size); 27955 } 27956 // End of generated code. 27957 27958 } // namespace aarch32 27959 } // namespace vixl