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 I8: 1314 SetEncodingValue(0x0); 1315 break; 1316 case I16: 1317 SetEncodingValue(0x1); 1318 break; 1319 case I32: 1320 SetEncodingValue(0x2); 1321 break; 1322 default: 1323 break; 1324 } 1325 } 1326 1327 class Index_1 : public EncodingValue { 1328 public: 1329 Index_1(const NeonRegisterList& nreglist, DataType dt); 1330 }; 1331 1332 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) { 1333 switch (dt.GetValue()) { 1334 case Untyped8: { 1335 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1336 return; 1337 } 1338 uint32_t value = nreglist.GetTransferLane() << 1; 1339 if (!nreglist.IsSingleSpaced()) return; 1340 SetEncodingValue(value); 1341 break; 1342 } 1343 case Untyped16: { 1344 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1345 return; 1346 } 1347 uint32_t value = nreglist.GetTransferLane() << 2; 1348 if (nreglist.IsDoubleSpaced()) value |= 2; 1349 SetEncodingValue(value); 1350 break; 1351 } 1352 case Untyped32: { 1353 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1354 return; 1355 } 1356 uint32_t value = nreglist.GetTransferLane() << 3; 1357 if (nreglist.IsDoubleSpaced()) value |= 4; 1358 SetEncodingValue(value); 1359 break; 1360 } 1361 default: 1362 break; 1363 } 1364 } 1365 1366 class Align_index_align_1 : public EncodingValue { 1367 public: 1368 Align_index_align_1(Alignment align, 1369 const NeonRegisterList& nreglist, 1370 DataType dt); 1371 }; 1372 1373 Align_index_align_1::Align_index_align_1(Alignment align, 1374 const NeonRegisterList& nreglist, 1375 DataType dt) { 1376 switch (dt.GetValue()) { 1377 case Untyped8: { 1378 uint32_t value; 1379 if (align.GetType() == kNoAlignment) { 1380 value = 0; 1381 } else { 1382 return; 1383 } 1384 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1385 return; 1386 } 1387 value |= nreglist.GetTransferLane() << 1; 1388 SetEncodingValue(value); 1389 break; 1390 } 1391 case Untyped16: { 1392 uint32_t value; 1393 if (align.GetType() == k16BitAlign) { 1394 value = 1; 1395 } else if (align.GetType() == kNoAlignment) { 1396 value = 0; 1397 } else { 1398 return; 1399 } 1400 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1401 return; 1402 } 1403 value |= nreglist.GetTransferLane() << 2; 1404 SetEncodingValue(value); 1405 break; 1406 } 1407 case Untyped32: { 1408 uint32_t value; 1409 if (align.GetType() == k32BitAlign) { 1410 value = 3; 1411 } else if (align.GetType() == kNoAlignment) { 1412 value = 0; 1413 } else { 1414 return; 1415 } 1416 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1417 return; 1418 } 1419 value |= nreglist.GetTransferLane() << 3; 1420 SetEncodingValue(value); 1421 break; 1422 } 1423 default: 1424 break; 1425 } 1426 } 1427 1428 class Align_index_align_2 : public EncodingValue { 1429 public: 1430 Align_index_align_2(Alignment align, 1431 const NeonRegisterList& nreglist, 1432 DataType dt); 1433 }; 1434 1435 Align_index_align_2::Align_index_align_2(Alignment align, 1436 const NeonRegisterList& nreglist, 1437 DataType dt) { 1438 switch (dt.GetValue()) { 1439 case Untyped8: { 1440 uint32_t value; 1441 if (align.GetType() == k16BitAlign) { 1442 value = 1; 1443 } else if (align.GetType() == kNoAlignment) { 1444 value = 0; 1445 } else { 1446 return; 1447 } 1448 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1449 return; 1450 } 1451 value |= nreglist.GetTransferLane() << 1; 1452 if (!nreglist.IsSingleSpaced()) return; 1453 SetEncodingValue(value); 1454 break; 1455 } 1456 case Untyped16: { 1457 uint32_t value; 1458 if (align.GetType() == k32BitAlign) { 1459 value = 1; 1460 } else if (align.GetType() == kNoAlignment) { 1461 value = 0; 1462 } else { 1463 return; 1464 } 1465 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1466 return; 1467 } 1468 value |= nreglist.GetTransferLane() << 2; 1469 if (nreglist.IsDoubleSpaced()) value |= 2; 1470 SetEncodingValue(value); 1471 break; 1472 } 1473 case Untyped32: { 1474 uint32_t value; 1475 if (align.GetType() == k64BitAlign) { 1476 value = 1; 1477 } else if (align.GetType() == kNoAlignment) { 1478 value = 0; 1479 } else { 1480 return; 1481 } 1482 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1483 return; 1484 } 1485 value |= nreglist.GetTransferLane() << 3; 1486 if (nreglist.IsDoubleSpaced()) value |= 4; 1487 SetEncodingValue(value); 1488 break; 1489 } 1490 default: 1491 break; 1492 } 1493 } 1494 1495 class Align_index_align_3 : public EncodingValue { 1496 public: 1497 Align_index_align_3(Alignment align, 1498 const NeonRegisterList& nreglist, 1499 DataType dt); 1500 }; 1501 1502 Align_index_align_3::Align_index_align_3(Alignment align, 1503 const NeonRegisterList& nreglist, 1504 DataType dt) { 1505 switch (dt.GetValue()) { 1506 case Untyped8: { 1507 uint32_t value; 1508 if (align.GetType() == k32BitAlign) { 1509 value = 1; 1510 } else if (align.GetType() == kNoAlignment) { 1511 value = 0; 1512 } else { 1513 return; 1514 } 1515 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1516 return; 1517 } 1518 value |= nreglist.GetTransferLane() << 1; 1519 if (!nreglist.IsSingleSpaced()) return; 1520 SetEncodingValue(value); 1521 break; 1522 } 1523 case Untyped16: { 1524 uint32_t value; 1525 if (align.GetType() == k64BitAlign) { 1526 value = 1; 1527 } else if (align.GetType() == kNoAlignment) { 1528 value = 0; 1529 } else { 1530 return; 1531 } 1532 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1533 return; 1534 } 1535 value |= nreglist.GetTransferLane() << 2; 1536 if (nreglist.IsDoubleSpaced()) value |= 2; 1537 SetEncodingValue(value); 1538 break; 1539 } 1540 case Untyped32: { 1541 uint32_t value; 1542 if (align.GetType() == k64BitAlign) { 1543 value = 1; 1544 } else if (align.GetType() == k128BitAlign) { 1545 value = 2; 1546 } else if (align.GetType() == kNoAlignment) { 1547 value = 0; 1548 } else { 1549 return; 1550 } 1551 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1552 return; 1553 } 1554 value |= nreglist.GetTransferLane() << 3; 1555 if (nreglist.IsDoubleSpaced()) value |= 4; 1556 SetEncodingValue(value); 1557 break; 1558 } 1559 default: 1560 break; 1561 } 1562 } 1563 1564 class Align_a_1 : public EncodingValue { 1565 public: 1566 Align_a_1(Alignment align, DataType dt); 1567 }; 1568 1569 Align_a_1::Align_a_1(Alignment align, DataType dt) { 1570 switch (align.GetType()) { 1571 case k16BitAlign: 1572 if (dt.Is(Untyped16)) SetEncodingValue(0x1); 1573 break; 1574 case k32BitAlign: 1575 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1576 break; 1577 case kNoAlignment: 1578 SetEncodingValue(0x0); 1579 break; 1580 default: 1581 break; 1582 } 1583 } 1584 1585 class Align_a_2 : public EncodingValue { 1586 public: 1587 Align_a_2(Alignment align, DataType dt); 1588 }; 1589 1590 Align_a_2::Align_a_2(Alignment align, DataType dt) { 1591 switch (align.GetType()) { 1592 case k16BitAlign: 1593 if (dt.Is(Untyped8)) SetEncodingValue(0x1); 1594 break; 1595 case k32BitAlign: 1596 if (dt.Is(Untyped16)) SetEncodingValue(0x1); 1597 break; 1598 case k64BitAlign: 1599 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1600 break; 1601 case kNoAlignment: 1602 SetEncodingValue(0x0); 1603 break; 1604 default: 1605 break; 1606 } 1607 } 1608 1609 class Align_a_3 : public EncodingValue { 1610 public: 1611 Align_a_3(Alignment align, DataType dt); 1612 }; 1613 1614 Align_a_3::Align_a_3(Alignment align, DataType dt) { 1615 switch (align.GetType()) { 1616 case k32BitAlign: 1617 if (dt.Is(Untyped8)) SetEncodingValue(0x1); 1618 break; 1619 case k64BitAlign: 1620 if (dt.Is(Untyped16)) 1621 SetEncodingValue(0x1); 1622 else if (dt.Is(Untyped32)) 1623 SetEncodingValue(0x1); 1624 break; 1625 case k128BitAlign: 1626 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1627 break; 1628 case kNoAlignment: 1629 SetEncodingValue(0x0); 1630 break; 1631 default: 1632 break; 1633 } 1634 } 1635 1636 class Align_align_1 : public EncodingValue { 1637 public: 1638 Align_align_1(Alignment align, const NeonRegisterList& nreglist); 1639 }; 1640 1641 Align_align_1::Align_align_1(Alignment align, 1642 const NeonRegisterList& nreglist) { 1643 switch (align.GetType()) { 1644 case k64BitAlign: 1645 SetEncodingValue(0x1); 1646 break; 1647 case k128BitAlign: 1648 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1649 SetEncodingValue(0x2); 1650 break; 1651 case k256BitAlign: 1652 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1653 SetEncodingValue(0x3); 1654 break; 1655 case kNoAlignment: 1656 SetEncodingValue(0x0); 1657 break; 1658 default: 1659 break; 1660 } 1661 } 1662 1663 class Align_align_2 : public EncodingValue { 1664 public: 1665 Align_align_2(Alignment align, const NeonRegisterList& nreglist); 1666 }; 1667 1668 Align_align_2::Align_align_2(Alignment align, 1669 const NeonRegisterList& nreglist) { 1670 switch (align.GetType()) { 1671 case k64BitAlign: 1672 SetEncodingValue(0x1); 1673 break; 1674 case k128BitAlign: 1675 SetEncodingValue(0x2); 1676 break; 1677 case k256BitAlign: 1678 if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3); 1679 break; 1680 case kNoAlignment: 1681 SetEncodingValue(0x0); 1682 break; 1683 default: 1684 break; 1685 } 1686 } 1687 1688 class Align_align_3 : public EncodingValue { 1689 public: 1690 explicit Align_align_3(Alignment align); 1691 }; 1692 1693 Align_align_3::Align_align_3(Alignment align) { 1694 switch (align.GetType()) { 1695 case k64BitAlign: 1696 SetEncodingValue(0x1); 1697 break; 1698 case kNoAlignment: 1699 SetEncodingValue(0x0); 1700 break; 1701 default: 1702 break; 1703 } 1704 } 1705 1706 class Align_align_4 : public EncodingValue { 1707 public: 1708 explicit Align_align_4(Alignment align); 1709 }; 1710 1711 Align_align_4::Align_align_4(Alignment align) { 1712 switch (align.GetType()) { 1713 case k64BitAlign: 1714 SetEncodingValue(0x1); 1715 break; 1716 case k128BitAlign: 1717 SetEncodingValue(0x2); 1718 break; 1719 case k256BitAlign: 1720 SetEncodingValue(0x3); 1721 break; 1722 case kNoAlignment: 1723 SetEncodingValue(0x0); 1724 break; 1725 default: 1726 break; 1727 } 1728 } 1729 1730 class Align_align_5 : public EncodingValue { 1731 public: 1732 Align_align_5(Alignment align, const NeonRegisterList& nreglist); 1733 }; 1734 1735 Align_align_5::Align_align_5(Alignment align, 1736 const NeonRegisterList& nreglist) { 1737 switch (align.GetType()) { 1738 case k64BitAlign: 1739 SetEncodingValue(0x1); 1740 break; 1741 case k128BitAlign: 1742 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1743 SetEncodingValue(0x2); 1744 break; 1745 case k256BitAlign: 1746 if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3); 1747 break; 1748 case kNoAlignment: 1749 SetEncodingValue(0x0); 1750 break; 1751 default: 1752 break; 1753 } 1754 } 1755 1756 1757 // CBNZ{<q>} <Rn>, <label> ; T1 1758 // CBZ{<q>} <Rn>, <label> ; T1 1759 static const struct ReferenceInfo kT16CbzInfo = 1760 {k16BitT32InstructionSizeInBytes, 1761 0, // Min offset. 1762 126, // Max offset. 1763 2, // Alignment. 1764 ReferenceInfo::kDontAlignPc}; 1765 1766 1767 // B<c>{<q>} <label> ; T1 1768 static const struct ReferenceInfo kT16ConditionalBranchInfo = 1769 {k16BitT32InstructionSizeInBytes, 1770 -256, // Min offset. 1771 254, // Max offset. 1772 2, // Alignment. 1773 ReferenceInfo::kDontAlignPc}; 1774 1775 1776 // ADR{<c>}{<q>} <Rd>, <label> ; T1 1777 // LDR{<c>}{<q>} <Rt>, <label> ; T1 1778 static const struct ReferenceInfo kT16DataInfo = 1779 {k16BitT32InstructionSizeInBytes, 1780 0, // Min offset. 1781 1020, // Max offset. 1782 4, // Alignment. 1783 ReferenceInfo::kAlignPc}; 1784 1785 1786 // B{<c>}{<q>} <label> ; T2 1787 static const struct ReferenceInfo kT16BranchInfo = 1788 {k16BitT32InstructionSizeInBytes, 1789 -2048, // Min offset. 1790 2046, // Max offset. 1791 2, // Alignment. 1792 ReferenceInfo::kDontAlignPc}; 1793 1794 1795 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1 1796 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1 1797 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2 1798 static const struct ReferenceInfo kT32DataInfo = 1799 {k32BitT32InstructionSizeInBytes, 1800 -1020, // Min offset. 1801 1020, // Max offset. 1802 4, // Alignment. 1803 ReferenceInfo::kAlignPc}; 1804 1805 1806 // ADR{<c>}{<q>} <Rd>, <label> ; T3 1807 // LDR{<c>}{<q>} <Rt>, <label> ; T2 1808 // LDRB{<c>}{<q>} <Rt>, <label> ; T1 1809 // LDRH{<c>}{<q>} <Rt>, <label> ; T1 1810 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1 1811 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1 1812 // PLD{<c>}{<q>} <label> ; T1 1813 // PLI{<c>}{<q>} <label> ; T3 1814 static const struct ReferenceInfo kT32FarDataInfo = 1815 {k32BitT32InstructionSizeInBytes, 1816 -4095, // Min offset. 1817 4095, // Max offset. 1818 1, // Alignment. 1819 ReferenceInfo::kAlignPc}; 1820 1821 1822 // B<c>{<q>} <label> ; T3 1823 static const struct ReferenceInfo kT32ConditionalBranchInfo = 1824 {k32BitT32InstructionSizeInBytes, 1825 -1048576, // Min offset. 1826 1048574, // Max offset. 1827 2, // Alignment. 1828 ReferenceInfo::kDontAlignPc}; 1829 1830 1831 // B{<c>}{<q>} <label> ; T4 1832 // BL{<c>}{<q>} <label> ; T1 1833 static const struct ReferenceInfo kT32BranchInfo = 1834 {k32BitT32InstructionSizeInBytes, 1835 -16777216, // Min offset. 1836 16777214, // Max offset. 1837 2, // Alignment. 1838 ReferenceInfo::kDontAlignPc}; 1839 1840 1841 // BLX{<c>}{<q>} <label> ; T2 1842 static const struct ReferenceInfo kT32BlxInfo = 1843 {k32BitT32InstructionSizeInBytes, 1844 -16777216, // Min offset. 1845 16777212, // Max offset. 1846 4, // Alignment. 1847 ReferenceInfo::kAlignPc}; 1848 1849 1850 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1 1851 // LDRH{<c>}{<q>} <Rt>, <label> ; A1 1852 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1 1853 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1 1854 static const struct ReferenceInfo kA32VeryNearDataInfo = 1855 {kA32InstructionSizeInBytes, 1856 -255, // Min offset. 1857 255, // Max offset. 1858 1, // Alignment. 1859 ReferenceInfo::kAlignPc}; 1860 1861 1862 // ADR{<c>}{<q>} <Rd>, <label> ; A1 1863 static const struct ReferenceInfo kA32AdrInfo = {kA32InstructionSizeInBytes, 1864 -256, // Min offset. 1865 256, // Max offset. 1866 1, // Alignment. 1867 ReferenceInfo::kAlignPc}; 1868 1869 1870 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1 1871 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2 1872 static const struct ReferenceInfo kA32DataInfo = {kA32InstructionSizeInBytes, 1873 -1020, // Min offset. 1874 1020, // Max offset. 1875 4, // Alignment. 1876 ReferenceInfo::kAlignPc}; 1877 1878 1879 // LDR{<c>}{<q>} <Rt>, <label> ; A1 1880 // LDRB{<c>}{<q>} <Rt>, <label> ; A1 1881 // PLD{<c>}{<q>} <label> ; A1 1882 // PLI{<c>}{<q>} <label> ; A1 1883 static const struct ReferenceInfo kA32FarDataInfo = {kA32InstructionSizeInBytes, 1884 -4095, // Min offset. 1885 4095, // Max offset. 1886 1, // Alignment. 1887 ReferenceInfo::kAlignPc}; 1888 1889 1890 // B{<c>}{<q>} <label> ; A1 1891 // BL{<c>}{<q>} <label> ; A1 1892 static const struct ReferenceInfo kA32BranchInfo = 1893 {kA32InstructionSizeInBytes, 1894 -33554432, // Min offset. 1895 33554428, // Max offset. 1896 4, // Alignment. 1897 ReferenceInfo::kDontAlignPc}; 1898 1899 1900 // BLX{<c>}{<q>} <label> ; A2 1901 static const struct ReferenceInfo kA32BlxInfo = {kA32InstructionSizeInBytes, 1902 -33554432, // Min offset. 1903 33554430, // Max offset. 1904 2, // Alignment. 1905 ReferenceInfo::kAlignPc}; 1906 1907 1908 void Assembler::adc(Condition cond, 1909 EncodingSize size, 1910 Register rd, 1911 Register rn, 1912 const Operand& operand) { 1913 VIXL_ASSERT(AllowAssembler()); 1914 CheckIT(cond); 1915 if (operand.IsImmediate()) { 1916 uint32_t imm = operand.GetImmediate(); 1917 if (IsUsingT32()) { 1918 ImmediateT32 immediate_t32(imm); 1919 // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 1920 if (!size.IsNarrow() && immediate_t32.IsValid() && 1921 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 1922 EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 1923 (immediate_t32.GetEncodingValue() & 0xff) | 1924 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 1925 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 1926 AdvanceIT(); 1927 return; 1928 } 1929 } else { 1930 ImmediateA32 immediate_a32(imm); 1931 // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 1932 if (immediate_a32.IsValid() && cond.IsNotNever()) { 1933 EmitA32(0x02a00000U | (cond.GetCondition() << 28) | 1934 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 1935 immediate_a32.GetEncodingValue()); 1936 return; 1937 } 1938 } 1939 } 1940 if (operand.IsImmediateShiftedRegister()) { 1941 Register rm = operand.GetBaseRegister(); 1942 if (operand.IsPlainRegister()) { 1943 if (IsUsingT32()) { 1944 // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 1945 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 1946 rm.IsLow()) { 1947 EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); 1948 AdvanceIT(); 1949 return; 1950 } 1951 } 1952 } 1953 Shift shift = operand.GetShift(); 1954 uint32_t amount = operand.GetShiftAmount(); 1955 if (IsUsingT32()) { 1956 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 1957 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 1958 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 1959 uint32_t amount_ = amount % 32; 1960 EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 1961 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 1962 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 1963 AdvanceIT(); 1964 return; 1965 } 1966 } else { 1967 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 1968 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 1969 uint32_t amount_ = amount % 32; 1970 EmitA32(0x00a00000U | (cond.GetCondition() << 28) | 1971 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 1972 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 1973 return; 1974 } 1975 } 1976 } 1977 if (operand.IsRegisterShiftedRegister()) { 1978 Register rm = operand.GetBaseRegister(); 1979 Shift shift = operand.GetShift(); 1980 Register rs = operand.GetShiftRegister(); 1981 if (IsUsingA32()) { 1982 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 1983 if (cond.IsNotNever() && 1984 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 1985 AllowUnpredictable())) { 1986 EmitA32(0x00a00010U | (cond.GetCondition() << 28) | 1987 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 1988 (shift.GetType() << 5) | (rs.GetCode() << 8)); 1989 return; 1990 } 1991 } 1992 } 1993 Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); 1994 } 1995 1996 void Assembler::adcs(Condition cond, 1997 EncodingSize size, 1998 Register rd, 1999 Register rn, 2000 const Operand& operand) { 2001 VIXL_ASSERT(AllowAssembler()); 2002 CheckIT(cond); 2003 if (operand.IsImmediate()) { 2004 uint32_t imm = operand.GetImmediate(); 2005 if (IsUsingT32()) { 2006 ImmediateT32 immediate_t32(imm); 2007 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 2008 if (!size.IsNarrow() && immediate_t32.IsValid() && 2009 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 2010 EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2011 (immediate_t32.GetEncodingValue() & 0xff) | 2012 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2013 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2014 AdvanceIT(); 2015 return; 2016 } 2017 } else { 2018 ImmediateA32 immediate_a32(imm); 2019 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2020 if (immediate_a32.IsValid() && cond.IsNotNever()) { 2021 EmitA32(0x02b00000U | (cond.GetCondition() << 28) | 2022 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2023 immediate_a32.GetEncodingValue()); 2024 return; 2025 } 2026 } 2027 } 2028 if (operand.IsImmediateShiftedRegister()) { 2029 Register rm = operand.GetBaseRegister(); 2030 if (operand.IsPlainRegister()) { 2031 if (IsUsingT32()) { 2032 // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 2033 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2034 rm.IsLow()) { 2035 EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); 2036 AdvanceIT(); 2037 return; 2038 } 2039 } 2040 } 2041 Shift shift = operand.GetShift(); 2042 uint32_t amount = operand.GetShiftAmount(); 2043 if (IsUsingT32()) { 2044 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 2045 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 2046 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2047 uint32_t amount_ = amount % 32; 2048 EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2049 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2050 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2051 AdvanceIT(); 2052 return; 2053 } 2054 } else { 2055 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2056 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 2057 uint32_t amount_ = amount % 32; 2058 EmitA32(0x00b00000U | (cond.GetCondition() << 28) | 2059 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2060 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2061 return; 2062 } 2063 } 2064 } 2065 if (operand.IsRegisterShiftedRegister()) { 2066 Register rm = operand.GetBaseRegister(); 2067 Shift shift = operand.GetShift(); 2068 Register rs = operand.GetShiftRegister(); 2069 if (IsUsingA32()) { 2070 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2071 if (cond.IsNotNever() && 2072 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2073 AllowUnpredictable())) { 2074 EmitA32(0x00b00010U | (cond.GetCondition() << 28) | 2075 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2076 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2077 return; 2078 } 2079 } 2080 } 2081 Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); 2082 } 2083 2084 void Assembler::add(Condition cond, 2085 EncodingSize size, 2086 Register rd, 2087 Register rn, 2088 const Operand& operand) { 2089 VIXL_ASSERT(AllowAssembler()); 2090 CheckIT(cond); 2091 if (operand.IsImmediate()) { 2092 uint32_t imm = operand.GetImmediate(); 2093 if (IsUsingT32()) { 2094 ImmediateT32 immediate_t32(imm); 2095 // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1 2096 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && 2097 ((imm % 4) == 0)) { 2098 uint32_t imm_ = imm >> 2; 2099 EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); 2100 AdvanceIT(); 2101 return; 2102 } 2103 // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1 2104 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2105 (imm <= 7)) { 2106 EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 2107 AdvanceIT(); 2108 return; 2109 } 2110 // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 2111 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2112 (imm <= 255)) { 2113 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2114 AdvanceIT(); 2115 return; 2116 } 2117 // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1 2118 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && 2119 ((imm % 4) == 0)) { 2120 uint32_t imm_ = imm >> 2; 2121 EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); 2122 AdvanceIT(); 2123 return; 2124 } 2125 // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2 2126 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && 2127 ((imm % 4) == 0)) { 2128 uint32_t imm_ = imm >> 2; 2129 EmitT32_16(0xb000 | imm_); 2130 AdvanceIT(); 2131 return; 2132 } 2133 // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3 2134 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && 2135 (!rd.IsPC() || AllowUnpredictable())) { 2136 EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2137 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2138 AdvanceIT(); 2139 return; 2140 } 2141 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 2142 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 2143 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 2144 EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2145 (immediate_t32.GetEncodingValue() & 0xff) | 2146 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2147 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2148 AdvanceIT(); 2149 return; 2150 } 2151 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 2152 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 2153 (!rd.IsPC() || AllowUnpredictable())) { 2154 EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2155 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2156 AdvanceIT(); 2157 return; 2158 } 2159 // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3 2160 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 2161 (!rd.IsPC() || AllowUnpredictable())) { 2162 EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | 2163 (immediate_t32.GetEncodingValue() & 0xff) | 2164 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2165 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2166 AdvanceIT(); 2167 return; 2168 } 2169 // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4 2170 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && 2171 (!rd.IsPC() || AllowUnpredictable())) { 2172 EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2173 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2174 AdvanceIT(); 2175 return; 2176 } 2177 } else { 2178 ImmediateA32 immediate_a32(imm); 2179 // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1 2180 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { 2181 EmitA32(0x028f0000U | (cond.GetCondition() << 28) | 2182 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2183 return; 2184 } 2185 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2186 if (immediate_a32.IsValid() && cond.IsNotNever() && 2187 ((rn.GetCode() & 0xd) != 0xd)) { 2188 EmitA32(0x02800000U | (cond.GetCondition() << 28) | 2189 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2190 immediate_a32.GetEncodingValue()); 2191 return; 2192 } 2193 // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 2194 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 2195 EmitA32(0x028d0000U | (cond.GetCondition() << 28) | 2196 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2197 return; 2198 } 2199 } 2200 } 2201 if (operand.IsImmediateShiftedRegister()) { 2202 Register rm = operand.GetBaseRegister(); 2203 if (operand.IsPlainRegister()) { 2204 if (IsUsingT32()) { 2205 // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 2206 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2207 rm.IsLow()) { 2208 EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | 2209 (rm.GetCode() << 6)); 2210 AdvanceIT(); 2211 return; 2212 } 2213 // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2 2214 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && 2215 (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && 2216 (!rd.IsPC() || !rm.IsPC())) || 2217 AllowUnpredictable())) { 2218 EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | 2219 ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 2220 AdvanceIT(); 2221 return; 2222 } 2223 // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1 2224 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && 2225 ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 2226 AllowUnpredictable())) { 2227 EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | 2228 ((rd.GetCode() & 0x8) << 4)); 2229 AdvanceIT(); 2230 return; 2231 } 2232 // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2 2233 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { 2234 EmitT32_16(0x4485 | (rm.GetCode() << 3)); 2235 AdvanceIT(); 2236 return; 2237 } 2238 } 2239 } 2240 Shift shift = operand.GetShift(); 2241 uint32_t amount = operand.GetShiftAmount(); 2242 if (IsUsingT32()) { 2243 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 2244 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 2245 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2246 uint32_t amount_ = amount % 32; 2247 EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2248 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2249 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2250 AdvanceIT(); 2251 return; 2252 } 2253 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 2254 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 2255 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2256 uint32_t amount_ = amount % 32; 2257 EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | 2258 (operand.GetTypeEncodingValue() << 4) | 2259 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2260 AdvanceIT(); 2261 return; 2262 } 2263 } else { 2264 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2265 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 2266 uint32_t amount_ = amount % 32; 2267 EmitA32(0x00800000U | (cond.GetCondition() << 28) | 2268 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2269 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2270 return; 2271 } 2272 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 2273 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 2274 uint32_t amount_ = amount % 32; 2275 EmitA32(0x008d0000U | (cond.GetCondition() << 28) | 2276 (rd.GetCode() << 12) | rm.GetCode() | 2277 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2278 return; 2279 } 2280 } 2281 } 2282 if (operand.IsRegisterShiftedRegister()) { 2283 Register rm = operand.GetBaseRegister(); 2284 Shift shift = operand.GetShift(); 2285 Register rs = operand.GetShiftRegister(); 2286 if (IsUsingA32()) { 2287 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2288 if (cond.IsNotNever() && 2289 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2290 AllowUnpredictable())) { 2291 EmitA32(0x00800010U | (cond.GetCondition() << 28) | 2292 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2293 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2294 return; 2295 } 2296 } 2297 } 2298 Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); 2299 } 2300 2301 void Assembler::add(Condition cond, Register rd, const Operand& operand) { 2302 VIXL_ASSERT(AllowAssembler()); 2303 CheckIT(cond); 2304 if (operand.IsImmediate()) { 2305 uint32_t imm = operand.GetImmediate(); 2306 if (IsUsingT32()) { 2307 // ADD<c>{<q>} <Rdn>, #<imm8> ; T2 2308 if (InITBlock() && rd.IsLow() && (imm <= 255)) { 2309 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2310 AdvanceIT(); 2311 return; 2312 } 2313 } 2314 } 2315 if (operand.IsPlainRegister()) { 2316 Register rm = operand.GetBaseRegister(); 2317 if (IsUsingT32()) { 2318 // ADD<c>{<q>} <Rdn>, <Rm> ; T2 2319 if (InITBlock() && !rm.Is(sp) && 2320 (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && 2321 (!rd.IsPC() || !rm.IsPC())) || 2322 AllowUnpredictable())) { 2323 EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | 2324 (rm.GetCode() << 3)); 2325 AdvanceIT(); 2326 return; 2327 } 2328 } 2329 } 2330 Delegate(kAdd, &Assembler::add, cond, rd, operand); 2331 } 2332 2333 void Assembler::adds(Condition cond, 2334 EncodingSize size, 2335 Register rd, 2336 Register rn, 2337 const Operand& operand) { 2338 VIXL_ASSERT(AllowAssembler()); 2339 CheckIT(cond); 2340 if (operand.IsImmediate()) { 2341 uint32_t imm = operand.GetImmediate(); 2342 if (IsUsingT32()) { 2343 ImmediateT32 immediate_t32(imm); 2344 // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1 2345 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2346 (imm <= 7)) { 2347 EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 2348 AdvanceIT(); 2349 return; 2350 } 2351 // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 2352 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2353 (imm <= 255)) { 2354 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2355 AdvanceIT(); 2356 return; 2357 } 2358 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 2359 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 2360 !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { 2361 EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2362 (immediate_t32.GetEncodingValue() & 0xff) | 2363 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2364 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2365 AdvanceIT(); 2366 return; 2367 } 2368 // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3 2369 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 2370 !rd.Is(pc)) { 2371 EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | 2372 (immediate_t32.GetEncodingValue() & 0xff) | 2373 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2374 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2375 AdvanceIT(); 2376 return; 2377 } 2378 } else { 2379 ImmediateA32 immediate_a32(imm); 2380 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2381 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { 2382 EmitA32(0x02900000U | (cond.GetCondition() << 28) | 2383 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2384 immediate_a32.GetEncodingValue()); 2385 return; 2386 } 2387 // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 2388 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 2389 EmitA32(0x029d0000U | (cond.GetCondition() << 28) | 2390 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2391 return; 2392 } 2393 } 2394 } 2395 if (operand.IsImmediateShiftedRegister()) { 2396 Register rm = operand.GetBaseRegister(); 2397 if (operand.IsPlainRegister()) { 2398 if (IsUsingT32()) { 2399 // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1 2400 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2401 rm.IsLow()) { 2402 EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | 2403 (rm.GetCode() << 6)); 2404 AdvanceIT(); 2405 return; 2406 } 2407 } 2408 } 2409 Shift shift = operand.GetShift(); 2410 uint32_t amount = operand.GetShiftAmount(); 2411 if (IsUsingT32()) { 2412 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 2413 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 2414 !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2415 uint32_t amount_ = amount % 32; 2416 EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2417 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2418 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2419 AdvanceIT(); 2420 return; 2421 } 2422 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 2423 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 2424 !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { 2425 uint32_t amount_ = amount % 32; 2426 EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | 2427 (operand.GetTypeEncodingValue() << 4) | 2428 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2429 AdvanceIT(); 2430 return; 2431 } 2432 } else { 2433 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2434 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 2435 uint32_t amount_ = amount % 32; 2436 EmitA32(0x00900000U | (cond.GetCondition() << 28) | 2437 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2438 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2439 return; 2440 } 2441 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 2442 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 2443 uint32_t amount_ = amount % 32; 2444 EmitA32(0x009d0000U | (cond.GetCondition() << 28) | 2445 (rd.GetCode() << 12) | rm.GetCode() | 2446 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2447 return; 2448 } 2449 } 2450 } 2451 if (operand.IsRegisterShiftedRegister()) { 2452 Register rm = operand.GetBaseRegister(); 2453 Shift shift = operand.GetShift(); 2454 Register rs = operand.GetShiftRegister(); 2455 if (IsUsingA32()) { 2456 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2457 if (cond.IsNotNever() && 2458 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2459 AllowUnpredictable())) { 2460 EmitA32(0x00900010U | (cond.GetCondition() << 28) | 2461 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2462 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2463 return; 2464 } 2465 } 2466 } 2467 Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand); 2468 } 2469 2470 void Assembler::adds(Register rd, const Operand& operand) { 2471 VIXL_ASSERT(AllowAssembler()); 2472 CheckIT(al); 2473 if (operand.IsImmediate()) { 2474 uint32_t imm = operand.GetImmediate(); 2475 if (IsUsingT32()) { 2476 // ADDS{<q>} <Rdn>, #<imm8> ; T2 2477 if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) { 2478 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2479 AdvanceIT(); 2480 return; 2481 } 2482 } 2483 } 2484 Delegate(kAdds, &Assembler::adds, rd, operand); 2485 } 2486 2487 void Assembler::addw(Condition cond, 2488 Register rd, 2489 Register rn, 2490 const Operand& operand) { 2491 VIXL_ASSERT(AllowAssembler()); 2492 CheckIT(cond); 2493 if (operand.IsImmediate()) { 2494 uint32_t imm = operand.GetImmediate(); 2495 if (IsUsingT32()) { 2496 // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3 2497 if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2498 EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2499 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2500 AdvanceIT(); 2501 return; 2502 } 2503 // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 2504 if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 2505 (!rd.IsPC() || AllowUnpredictable())) { 2506 EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2507 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2508 AdvanceIT(); 2509 return; 2510 } 2511 // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4 2512 if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2513 EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2514 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2515 AdvanceIT(); 2516 return; 2517 } 2518 } 2519 } 2520 Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand); 2521 } 2522 2523 void Assembler::adr(Condition cond, 2524 EncodingSize size, 2525 Register rd, 2526 Location* location) { 2527 VIXL_ASSERT(AllowAssembler()); 2528 CheckIT(cond); 2529 Location::Offset offset = 2530 location->IsBound() 2531 ? location->GetLocation() - 2532 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 2533 : 0; 2534 if (IsUsingT32()) { 2535 int32_t neg_offset = -offset; 2536 // ADR{<c>}{<q>} <Rd>, <label> ; T1 2537 if (!size.IsWide() && rd.IsLow() && 2538 ((location->IsBound() && (offset >= 0) && (offset <= 1020) && 2539 ((offset & 0x3) == 0)) || 2540 (!location->IsBound() && size.IsNarrow()))) { 2541 static class EmitOp : public Location::EmitOperator { 2542 public: 2543 EmitOp() : Location::EmitOperator(T32) {} 2544 virtual uint32_t Encode(uint32_t instr, 2545 Location::Offset pc, 2546 const Location* location) const VIXL_OVERRIDE { 2547 pc += kT32PcDelta; 2548 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 2549 VIXL_ASSERT((offset >= 0) && (offset <= 1020) && 2550 ((offset & 0x3) == 0)); 2551 const int32_t target = offset >> 2; 2552 return instr | (target & 0xff); 2553 } 2554 } immop; 2555 EmitT32_16( 2556 Link(0xa000 | (rd.GetCode() << 8), location, immop, &kT16DataInfo)); 2557 AdvanceIT(); 2558 return; 2559 } 2560 // ADR{<c>}{<q>} <Rd>, <label> ; T2 2561 if (!size.IsNarrow() && location->IsBound() && (neg_offset > 0) && 2562 (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2563 EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) | 2564 ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15)); 2565 AdvanceIT(); 2566 return; 2567 } 2568 // ADR{<c>}{<q>} <Rd>, <label> ; T3 2569 if (!size.IsNarrow() && 2570 (!location->IsBound() || ((offset >= 0) && (offset <= 4095))) && 2571 (!rd.IsPC() || AllowUnpredictable())) { 2572 static class EmitOp : public Location::EmitOperator { 2573 public: 2574 EmitOp() : Location::EmitOperator(T32) {} 2575 virtual uint32_t Encode(uint32_t instr, 2576 Location::Offset pc, 2577 const Location* location) const VIXL_OVERRIDE { 2578 pc += kT32PcDelta; 2579 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 2580 int32_t target; 2581 if ((offset >= 0) && (offset <= 4095)) { 2582 target = offset; 2583 } else { 2584 target = -offset; 2585 VIXL_ASSERT((target >= 0) && (target <= 4095)); 2586 // Emit the T2 encoding. 2587 instr |= 0x00a00000; 2588 } 2589 return instr | (target & 0xff) | ((target & 0x700) << 4) | 2590 ((target & 0x800) << 15); 2591 } 2592 } immop; 2593 EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8), 2594 location, 2595 immop, 2596 &kT32FarDataInfo)); 2597 AdvanceIT(); 2598 return; 2599 } 2600 } else { 2601 ImmediateA32 positive_immediate_a32(offset); 2602 ImmediateA32 negative_immediate_a32(-offset); 2603 // ADR{<c>}{<q>} <Rd>, <label> ; A1 2604 if ((!location->IsBound() || positive_immediate_a32.IsValid()) && 2605 cond.IsNotNever()) { 2606 static class EmitOp : public Location::EmitOperator { 2607 public: 2608 EmitOp() : Location::EmitOperator(A32) {} 2609 virtual uint32_t Encode(uint32_t instr, 2610 Location::Offset pc, 2611 const Location* location) const VIXL_OVERRIDE { 2612 pc += kA32PcDelta; 2613 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 2614 int32_t target; 2615 ImmediateA32 positive_immediate_a32(offset); 2616 if (positive_immediate_a32.IsValid()) { 2617 target = positive_immediate_a32.GetEncodingValue(); 2618 } else { 2619 ImmediateA32 negative_immediate_a32(-offset); 2620 VIXL_ASSERT(negative_immediate_a32.IsValid()); 2621 // Emit the A2 encoding. 2622 target = negative_immediate_a32.GetEncodingValue(); 2623 instr = (instr & ~0x00f00000) | 0x00400000; 2624 } 2625 return instr | (target & 0xfff); 2626 } 2627 } immop; 2628 EmitA32( 2629 Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12), 2630 location, 2631 immop, 2632 &kA32AdrInfo)); 2633 return; 2634 } 2635 // ADR{<c>}{<q>} <Rd>, <label> ; A2 2636 if (location->IsBound() && negative_immediate_a32.IsValid() && 2637 cond.IsNotNever()) { 2638 EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 2639 negative_immediate_a32.GetEncodingValue()); 2640 return; 2641 } 2642 } 2643 Delegate(kAdr, &Assembler::adr, cond, size, rd, location); 2644 } 2645 2646 bool Assembler::adr_info(Condition cond, 2647 EncodingSize size, 2648 Register rd, 2649 Location* location, 2650 const struct ReferenceInfo** info) { 2651 VIXL_ASSERT(!location->IsBound()); 2652 USE(location); 2653 if (IsUsingT32()) { 2654 // ADR{<c>}{<q>} <Rd>, <label> ; T1 2655 if (!size.IsWide() && rd.IsLow() && size.IsNarrow()) { 2656 *info = &kT16DataInfo; 2657 return true; 2658 } 2659 // Skipped T2, as it is a negative offset variant. 2660 // The minimum offset is included in the corresponding 2661 // positive variant. 2662 // ADR{<c>}{<q>} <Rd>, <label> ; T3 2663 if (!size.IsNarrow()) { 2664 *info = &kT32FarDataInfo; 2665 return true; 2666 } 2667 } else { 2668 // ADR{<c>}{<q>} <Rd>, <label> ; A1 2669 if (cond.IsNotNever()) { 2670 *info = &kA32AdrInfo; 2671 return true; 2672 } 2673 // Skipped A2, as it is a negative offset variant. 2674 // The minimum offset is included in the corresponding 2675 // positive variant. 2676 } 2677 return false; 2678 } 2679 2680 void Assembler::and_(Condition cond, 2681 EncodingSize size, 2682 Register rd, 2683 Register rn, 2684 const Operand& operand) { 2685 VIXL_ASSERT(AllowAssembler()); 2686 CheckIT(cond); 2687 if (operand.IsImmediate()) { 2688 uint32_t imm = operand.GetImmediate(); 2689 if (IsUsingT32()) { 2690 ImmediateT32 immediate_t32(imm); 2691 // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 2692 if (!size.IsNarrow() && immediate_t32.IsValid() && 2693 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 2694 EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2695 (immediate_t32.GetEncodingValue() & 0xff) | 2696 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2697 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2698 AdvanceIT(); 2699 return; 2700 } 2701 } else { 2702 ImmediateA32 immediate_a32(imm); 2703 // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2704 if (immediate_a32.IsValid() && cond.IsNotNever()) { 2705 EmitA32(0x02000000U | (cond.GetCondition() << 28) | 2706 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2707 immediate_a32.GetEncodingValue()); 2708 return; 2709 } 2710 } 2711 } 2712 if (operand.IsImmediateShiftedRegister()) { 2713 Register rm = operand.GetBaseRegister(); 2714 if (operand.IsPlainRegister()) { 2715 if (IsUsingT32()) { 2716 // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 2717 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2718 rm.IsLow()) { 2719 EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3)); 2720 AdvanceIT(); 2721 return; 2722 } 2723 } 2724 } 2725 Shift shift = operand.GetShift(); 2726 uint32_t amount = operand.GetShiftAmount(); 2727 if (IsUsingT32()) { 2728 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 2729 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 2730 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2731 uint32_t amount_ = amount % 32; 2732 EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2733 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2734 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2735 AdvanceIT(); 2736 return; 2737 } 2738 } else { 2739 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2740 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 2741 uint32_t amount_ = amount % 32; 2742 EmitA32(0x00000000U | (cond.GetCondition() << 28) | 2743 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2744 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2745 return; 2746 } 2747 } 2748 } 2749 if (operand.IsRegisterShiftedRegister()) { 2750 Register rm = operand.GetBaseRegister(); 2751 Shift shift = operand.GetShift(); 2752 Register rs = operand.GetShiftRegister(); 2753 if (IsUsingA32()) { 2754 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2755 if (cond.IsNotNever() && 2756 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2757 AllowUnpredictable())) { 2758 EmitA32(0x00000010U | (cond.GetCondition() << 28) | 2759 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2760 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2761 return; 2762 } 2763 } 2764 } 2765 Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand); 2766 } 2767 2768 void Assembler::ands(Condition cond, 2769 EncodingSize size, 2770 Register rd, 2771 Register rn, 2772 const Operand& operand) { 2773 VIXL_ASSERT(AllowAssembler()); 2774 CheckIT(cond); 2775 if (operand.IsImmediate()) { 2776 uint32_t imm = operand.GetImmediate(); 2777 if (IsUsingT32()) { 2778 ImmediateT32 immediate_t32(imm); 2779 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 2780 if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) && 2781 (!rn.IsPC() || AllowUnpredictable())) { 2782 EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2783 (immediate_t32.GetEncodingValue() & 0xff) | 2784 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2785 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2786 AdvanceIT(); 2787 return; 2788 } 2789 } else { 2790 ImmediateA32 immediate_a32(imm); 2791 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2792 if (immediate_a32.IsValid() && cond.IsNotNever()) { 2793 EmitA32(0x02100000U | (cond.GetCondition() << 28) | 2794 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2795 immediate_a32.GetEncodingValue()); 2796 return; 2797 } 2798 } 2799 } 2800 if (operand.IsImmediateShiftedRegister()) { 2801 Register rm = operand.GetBaseRegister(); 2802 if (operand.IsPlainRegister()) { 2803 if (IsUsingT32()) { 2804 // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 2805 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2806 rm.IsLow()) { 2807 EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3)); 2808 AdvanceIT(); 2809 return; 2810 } 2811 } 2812 } 2813 Shift shift = operand.GetShift(); 2814 uint32_t amount = operand.GetShiftAmount(); 2815 if (IsUsingT32()) { 2816 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 2817 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) && 2818 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2819 uint32_t amount_ = amount % 32; 2820 EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2821 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2822 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2823 AdvanceIT(); 2824 return; 2825 } 2826 } else { 2827 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2828 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 2829 uint32_t amount_ = amount % 32; 2830 EmitA32(0x00100000U | (cond.GetCondition() << 28) | 2831 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2832 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2833 return; 2834 } 2835 } 2836 } 2837 if (operand.IsRegisterShiftedRegister()) { 2838 Register rm = operand.GetBaseRegister(); 2839 Shift shift = operand.GetShift(); 2840 Register rs = operand.GetShiftRegister(); 2841 if (IsUsingA32()) { 2842 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2843 if (cond.IsNotNever() && 2844 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 2845 AllowUnpredictable())) { 2846 EmitA32(0x00100010U | (cond.GetCondition() << 28) | 2847 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2848 (shift.GetType() << 5) | (rs.GetCode() << 8)); 2849 return; 2850 } 2851 } 2852 } 2853 Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand); 2854 } 2855 2856 void Assembler::asr(Condition cond, 2857 EncodingSize size, 2858 Register rd, 2859 Register rm, 2860 const Operand& operand) { 2861 VIXL_ASSERT(AllowAssembler()); 2862 CheckIT(cond); 2863 if (operand.IsImmediate()) { 2864 uint32_t imm = operand.GetImmediate(); 2865 if (IsUsingT32()) { 2866 // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 2867 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 2868 (imm >= 1) && (imm <= 32)) { 2869 uint32_t amount_ = imm % 32; 2870 EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) | 2871 (amount_ << 6)); 2872 AdvanceIT(); 2873 return; 2874 } 2875 // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 2876 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) && 2877 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2878 uint32_t amount_ = imm % 32; 2879 EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() | 2880 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2881 AdvanceIT(); 2882 return; 2883 } 2884 } else { 2885 // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 2886 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 2887 uint32_t amount_ = imm % 32; 2888 EmitA32(0x01a00040U | (cond.GetCondition() << 28) | 2889 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 2890 return; 2891 } 2892 } 2893 } 2894 if (operand.IsPlainRegister()) { 2895 Register rs = operand.GetBaseRegister(); 2896 if (IsUsingT32()) { 2897 // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 2898 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 2899 rs.IsLow()) { 2900 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 2901 AdvanceIT(); 2902 return; 2903 } 2904 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 2905 if (!size.IsNarrow() && 2906 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 2907 EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 2908 rs.GetCode()); 2909 AdvanceIT(); 2910 return; 2911 } 2912 } else { 2913 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 2914 if (cond.IsNotNever() && 2915 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 2916 EmitA32(0x01a00050U | (cond.GetCondition() << 28) | 2917 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 2918 return; 2919 } 2920 } 2921 } 2922 Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand); 2923 } 2924 2925 void Assembler::asrs(Condition cond, 2926 EncodingSize size, 2927 Register rd, 2928 Register rm, 2929 const Operand& operand) { 2930 VIXL_ASSERT(AllowAssembler()); 2931 CheckIT(cond); 2932 if (operand.IsImmediate()) { 2933 uint32_t imm = operand.GetImmediate(); 2934 if (IsUsingT32()) { 2935 // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 2936 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 2937 (imm >= 1) && (imm <= 32)) { 2938 uint32_t amount_ = imm % 32; 2939 EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) | 2940 (amount_ << 6)); 2941 AdvanceIT(); 2942 return; 2943 } 2944 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 2945 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) && 2946 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2947 uint32_t amount_ = imm % 32; 2948 EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() | 2949 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2950 AdvanceIT(); 2951 return; 2952 } 2953 } else { 2954 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 2955 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 2956 uint32_t amount_ = imm % 32; 2957 EmitA32(0x01b00040U | (cond.GetCondition() << 28) | 2958 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 2959 return; 2960 } 2961 } 2962 } 2963 if (operand.IsPlainRegister()) { 2964 Register rs = operand.GetBaseRegister(); 2965 if (IsUsingT32()) { 2966 // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 2967 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 2968 rs.IsLow()) { 2969 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 2970 AdvanceIT(); 2971 return; 2972 } 2973 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 2974 if (!size.IsNarrow() && 2975 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 2976 EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 2977 rs.GetCode()); 2978 AdvanceIT(); 2979 return; 2980 } 2981 } else { 2982 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 2983 if (cond.IsNotNever() && 2984 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 2985 EmitA32(0x01b00050U | (cond.GetCondition() << 28) | 2986 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 2987 return; 2988 } 2989 } 2990 } 2991 Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand); 2992 } 2993 2994 void Assembler::b(Condition cond, EncodingSize size, Location* location) { 2995 VIXL_ASSERT(AllowAssembler()); 2996 Location::Offset offset = 2997 location->IsBound() 2998 ? location->GetLocation() - 2999 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3000 : 0; 3001 if (IsUsingT32()) { 3002 // B<c>{<q>} <label> ; T1 3003 if (OutsideITBlock() && !size.IsWide() && 3004 ((location->IsBound() && (offset >= -256) && (offset <= 254) && 3005 ((offset & 0x1) == 0)) || 3006 (!location->IsBound() && size.IsNarrow())) && 3007 !cond.Is(al) && cond.IsNotNever()) { 3008 static class EmitOp : public Location::EmitOperator { 3009 public: 3010 EmitOp() : Location::EmitOperator(T32) {} 3011 virtual uint32_t Encode(uint32_t instr, 3012 Location::Offset pc, 3013 const Location* location) const VIXL_OVERRIDE { 3014 pc += kT32PcDelta; 3015 Location::Offset offset = location->GetLocation() - pc; 3016 VIXL_ASSERT((offset >= -256) && (offset <= 254) && 3017 ((offset & 0x1) == 0)); 3018 const int32_t target = offset >> 1; 3019 return instr | (target & 0xff); 3020 } 3021 } immop; 3022 EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8), 3023 location, 3024 immop, 3025 &kT16ConditionalBranchInfo)); 3026 AdvanceIT(); 3027 return; 3028 } 3029 // B{<c>}{<q>} <label> ; T2 3030 if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && 3031 ((location->IsBound() && (offset >= -2048) && (offset <= 2046) && 3032 ((offset & 0x1) == 0)) || 3033 (!location->IsBound() && size.IsNarrow()))) { 3034 CheckIT(cond); 3035 static class EmitOp : public Location::EmitOperator { 3036 public: 3037 EmitOp() : Location::EmitOperator(T32) {} 3038 virtual uint32_t Encode(uint32_t instr, 3039 Location::Offset pc, 3040 const Location* location) const VIXL_OVERRIDE { 3041 pc += kT32PcDelta; 3042 Location::Offset offset = location->GetLocation() - pc; 3043 VIXL_ASSERT((offset >= -2048) && (offset <= 2046) && 3044 ((offset & 0x1) == 0)); 3045 const int32_t target = offset >> 1; 3046 return instr | (target & 0x7ff); 3047 } 3048 } immop; 3049 EmitT32_16(Link(0xe000, location, immop, &kT16BranchInfo)); 3050 AdvanceIT(); 3051 return; 3052 } 3053 // B<c>{<q>} <label> ; T3 3054 if (OutsideITBlock() && !size.IsNarrow() && 3055 ((location->IsBound() && (offset >= -1048576) && (offset <= 1048574) && 3056 ((offset & 0x1) == 0)) || 3057 !location->IsBound()) && 3058 !cond.Is(al) && cond.IsNotNever()) { 3059 static class EmitOp : public Location::EmitOperator { 3060 public: 3061 EmitOp() : Location::EmitOperator(T32) {} 3062 virtual uint32_t Encode(uint32_t instr, 3063 Location::Offset pc, 3064 const Location* location) const VIXL_OVERRIDE { 3065 pc += kT32PcDelta; 3066 Location::Offset offset = location->GetLocation() - pc; 3067 VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) && 3068 ((offset & 0x1) == 0)); 3069 const int32_t target = offset >> 1; 3070 return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) | 3071 ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) | 3072 ((target & 0x80000) << 7); 3073 } 3074 } immop; 3075 EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22), 3076 location, 3077 immop, 3078 &kT32ConditionalBranchInfo)); 3079 AdvanceIT(); 3080 return; 3081 } 3082 // B{<c>}{<q>} <label> ; T4 3083 if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() && 3084 ((location->IsBound() && (offset >= -16777216) && 3085 (offset <= 16777214) && ((offset & 0x1) == 0)) || 3086 !location->IsBound())) { 3087 CheckIT(cond); 3088 static class EmitOp : public Location::EmitOperator { 3089 public: 3090 EmitOp() : Location::EmitOperator(T32) {} 3091 virtual uint32_t Encode(uint32_t instr, 3092 Location::Offset pc, 3093 const Location* location) const VIXL_OVERRIDE { 3094 pc += kT32PcDelta; 3095 Location::Offset offset = location->GetLocation() - pc; 3096 VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) && 3097 ((offset & 0x1) == 0)); 3098 int32_t target = offset >> 1; 3099 uint32_t S = target & (1 << 23); 3100 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21); 3101 return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) | 3102 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) | 3103 ((target & 0x800000) << 3); 3104 } 3105 } immop; 3106 EmitT32_32(Link(0xf0009000U, location, immop, &kT32BranchInfo)); 3107 AdvanceIT(); 3108 return; 3109 } 3110 } else { 3111 // B{<c>}{<q>} <label> ; A1 3112 if (((location->IsBound() && (offset >= -33554432) && 3113 (offset <= 33554428) && ((offset & 0x3) == 0)) || 3114 !location->IsBound()) && 3115 cond.IsNotNever()) { 3116 static class EmitOp : public Location::EmitOperator { 3117 public: 3118 EmitOp() : Location::EmitOperator(A32) {} 3119 virtual uint32_t Encode(uint32_t instr, 3120 Location::Offset pc, 3121 const Location* location) const VIXL_OVERRIDE { 3122 pc += kA32PcDelta; 3123 Location::Offset offset = location->GetLocation() - pc; 3124 VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) && 3125 ((offset & 0x3) == 0)); 3126 const int32_t target = offset >> 2; 3127 return instr | (target & 0xffffff); 3128 } 3129 } immop; 3130 EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28), 3131 location, 3132 immop, 3133 &kA32BranchInfo)); 3134 return; 3135 } 3136 } 3137 Delegate(kB, &Assembler::b, cond, size, location); 3138 } 3139 3140 bool Assembler::b_info(Condition cond, 3141 EncodingSize size, 3142 Location* location, 3143 const struct ReferenceInfo** info) { 3144 VIXL_ASSERT(!location->IsBound()); 3145 USE(location); 3146 if (IsUsingT32()) { 3147 // B<c>{<q>} <label> ; T1 3148 if (OutsideITBlock() && !size.IsWide() && size.IsNarrow() && !cond.Is(al) && 3149 cond.IsNotNever()) { 3150 *info = &kT16ConditionalBranchInfo; 3151 return true; 3152 } 3153 // B{<c>}{<q>} <label> ; T2 3154 if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && size.IsNarrow()) { 3155 *info = &kT16BranchInfo; 3156 return true; 3157 } 3158 // B<c>{<q>} <label> ; T3 3159 if (OutsideITBlock() && !size.IsNarrow() && !cond.Is(al) && 3160 cond.IsNotNever()) { 3161 *info = &kT32ConditionalBranchInfo; 3162 return true; 3163 } 3164 // B{<c>}{<q>} <label> ; T4 3165 if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow()) { 3166 *info = &kT32BranchInfo; 3167 return true; 3168 } 3169 } else { 3170 // B{<c>}{<q>} <label> ; A1 3171 if (cond.IsNotNever()) { 3172 *info = &kA32BranchInfo; 3173 return true; 3174 } 3175 } 3176 return false; 3177 } 3178 3179 void Assembler::bfc(Condition cond, Register rd, uint32_t lsb, uint32_t width) { 3180 VIXL_ASSERT(AllowAssembler()); 3181 CheckIT(cond); 3182 if (IsUsingT32()) { 3183 // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1 3184 if ((lsb <= 31) && (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) || 3185 AllowUnpredictable())) { 3186 uint32_t msb = lsb + width - 1; 3187 EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) | 3188 ((lsb & 0x1c) << 10) | msb); 3189 AdvanceIT(); 3190 return; 3191 } 3192 } else { 3193 // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1 3194 if ((lsb <= 31) && cond.IsNotNever() && 3195 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) || 3196 AllowUnpredictable())) { 3197 uint32_t msb = lsb + width - 1; 3198 EmitA32(0x07c0001fU | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3199 (lsb << 7) | (msb << 16)); 3200 return; 3201 } 3202 } 3203 Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, width); 3204 } 3205 3206 void Assembler::bfi( 3207 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) { 3208 VIXL_ASSERT(AllowAssembler()); 3209 CheckIT(cond); 3210 if (IsUsingT32()) { 3211 // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 3212 if ((lsb <= 31) && !rn.Is(pc) && 3213 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) || 3214 AllowUnpredictable())) { 3215 uint32_t msb = lsb + width - 1; 3216 EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3217 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb); 3218 AdvanceIT(); 3219 return; 3220 } 3221 } else { 3222 // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 3223 if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) && 3224 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) || 3225 AllowUnpredictable())) { 3226 uint32_t msb = lsb + width - 1; 3227 EmitA32(0x07c00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3228 rn.GetCode() | (lsb << 7) | (msb << 16)); 3229 return; 3230 } 3231 } 3232 Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, width); 3233 } 3234 3235 void Assembler::bic(Condition cond, 3236 EncodingSize size, 3237 Register rd, 3238 Register rn, 3239 const Operand& operand) { 3240 VIXL_ASSERT(AllowAssembler()); 3241 CheckIT(cond); 3242 if (operand.IsImmediate()) { 3243 uint32_t imm = operand.GetImmediate(); 3244 if (IsUsingT32()) { 3245 ImmediateT32 immediate_t32(imm); 3246 // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 3247 if (!size.IsNarrow() && immediate_t32.IsValid() && 3248 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 3249 EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3250 (immediate_t32.GetEncodingValue() & 0xff) | 3251 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3252 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3253 AdvanceIT(); 3254 return; 3255 } 3256 } else { 3257 ImmediateA32 immediate_a32(imm); 3258 // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 3259 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3260 EmitA32(0x03c00000U | (cond.GetCondition() << 28) | 3261 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 3262 immediate_a32.GetEncodingValue()); 3263 return; 3264 } 3265 } 3266 } 3267 if (operand.IsImmediateShiftedRegister()) { 3268 Register rm = operand.GetBaseRegister(); 3269 if (operand.IsPlainRegister()) { 3270 if (IsUsingT32()) { 3271 // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 3272 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 3273 rm.IsLow()) { 3274 EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3)); 3275 AdvanceIT(); 3276 return; 3277 } 3278 } 3279 } 3280 Shift shift = operand.GetShift(); 3281 uint32_t amount = operand.GetShiftAmount(); 3282 if (IsUsingT32()) { 3283 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 3284 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 3285 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3286 uint32_t amount_ = amount % 32; 3287 EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3288 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 3289 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3290 AdvanceIT(); 3291 return; 3292 } 3293 } else { 3294 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 3295 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3296 uint32_t amount_ = amount % 32; 3297 EmitA32(0x01c00000U | (cond.GetCondition() << 28) | 3298 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3299 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3300 return; 3301 } 3302 } 3303 } 3304 if (operand.IsRegisterShiftedRegister()) { 3305 Register rm = operand.GetBaseRegister(); 3306 Shift shift = operand.GetShift(); 3307 Register rs = operand.GetShiftRegister(); 3308 if (IsUsingA32()) { 3309 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 3310 if (cond.IsNotNever() && 3311 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 3312 AllowUnpredictable())) { 3313 EmitA32(0x01c00010U | (cond.GetCondition() << 28) | 3314 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3315 (shift.GetType() << 5) | (rs.GetCode() << 8)); 3316 return; 3317 } 3318 } 3319 } 3320 Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand); 3321 } 3322 3323 void Assembler::bics(Condition cond, 3324 EncodingSize size, 3325 Register rd, 3326 Register rn, 3327 const Operand& operand) { 3328 VIXL_ASSERT(AllowAssembler()); 3329 CheckIT(cond); 3330 if (operand.IsImmediate()) { 3331 uint32_t imm = operand.GetImmediate(); 3332 if (IsUsingT32()) { 3333 ImmediateT32 immediate_t32(imm); 3334 // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 3335 if (!size.IsNarrow() && immediate_t32.IsValid() && 3336 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 3337 EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3338 (immediate_t32.GetEncodingValue() & 0xff) | 3339 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3340 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3341 AdvanceIT(); 3342 return; 3343 } 3344 } else { 3345 ImmediateA32 immediate_a32(imm); 3346 // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 3347 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3348 EmitA32(0x03d00000U | (cond.GetCondition() << 28) | 3349 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 3350 immediate_a32.GetEncodingValue()); 3351 return; 3352 } 3353 } 3354 } 3355 if (operand.IsImmediateShiftedRegister()) { 3356 Register rm = operand.GetBaseRegister(); 3357 if (operand.IsPlainRegister()) { 3358 if (IsUsingT32()) { 3359 // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 3360 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 3361 rm.IsLow()) { 3362 EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3)); 3363 AdvanceIT(); 3364 return; 3365 } 3366 } 3367 } 3368 Shift shift = operand.GetShift(); 3369 uint32_t amount = operand.GetShiftAmount(); 3370 if (IsUsingT32()) { 3371 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 3372 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 3373 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3374 uint32_t amount_ = amount % 32; 3375 EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3376 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 3377 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3378 AdvanceIT(); 3379 return; 3380 } 3381 } else { 3382 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 3383 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3384 uint32_t amount_ = amount % 32; 3385 EmitA32(0x01d00000U | (cond.GetCondition() << 28) | 3386 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3387 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3388 return; 3389 } 3390 } 3391 } 3392 if (operand.IsRegisterShiftedRegister()) { 3393 Register rm = operand.GetBaseRegister(); 3394 Shift shift = operand.GetShift(); 3395 Register rs = operand.GetShiftRegister(); 3396 if (IsUsingA32()) { 3397 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 3398 if (cond.IsNotNever() && 3399 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 3400 AllowUnpredictable())) { 3401 EmitA32(0x01d00010U | (cond.GetCondition() << 28) | 3402 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3403 (shift.GetType() << 5) | (rs.GetCode() << 8)); 3404 return; 3405 } 3406 } 3407 } 3408 Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand); 3409 } 3410 3411 void Assembler::bkpt(Condition cond, uint32_t imm) { 3412 VIXL_ASSERT(AllowAssembler()); 3413 CheckIT(cond); 3414 if (IsUsingT32()) { 3415 // BKPT{<q>} {#}<imm> ; T1 3416 if ((imm <= 255)) { 3417 EmitT32_16(0xbe00 | imm); 3418 AdvanceIT(); 3419 return; 3420 } 3421 } else { 3422 // BKPT{<q>} {#}<imm> ; A1 3423 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 3424 EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) | 3425 ((imm & 0xfff0) << 4)); 3426 return; 3427 } 3428 } 3429 Delegate(kBkpt, &Assembler::bkpt, cond, imm); 3430 } 3431 3432 void Assembler::bl(Condition cond, Location* location) { 3433 VIXL_ASSERT(AllowAssembler()); 3434 CheckIT(cond); 3435 Location::Offset offset = 3436 location->IsBound() 3437 ? location->GetLocation() - 3438 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3439 : 0; 3440 if (IsUsingT32()) { 3441 // BL{<c>}{<q>} <label> ; T1 3442 if (((location->IsBound() && (offset >= -16777216) && 3443 (offset <= 16777214) && ((offset & 0x1) == 0)) || 3444 !location->IsBound()) && 3445 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) { 3446 static class EmitOp : public Location::EmitOperator { 3447 public: 3448 EmitOp() : Location::EmitOperator(T32) {} 3449 virtual uint32_t Encode(uint32_t instr, 3450 Location::Offset pc, 3451 const Location* location) const VIXL_OVERRIDE { 3452 pc += kT32PcDelta; 3453 Location::Offset offset = location->GetLocation() - pc; 3454 VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) && 3455 ((offset & 0x1) == 0)); 3456 int32_t target = offset >> 1; 3457 uint32_t S = target & (1 << 23); 3458 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21); 3459 return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) | 3460 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) | 3461 ((target & 0x800000) << 3); 3462 } 3463 } immop; 3464 EmitT32_32(Link(0xf000d000U, location, immop, &kT32BranchInfo)); 3465 AdvanceIT(); 3466 return; 3467 } 3468 } else { 3469 // BL{<c>}{<q>} <label> ; A1 3470 if (((location->IsBound() && (offset >= -33554432) && 3471 (offset <= 33554428) && ((offset & 0x3) == 0)) || 3472 !location->IsBound()) && 3473 cond.IsNotNever()) { 3474 static class EmitOp : public Location::EmitOperator { 3475 public: 3476 EmitOp() : Location::EmitOperator(A32) {} 3477 virtual uint32_t Encode(uint32_t instr, 3478 Location::Offset pc, 3479 const Location* location) const VIXL_OVERRIDE { 3480 pc += kA32PcDelta; 3481 Location::Offset offset = location->GetLocation() - pc; 3482 VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) && 3483 ((offset & 0x3) == 0)); 3484 const int32_t target = offset >> 2; 3485 return instr | (target & 0xffffff); 3486 } 3487 } immop; 3488 EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28), 3489 location, 3490 immop, 3491 &kA32BranchInfo)); 3492 return; 3493 } 3494 } 3495 Delegate(kBl, &Assembler::bl, cond, location); 3496 } 3497 3498 bool Assembler::bl_info(Condition cond, 3499 Location* location, 3500 const struct ReferenceInfo** info) { 3501 VIXL_ASSERT(!location->IsBound()); 3502 USE(location); 3503 if (IsUsingT32()) { 3504 // BL{<c>}{<q>} <label> ; T1 3505 if (true) { 3506 *info = &kT32BranchInfo; 3507 return true; 3508 } 3509 } else { 3510 // BL{<c>}{<q>} <label> ; A1 3511 if (cond.IsNotNever()) { 3512 *info = &kA32BranchInfo; 3513 return true; 3514 } 3515 } 3516 return false; 3517 } 3518 3519 void Assembler::blx(Condition cond, Location* location) { 3520 VIXL_ASSERT(AllowAssembler()); 3521 CheckIT(cond); 3522 Location::Offset offset = 3523 location->IsBound() 3524 ? location->GetLocation() - 3525 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 3526 : 0; 3527 if (IsUsingT32()) { 3528 // BLX{<c>}{<q>} <label> ; T2 3529 if (((location->IsBound() && (offset >= -16777216) && 3530 (offset <= 16777212) && ((offset & 0x3) == 0)) || 3531 !location->IsBound()) && 3532 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) { 3533 static class EmitOp : public Location::EmitOperator { 3534 public: 3535 EmitOp() : Location::EmitOperator(T32) {} 3536 virtual uint32_t Encode(uint32_t instr, 3537 Location::Offset pc, 3538 const Location* location) const VIXL_OVERRIDE { 3539 pc += kT32PcDelta; 3540 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 3541 VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) && 3542 ((offset & 0x3) == 0)); 3543 int32_t target = offset >> 2; 3544 uint32_t S = target & (1 << 22); 3545 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20); 3546 return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) | 3547 ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) | 3548 ((target & 0x400000) << 4); 3549 } 3550 } immop; 3551 EmitT32_32(Link(0xf000c000U, location, immop, &kT32BlxInfo)); 3552 AdvanceIT(); 3553 return; 3554 } 3555 } else { 3556 // BLX{<c>}{<q>} <label> ; A2 3557 if (((location->IsBound() && (offset >= -33554432) && 3558 (offset <= 33554430) && ((offset & 0x1) == 0)) || 3559 !location->IsBound())) { 3560 if (cond.Is(al) || AllowStronglyDiscouraged()) { 3561 static class EmitOp : public Location::EmitOperator { 3562 public: 3563 EmitOp() : Location::EmitOperator(A32) {} 3564 virtual uint32_t Encode(uint32_t instr, 3565 Location::Offset pc, 3566 const Location* location) const 3567 VIXL_OVERRIDE { 3568 pc += kA32PcDelta; 3569 Location::Offset offset = 3570 location->GetLocation() - AlignDown(pc, 4); 3571 VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) && 3572 ((offset & 0x1) == 0)); 3573 const int32_t target = offset >> 1; 3574 return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1); 3575 } 3576 } immop; 3577 EmitA32(Link(0xfa000000U, location, immop, &kA32BlxInfo)); 3578 return; 3579 } 3580 } 3581 } 3582 Delegate(kBlx, &Assembler::blx, cond, location); 3583 } 3584 3585 bool Assembler::blx_info(Condition cond, 3586 Location* location, 3587 const struct ReferenceInfo** info) { 3588 VIXL_ASSERT(!location->IsBound()); 3589 USE(location); 3590 USE(cond); 3591 if (IsUsingT32()) { 3592 // BLX{<c>}{<q>} <label> ; T2 3593 if (true) { 3594 *info = &kT32BlxInfo; 3595 return true; 3596 } 3597 } else { 3598 // BLX{<c>}{<q>} <label> ; A2 3599 if (true) { 3600 *info = &kA32BlxInfo; 3601 return true; 3602 } 3603 } 3604 return false; 3605 } 3606 3607 void Assembler::blx(Condition cond, Register rm) { 3608 VIXL_ASSERT(AllowAssembler()); 3609 CheckIT(cond); 3610 if (IsUsingT32()) { 3611 // BLX{<c>}{<q>} <Rm> ; T1 3612 if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) || 3613 AllowUnpredictable())) { 3614 EmitT32_16(0x4780 | (rm.GetCode() << 3)); 3615 AdvanceIT(); 3616 return; 3617 } 3618 } else { 3619 // BLX{<c>}{<q>} <Rm> ; A1 3620 if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) { 3621 EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode()); 3622 return; 3623 } 3624 } 3625 Delegate(kBlx, &Assembler::blx, cond, rm); 3626 } 3627 3628 void Assembler::bx(Condition cond, Register rm) { 3629 VIXL_ASSERT(AllowAssembler()); 3630 CheckIT(cond); 3631 if (IsUsingT32()) { 3632 // BX{<c>}{<q>} <Rm> ; T1 3633 if ((OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) { 3634 EmitT32_16(0x4700 | (rm.GetCode() << 3)); 3635 AdvanceIT(); 3636 return; 3637 } 3638 } else { 3639 // BX{<c>}{<q>} <Rm> ; A1 3640 if (cond.IsNotNever()) { 3641 EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode()); 3642 return; 3643 } 3644 } 3645 Delegate(kBx, &Assembler::bx, cond, rm); 3646 } 3647 3648 void Assembler::bxj(Condition cond, Register rm) { 3649 VIXL_ASSERT(AllowAssembler()); 3650 CheckIT(cond); 3651 if (IsUsingT32()) { 3652 // BXJ{<c>}{<q>} <Rm> ; T1 3653 if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) || 3654 AllowUnpredictable())) { 3655 EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16)); 3656 AdvanceIT(); 3657 return; 3658 } 3659 } else { 3660 // BXJ{<c>}{<q>} <Rm> ; A1 3661 if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) { 3662 EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode()); 3663 return; 3664 } 3665 } 3666 Delegate(kBxj, &Assembler::bxj, cond, rm); 3667 } 3668 3669 void Assembler::cbnz(Register rn, Location* location) { 3670 VIXL_ASSERT(AllowAssembler()); 3671 CheckIT(al); 3672 Location::Offset offset = 3673 location->IsBound() 3674 ? location->GetLocation() - 3675 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3676 : 0; 3677 if (IsUsingT32()) { 3678 // CBNZ{<q>} <Rn>, <label> ; T1 3679 if (rn.IsLow() && ((location->IsBound() && (offset >= 0) && 3680 (offset <= 126) && ((offset & 0x1) == 0)) || 3681 !location->IsBound())) { 3682 static class EmitOp : public Location::EmitOperator { 3683 public: 3684 EmitOp() : Location::EmitOperator(T32) {} 3685 virtual uint32_t Encode(uint32_t instr, 3686 Location::Offset pc, 3687 const Location* location) const VIXL_OVERRIDE { 3688 pc += kT32PcDelta; 3689 Location::Offset offset = location->GetLocation() - pc; 3690 VIXL_ASSERT((offset >= 0) && (offset <= 126) && 3691 ((offset & 0x1) == 0)); 3692 const int32_t target = offset >> 1; 3693 return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4); 3694 } 3695 } immop; 3696 EmitT32_16(Link(0xb900 | rn.GetCode(), location, immop, &kT16CbzInfo)); 3697 AdvanceIT(); 3698 return; 3699 } 3700 } 3701 Delegate(kCbnz, &Assembler::cbnz, rn, location); 3702 } 3703 3704 bool Assembler::cbnz_info(Register rn, 3705 Location* location, 3706 const struct ReferenceInfo** info) { 3707 VIXL_ASSERT(!location->IsBound()); 3708 USE(location); 3709 if (IsUsingT32()) { 3710 // CBNZ{<q>} <Rn>, <label> ; T1 3711 if (rn.IsLow()) { 3712 *info = &kT16CbzInfo; 3713 return true; 3714 } 3715 } 3716 return false; 3717 } 3718 3719 void Assembler::cbz(Register rn, Location* location) { 3720 VIXL_ASSERT(AllowAssembler()); 3721 CheckIT(al); 3722 Location::Offset offset = 3723 location->IsBound() 3724 ? location->GetLocation() - 3725 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3726 : 0; 3727 if (IsUsingT32()) { 3728 // CBZ{<q>} <Rn>, <label> ; T1 3729 if (rn.IsLow() && ((location->IsBound() && (offset >= 0) && 3730 (offset <= 126) && ((offset & 0x1) == 0)) || 3731 !location->IsBound())) { 3732 static class EmitOp : public Location::EmitOperator { 3733 public: 3734 EmitOp() : Location::EmitOperator(T32) {} 3735 virtual uint32_t Encode(uint32_t instr, 3736 Location::Offset pc, 3737 const Location* location) const VIXL_OVERRIDE { 3738 pc += kT32PcDelta; 3739 Location::Offset offset = location->GetLocation() - pc; 3740 VIXL_ASSERT((offset >= 0) && (offset <= 126) && 3741 ((offset & 0x1) == 0)); 3742 const int32_t target = offset >> 1; 3743 return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4); 3744 } 3745 } immop; 3746 EmitT32_16(Link(0xb100 | rn.GetCode(), location, immop, &kT16CbzInfo)); 3747 AdvanceIT(); 3748 return; 3749 } 3750 } 3751 Delegate(kCbz, &Assembler::cbz, rn, location); 3752 } 3753 3754 bool Assembler::cbz_info(Register rn, 3755 Location* location, 3756 const struct ReferenceInfo** info) { 3757 VIXL_ASSERT(!location->IsBound()); 3758 USE(location); 3759 if (IsUsingT32()) { 3760 // CBZ{<q>} <Rn>, <label> ; T1 3761 if (rn.IsLow()) { 3762 *info = &kT16CbzInfo; 3763 return true; 3764 } 3765 } 3766 return false; 3767 } 3768 3769 void Assembler::clrex(Condition cond) { 3770 VIXL_ASSERT(AllowAssembler()); 3771 CheckIT(cond); 3772 if (IsUsingT32()) { 3773 // CLREX{<c>}{<q>} ; T1 3774 EmitT32_32(0xf3bf8f2fU); 3775 AdvanceIT(); 3776 return; 3777 } else { 3778 // CLREX{<c>}{<q>} ; A1 3779 if (cond.Is(al)) { 3780 EmitA32(0xf57ff01fU); 3781 return; 3782 } 3783 } 3784 Delegate(kClrex, &Assembler::clrex, cond); 3785 } 3786 3787 void Assembler::clz(Condition cond, Register rd, Register rm) { 3788 VIXL_ASSERT(AllowAssembler()); 3789 CheckIT(cond); 3790 if (IsUsingT32()) { 3791 // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1 3792 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3793 EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() | 3794 (rm.GetCode() << 16)); 3795 AdvanceIT(); 3796 return; 3797 } 3798 } else { 3799 // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1 3800 if (cond.IsNotNever() && 3801 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3802 EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3803 rm.GetCode()); 3804 return; 3805 } 3806 } 3807 Delegate(kClz, &Assembler::clz, cond, rd, rm); 3808 } 3809 3810 void Assembler::cmn(Condition cond, 3811 EncodingSize size, 3812 Register rn, 3813 const Operand& operand) { 3814 VIXL_ASSERT(AllowAssembler()); 3815 CheckIT(cond); 3816 if (operand.IsImmediate()) { 3817 uint32_t imm = operand.GetImmediate(); 3818 if (IsUsingT32()) { 3819 ImmediateT32 immediate_t32(imm); 3820 // CMN{<c>}{<q>} <Rn>, #<const> ; T1 3821 if (!size.IsNarrow() && immediate_t32.IsValid() && 3822 (!rn.IsPC() || AllowUnpredictable())) { 3823 EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) | 3824 (immediate_t32.GetEncodingValue() & 0xff) | 3825 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3826 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3827 AdvanceIT(); 3828 return; 3829 } 3830 } else { 3831 ImmediateA32 immediate_a32(imm); 3832 // CMN{<c>}{<q>} <Rn>, #<const> ; A1 3833 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3834 EmitA32(0x03700000U | (cond.GetCondition() << 28) | 3835 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 3836 return; 3837 } 3838 } 3839 } 3840 if (operand.IsImmediateShiftedRegister()) { 3841 Register rm = operand.GetBaseRegister(); 3842 if (operand.IsPlainRegister()) { 3843 if (IsUsingT32()) { 3844 // CMN{<c>}{<q>} <Rn>, <Rm> ; T1 3845 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 3846 EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3)); 3847 AdvanceIT(); 3848 return; 3849 } 3850 } 3851 } 3852 Shift shift = operand.GetShift(); 3853 uint32_t amount = operand.GetShiftAmount(); 3854 if (IsUsingT32()) { 3855 // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2 3856 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 3857 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3858 uint32_t amount_ = amount % 32; 3859 EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() | 3860 (operand.GetTypeEncodingValue() << 4) | 3861 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3862 AdvanceIT(); 3863 return; 3864 } 3865 } else { 3866 // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 3867 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3868 uint32_t amount_ = amount % 32; 3869 EmitA32(0x01700000U | (cond.GetCondition() << 28) | 3870 (rn.GetCode() << 16) | rm.GetCode() | 3871 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3872 return; 3873 } 3874 } 3875 } 3876 if (operand.IsRegisterShiftedRegister()) { 3877 Register rm = operand.GetBaseRegister(); 3878 Shift shift = operand.GetShift(); 3879 Register rs = operand.GetShiftRegister(); 3880 if (IsUsingA32()) { 3881 // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 3882 if (cond.IsNotNever() && 3883 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 3884 EmitA32(0x01700010U | (cond.GetCondition() << 28) | 3885 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 3886 (rs.GetCode() << 8)); 3887 return; 3888 } 3889 } 3890 } 3891 Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand); 3892 } 3893 3894 void Assembler::cmp(Condition cond, 3895 EncodingSize size, 3896 Register rn, 3897 const Operand& operand) { 3898 VIXL_ASSERT(AllowAssembler()); 3899 CheckIT(cond); 3900 if (operand.IsImmediate()) { 3901 uint32_t imm = operand.GetImmediate(); 3902 if (IsUsingT32()) { 3903 ImmediateT32 immediate_t32(imm); 3904 // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1 3905 if (!size.IsWide() && rn.IsLow() && (imm <= 255)) { 3906 EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm); 3907 AdvanceIT(); 3908 return; 3909 } 3910 // CMP{<c>}{<q>} <Rn>, #<const> ; T2 3911 if (!size.IsNarrow() && immediate_t32.IsValid() && 3912 (!rn.IsPC() || AllowUnpredictable())) { 3913 EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) | 3914 (immediate_t32.GetEncodingValue() & 0xff) | 3915 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3916 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3917 AdvanceIT(); 3918 return; 3919 } 3920 } else { 3921 ImmediateA32 immediate_a32(imm); 3922 // CMP{<c>}{<q>} <Rn>, #<const> ; A1 3923 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3924 EmitA32(0x03500000U | (cond.GetCondition() << 28) | 3925 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 3926 return; 3927 } 3928 } 3929 } 3930 if (operand.IsImmediateShiftedRegister()) { 3931 Register rm = operand.GetBaseRegister(); 3932 if (operand.IsPlainRegister()) { 3933 if (IsUsingT32()) { 3934 // CMP{<c>}{<q>} <Rn>, <Rm> ; T1 3935 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 3936 EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3)); 3937 AdvanceIT(); 3938 return; 3939 } 3940 // CMP{<c>}{<q>} <Rn>, <Rm> ; T2 3941 if (!size.IsWide() && 3942 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3943 EmitT32_16(0x4500 | (rn.GetCode() & 0x7) | 3944 ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 3945 AdvanceIT(); 3946 return; 3947 } 3948 } 3949 } 3950 Shift shift = operand.GetShift(); 3951 uint32_t amount = operand.GetShiftAmount(); 3952 if (IsUsingT32()) { 3953 // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3 3954 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 3955 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3956 uint32_t amount_ = amount % 32; 3957 EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() | 3958 (operand.GetTypeEncodingValue() << 4) | 3959 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3960 AdvanceIT(); 3961 return; 3962 } 3963 } else { 3964 // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 3965 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3966 uint32_t amount_ = amount % 32; 3967 EmitA32(0x01500000U | (cond.GetCondition() << 28) | 3968 (rn.GetCode() << 16) | rm.GetCode() | 3969 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3970 return; 3971 } 3972 } 3973 } 3974 if (operand.IsRegisterShiftedRegister()) { 3975 Register rm = operand.GetBaseRegister(); 3976 Shift shift = operand.GetShift(); 3977 Register rs = operand.GetShiftRegister(); 3978 if (IsUsingA32()) { 3979 // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 3980 if (cond.IsNotNever() && 3981 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 3982 EmitA32(0x01500010U | (cond.GetCondition() << 28) | 3983 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 3984 (rs.GetCode() << 8)); 3985 return; 3986 } 3987 } 3988 } 3989 Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand); 3990 } 3991 3992 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) { 3993 VIXL_ASSERT(AllowAssembler()); 3994 CheckIT(cond); 3995 if (IsUsingT32()) { 3996 // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1 3997 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 3998 AllowUnpredictable())) { 3999 EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4000 rm.GetCode()); 4001 AdvanceIT(); 4002 return; 4003 } 4004 } else { 4005 // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1 4006 if ((cond.Is(al) || AllowUnpredictable()) && 4007 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4008 EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4009 (rn.GetCode() << 16) | rm.GetCode()); 4010 return; 4011 } 4012 } 4013 Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm); 4014 } 4015 4016 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) { 4017 VIXL_ASSERT(AllowAssembler()); 4018 CheckIT(cond); 4019 if (IsUsingT32()) { 4020 // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1 4021 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4022 AllowUnpredictable())) { 4023 EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4024 rm.GetCode()); 4025 AdvanceIT(); 4026 return; 4027 } 4028 } else { 4029 // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1 4030 if ((cond.Is(al) || AllowUnpredictable()) && 4031 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4032 EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4033 (rn.GetCode() << 16) | rm.GetCode()); 4034 return; 4035 } 4036 } 4037 Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm); 4038 } 4039 4040 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) { 4041 VIXL_ASSERT(AllowAssembler()); 4042 CheckIT(cond); 4043 if (IsUsingT32()) { 4044 // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1 4045 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4046 AllowUnpredictable())) { 4047 EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4048 rm.GetCode()); 4049 AdvanceIT(); 4050 return; 4051 } 4052 } else { 4053 // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1 4054 if ((cond.Is(al) || AllowUnpredictable()) && 4055 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4056 EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4057 (rn.GetCode() << 16) | rm.GetCode()); 4058 return; 4059 } 4060 } 4061 Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm); 4062 } 4063 4064 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) { 4065 VIXL_ASSERT(AllowAssembler()); 4066 CheckIT(cond); 4067 if (IsUsingT32()) { 4068 // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1 4069 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4070 AllowUnpredictable())) { 4071 EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4072 rm.GetCode()); 4073 AdvanceIT(); 4074 return; 4075 } 4076 } else { 4077 // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1 4078 if ((cond.Is(al) || AllowUnpredictable()) && 4079 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4080 EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4081 (rn.GetCode() << 16) | rm.GetCode()); 4082 return; 4083 } 4084 } 4085 Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm); 4086 } 4087 4088 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) { 4089 VIXL_ASSERT(AllowAssembler()); 4090 CheckIT(cond); 4091 if (IsUsingT32()) { 4092 // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1 4093 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4094 AllowUnpredictable())) { 4095 EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4096 rm.GetCode()); 4097 AdvanceIT(); 4098 return; 4099 } 4100 } else { 4101 // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1 4102 if ((cond.Is(al) || AllowUnpredictable()) && 4103 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4104 EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4105 (rn.GetCode() << 16) | rm.GetCode()); 4106 return; 4107 } 4108 } 4109 Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm); 4110 } 4111 4112 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) { 4113 VIXL_ASSERT(AllowAssembler()); 4114 CheckIT(cond); 4115 if (IsUsingT32()) { 4116 // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1 4117 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) || 4118 AllowUnpredictable())) { 4119 EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4120 rm.GetCode()); 4121 AdvanceIT(); 4122 return; 4123 } 4124 } else { 4125 // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1 4126 if ((cond.Is(al) || AllowUnpredictable()) && 4127 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4128 EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 4129 (rn.GetCode() << 16) | rm.GetCode()); 4130 return; 4131 } 4132 } 4133 Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm); 4134 } 4135 4136 void Assembler::dmb(Condition cond, MemoryBarrier option) { 4137 VIXL_ASSERT(AllowAssembler()); 4138 CheckIT(cond); 4139 if (IsUsingT32()) { 4140 // DMB{<c>}{<q>} {<option>} ; T1 4141 EmitT32_32(0xf3bf8f50U | option.GetType()); 4142 AdvanceIT(); 4143 return; 4144 } else { 4145 // DMB{<c>}{<q>} {<option>} ; A1 4146 if (cond.Is(al)) { 4147 EmitA32(0xf57ff050U | option.GetType()); 4148 return; 4149 } 4150 } 4151 Delegate(kDmb, &Assembler::dmb, cond, option); 4152 } 4153 4154 void Assembler::dsb(Condition cond, MemoryBarrier option) { 4155 VIXL_ASSERT(AllowAssembler()); 4156 CheckIT(cond); 4157 if (IsUsingT32()) { 4158 // DSB{<c>}{<q>} {<option>} ; T1 4159 EmitT32_32(0xf3bf8f40U | option.GetType()); 4160 AdvanceIT(); 4161 return; 4162 } else { 4163 // DSB{<c>}{<q>} {<option>} ; A1 4164 if (cond.Is(al)) { 4165 EmitA32(0xf57ff040U | option.GetType()); 4166 return; 4167 } 4168 } 4169 Delegate(kDsb, &Assembler::dsb, cond, option); 4170 } 4171 4172 void Assembler::eor(Condition cond, 4173 EncodingSize size, 4174 Register rd, 4175 Register rn, 4176 const Operand& operand) { 4177 VIXL_ASSERT(AllowAssembler()); 4178 CheckIT(cond); 4179 if (operand.IsImmediate()) { 4180 uint32_t imm = operand.GetImmediate(); 4181 if (IsUsingT32()) { 4182 ImmediateT32 immediate_t32(imm); 4183 // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 4184 if (!size.IsNarrow() && immediate_t32.IsValid() && 4185 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4186 EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4187 (immediate_t32.GetEncodingValue() & 0xff) | 4188 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 4189 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 4190 AdvanceIT(); 4191 return; 4192 } 4193 } else { 4194 ImmediateA32 immediate_a32(imm); 4195 // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 4196 if (immediate_a32.IsValid() && cond.IsNotNever()) { 4197 EmitA32(0x02200000U | (cond.GetCondition() << 28) | 4198 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 4199 immediate_a32.GetEncodingValue()); 4200 return; 4201 } 4202 } 4203 } 4204 if (operand.IsImmediateShiftedRegister()) { 4205 Register rm = operand.GetBaseRegister(); 4206 if (operand.IsPlainRegister()) { 4207 if (IsUsingT32()) { 4208 // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 4209 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 4210 rm.IsLow()) { 4211 EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3)); 4212 AdvanceIT(); 4213 return; 4214 } 4215 } 4216 } 4217 Shift shift = operand.GetShift(); 4218 uint32_t amount = operand.GetShiftAmount(); 4219 if (IsUsingT32()) { 4220 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 4221 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 4222 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4223 uint32_t amount_ = amount % 32; 4224 EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4225 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 4226 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 4227 AdvanceIT(); 4228 return; 4229 } 4230 } else { 4231 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 4232 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 4233 uint32_t amount_ = amount % 32; 4234 EmitA32(0x00200000U | (cond.GetCondition() << 28) | 4235 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4236 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 4237 return; 4238 } 4239 } 4240 } 4241 if (operand.IsRegisterShiftedRegister()) { 4242 Register rm = operand.GetBaseRegister(); 4243 Shift shift = operand.GetShift(); 4244 Register rs = operand.GetShiftRegister(); 4245 if (IsUsingA32()) { 4246 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 4247 if (cond.IsNotNever() && 4248 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 4249 AllowUnpredictable())) { 4250 EmitA32(0x00200010U | (cond.GetCondition() << 28) | 4251 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4252 (shift.GetType() << 5) | (rs.GetCode() << 8)); 4253 return; 4254 } 4255 } 4256 } 4257 Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand); 4258 } 4259 4260 void Assembler::eors(Condition cond, 4261 EncodingSize size, 4262 Register rd, 4263 Register rn, 4264 const Operand& operand) { 4265 VIXL_ASSERT(AllowAssembler()); 4266 CheckIT(cond); 4267 if (operand.IsImmediate()) { 4268 uint32_t imm = operand.GetImmediate(); 4269 if (IsUsingT32()) { 4270 ImmediateT32 immediate_t32(imm); 4271 // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 4272 if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) && 4273 (!rn.IsPC() || AllowUnpredictable())) { 4274 EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4275 (immediate_t32.GetEncodingValue() & 0xff) | 4276 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 4277 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 4278 AdvanceIT(); 4279 return; 4280 } 4281 } else { 4282 ImmediateA32 immediate_a32(imm); 4283 // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 4284 if (immediate_a32.IsValid() && cond.IsNotNever()) { 4285 EmitA32(0x02300000U | (cond.GetCondition() << 28) | 4286 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 4287 immediate_a32.GetEncodingValue()); 4288 return; 4289 } 4290 } 4291 } 4292 if (operand.IsImmediateShiftedRegister()) { 4293 Register rm = operand.GetBaseRegister(); 4294 if (operand.IsPlainRegister()) { 4295 if (IsUsingT32()) { 4296 // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 4297 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 4298 rm.IsLow()) { 4299 EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3)); 4300 AdvanceIT(); 4301 return; 4302 } 4303 } 4304 } 4305 Shift shift = operand.GetShift(); 4306 uint32_t amount = operand.GetShiftAmount(); 4307 if (IsUsingT32()) { 4308 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 4309 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) && 4310 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 4311 uint32_t amount_ = amount % 32; 4312 EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 4313 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 4314 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 4315 AdvanceIT(); 4316 return; 4317 } 4318 } else { 4319 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 4320 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 4321 uint32_t amount_ = amount % 32; 4322 EmitA32(0x00300000U | (cond.GetCondition() << 28) | 4323 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4324 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 4325 return; 4326 } 4327 } 4328 } 4329 if (operand.IsRegisterShiftedRegister()) { 4330 Register rm = operand.GetBaseRegister(); 4331 Shift shift = operand.GetShift(); 4332 Register rs = operand.GetShiftRegister(); 4333 if (IsUsingA32()) { 4334 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 4335 if (cond.IsNotNever() && 4336 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 4337 AllowUnpredictable())) { 4338 EmitA32(0x00300010U | (cond.GetCondition() << 28) | 4339 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4340 (shift.GetType() << 5) | (rs.GetCode() << 8)); 4341 return; 4342 } 4343 } 4344 } 4345 Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand); 4346 } 4347 4348 void Assembler::fldmdbx(Condition cond, 4349 Register rn, 4350 WriteBack write_back, 4351 DRegisterList dreglist) { 4352 VIXL_ASSERT(AllowAssembler()); 4353 CheckIT(cond); 4354 if (IsUsingT32()) { 4355 // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1 4356 if (write_back.DoesWriteBack() && 4357 (((dreglist.GetLength() <= 16) && 4358 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4359 AllowUnpredictable())) { 4360 const DRegister& dreg = dreglist.GetFirstDRegister(); 4361 unsigned len = dreglist.GetLength() * 2; 4362 EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 4363 (len & 0xff)); 4364 AdvanceIT(); 4365 return; 4366 } 4367 } else { 4368 // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1 4369 if (write_back.DoesWriteBack() && cond.IsNotNever() && 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 EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4376 dreg.Encode(22, 12) | (len & 0xff)); 4377 return; 4378 } 4379 } 4380 Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist); 4381 } 4382 4383 void Assembler::fldmiax(Condition cond, 4384 Register rn, 4385 WriteBack write_back, 4386 DRegisterList dreglist) { 4387 VIXL_ASSERT(AllowAssembler()); 4388 CheckIT(cond); 4389 if (IsUsingT32()) { 4390 // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1 4391 if ((((dreglist.GetLength() <= 16) && 4392 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4393 AllowUnpredictable())) { 4394 const DRegister& dreg = dreglist.GetFirstDRegister(); 4395 unsigned len = dreglist.GetLength() * 2; 4396 EmitT32_32(0xec900b01U | (rn.GetCode() << 16) | 4397 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4398 (len & 0xff)); 4399 AdvanceIT(); 4400 return; 4401 } 4402 } else { 4403 // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1 4404 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 4405 (dreglist.GetLastDRegister().GetCode() < 16) && 4406 (!rn.IsPC() || !write_back.DoesWriteBack())) || 4407 AllowUnpredictable())) { 4408 const DRegister& dreg = dreglist.GetFirstDRegister(); 4409 unsigned len = dreglist.GetLength() * 2; 4410 EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4411 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4412 (len & 0xff)); 4413 return; 4414 } 4415 } 4416 Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist); 4417 } 4418 4419 void Assembler::fstmdbx(Condition cond, 4420 Register rn, 4421 WriteBack write_back, 4422 DRegisterList dreglist) { 4423 VIXL_ASSERT(AllowAssembler()); 4424 CheckIT(cond); 4425 if (IsUsingT32()) { 4426 // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1 4427 if (write_back.DoesWriteBack() && 4428 (((dreglist.GetLength() <= 16) && 4429 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4430 AllowUnpredictable())) { 4431 const DRegister& dreg = dreglist.GetFirstDRegister(); 4432 unsigned len = dreglist.GetLength() * 2; 4433 EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 4434 (len & 0xff)); 4435 AdvanceIT(); 4436 return; 4437 } 4438 } else { 4439 // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1 4440 if (write_back.DoesWriteBack() && cond.IsNotNever() && 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 EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4447 dreg.Encode(22, 12) | (len & 0xff)); 4448 return; 4449 } 4450 } 4451 Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist); 4452 } 4453 4454 void Assembler::fstmiax(Condition cond, 4455 Register rn, 4456 WriteBack write_back, 4457 DRegisterList dreglist) { 4458 VIXL_ASSERT(AllowAssembler()); 4459 CheckIT(cond); 4460 if (IsUsingT32()) { 4461 // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1 4462 if ((((dreglist.GetLength() <= 16) && 4463 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) || 4464 AllowUnpredictable())) { 4465 const DRegister& dreg = dreglist.GetFirstDRegister(); 4466 unsigned len = dreglist.GetLength() * 2; 4467 EmitT32_32(0xec800b01U | (rn.GetCode() << 16) | 4468 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4469 (len & 0xff)); 4470 AdvanceIT(); 4471 return; 4472 } 4473 } else { 4474 // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1 4475 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 4476 (dreglist.GetLastDRegister().GetCode() < 16) && 4477 (!rn.IsPC() || !write_back.DoesWriteBack())) || 4478 AllowUnpredictable())) { 4479 const DRegister& dreg = dreglist.GetFirstDRegister(); 4480 unsigned len = dreglist.GetLength() * 2; 4481 EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4482 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4483 (len & 0xff)); 4484 return; 4485 } 4486 } 4487 Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist); 4488 } 4489 4490 void Assembler::hlt(Condition cond, uint32_t imm) { 4491 VIXL_ASSERT(AllowAssembler()); 4492 CheckIT(cond); 4493 if (IsUsingT32()) { 4494 // HLT{<q>} {#}<imm> ; T1 4495 if ((imm <= 63)) { 4496 EmitT32_16(0xba80 | imm); 4497 AdvanceIT(); 4498 return; 4499 } 4500 } else { 4501 // HLT{<q>} {#}<imm> ; A1 4502 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 4503 EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) | 4504 ((imm & 0xfff0) << 4)); 4505 return; 4506 } 4507 } 4508 Delegate(kHlt, &Assembler::hlt, cond, imm); 4509 } 4510 4511 void Assembler::hvc(Condition cond, uint32_t imm) { 4512 VIXL_ASSERT(AllowAssembler()); 4513 CheckIT(cond); 4514 if (IsUsingT32()) { 4515 // HVC{<q>} {#}<imm16> ; T1 4516 if ((imm <= 65535) && (OutsideITBlock() || AllowUnpredictable())) { 4517 EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4)); 4518 AdvanceIT(); 4519 return; 4520 } 4521 } else { 4522 // HVC{<q>} {#}<imm16> ; A1 4523 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 4524 EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) | 4525 ((imm & 0xfff0) << 4)); 4526 return; 4527 } 4528 } 4529 Delegate(kHvc, &Assembler::hvc, cond, imm); 4530 } 4531 4532 void Assembler::isb(Condition cond, MemoryBarrier option) { 4533 VIXL_ASSERT(AllowAssembler()); 4534 CheckIT(cond); 4535 if (IsUsingT32()) { 4536 // ISB{<c>}{<q>} {<option>} ; T1 4537 EmitT32_32(0xf3bf8f60U | option.GetType()); 4538 AdvanceIT(); 4539 return; 4540 } else { 4541 // ISB{<c>}{<q>} {<option>} ; A1 4542 if (cond.Is(al)) { 4543 EmitA32(0xf57ff060U | option.GetType()); 4544 return; 4545 } 4546 } 4547 Delegate(kIsb, &Assembler::isb, cond, option); 4548 } 4549 4550 void Assembler::it(Condition cond, uint16_t mask) { 4551 VIXL_ASSERT(AllowAssembler()); 4552 CheckNotIT(); 4553 if (mask != 0) { 4554 if ((cond.GetCondition() & 0x1) != 0) { 4555 if ((mask & 0x1) != 0) { 4556 mask ^= 0xE; 4557 } else if ((mask & 0x2) != 0) { 4558 mask ^= 0xC; 4559 } else if ((mask & 0x4) != 0) { 4560 mask ^= 0x8; 4561 } 4562 } 4563 if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask); 4564 SetIT(cond, mask); 4565 return; 4566 } 4567 DelegateIt(cond, mask); 4568 } 4569 4570 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) { 4571 VIXL_ASSERT(AllowAssembler()); 4572 CheckIT(cond); 4573 if (operand.IsImmediateZero()) { 4574 Register rn = operand.GetBaseRegister(); 4575 if (IsUsingT32()) { 4576 // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1 4577 if (operand.IsOffset() && 4578 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4579 EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4580 AdvanceIT(); 4581 return; 4582 } 4583 } else { 4584 // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1 4585 if (operand.IsOffset() && cond.IsNotNever() && 4586 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4587 EmitA32(0x01900c9fU | (cond.GetCondition() << 28) | 4588 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4589 return; 4590 } 4591 } 4592 } 4593 Delegate(kLda, &Assembler::lda, cond, rt, operand); 4594 } 4595 4596 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) { 4597 VIXL_ASSERT(AllowAssembler()); 4598 CheckIT(cond); 4599 if (operand.IsImmediateZero()) { 4600 Register rn = operand.GetBaseRegister(); 4601 if (IsUsingT32()) { 4602 // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1 4603 if (operand.IsOffset() && 4604 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4605 EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4606 AdvanceIT(); 4607 return; 4608 } 4609 } else { 4610 // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1 4611 if (operand.IsOffset() && cond.IsNotNever() && 4612 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4613 EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) | 4614 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4615 return; 4616 } 4617 } 4618 } 4619 Delegate(kLdab, &Assembler::ldab, cond, rt, operand); 4620 } 4621 4622 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) { 4623 VIXL_ASSERT(AllowAssembler()); 4624 CheckIT(cond); 4625 if (operand.IsImmediateZero()) { 4626 Register rn = operand.GetBaseRegister(); 4627 if (IsUsingT32()) { 4628 // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1 4629 if (operand.IsOffset() && 4630 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4631 EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4632 AdvanceIT(); 4633 return; 4634 } 4635 } else { 4636 // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1 4637 if (operand.IsOffset() && cond.IsNotNever() && 4638 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4639 EmitA32(0x01900e9fU | (cond.GetCondition() << 28) | 4640 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4641 return; 4642 } 4643 } 4644 } 4645 Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand); 4646 } 4647 4648 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) { 4649 VIXL_ASSERT(AllowAssembler()); 4650 CheckIT(cond); 4651 if (operand.IsImmediateZero()) { 4652 Register rn = operand.GetBaseRegister(); 4653 if (IsUsingT32()) { 4654 // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1 4655 if (operand.IsOffset() && 4656 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4657 EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4658 AdvanceIT(); 4659 return; 4660 } 4661 } else { 4662 // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1 4663 if (operand.IsOffset() && cond.IsNotNever() && 4664 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4665 EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) | 4666 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4667 return; 4668 } 4669 } 4670 } 4671 Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand); 4672 } 4673 4674 void Assembler::ldaexd(Condition cond, 4675 Register rt, 4676 Register rt2, 4677 const MemOperand& operand) { 4678 VIXL_ASSERT(AllowAssembler()); 4679 CheckIT(cond); 4680 if (operand.IsImmediateZero()) { 4681 Register rn = operand.GetBaseRegister(); 4682 if (IsUsingT32()) { 4683 // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1 4684 if (operand.IsOffset() && 4685 ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4686 EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 4687 (rn.GetCode() << 16)); 4688 AdvanceIT(); 4689 return; 4690 } 4691 } else { 4692 // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1 4693 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 4694 operand.IsOffset() && cond.IsNotNever() && 4695 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) || 4696 AllowUnpredictable())) { 4697 EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) | 4698 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4699 return; 4700 } 4701 } 4702 } 4703 Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand); 4704 } 4705 4706 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) { 4707 VIXL_ASSERT(AllowAssembler()); 4708 CheckIT(cond); 4709 if (operand.IsImmediateZero()) { 4710 Register rn = operand.GetBaseRegister(); 4711 if (IsUsingT32()) { 4712 // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1 4713 if (operand.IsOffset() && 4714 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4715 EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4716 AdvanceIT(); 4717 return; 4718 } 4719 } else { 4720 // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1 4721 if (operand.IsOffset() && cond.IsNotNever() && 4722 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4723 EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) | 4724 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4725 return; 4726 } 4727 } 4728 } 4729 Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand); 4730 } 4731 4732 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) { 4733 VIXL_ASSERT(AllowAssembler()); 4734 CheckIT(cond); 4735 if (operand.IsImmediateZero()) { 4736 Register rn = operand.GetBaseRegister(); 4737 if (IsUsingT32()) { 4738 // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1 4739 if (operand.IsOffset() && 4740 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4741 EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4742 AdvanceIT(); 4743 return; 4744 } 4745 } else { 4746 // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1 4747 if (operand.IsOffset() && cond.IsNotNever() && 4748 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 4749 EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) | 4750 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4751 return; 4752 } 4753 } 4754 } 4755 Delegate(kLdah, &Assembler::ldah, cond, rt, operand); 4756 } 4757 4758 void Assembler::ldm(Condition cond, 4759 EncodingSize size, 4760 Register rn, 4761 WriteBack write_back, 4762 RegisterList registers) { 4763 VIXL_ASSERT(AllowAssembler()); 4764 CheckIT(cond); 4765 if (IsUsingT32()) { 4766 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1 4767 if (!size.IsWide() && rn.IsLow() && 4768 (((registers.GetList() & (1 << rn.GetCode())) == 0) == 4769 write_back.DoesWriteBack()) && 4770 ((registers.GetList() & ~0xff) == 0)) { 4771 EmitT32_16(0xc800 | (rn.GetCode() << 8) | 4772 GetRegisterListEncoding(registers, 0, 8)); 4773 AdvanceIT(); 4774 return; 4775 } 4776 // LDM{<c>}{<q>} SP!, <registers> ; T1 4777 if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() && 4778 ((registers.GetList() & ~0x80ff) == 0)) { 4779 EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) | 4780 GetRegisterListEncoding(registers, 0, 8)); 4781 AdvanceIT(); 4782 return; 4783 } 4784 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2 4785 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) && 4786 (!rn.IsPC() || AllowUnpredictable())) { 4787 EmitT32_32(0xe8900000U | (rn.GetCode() << 16) | 4788 (write_back.GetWriteBackUint32() << 21) | 4789 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4790 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4791 GetRegisterListEncoding(registers, 0, 13)); 4792 AdvanceIT(); 4793 return; 4794 } 4795 } else { 4796 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1 4797 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4798 EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4799 (write_back.GetWriteBackUint32() << 21) | 4800 GetRegisterListEncoding(registers, 0, 16)); 4801 return; 4802 } 4803 } 4804 Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers); 4805 } 4806 4807 void Assembler::ldmda(Condition cond, 4808 Register rn, 4809 WriteBack write_back, 4810 RegisterList registers) { 4811 VIXL_ASSERT(AllowAssembler()); 4812 CheckIT(cond); 4813 if (IsUsingA32()) { 4814 // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4815 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4816 EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4817 (write_back.GetWriteBackUint32() << 21) | 4818 GetRegisterListEncoding(registers, 0, 16)); 4819 return; 4820 } 4821 } 4822 Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers); 4823 } 4824 4825 void Assembler::ldmdb(Condition cond, 4826 Register rn, 4827 WriteBack write_back, 4828 RegisterList registers) { 4829 VIXL_ASSERT(AllowAssembler()); 4830 CheckIT(cond); 4831 if (IsUsingT32()) { 4832 // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1 4833 if (((registers.GetList() & ~0xdfff) == 0) && 4834 (!rn.IsPC() || AllowUnpredictable())) { 4835 EmitT32_32(0xe9100000U | (rn.GetCode() << 16) | 4836 (write_back.GetWriteBackUint32() << 21) | 4837 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4838 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4839 GetRegisterListEncoding(registers, 0, 13)); 4840 AdvanceIT(); 4841 return; 4842 } 4843 } else { 4844 // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1 4845 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4846 EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4847 (write_back.GetWriteBackUint32() << 21) | 4848 GetRegisterListEncoding(registers, 0, 16)); 4849 return; 4850 } 4851 } 4852 Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers); 4853 } 4854 4855 void Assembler::ldmea(Condition cond, 4856 Register rn, 4857 WriteBack write_back, 4858 RegisterList registers) { 4859 VIXL_ASSERT(AllowAssembler()); 4860 CheckIT(cond); 4861 if (IsUsingT32()) { 4862 // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1 4863 if (((registers.GetList() & ~0xdfff) == 0) && 4864 (!rn.IsPC() || AllowUnpredictable())) { 4865 EmitT32_32(0xe9100000U | (rn.GetCode() << 16) | 4866 (write_back.GetWriteBackUint32() << 21) | 4867 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4868 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4869 GetRegisterListEncoding(registers, 0, 13)); 4870 AdvanceIT(); 4871 return; 4872 } 4873 } else { 4874 // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4875 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4876 EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4877 (write_back.GetWriteBackUint32() << 21) | 4878 GetRegisterListEncoding(registers, 0, 16)); 4879 return; 4880 } 4881 } 4882 Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers); 4883 } 4884 4885 void Assembler::ldmed(Condition cond, 4886 Register rn, 4887 WriteBack write_back, 4888 RegisterList registers) { 4889 VIXL_ASSERT(AllowAssembler()); 4890 CheckIT(cond); 4891 if (IsUsingA32()) { 4892 // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1 4893 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4894 EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4895 (write_back.GetWriteBackUint32() << 21) | 4896 GetRegisterListEncoding(registers, 0, 16)); 4897 return; 4898 } 4899 } 4900 Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers); 4901 } 4902 4903 void Assembler::ldmfa(Condition cond, 4904 Register rn, 4905 WriteBack write_back, 4906 RegisterList registers) { 4907 VIXL_ASSERT(AllowAssembler()); 4908 CheckIT(cond); 4909 if (IsUsingA32()) { 4910 // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4911 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4912 EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4913 (write_back.GetWriteBackUint32() << 21) | 4914 GetRegisterListEncoding(registers, 0, 16)); 4915 return; 4916 } 4917 } 4918 Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers); 4919 } 4920 4921 void Assembler::ldmfd(Condition cond, 4922 EncodingSize size, 4923 Register rn, 4924 WriteBack write_back, 4925 RegisterList registers) { 4926 VIXL_ASSERT(AllowAssembler()); 4927 CheckIT(cond); 4928 if (IsUsingT32()) { 4929 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1 4930 if (!size.IsWide() && rn.IsLow() && 4931 (((registers.GetList() & (1 << rn.GetCode())) == 0) == 4932 write_back.DoesWriteBack()) && 4933 ((registers.GetList() & ~0xff) == 0)) { 4934 EmitT32_16(0xc800 | (rn.GetCode() << 8) | 4935 GetRegisterListEncoding(registers, 0, 8)); 4936 AdvanceIT(); 4937 return; 4938 } 4939 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2 4940 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) && 4941 (!rn.IsPC() || AllowUnpredictable())) { 4942 EmitT32_32(0xe8900000U | (rn.GetCode() << 16) | 4943 (write_back.GetWriteBackUint32() << 21) | 4944 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4945 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4946 GetRegisterListEncoding(registers, 0, 13)); 4947 AdvanceIT(); 4948 return; 4949 } 4950 } else { 4951 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1 4952 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4953 EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4954 (write_back.GetWriteBackUint32() << 21) | 4955 GetRegisterListEncoding(registers, 0, 16)); 4956 return; 4957 } 4958 } 4959 Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers); 4960 } 4961 4962 void Assembler::ldmib(Condition cond, 4963 Register rn, 4964 WriteBack write_back, 4965 RegisterList registers) { 4966 VIXL_ASSERT(AllowAssembler()); 4967 CheckIT(cond); 4968 if (IsUsingA32()) { 4969 // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1 4970 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 4971 EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4972 (write_back.GetWriteBackUint32() << 21) | 4973 GetRegisterListEncoding(registers, 0, 16)); 4974 return; 4975 } 4976 } 4977 Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers); 4978 } 4979 4980 void Assembler::ldr(Condition cond, 4981 EncodingSize size, 4982 Register rt, 4983 const MemOperand& operand) { 4984 VIXL_ASSERT(AllowAssembler()); 4985 CheckIT(cond); 4986 if (operand.IsImmediate()) { 4987 Register rn = operand.GetBaseRegister(); 4988 int32_t offset = operand.GetOffsetImmediate(); 4989 if (IsUsingT32()) { 4990 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 4991 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 4992 (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) { 4993 int32_t offset_ = offset >> 2; 4994 EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) | 4995 ((offset_ & 0x1f) << 6)); 4996 AdvanceIT(); 4997 return; 4998 } 4999 // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2 5000 if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) && 5001 ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) { 5002 int32_t offset_ = offset >> 2; 5003 EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff)); 5004 AdvanceIT(); 5005 return; 5006 } 5007 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3 5008 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5009 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 5010 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5011 AllowUnpredictable())) { 5012 EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5013 (offset & 0xfff)); 5014 AdvanceIT(); 5015 return; 5016 } 5017 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4 5018 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5019 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 5020 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5021 AllowUnpredictable())) { 5022 EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5023 (-offset & 0xff)); 5024 AdvanceIT(); 5025 return; 5026 } 5027 // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4 5028 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5029 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 5030 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5031 AllowUnpredictable())) { 5032 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5033 uint32_t offset_ = abs(offset); 5034 EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5035 offset_ | (sign << 9)); 5036 AdvanceIT(); 5037 return; 5038 } 5039 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4 5040 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5041 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 5042 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5043 AllowUnpredictable())) { 5044 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5045 uint32_t offset_ = abs(offset); 5046 EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5047 offset_ | (sign << 9)); 5048 AdvanceIT(); 5049 return; 5050 } 5051 // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2 5052 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 5053 rn.Is(pc) && operand.IsOffset() && 5054 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5055 AllowUnpredictable())) { 5056 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5057 uint32_t offset_ = abs(offset); 5058 EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 5059 AdvanceIT(); 5060 return; 5061 } 5062 } else { 5063 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 5064 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 5065 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5066 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5067 uint32_t offset_ = abs(offset); 5068 EmitA32(0x05100000U | (cond.GetCondition() << 28) | 5069 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5070 (sign << 23)); 5071 return; 5072 } 5073 // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 5074 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 5075 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5076 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5077 uint32_t offset_ = abs(offset); 5078 EmitA32(0x04100000U | (cond.GetCondition() << 28) | 5079 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5080 (sign << 23)); 5081 return; 5082 } 5083 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 5084 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 5085 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5086 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5087 uint32_t offset_ = abs(offset); 5088 EmitA32(0x05300000U | (cond.GetCondition() << 28) | 5089 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5090 (sign << 23)); 5091 return; 5092 } 5093 // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 5094 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 5095 operand.IsOffset() && cond.IsNotNever()) { 5096 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5097 uint32_t offset_ = abs(offset); 5098 EmitA32(0x051f0000U | (cond.GetCondition() << 28) | 5099 (rt.GetCode() << 12) | offset_ | (sign << 23)); 5100 return; 5101 } 5102 } 5103 } 5104 if (operand.IsPlainRegister()) { 5105 Register rn = operand.GetBaseRegister(); 5106 Sign sign = operand.GetSign(); 5107 Register rm = operand.GetOffsetRegister(); 5108 if (IsUsingT32()) { 5109 // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 5110 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 5111 sign.IsPlus() && operand.IsOffset()) { 5112 EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) | 5113 (rm.GetCode() << 6)); 5114 AdvanceIT(); 5115 return; 5116 } 5117 } 5118 } 5119 if (operand.IsShiftedRegister()) { 5120 Register rn = operand.GetBaseRegister(); 5121 Sign sign = operand.GetSign(); 5122 Register rm = operand.GetOffsetRegister(); 5123 Shift shift = operand.GetShift(); 5124 uint32_t amount = operand.GetShiftAmount(); 5125 if (IsUsingT32()) { 5126 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 5127 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 5128 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 5129 ((!rm.IsPC() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) || 5130 AllowUnpredictable())) { 5131 EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5132 rm.GetCode() | (amount << 4)); 5133 AdvanceIT(); 5134 return; 5135 } 5136 } else { 5137 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 5138 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() && 5139 (!rm.IsPC() || AllowUnpredictable())) { 5140 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5141 uint32_t shift_ = TypeEncodingValue(shift); 5142 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5143 EmitA32(0x07100000U | (cond.GetCondition() << 28) | 5144 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5145 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5146 return; 5147 } 5148 // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 5149 if (operand.IsShiftValid() && operand.IsPostIndex() && 5150 cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) { 5151 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5152 uint32_t shift_ = TypeEncodingValue(shift); 5153 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5154 EmitA32(0x06100000U | (cond.GetCondition() << 28) | 5155 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5156 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5157 return; 5158 } 5159 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 5160 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() && 5161 (!rm.IsPC() || AllowUnpredictable())) { 5162 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5163 uint32_t shift_ = TypeEncodingValue(shift); 5164 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5165 EmitA32(0x07300000U | (cond.GetCondition() << 28) | 5166 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5167 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5168 return; 5169 } 5170 } 5171 } 5172 Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand); 5173 } 5174 5175 void Assembler::ldr(Condition cond, 5176 EncodingSize size, 5177 Register rt, 5178 Location* location) { 5179 VIXL_ASSERT(AllowAssembler()); 5180 CheckIT(cond); 5181 Location::Offset offset = 5182 location->IsBound() 5183 ? location->GetLocation() - 5184 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5185 : 0; 5186 if (IsUsingT32()) { 5187 // LDR{<c>}{<q>} <Rt>, <label> ; T1 5188 if (!size.IsWide() && rt.IsLow() && 5189 ((location->IsBound() && (offset >= 0) && (offset <= 1020) && 5190 ((offset & 0x3) == 0)) || 5191 (!location->IsBound() && size.IsNarrow()))) { 5192 static class EmitOp : public Location::EmitOperator { 5193 public: 5194 EmitOp() : Location::EmitOperator(T32) {} 5195 virtual uint32_t Encode(uint32_t instr, 5196 Location::Offset pc, 5197 const Location* location) const VIXL_OVERRIDE { 5198 pc += kT32PcDelta; 5199 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 5200 VIXL_ASSERT((offset >= 0) && (offset <= 1020) && 5201 ((offset & 0x3) == 0)); 5202 const int32_t target = offset >> 2; 5203 return instr | (target & 0xff); 5204 } 5205 } immop; 5206 EmitT32_16( 5207 Link(0x4800 | (rt.GetCode() << 8), location, immop, &kT16DataInfo)); 5208 AdvanceIT(); 5209 return; 5210 } 5211 // LDR{<c>}{<q>} <Rt>, <label> ; T2 5212 if (!size.IsNarrow() && 5213 ((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5214 !location->IsBound()) && 5215 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 5216 AllowUnpredictable())) { 5217 static class EmitOp : public Location::EmitOperator { 5218 public: 5219 EmitOp() : Location::EmitOperator(T32) {} 5220 virtual uint32_t Encode(uint32_t instr, 5221 Location::Offset pc, 5222 const Location* location) const VIXL_OVERRIDE { 5223 pc += kT32PcDelta; 5224 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 5225 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 5226 uint32_t U = (offset >= 0); 5227 int32_t target = abs(offset) | (U << 12); 5228 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5229 } 5230 } immop; 5231 EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12), 5232 location, 5233 immop, 5234 &kT32FarDataInfo)); 5235 AdvanceIT(); 5236 return; 5237 } 5238 } else { 5239 // LDR{<c>}{<q>} <Rt>, <label> ; A1 5240 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5241 !location->IsBound()) && 5242 cond.IsNotNever()) { 5243 static class EmitOp : public Location::EmitOperator { 5244 public: 5245 EmitOp() : Location::EmitOperator(A32) {} 5246 virtual uint32_t Encode(uint32_t instr, 5247 Location::Offset pc, 5248 const Location* location) const VIXL_OVERRIDE { 5249 pc += kA32PcDelta; 5250 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 5251 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 5252 uint32_t U = (offset >= 0); 5253 int32_t target = abs(offset) | (U << 12); 5254 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5255 } 5256 } immop; 5257 EmitA32( 5258 Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5259 location, 5260 immop, 5261 &kA32FarDataInfo)); 5262 return; 5263 } 5264 } 5265 Delegate(kLdr, &Assembler::ldr, cond, size, rt, location); 5266 } 5267 5268 bool Assembler::ldr_info(Condition cond, 5269 EncodingSize size, 5270 Register rt, 5271 Location* location, 5272 const struct ReferenceInfo** info) { 5273 VIXL_ASSERT(!location->IsBound()); 5274 USE(location); 5275 if (IsUsingT32()) { 5276 // LDR{<c>}{<q>} <Rt>, <label> ; T1 5277 if (!size.IsWide() && rt.IsLow() && size.IsNarrow()) { 5278 *info = &kT16DataInfo; 5279 return true; 5280 } 5281 // LDR{<c>}{<q>} <Rt>, <label> ; T2 5282 if (!size.IsNarrow()) { 5283 *info = &kT32FarDataInfo; 5284 return true; 5285 } 5286 } else { 5287 // LDR{<c>}{<q>} <Rt>, <label> ; A1 5288 if (cond.IsNotNever()) { 5289 *info = &kA32FarDataInfo; 5290 return true; 5291 } 5292 } 5293 return false; 5294 } 5295 5296 void Assembler::ldrb(Condition cond, 5297 EncodingSize size, 5298 Register rt, 5299 const MemOperand& operand) { 5300 VIXL_ASSERT(AllowAssembler()); 5301 CheckIT(cond); 5302 if (operand.IsImmediate()) { 5303 Register rn = operand.GetBaseRegister(); 5304 int32_t offset = operand.GetOffsetImmediate(); 5305 if (IsUsingT32()) { 5306 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 5307 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 5308 (offset <= 31) && operand.IsOffset()) { 5309 EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) | 5310 ((offset & 0x1f) << 6)); 5311 AdvanceIT(); 5312 return; 5313 } 5314 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 5315 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5316 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5317 EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5318 (offset & 0xfff)); 5319 AdvanceIT(); 5320 return; 5321 } 5322 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 5323 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5324 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5325 EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5326 (-offset & 0xff)); 5327 AdvanceIT(); 5328 return; 5329 } 5330 // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 5331 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5332 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5333 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5334 uint32_t offset_ = abs(offset); 5335 EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5336 offset_ | (sign << 9)); 5337 AdvanceIT(); 5338 return; 5339 } 5340 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 5341 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5342 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5343 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5344 uint32_t offset_ = abs(offset); 5345 EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5346 offset_ | (sign << 9)); 5347 AdvanceIT(); 5348 return; 5349 } 5350 // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 5351 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 5352 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 5353 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5354 uint32_t offset_ = abs(offset); 5355 EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 5356 AdvanceIT(); 5357 return; 5358 } 5359 } else { 5360 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 5361 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 5362 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5363 (!rt.IsPC() || AllowUnpredictable())) { 5364 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5365 uint32_t offset_ = abs(offset); 5366 EmitA32(0x05500000U | (cond.GetCondition() << 28) | 5367 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5368 (sign << 23)); 5369 return; 5370 } 5371 // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 5372 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 5373 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5374 (!rt.IsPC() || AllowUnpredictable())) { 5375 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5376 uint32_t offset_ = abs(offset); 5377 EmitA32(0x04500000U | (cond.GetCondition() << 28) | 5378 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5379 (sign << 23)); 5380 return; 5381 } 5382 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 5383 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 5384 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5385 (!rt.IsPC() || AllowUnpredictable())) { 5386 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5387 uint32_t offset_ = abs(offset); 5388 EmitA32(0x05700000U | (cond.GetCondition() << 28) | 5389 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 5390 (sign << 23)); 5391 return; 5392 } 5393 // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 5394 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 5395 operand.IsOffset() && cond.IsNotNever() && 5396 (!rt.IsPC() || AllowUnpredictable())) { 5397 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5398 uint32_t offset_ = abs(offset); 5399 EmitA32(0x055f0000U | (cond.GetCondition() << 28) | 5400 (rt.GetCode() << 12) | offset_ | (sign << 23)); 5401 return; 5402 } 5403 } 5404 } 5405 if (operand.IsPlainRegister()) { 5406 Register rn = operand.GetBaseRegister(); 5407 Sign sign = operand.GetSign(); 5408 Register rm = operand.GetOffsetRegister(); 5409 if (IsUsingT32()) { 5410 // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 5411 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 5412 sign.IsPlus() && operand.IsOffset()) { 5413 EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) | 5414 (rm.GetCode() << 6)); 5415 AdvanceIT(); 5416 return; 5417 } 5418 } 5419 } 5420 if (operand.IsShiftedRegister()) { 5421 Register rn = operand.GetBaseRegister(); 5422 Sign sign = operand.GetSign(); 5423 Register rm = operand.GetOffsetRegister(); 5424 Shift shift = operand.GetShift(); 5425 uint32_t amount = operand.GetShiftAmount(); 5426 if (IsUsingT32()) { 5427 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 5428 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 5429 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) && 5430 (!rm.IsPC() || AllowUnpredictable())) { 5431 EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5432 rm.GetCode() | (amount << 4)); 5433 AdvanceIT(); 5434 return; 5435 } 5436 } else { 5437 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 5438 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() && 5439 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 5440 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5441 uint32_t shift_ = TypeEncodingValue(shift); 5442 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5443 EmitA32(0x07500000U | (cond.GetCondition() << 28) | 5444 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5445 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5446 return; 5447 } 5448 // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 5449 if (operand.IsShiftValid() && operand.IsPostIndex() && 5450 cond.IsNotNever() && 5451 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 5452 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5453 uint32_t shift_ = TypeEncodingValue(shift); 5454 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5455 EmitA32(0x06500000U | (cond.GetCondition() << 28) | 5456 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5457 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5458 return; 5459 } 5460 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 5461 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() && 5462 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 5463 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5464 uint32_t shift_ = TypeEncodingValue(shift); 5465 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5466 EmitA32(0x07700000U | (cond.GetCondition() << 28) | 5467 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5468 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5469 return; 5470 } 5471 } 5472 } 5473 Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand); 5474 } 5475 5476 void Assembler::ldrb(Condition cond, Register rt, Location* location) { 5477 VIXL_ASSERT(AllowAssembler()); 5478 CheckIT(cond); 5479 Location::Offset offset = 5480 location->IsBound() 5481 ? location->GetLocation() - 5482 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5483 : 0; 5484 if (IsUsingT32()) { 5485 // LDRB{<c>}{<q>} <Rt>, <label> ; T1 5486 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5487 !location->IsBound()) && 5488 !rt.Is(pc)) { 5489 static class EmitOp : public Location::EmitOperator { 5490 public: 5491 EmitOp() : Location::EmitOperator(T32) {} 5492 virtual uint32_t Encode(uint32_t instr, 5493 Location::Offset pc, 5494 const Location* location) const VIXL_OVERRIDE { 5495 pc += kT32PcDelta; 5496 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 5497 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 5498 uint32_t U = (offset >= 0); 5499 int32_t target = abs(offset) | (U << 12); 5500 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5501 } 5502 } immop; 5503 EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12), 5504 location, 5505 immop, 5506 &kT32FarDataInfo)); 5507 AdvanceIT(); 5508 return; 5509 } 5510 } else { 5511 // LDRB{<c>}{<q>} <Rt>, <label> ; A1 5512 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5513 !location->IsBound()) && 5514 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 5515 static class EmitOp : public Location::EmitOperator { 5516 public: 5517 EmitOp() : Location::EmitOperator(A32) {} 5518 virtual uint32_t Encode(uint32_t instr, 5519 Location::Offset pc, 5520 const Location* location) const VIXL_OVERRIDE { 5521 pc += kA32PcDelta; 5522 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 5523 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 5524 uint32_t U = (offset >= 0); 5525 int32_t target = abs(offset) | (U << 12); 5526 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5527 } 5528 } immop; 5529 EmitA32( 5530 Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5531 location, 5532 immop, 5533 &kA32FarDataInfo)); 5534 return; 5535 } 5536 } 5537 Delegate(kLdrb, &Assembler::ldrb, cond, rt, location); 5538 } 5539 5540 bool Assembler::ldrb_info(Condition cond, 5541 Register rt, 5542 Location* location, 5543 const struct ReferenceInfo** info) { 5544 VIXL_ASSERT(!location->IsBound()); 5545 USE(location); 5546 if (IsUsingT32()) { 5547 // LDRB{<c>}{<q>} <Rt>, <label> ; T1 5548 if (!rt.Is(pc)) { 5549 *info = &kT32FarDataInfo; 5550 return true; 5551 } 5552 } else { 5553 // LDRB{<c>}{<q>} <Rt>, <label> ; A1 5554 if (cond.IsNotNever()) { 5555 *info = &kA32FarDataInfo; 5556 return true; 5557 } 5558 } 5559 return false; 5560 } 5561 5562 void Assembler::ldrd(Condition cond, 5563 Register rt, 5564 Register rt2, 5565 const MemOperand& operand) { 5566 VIXL_ASSERT(AllowAssembler()); 5567 CheckIT(cond); 5568 if (operand.IsImmediate()) { 5569 Register rn = operand.GetBaseRegister(); 5570 int32_t offset = operand.GetOffsetImmediate(); 5571 if (IsUsingT32()) { 5572 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1 5573 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5574 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 5575 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5576 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5577 uint32_t offset_ = abs(offset) >> 2; 5578 EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5579 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5580 AdvanceIT(); 5581 return; 5582 } 5583 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1 5584 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5585 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 5586 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5587 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5588 uint32_t offset_ = abs(offset) >> 2; 5589 EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5590 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5591 AdvanceIT(); 5592 return; 5593 } 5594 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1 5595 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5596 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 5597 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5598 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5599 uint32_t offset_ = abs(offset) >> 2; 5600 EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5601 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5602 AdvanceIT(); 5603 return; 5604 } 5605 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1 5606 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 5607 operand.IsOffset() && 5608 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5609 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5610 uint32_t offset_ = abs(offset); 5611 EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5612 offset_ | (sign << 23)); 5613 AdvanceIT(); 5614 return; 5615 } 5616 } else { 5617 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1 5618 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5619 (offset >= -255) && (offset <= 255) && operand.IsOffset() && 5620 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5621 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 5622 AllowUnpredictable())) { 5623 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5624 uint32_t offset_ = abs(offset); 5625 EmitA32(0x014000d0U | (cond.GetCondition() << 28) | 5626 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5627 ((offset_ & 0xf0) << 4) | (sign << 23)); 5628 return; 5629 } 5630 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1 5631 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5632 (offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 5633 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5634 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 5635 AllowUnpredictable())) { 5636 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5637 uint32_t offset_ = abs(offset); 5638 EmitA32(0x004000d0U | (cond.GetCondition() << 28) | 5639 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5640 ((offset_ & 0xf0) << 4) | (sign << 23)); 5641 return; 5642 } 5643 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1 5644 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5645 (offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 5646 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5647 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 5648 AllowUnpredictable())) { 5649 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5650 uint32_t offset_ = abs(offset); 5651 EmitA32(0x016000d0U | (cond.GetCondition() << 28) | 5652 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5653 ((offset_ & 0xf0) << 4) | (sign << 23)); 5654 return; 5655 } 5656 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1 5657 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5658 (offset >= -255) && (offset <= 255) && rn.Is(pc) && 5659 operand.IsOffset() && cond.IsNotNever() && 5660 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 5661 AllowUnpredictable())) { 5662 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5663 uint32_t offset_ = abs(offset); 5664 EmitA32(0x014f00d0U | (cond.GetCondition() << 28) | 5665 (rt.GetCode() << 12) | (offset_ & 0xf) | 5666 ((offset_ & 0xf0) << 4) | (sign << 23)); 5667 return; 5668 } 5669 } 5670 } 5671 if (operand.IsPlainRegister()) { 5672 Register rn = operand.GetBaseRegister(); 5673 Sign sign = operand.GetSign(); 5674 Register rm = operand.GetOffsetRegister(); 5675 if (IsUsingA32()) { 5676 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1 5677 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5678 operand.IsOffset() && cond.IsNotNever() && 5679 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 5680 AllowUnpredictable())) { 5681 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5682 EmitA32(0x010000d0U | (cond.GetCondition() << 28) | 5683 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5684 (sign_ << 23)); 5685 return; 5686 } 5687 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1 5688 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5689 operand.IsPostIndex() && cond.IsNotNever() && 5690 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 5691 AllowUnpredictable())) { 5692 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5693 EmitA32(0x000000d0U | (cond.GetCondition() << 28) | 5694 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5695 (sign_ << 23)); 5696 return; 5697 } 5698 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1 5699 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5700 operand.IsPreIndex() && cond.IsNotNever() && 5701 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 5702 AllowUnpredictable())) { 5703 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5704 EmitA32(0x012000d0U | (cond.GetCondition() << 28) | 5705 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5706 (sign_ << 23)); 5707 return; 5708 } 5709 } 5710 } 5711 Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand); 5712 } 5713 5714 void Assembler::ldrd(Condition cond, 5715 Register rt, 5716 Register rt2, 5717 Location* location) { 5718 VIXL_ASSERT(AllowAssembler()); 5719 CheckIT(cond); 5720 Location::Offset offset = 5721 location->IsBound() 5722 ? location->GetLocation() - 5723 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5724 : 0; 5725 if (IsUsingT32()) { 5726 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1 5727 if (((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 5728 ((offset & 0x3) == 0)) || 5729 !location->IsBound()) && 5730 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 5731 static class EmitOp : public Location::EmitOperator { 5732 public: 5733 EmitOp() : Location::EmitOperator(T32) {} 5734 virtual uint32_t Encode(uint32_t instr, 5735 Location::Offset pc, 5736 const Location* location) const VIXL_OVERRIDE { 5737 pc += kT32PcDelta; 5738 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 5739 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 5740 ((offset & 0x3) == 0)); 5741 int32_t target = offset >> 2; 5742 uint32_t U = (target >= 0); 5743 target = abs(target) | (U << 8); 5744 return instr | (target & 0xff) | ((target & 0x100) << 15); 5745 } 5746 } immop; 5747 EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8), 5748 location, 5749 immop, 5750 &kT32DataInfo)); 5751 AdvanceIT(); 5752 return; 5753 } 5754 } else { 5755 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1 5756 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5757 ((location->IsBound() && (offset >= -255) && (offset <= 255)) || 5758 !location->IsBound()) && 5759 cond.IsNotNever() && 5760 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || AllowUnpredictable())) { 5761 static class EmitOp : public Location::EmitOperator { 5762 public: 5763 EmitOp() : Location::EmitOperator(A32) {} 5764 virtual uint32_t Encode(uint32_t instr, 5765 Location::Offset pc, 5766 const Location* location) const VIXL_OVERRIDE { 5767 pc += kA32PcDelta; 5768 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 5769 VIXL_ASSERT((offset >= -255) && (offset <= 255)); 5770 uint32_t U = (offset >= 0); 5771 int32_t target = abs(offset) | (U << 8); 5772 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 5773 ((target & 0x100) << 15); 5774 } 5775 } immop; 5776 EmitA32( 5777 Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5778 location, 5779 immop, 5780 &kA32VeryNearDataInfo)); 5781 return; 5782 } 5783 } 5784 Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, location); 5785 } 5786 5787 bool Assembler::ldrd_info(Condition cond, 5788 Register rt, 5789 Register rt2, 5790 Location* location, 5791 const struct ReferenceInfo** info) { 5792 VIXL_ASSERT(!location->IsBound()); 5793 USE(location); 5794 if (IsUsingT32()) { 5795 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1 5796 if (true) { 5797 *info = &kT32DataInfo; 5798 return true; 5799 } 5800 } else { 5801 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1 5802 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5803 cond.IsNotNever()) { 5804 *info = &kA32VeryNearDataInfo; 5805 return true; 5806 } 5807 } 5808 return false; 5809 } 5810 5811 void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) { 5812 VIXL_ASSERT(AllowAssembler()); 5813 CheckIT(cond); 5814 if (operand.IsImmediate()) { 5815 Register rn = operand.GetBaseRegister(); 5816 int32_t offset = operand.GetOffsetImmediate(); 5817 if (IsUsingT32()) { 5818 // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1 5819 if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) && 5820 operand.IsOffset() && 5821 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5822 int32_t offset_ = offset >> 2; 5823 EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5824 (offset_ & 0xff)); 5825 AdvanceIT(); 5826 return; 5827 } 5828 } else { 5829 // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1 5830 if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() && 5831 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5832 EmitA32(0x01900f9fU | (cond.GetCondition() << 28) | 5833 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5834 return; 5835 } 5836 } 5837 } 5838 Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand); 5839 } 5840 5841 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) { 5842 VIXL_ASSERT(AllowAssembler()); 5843 CheckIT(cond); 5844 if (operand.IsImmediateZero()) { 5845 Register rn = operand.GetBaseRegister(); 5846 if (IsUsingT32()) { 5847 // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1 5848 if (operand.IsOffset() && 5849 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5850 EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5851 AdvanceIT(); 5852 return; 5853 } 5854 } else { 5855 // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1 5856 if (operand.IsOffset() && cond.IsNotNever() && 5857 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5858 EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) | 5859 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5860 return; 5861 } 5862 } 5863 } 5864 Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand); 5865 } 5866 5867 void Assembler::ldrexd(Condition cond, 5868 Register rt, 5869 Register rt2, 5870 const MemOperand& operand) { 5871 VIXL_ASSERT(AllowAssembler()); 5872 CheckIT(cond); 5873 if (operand.IsImmediateZero()) { 5874 Register rn = operand.GetBaseRegister(); 5875 if (IsUsingT32()) { 5876 // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1 5877 if (operand.IsOffset() && 5878 ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5879 EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5880 (rn.GetCode() << 16)); 5881 AdvanceIT(); 5882 return; 5883 } 5884 } else { 5885 // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1 5886 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5887 operand.IsOffset() && cond.IsNotNever() && 5888 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) || 5889 AllowUnpredictable())) { 5890 EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) | 5891 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5892 return; 5893 } 5894 } 5895 } 5896 Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand); 5897 } 5898 5899 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) { 5900 VIXL_ASSERT(AllowAssembler()); 5901 CheckIT(cond); 5902 if (operand.IsImmediateZero()) { 5903 Register rn = operand.GetBaseRegister(); 5904 if (IsUsingT32()) { 5905 // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1 5906 if (operand.IsOffset() && 5907 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5908 EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5909 AdvanceIT(); 5910 return; 5911 } 5912 } else { 5913 // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1 5914 if (operand.IsOffset() && cond.IsNotNever() && 5915 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 5916 EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) | 5917 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5918 return; 5919 } 5920 } 5921 } 5922 Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand); 5923 } 5924 5925 void Assembler::ldrh(Condition cond, 5926 EncodingSize size, 5927 Register rt, 5928 const MemOperand& operand) { 5929 VIXL_ASSERT(AllowAssembler()); 5930 CheckIT(cond); 5931 if (operand.IsImmediate()) { 5932 Register rn = operand.GetBaseRegister(); 5933 int32_t offset = operand.GetOffsetImmediate(); 5934 if (IsUsingT32()) { 5935 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 5936 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 5937 (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) { 5938 int32_t offset_ = offset >> 1; 5939 EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) | 5940 ((offset_ & 0x1f) << 6)); 5941 AdvanceIT(); 5942 return; 5943 } 5944 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 5945 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5946 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5947 EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5948 (offset & 0xfff)); 5949 AdvanceIT(); 5950 return; 5951 } 5952 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 5953 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5954 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5955 EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5956 (-offset & 0xff)); 5957 AdvanceIT(); 5958 return; 5959 } 5960 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 5961 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5962 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5963 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5964 uint32_t offset_ = abs(offset); 5965 EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5966 offset_ | (sign << 9)); 5967 AdvanceIT(); 5968 return; 5969 } 5970 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 5971 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5972 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5973 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5974 uint32_t offset_ = abs(offset); 5975 EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5976 offset_ | (sign << 9)); 5977 AdvanceIT(); 5978 return; 5979 } 5980 // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 5981 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 5982 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 5983 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5984 uint32_t offset_ = abs(offset); 5985 EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 5986 AdvanceIT(); 5987 return; 5988 } 5989 } else { 5990 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 5991 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 5992 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5993 (!rt.IsPC() || AllowUnpredictable())) { 5994 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5995 uint32_t offset_ = abs(offset); 5996 EmitA32(0x015000b0U | (cond.GetCondition() << 28) | 5997 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5998 ((offset_ & 0xf0) << 4) | (sign << 23)); 5999 return; 6000 } 6001 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 6002 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 6003 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6004 (!rt.IsPC() || AllowUnpredictable())) { 6005 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6006 uint32_t offset_ = abs(offset); 6007 EmitA32(0x005000b0U | (cond.GetCondition() << 28) | 6008 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6009 ((offset_ & 0xf0) << 4) | (sign << 23)); 6010 return; 6011 } 6012 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 6013 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 6014 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6015 (!rt.IsPC() || AllowUnpredictable())) { 6016 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6017 uint32_t offset_ = abs(offset); 6018 EmitA32(0x017000b0U | (cond.GetCondition() << 28) | 6019 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6020 ((offset_ & 0xf0) << 4) | (sign << 23)); 6021 return; 6022 } 6023 // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 6024 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 6025 operand.IsOffset() && cond.IsNotNever() && 6026 (!rt.IsPC() || AllowUnpredictable())) { 6027 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6028 uint32_t offset_ = abs(offset); 6029 EmitA32(0x015f00b0U | (cond.GetCondition() << 28) | 6030 (rt.GetCode() << 12) | (offset_ & 0xf) | 6031 ((offset_ & 0xf0) << 4) | (sign << 23)); 6032 return; 6033 } 6034 } 6035 } 6036 if (operand.IsPlainRegister()) { 6037 Register rn = operand.GetBaseRegister(); 6038 Sign sign = operand.GetSign(); 6039 Register rm = operand.GetOffsetRegister(); 6040 if (IsUsingT32()) { 6041 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 6042 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 6043 sign.IsPlus() && operand.IsOffset()) { 6044 EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) | 6045 (rm.GetCode() << 6)); 6046 AdvanceIT(); 6047 return; 6048 } 6049 } else { 6050 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 6051 if (operand.IsOffset() && cond.IsNotNever() && 6052 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6053 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6054 EmitA32(0x011000b0U | (cond.GetCondition() << 28) | 6055 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6056 (sign_ << 23)); 6057 return; 6058 } 6059 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 6060 if (operand.IsPostIndex() && cond.IsNotNever() && 6061 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6062 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6063 EmitA32(0x001000b0U | (cond.GetCondition() << 28) | 6064 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6065 (sign_ << 23)); 6066 return; 6067 } 6068 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 6069 if (operand.IsPreIndex() && cond.IsNotNever() && 6070 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6071 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6072 EmitA32(0x013000b0U | (cond.GetCondition() << 28) | 6073 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6074 (sign_ << 23)); 6075 return; 6076 } 6077 } 6078 } 6079 if (operand.IsShiftedRegister()) { 6080 Register rn = operand.GetBaseRegister(); 6081 Sign sign = operand.GetSign(); 6082 Register rm = operand.GetOffsetRegister(); 6083 Shift shift = operand.GetShift(); 6084 uint32_t amount = operand.GetShiftAmount(); 6085 if (IsUsingT32()) { 6086 // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 6087 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 6088 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) && 6089 (!rm.IsPC() || AllowUnpredictable())) { 6090 EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6091 rm.GetCode() | (amount << 4)); 6092 AdvanceIT(); 6093 return; 6094 } 6095 } 6096 } 6097 Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand); 6098 } 6099 6100 void Assembler::ldrh(Condition cond, Register rt, Location* location) { 6101 VIXL_ASSERT(AllowAssembler()); 6102 CheckIT(cond); 6103 Location::Offset offset = 6104 location->IsBound() 6105 ? location->GetLocation() - 6106 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 6107 : 0; 6108 if (IsUsingT32()) { 6109 // LDRH{<c>}{<q>} <Rt>, <label> ; T1 6110 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 6111 !location->IsBound()) && 6112 !rt.Is(pc)) { 6113 static class EmitOp : public Location::EmitOperator { 6114 public: 6115 EmitOp() : Location::EmitOperator(T32) {} 6116 virtual uint32_t Encode(uint32_t instr, 6117 Location::Offset pc, 6118 const Location* location) const VIXL_OVERRIDE { 6119 pc += kT32PcDelta; 6120 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 6121 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 6122 uint32_t U = (offset >= 0); 6123 int32_t target = abs(offset) | (U << 12); 6124 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 6125 } 6126 } immop; 6127 EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12), 6128 location, 6129 immop, 6130 &kT32FarDataInfo)); 6131 AdvanceIT(); 6132 return; 6133 } 6134 } else { 6135 // LDRH{<c>}{<q>} <Rt>, <label> ; A1 6136 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) || 6137 !location->IsBound()) && 6138 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 6139 static class EmitOp : public Location::EmitOperator { 6140 public: 6141 EmitOp() : Location::EmitOperator(A32) {} 6142 virtual uint32_t Encode(uint32_t instr, 6143 Location::Offset pc, 6144 const Location* location) const VIXL_OVERRIDE { 6145 pc += kA32PcDelta; 6146 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 6147 VIXL_ASSERT((offset >= -255) && (offset <= 255)); 6148 uint32_t U = (offset >= 0); 6149 int32_t target = abs(offset) | (U << 8); 6150 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 6151 ((target & 0x100) << 15); 6152 } 6153 } immop; 6154 EmitA32( 6155 Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 6156 location, 6157 immop, 6158 &kA32VeryNearDataInfo)); 6159 return; 6160 } 6161 } 6162 Delegate(kLdrh, &Assembler::ldrh, cond, rt, location); 6163 } 6164 6165 bool Assembler::ldrh_info(Condition cond, 6166 Register rt, 6167 Location* location, 6168 const struct ReferenceInfo** info) { 6169 VIXL_ASSERT(!location->IsBound()); 6170 USE(location); 6171 if (IsUsingT32()) { 6172 // LDRH{<c>}{<q>} <Rt>, <label> ; T1 6173 if (!rt.Is(pc)) { 6174 *info = &kT32FarDataInfo; 6175 return true; 6176 } 6177 } else { 6178 // LDRH{<c>}{<q>} <Rt>, <label> ; A1 6179 if (cond.IsNotNever()) { 6180 *info = &kA32VeryNearDataInfo; 6181 return true; 6182 } 6183 } 6184 return false; 6185 } 6186 6187 void Assembler::ldrsb(Condition cond, 6188 EncodingSize size, 6189 Register rt, 6190 const MemOperand& operand) { 6191 VIXL_ASSERT(AllowAssembler()); 6192 CheckIT(cond); 6193 if (operand.IsImmediate()) { 6194 Register rn = operand.GetBaseRegister(); 6195 int32_t offset = operand.GetOffsetImmediate(); 6196 if (IsUsingT32()) { 6197 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 6198 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 6199 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6200 EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6201 (offset & 0xfff)); 6202 AdvanceIT(); 6203 return; 6204 } 6205 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2 6206 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 6207 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6208 EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6209 (-offset & 0xff)); 6210 AdvanceIT(); 6211 return; 6212 } 6213 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2 6214 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 6215 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 6216 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6217 uint32_t offset_ = abs(offset); 6218 EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6219 offset_ | (sign << 9)); 6220 AdvanceIT(); 6221 return; 6222 } 6223 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2 6224 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 6225 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 6226 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6227 uint32_t offset_ = abs(offset); 6228 EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6229 offset_ | (sign << 9)); 6230 AdvanceIT(); 6231 return; 6232 } 6233 // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 6234 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 6235 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 6236 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6237 uint32_t offset_ = abs(offset); 6238 EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 6239 AdvanceIT(); 6240 return; 6241 } 6242 } else { 6243 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1 6244 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 6245 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6246 (!rt.IsPC() || AllowUnpredictable())) { 6247 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6248 uint32_t offset_ = abs(offset); 6249 EmitA32(0x015000d0U | (cond.GetCondition() << 28) | 6250 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6251 ((offset_ & 0xf0) << 4) | (sign << 23)); 6252 return; 6253 } 6254 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1 6255 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 6256 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6257 (!rt.IsPC() || AllowUnpredictable())) { 6258 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6259 uint32_t offset_ = abs(offset); 6260 EmitA32(0x005000d0U | (cond.GetCondition() << 28) | 6261 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6262 ((offset_ & 0xf0) << 4) | (sign << 23)); 6263 return; 6264 } 6265 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1 6266 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 6267 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6268 (!rt.IsPC() || AllowUnpredictable())) { 6269 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6270 uint32_t offset_ = abs(offset); 6271 EmitA32(0x017000d0U | (cond.GetCondition() << 28) | 6272 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6273 ((offset_ & 0xf0) << 4) | (sign << 23)); 6274 return; 6275 } 6276 // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 6277 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 6278 operand.IsOffset() && cond.IsNotNever() && 6279 (!rt.IsPC() || AllowUnpredictable())) { 6280 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6281 uint32_t offset_ = abs(offset); 6282 EmitA32(0x015f00d0U | (cond.GetCondition() << 28) | 6283 (rt.GetCode() << 12) | (offset_ & 0xf) | 6284 ((offset_ & 0xf0) << 4) | (sign << 23)); 6285 return; 6286 } 6287 } 6288 } 6289 if (operand.IsPlainRegister()) { 6290 Register rn = operand.GetBaseRegister(); 6291 Sign sign = operand.GetSign(); 6292 Register rm = operand.GetOffsetRegister(); 6293 if (IsUsingT32()) { 6294 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 6295 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 6296 sign.IsPlus() && operand.IsOffset()) { 6297 EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) | 6298 (rm.GetCode() << 6)); 6299 AdvanceIT(); 6300 return; 6301 } 6302 } else { 6303 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 6304 if (operand.IsOffset() && cond.IsNotNever() && 6305 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6306 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6307 EmitA32(0x011000d0U | (cond.GetCondition() << 28) | 6308 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6309 (sign_ << 23)); 6310 return; 6311 } 6312 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 6313 if (operand.IsPostIndex() && cond.IsNotNever() && 6314 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6315 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6316 EmitA32(0x001000d0U | (cond.GetCondition() << 28) | 6317 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6318 (sign_ << 23)); 6319 return; 6320 } 6321 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 6322 if (operand.IsPreIndex() && cond.IsNotNever() && 6323 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6324 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6325 EmitA32(0x013000d0U | (cond.GetCondition() << 28) | 6326 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6327 (sign_ << 23)); 6328 return; 6329 } 6330 } 6331 } 6332 if (operand.IsShiftedRegister()) { 6333 Register rn = operand.GetBaseRegister(); 6334 Sign sign = operand.GetSign(); 6335 Register rm = operand.GetOffsetRegister(); 6336 Shift shift = operand.GetShift(); 6337 uint32_t amount = operand.GetShiftAmount(); 6338 if (IsUsingT32()) { 6339 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 6340 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 6341 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) && 6342 (!rm.IsPC() || AllowUnpredictable())) { 6343 EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6344 rm.GetCode() | (amount << 4)); 6345 AdvanceIT(); 6346 return; 6347 } 6348 } 6349 } 6350 Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand); 6351 } 6352 6353 void Assembler::ldrsb(Condition cond, Register rt, Location* location) { 6354 VIXL_ASSERT(AllowAssembler()); 6355 CheckIT(cond); 6356 Location::Offset offset = 6357 location->IsBound() 6358 ? location->GetLocation() - 6359 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 6360 : 0; 6361 if (IsUsingT32()) { 6362 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1 6363 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 6364 !location->IsBound()) && 6365 !rt.Is(pc)) { 6366 static class EmitOp : public Location::EmitOperator { 6367 public: 6368 EmitOp() : Location::EmitOperator(T32) {} 6369 virtual uint32_t Encode(uint32_t instr, 6370 Location::Offset pc, 6371 const Location* location) const VIXL_OVERRIDE { 6372 pc += kT32PcDelta; 6373 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 6374 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 6375 uint32_t U = (offset >= 0); 6376 int32_t target = abs(offset) | (U << 12); 6377 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 6378 } 6379 } immop; 6380 EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12), 6381 location, 6382 immop, 6383 &kT32FarDataInfo)); 6384 AdvanceIT(); 6385 return; 6386 } 6387 } else { 6388 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1 6389 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) || 6390 !location->IsBound()) && 6391 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 6392 static class EmitOp : public Location::EmitOperator { 6393 public: 6394 EmitOp() : Location::EmitOperator(A32) {} 6395 virtual uint32_t Encode(uint32_t instr, 6396 Location::Offset pc, 6397 const Location* location) const VIXL_OVERRIDE { 6398 pc += kA32PcDelta; 6399 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 6400 VIXL_ASSERT((offset >= -255) && (offset <= 255)); 6401 uint32_t U = (offset >= 0); 6402 int32_t target = abs(offset) | (U << 8); 6403 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 6404 ((target & 0x100) << 15); 6405 } 6406 } immop; 6407 EmitA32( 6408 Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 6409 location, 6410 immop, 6411 &kA32VeryNearDataInfo)); 6412 return; 6413 } 6414 } 6415 Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, location); 6416 } 6417 6418 bool Assembler::ldrsb_info(Condition cond, 6419 Register rt, 6420 Location* location, 6421 const struct ReferenceInfo** info) { 6422 VIXL_ASSERT(!location->IsBound()); 6423 USE(location); 6424 if (IsUsingT32()) { 6425 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1 6426 if (!rt.Is(pc)) { 6427 *info = &kT32FarDataInfo; 6428 return true; 6429 } 6430 } else { 6431 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1 6432 if (cond.IsNotNever()) { 6433 *info = &kA32VeryNearDataInfo; 6434 return true; 6435 } 6436 } 6437 return false; 6438 } 6439 6440 void Assembler::ldrsh(Condition cond, 6441 EncodingSize size, 6442 Register rt, 6443 const MemOperand& operand) { 6444 VIXL_ASSERT(AllowAssembler()); 6445 CheckIT(cond); 6446 if (operand.IsImmediate()) { 6447 Register rn = operand.GetBaseRegister(); 6448 int32_t offset = operand.GetOffsetImmediate(); 6449 if (IsUsingT32()) { 6450 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 6451 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 6452 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6453 EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6454 (offset & 0xfff)); 6455 AdvanceIT(); 6456 return; 6457 } 6458 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2 6459 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 6460 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6461 EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6462 (-offset & 0xff)); 6463 AdvanceIT(); 6464 return; 6465 } 6466 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2 6467 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 6468 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 6469 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6470 uint32_t offset_ = abs(offset); 6471 EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6472 offset_ | (sign << 9)); 6473 AdvanceIT(); 6474 return; 6475 } 6476 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2 6477 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 6478 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 6479 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6480 uint32_t offset_ = abs(offset); 6481 EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6482 offset_ | (sign << 9)); 6483 AdvanceIT(); 6484 return; 6485 } 6486 // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 6487 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 6488 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 6489 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6490 uint32_t offset_ = abs(offset); 6491 EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 6492 AdvanceIT(); 6493 return; 6494 } 6495 } else { 6496 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1 6497 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 6498 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6499 (!rt.IsPC() || AllowUnpredictable())) { 6500 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6501 uint32_t offset_ = abs(offset); 6502 EmitA32(0x015000f0U | (cond.GetCondition() << 28) | 6503 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6504 ((offset_ & 0xf0) << 4) | (sign << 23)); 6505 return; 6506 } 6507 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1 6508 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 6509 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 6510 (!rt.IsPC() || AllowUnpredictable())) { 6511 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6512 uint32_t offset_ = abs(offset); 6513 EmitA32(0x005000f0U | (cond.GetCondition() << 28) | 6514 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 6515 ((offset_ & 0xf0) << 4) | (sign << 23)); 6516 return; 6517 } 6518 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1 6519 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 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(0x017000f0U | (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>, [PC, #<_plusminus_><imm_1>] ; A1 6530 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 6531 operand.IsOffset() && cond.IsNotNever() && 6532 (!rt.IsPC() || AllowUnpredictable())) { 6533 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 6534 uint32_t offset_ = abs(offset); 6535 EmitA32(0x015f00f0U | (cond.GetCondition() << 28) | 6536 (rt.GetCode() << 12) | (offset_ & 0xf) | 6537 ((offset_ & 0xf0) << 4) | (sign << 23)); 6538 return; 6539 } 6540 } 6541 } 6542 if (operand.IsPlainRegister()) { 6543 Register rn = operand.GetBaseRegister(); 6544 Sign sign = operand.GetSign(); 6545 Register rm = operand.GetOffsetRegister(); 6546 if (IsUsingT32()) { 6547 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 6548 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 6549 sign.IsPlus() && operand.IsOffset()) { 6550 EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) | 6551 (rm.GetCode() << 6)); 6552 AdvanceIT(); 6553 return; 6554 } 6555 } else { 6556 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 6557 if (operand.IsOffset() && cond.IsNotNever() && 6558 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6559 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6560 EmitA32(0x011000f0U | (cond.GetCondition() << 28) | 6561 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6562 (sign_ << 23)); 6563 return; 6564 } 6565 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 6566 if (operand.IsPostIndex() && cond.IsNotNever() && 6567 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6568 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6569 EmitA32(0x001000f0U | (cond.GetCondition() << 28) | 6570 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6571 (sign_ << 23)); 6572 return; 6573 } 6574 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 6575 if (operand.IsPreIndex() && cond.IsNotNever() && 6576 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6577 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 6578 EmitA32(0x013000f0U | (cond.GetCondition() << 28) | 6579 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 6580 (sign_ << 23)); 6581 return; 6582 } 6583 } 6584 } 6585 if (operand.IsShiftedRegister()) { 6586 Register rn = operand.GetBaseRegister(); 6587 Sign sign = operand.GetSign(); 6588 Register rm = operand.GetOffsetRegister(); 6589 Shift shift = operand.GetShift(); 6590 uint32_t amount = operand.GetShiftAmount(); 6591 if (IsUsingT32()) { 6592 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 6593 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 6594 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) && 6595 (!rm.IsPC() || AllowUnpredictable())) { 6596 EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6597 rm.GetCode() | (amount << 4)); 6598 AdvanceIT(); 6599 return; 6600 } 6601 } 6602 } 6603 Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand); 6604 } 6605 6606 void Assembler::ldrsh(Condition cond, Register rt, Location* location) { 6607 VIXL_ASSERT(AllowAssembler()); 6608 CheckIT(cond); 6609 Location::Offset offset = 6610 location->IsBound() 6611 ? location->GetLocation() - 6612 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 6613 : 0; 6614 if (IsUsingT32()) { 6615 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1 6616 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 6617 !location->IsBound()) && 6618 !rt.Is(pc)) { 6619 static class EmitOp : public Location::EmitOperator { 6620 public: 6621 EmitOp() : Location::EmitOperator(T32) {} 6622 virtual uint32_t Encode(uint32_t instr, 6623 Location::Offset pc, 6624 const Location* location) const VIXL_OVERRIDE { 6625 pc += kT32PcDelta; 6626 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 6627 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 6628 uint32_t U = (offset >= 0); 6629 int32_t target = abs(offset) | (U << 12); 6630 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 6631 } 6632 } immop; 6633 EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12), 6634 location, 6635 immop, 6636 &kT32FarDataInfo)); 6637 AdvanceIT(); 6638 return; 6639 } 6640 } else { 6641 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1 6642 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) || 6643 !location->IsBound()) && 6644 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 6645 static class EmitOp : public Location::EmitOperator { 6646 public: 6647 EmitOp() : Location::EmitOperator(A32) {} 6648 virtual uint32_t Encode(uint32_t instr, 6649 Location::Offset pc, 6650 const Location* location) const VIXL_OVERRIDE { 6651 pc += kA32PcDelta; 6652 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 6653 VIXL_ASSERT((offset >= -255) && (offset <= 255)); 6654 uint32_t U = (offset >= 0); 6655 int32_t target = abs(offset) | (U << 8); 6656 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 6657 ((target & 0x100) << 15); 6658 } 6659 } immop; 6660 EmitA32( 6661 Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 6662 location, 6663 immop, 6664 &kA32VeryNearDataInfo)); 6665 return; 6666 } 6667 } 6668 Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, location); 6669 } 6670 6671 bool Assembler::ldrsh_info(Condition cond, 6672 Register rt, 6673 Location* location, 6674 const struct ReferenceInfo** info) { 6675 VIXL_ASSERT(!location->IsBound()); 6676 USE(location); 6677 if (IsUsingT32()) { 6678 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1 6679 if (!rt.Is(pc)) { 6680 *info = &kT32FarDataInfo; 6681 return true; 6682 } 6683 } else { 6684 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1 6685 if (cond.IsNotNever()) { 6686 *info = &kA32VeryNearDataInfo; 6687 return true; 6688 } 6689 } 6690 return false; 6691 } 6692 6693 void Assembler::lsl(Condition cond, 6694 EncodingSize size, 6695 Register rd, 6696 Register rm, 6697 const Operand& operand) { 6698 VIXL_ASSERT(AllowAssembler()); 6699 CheckIT(cond); 6700 if (operand.IsImmediate()) { 6701 uint32_t imm = operand.GetImmediate(); 6702 if (IsUsingT32()) { 6703 // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6704 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6705 (imm >= 1) && (imm <= 31)) { 6706 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6)); 6707 AdvanceIT(); 6708 return; 6709 } 6710 // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6711 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) && 6712 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6713 EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6714 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 6715 AdvanceIT(); 6716 return; 6717 } 6718 } else { 6719 // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6720 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 6721 EmitA32(0x01a00000U | (cond.GetCondition() << 28) | 6722 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 6723 return; 6724 } 6725 } 6726 } 6727 if (operand.IsPlainRegister()) { 6728 Register rs = operand.GetBaseRegister(); 6729 if (IsUsingT32()) { 6730 // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6731 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6732 rs.IsLow()) { 6733 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 6734 AdvanceIT(); 6735 return; 6736 } 6737 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6738 if (!size.IsNarrow() && 6739 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6740 EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6741 rs.GetCode()); 6742 AdvanceIT(); 6743 return; 6744 } 6745 } else { 6746 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6747 if (cond.IsNotNever() && 6748 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6749 EmitA32(0x01a00010U | (cond.GetCondition() << 28) | 6750 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6751 return; 6752 } 6753 } 6754 } 6755 Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand); 6756 } 6757 6758 void Assembler::lsls(Condition cond, 6759 EncodingSize size, 6760 Register rd, 6761 Register rm, 6762 const Operand& operand) { 6763 VIXL_ASSERT(AllowAssembler()); 6764 CheckIT(cond); 6765 if (operand.IsImmediate()) { 6766 uint32_t imm = operand.GetImmediate(); 6767 if (IsUsingT32()) { 6768 // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6769 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6770 (imm >= 1) && (imm <= 31)) { 6771 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6)); 6772 AdvanceIT(); 6773 return; 6774 } 6775 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6776 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) && 6777 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6778 EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6779 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 6780 AdvanceIT(); 6781 return; 6782 } 6783 } else { 6784 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6785 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 6786 EmitA32(0x01b00000U | (cond.GetCondition() << 28) | 6787 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 6788 return; 6789 } 6790 } 6791 } 6792 if (operand.IsPlainRegister()) { 6793 Register rs = operand.GetBaseRegister(); 6794 if (IsUsingT32()) { 6795 // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6796 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6797 rs.IsLow()) { 6798 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 6799 AdvanceIT(); 6800 return; 6801 } 6802 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6803 if (!size.IsNarrow() && 6804 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6805 EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6806 rs.GetCode()); 6807 AdvanceIT(); 6808 return; 6809 } 6810 } else { 6811 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6812 if (cond.IsNotNever() && 6813 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6814 EmitA32(0x01b00010U | (cond.GetCondition() << 28) | 6815 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6816 return; 6817 } 6818 } 6819 } 6820 Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand); 6821 } 6822 6823 void Assembler::lsr(Condition cond, 6824 EncodingSize size, 6825 Register rd, 6826 Register rm, 6827 const Operand& operand) { 6828 VIXL_ASSERT(AllowAssembler()); 6829 CheckIT(cond); 6830 if (operand.IsImmediate()) { 6831 uint32_t imm = operand.GetImmediate(); 6832 if (IsUsingT32()) { 6833 // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6834 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6835 (imm >= 1) && (imm <= 32)) { 6836 uint32_t amount_ = imm % 32; 6837 EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) | 6838 (amount_ << 6)); 6839 AdvanceIT(); 6840 return; 6841 } 6842 // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6843 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) && 6844 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6845 uint32_t amount_ = imm % 32; 6846 EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() | 6847 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6848 AdvanceIT(); 6849 return; 6850 } 6851 } else { 6852 // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6853 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 6854 uint32_t amount_ = imm % 32; 6855 EmitA32(0x01a00020U | (cond.GetCondition() << 28) | 6856 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 6857 return; 6858 } 6859 } 6860 } 6861 if (operand.IsPlainRegister()) { 6862 Register rs = operand.GetBaseRegister(); 6863 if (IsUsingT32()) { 6864 // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6865 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6866 rs.IsLow()) { 6867 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 6868 AdvanceIT(); 6869 return; 6870 } 6871 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6872 if (!size.IsNarrow() && 6873 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6874 EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6875 rs.GetCode()); 6876 AdvanceIT(); 6877 return; 6878 } 6879 } else { 6880 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6881 if (cond.IsNotNever() && 6882 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6883 EmitA32(0x01a00030U | (cond.GetCondition() << 28) | 6884 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6885 return; 6886 } 6887 } 6888 } 6889 Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand); 6890 } 6891 6892 void Assembler::lsrs(Condition cond, 6893 EncodingSize size, 6894 Register rd, 6895 Register rm, 6896 const Operand& operand) { 6897 VIXL_ASSERT(AllowAssembler()); 6898 CheckIT(cond); 6899 if (operand.IsImmediate()) { 6900 uint32_t imm = operand.GetImmediate(); 6901 if (IsUsingT32()) { 6902 // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6903 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6904 (imm >= 1) && (imm <= 32)) { 6905 uint32_t amount_ = imm % 32; 6906 EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) | 6907 (amount_ << 6)); 6908 AdvanceIT(); 6909 return; 6910 } 6911 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6912 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) && 6913 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6914 uint32_t amount_ = imm % 32; 6915 EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() | 6916 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6917 AdvanceIT(); 6918 return; 6919 } 6920 } else { 6921 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6922 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 6923 uint32_t amount_ = imm % 32; 6924 EmitA32(0x01b00020U | (cond.GetCondition() << 28) | 6925 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 6926 return; 6927 } 6928 } 6929 } 6930 if (operand.IsPlainRegister()) { 6931 Register rs = operand.GetBaseRegister(); 6932 if (IsUsingT32()) { 6933 // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6934 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6935 rs.IsLow()) { 6936 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 6937 AdvanceIT(); 6938 return; 6939 } 6940 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6941 if (!size.IsNarrow() && 6942 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6943 EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6944 rs.GetCode()); 6945 AdvanceIT(); 6946 return; 6947 } 6948 } else { 6949 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6950 if (cond.IsNotNever() && 6951 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 6952 EmitA32(0x01b00030U | (cond.GetCondition() << 28) | 6953 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6954 return; 6955 } 6956 } 6957 } 6958 Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand); 6959 } 6960 6961 void Assembler::mla( 6962 Condition cond, Register rd, Register rn, Register rm, Register ra) { 6963 VIXL_ASSERT(AllowAssembler()); 6964 CheckIT(cond); 6965 if (IsUsingT32()) { 6966 // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 6967 if (!ra.Is(pc) && 6968 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6969 EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 6970 rm.GetCode() | (ra.GetCode() << 12)); 6971 AdvanceIT(); 6972 return; 6973 } 6974 } else { 6975 // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 6976 if (cond.IsNotNever() && 6977 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 6978 AllowUnpredictable())) { 6979 EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 6980 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 6981 return; 6982 } 6983 } 6984 Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra); 6985 } 6986 6987 void Assembler::mlas( 6988 Condition cond, Register rd, Register rn, Register rm, Register ra) { 6989 VIXL_ASSERT(AllowAssembler()); 6990 CheckIT(cond); 6991 if (IsUsingA32()) { 6992 // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 6993 if (cond.IsNotNever() && 6994 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 6995 AllowUnpredictable())) { 6996 EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 6997 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 6998 return; 6999 } 7000 } 7001 Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra); 7002 } 7003 7004 void Assembler::mls( 7005 Condition cond, Register rd, Register rn, Register rm, Register ra) { 7006 VIXL_ASSERT(AllowAssembler()); 7007 CheckIT(cond); 7008 if (IsUsingT32()) { 7009 // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 7010 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 7011 AllowUnpredictable())) { 7012 EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7013 rm.GetCode() | (ra.GetCode() << 12)); 7014 AdvanceIT(); 7015 return; 7016 } 7017 } else { 7018 // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 7019 if (cond.IsNotNever() && 7020 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 7021 AllowUnpredictable())) { 7022 EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 7023 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 7024 return; 7025 } 7026 } 7027 Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra); 7028 } 7029 7030 void Assembler::mov(Condition cond, 7031 EncodingSize size, 7032 Register rd, 7033 const Operand& operand) { 7034 VIXL_ASSERT(AllowAssembler()); 7035 CheckIT(cond); 7036 if (operand.IsImmediateShiftedRegister()) { 7037 Register rm = operand.GetBaseRegister(); 7038 if (operand.IsPlainRegister()) { 7039 if (IsUsingT32()) { 7040 // MOV{<c>}{<q>} <Rd>, <Rm> ; T1 7041 if (!size.IsWide() && 7042 ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 7043 AllowUnpredictable())) { 7044 EmitT32_16(0x4600 | (rd.GetCode() & 0x7) | 7045 ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 7046 AdvanceIT(); 7047 return; 7048 } 7049 } 7050 } 7051 Shift shift = operand.GetShift(); 7052 uint32_t amount = operand.GetShiftAmount(); 7053 if (IsUsingT32()) { 7054 // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 7055 if (InITBlock() && !size.IsWide() && rd.IsLow() && 7056 shift.IsValidAmount(amount) && rm.IsLow() && 7057 (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) && 7058 ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) { 7059 uint32_t amount_ = amount % 32; 7060 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | 7061 (operand.GetTypeEncodingValue() << 11) | (amount_ << 6)); 7062 AdvanceIT(); 7063 return; 7064 } 7065 // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3 7066 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 7067 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7068 uint32_t amount_ = amount % 32; 7069 EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() | 7070 (operand.GetTypeEncodingValue() << 4) | 7071 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7072 AdvanceIT(); 7073 return; 7074 } 7075 } else { 7076 // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 7077 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7078 uint32_t amount_ = amount % 32; 7079 EmitA32(0x01a00000U | (cond.GetCondition() << 28) | 7080 (rd.GetCode() << 12) | rm.GetCode() | 7081 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7082 return; 7083 } 7084 } 7085 } 7086 if (operand.IsRegisterShiftedRegister()) { 7087 Register rm = operand.GetBaseRegister(); 7088 Shift shift = operand.GetShift(); 7089 Register rs = operand.GetShiftRegister(); 7090 if (IsUsingT32()) { 7091 // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1 7092 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7093 shift.IsASR() && rs.IsLow()) { 7094 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 7095 AdvanceIT(); 7096 return; 7097 } 7098 // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1 7099 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7100 shift.IsLSL() && rs.IsLow()) { 7101 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 7102 AdvanceIT(); 7103 return; 7104 } 7105 // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1 7106 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7107 shift.IsLSR() && rs.IsLow()) { 7108 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 7109 AdvanceIT(); 7110 return; 7111 } 7112 // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1 7113 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7114 shift.IsROR() && rs.IsLow()) { 7115 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 7116 AdvanceIT(); 7117 return; 7118 } 7119 // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2 7120 if (!size.IsNarrow() && 7121 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7122 EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 7123 (shift.GetType() << 21) | rs.GetCode()); 7124 AdvanceIT(); 7125 return; 7126 } 7127 } else { 7128 // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7129 if (cond.IsNotNever() && 7130 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7131 EmitA32(0x01a00010U | (cond.GetCondition() << 28) | 7132 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7133 (rs.GetCode() << 8)); 7134 return; 7135 } 7136 } 7137 } 7138 if (operand.IsImmediate()) { 7139 uint32_t imm = operand.GetImmediate(); 7140 if (IsUsingT32()) { 7141 ImmediateT32 immediate_t32(imm); 7142 // MOV<c>{<q>} <Rd>, #<imm8> ; T1 7143 if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) { 7144 EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm); 7145 AdvanceIT(); 7146 return; 7147 } 7148 // MOV{<c>}{<q>} <Rd>, #<const> ; T2 7149 if (!size.IsNarrow() && immediate_t32.IsValid() && 7150 (!rd.IsPC() || AllowUnpredictable())) { 7151 EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) | 7152 (immediate_t32.GetEncodingValue() & 0xff) | 7153 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7154 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7155 AdvanceIT(); 7156 return; 7157 } 7158 // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3 7159 if (!size.IsNarrow() && (imm <= 65535) && 7160 (!rd.IsPC() || AllowUnpredictable())) { 7161 EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) | 7162 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 7163 ((imm & 0xf000) << 4)); 7164 AdvanceIT(); 7165 return; 7166 } 7167 } else { 7168 ImmediateA32 immediate_a32(imm); 7169 // MOV{<c>}{<q>} <Rd>, #<const> ; A1 7170 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7171 EmitA32(0x03a00000U | (cond.GetCondition() << 28) | 7172 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 7173 return; 7174 } 7175 // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2 7176 if ((imm <= 65535) && cond.IsNotNever() && 7177 (!rd.IsPC() || AllowUnpredictable())) { 7178 EmitA32(0x03000000U | (cond.GetCondition() << 28) | 7179 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 7180 return; 7181 } 7182 } 7183 } 7184 Delegate(kMov, &Assembler::mov, cond, size, rd, operand); 7185 } 7186 7187 void Assembler::movs(Condition cond, 7188 EncodingSize size, 7189 Register rd, 7190 const Operand& operand) { 7191 VIXL_ASSERT(AllowAssembler()); 7192 CheckIT(cond); 7193 if (operand.IsImmediateShiftedRegister()) { 7194 Register rm = operand.GetBaseRegister(); 7195 Shift shift = operand.GetShift(); 7196 uint32_t amount = operand.GetShiftAmount(); 7197 if (IsUsingT32()) { 7198 // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 7199 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && 7200 shift.IsValidAmount(amount) && rm.IsLow() && 7201 (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) { 7202 uint32_t amount_ = amount % 32; 7203 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | 7204 (operand.GetTypeEncodingValue() << 11) | (amount_ << 6)); 7205 AdvanceIT(); 7206 return; 7207 } 7208 // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3 7209 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 7210 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7211 uint32_t amount_ = amount % 32; 7212 EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() | 7213 (operand.GetTypeEncodingValue() << 4) | 7214 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7215 AdvanceIT(); 7216 return; 7217 } 7218 } else { 7219 // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 7220 if (shift.IsValidAmount(amount) && cond.IsNotNever() && 7221 (!rd.IsPC() || AllowUnpredictable())) { 7222 uint32_t amount_ = amount % 32; 7223 EmitA32(0x01b00000U | (cond.GetCondition() << 28) | 7224 (rd.GetCode() << 12) | rm.GetCode() | 7225 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7226 return; 7227 } 7228 } 7229 } 7230 if (operand.IsRegisterShiftedRegister()) { 7231 Register rm = operand.GetBaseRegister(); 7232 Shift shift = operand.GetShift(); 7233 Register rs = operand.GetShiftRegister(); 7234 if (IsUsingT32()) { 7235 // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1 7236 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7237 shift.IsASR() && rs.IsLow()) { 7238 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 7239 AdvanceIT(); 7240 return; 7241 } 7242 // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1 7243 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7244 shift.IsLSL() && rs.IsLow()) { 7245 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 7246 AdvanceIT(); 7247 return; 7248 } 7249 // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1 7250 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7251 shift.IsLSR() && rs.IsLow()) { 7252 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 7253 AdvanceIT(); 7254 return; 7255 } 7256 // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1 7257 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 7258 shift.IsROR() && rs.IsLow()) { 7259 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 7260 AdvanceIT(); 7261 return; 7262 } 7263 // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2 7264 if (!size.IsNarrow() && 7265 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7266 EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 7267 (shift.GetType() << 21) | rs.GetCode()); 7268 AdvanceIT(); 7269 return; 7270 } 7271 } else { 7272 // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7273 if (cond.IsNotNever() && 7274 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7275 EmitA32(0x01b00010U | (cond.GetCondition() << 28) | 7276 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7277 (rs.GetCode() << 8)); 7278 return; 7279 } 7280 } 7281 } 7282 if (operand.IsImmediate()) { 7283 uint32_t imm = operand.GetImmediate(); 7284 if (IsUsingT32()) { 7285 ImmediateT32 immediate_t32(imm); 7286 // MOVS{<q>} <Rd>, #<imm8> ; T1 7287 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) { 7288 EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm); 7289 AdvanceIT(); 7290 return; 7291 } 7292 // MOVS{<c>}{<q>} <Rd>, #<const> ; T2 7293 if (!size.IsNarrow() && immediate_t32.IsValid() && 7294 (!rd.IsPC() || AllowUnpredictable())) { 7295 EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) | 7296 (immediate_t32.GetEncodingValue() & 0xff) | 7297 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7298 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7299 AdvanceIT(); 7300 return; 7301 } 7302 } else { 7303 ImmediateA32 immediate_a32(imm); 7304 // MOVS{<c>}{<q>} <Rd>, #<const> ; A1 7305 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7306 EmitA32(0x03b00000U | (cond.GetCondition() << 28) | 7307 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 7308 return; 7309 } 7310 } 7311 } 7312 Delegate(kMovs, &Assembler::movs, cond, size, rd, operand); 7313 } 7314 7315 void Assembler::movt(Condition cond, Register rd, const Operand& operand) { 7316 VIXL_ASSERT(AllowAssembler()); 7317 CheckIT(cond); 7318 if (operand.IsImmediate()) { 7319 uint32_t imm = operand.GetImmediate(); 7320 if (IsUsingT32()) { 7321 // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1 7322 if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) { 7323 EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) | 7324 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 7325 ((imm & 0xf000) << 4)); 7326 AdvanceIT(); 7327 return; 7328 } 7329 } else { 7330 // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1 7331 if ((imm <= 65535) && cond.IsNotNever() && 7332 (!rd.IsPC() || AllowUnpredictable())) { 7333 EmitA32(0x03400000U | (cond.GetCondition() << 28) | 7334 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 7335 return; 7336 } 7337 } 7338 } 7339 Delegate(kMovt, &Assembler::movt, cond, rd, operand); 7340 } 7341 7342 void Assembler::movw(Condition cond, Register rd, const Operand& operand) { 7343 VIXL_ASSERT(AllowAssembler()); 7344 CheckIT(cond); 7345 if (operand.IsImmediate()) { 7346 uint32_t imm = operand.GetImmediate(); 7347 if (IsUsingT32()) { 7348 // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3 7349 if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) { 7350 EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) | 7351 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 7352 ((imm & 0xf000) << 4)); 7353 AdvanceIT(); 7354 return; 7355 } 7356 } else { 7357 // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2 7358 if ((imm <= 65535) && cond.IsNotNever() && 7359 (!rd.IsPC() || AllowUnpredictable())) { 7360 EmitA32(0x03000000U | (cond.GetCondition() << 28) | 7361 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 7362 return; 7363 } 7364 } 7365 } 7366 Delegate(kMovw, &Assembler::movw, cond, rd, operand); 7367 } 7368 7369 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) { 7370 VIXL_ASSERT(AllowAssembler()); 7371 CheckIT(cond); 7372 if (IsUsingT32()) { 7373 // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1 7374 if ((!rd.IsPC() || AllowUnpredictable())) { 7375 EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20)); 7376 AdvanceIT(); 7377 return; 7378 } 7379 } else { 7380 // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1 7381 if (cond.IsNotNever() && (!rd.IsPC() || AllowUnpredictable())) { 7382 EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7383 (spec_reg.GetReg() << 22)); 7384 return; 7385 } 7386 } 7387 Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg); 7388 } 7389 7390 void Assembler::msr(Condition cond, 7391 MaskedSpecialRegister spec_reg, 7392 const Operand& operand) { 7393 VIXL_ASSERT(AllowAssembler()); 7394 CheckIT(cond); 7395 if (operand.IsImmediate()) { 7396 uint32_t imm = operand.GetImmediate(); 7397 if (IsUsingA32()) { 7398 ImmediateA32 immediate_a32(imm); 7399 // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1 7400 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7401 EmitA32(0x0320f000U | (cond.GetCondition() << 28) | 7402 ((spec_reg.GetReg() & 0xf) << 16) | 7403 ((spec_reg.GetReg() & 0x10) << 18) | 7404 immediate_a32.GetEncodingValue()); 7405 return; 7406 } 7407 } 7408 } 7409 if (operand.IsPlainRegister()) { 7410 Register rn = operand.GetBaseRegister(); 7411 if (IsUsingT32()) { 7412 // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1 7413 if ((!rn.IsPC() || AllowUnpredictable())) { 7414 EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) | 7415 ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16)); 7416 AdvanceIT(); 7417 return; 7418 } 7419 } else { 7420 // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1 7421 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 7422 EmitA32(0x0120f000U | (cond.GetCondition() << 28) | 7423 ((spec_reg.GetReg() & 0xf) << 16) | 7424 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode()); 7425 return; 7426 } 7427 } 7428 } 7429 Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand); 7430 } 7431 7432 void Assembler::mul( 7433 Condition cond, EncodingSize size, Register rd, Register rn, Register rm) { 7434 VIXL_ASSERT(AllowAssembler()); 7435 CheckIT(cond); 7436 if (IsUsingT32()) { 7437 // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1 7438 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() && 7439 rm.IsLow()) { 7440 EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3)); 7441 AdvanceIT(); 7442 return; 7443 } 7444 // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2 7445 if (!size.IsNarrow() && 7446 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7447 EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7448 rm.GetCode()); 7449 AdvanceIT(); 7450 return; 7451 } 7452 } else { 7453 // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1 7454 if (cond.IsNotNever() && 7455 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7456 EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 7457 rn.GetCode() | (rm.GetCode() << 8)); 7458 return; 7459 } 7460 } 7461 Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm); 7462 } 7463 7464 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) { 7465 VIXL_ASSERT(AllowAssembler()); 7466 CheckIT(cond); 7467 if (IsUsingT32()) { 7468 // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1 7469 if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) { 7470 EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3)); 7471 AdvanceIT(); 7472 return; 7473 } 7474 } else { 7475 // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1 7476 if (cond.IsNotNever() && 7477 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7478 EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 7479 rn.GetCode() | (rm.GetCode() << 8)); 7480 return; 7481 } 7482 } 7483 Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm); 7484 } 7485 7486 void Assembler::mvn(Condition cond, 7487 EncodingSize size, 7488 Register rd, 7489 const Operand& operand) { 7490 VIXL_ASSERT(AllowAssembler()); 7491 CheckIT(cond); 7492 if (operand.IsImmediate()) { 7493 uint32_t imm = operand.GetImmediate(); 7494 if (IsUsingT32()) { 7495 ImmediateT32 immediate_t32(imm); 7496 // MVN{<c>}{<q>} <Rd>, #<const> ; T1 7497 if (!size.IsNarrow() && immediate_t32.IsValid() && 7498 (!rd.IsPC() || AllowUnpredictable())) { 7499 EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) | 7500 (immediate_t32.GetEncodingValue() & 0xff) | 7501 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7502 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7503 AdvanceIT(); 7504 return; 7505 } 7506 } else { 7507 ImmediateA32 immediate_a32(imm); 7508 // MVN{<c>}{<q>} <Rd>, #<const> ; A1 7509 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7510 EmitA32(0x03e00000U | (cond.GetCondition() << 28) | 7511 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 7512 return; 7513 } 7514 } 7515 } 7516 if (operand.IsImmediateShiftedRegister()) { 7517 Register rm = operand.GetBaseRegister(); 7518 if (operand.IsPlainRegister()) { 7519 if (IsUsingT32()) { 7520 // MVN<c>{<q>} <Rd>, <Rm> ; T1 7521 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) { 7522 EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3)); 7523 AdvanceIT(); 7524 return; 7525 } 7526 } 7527 } 7528 Shift shift = operand.GetShift(); 7529 uint32_t amount = operand.GetShiftAmount(); 7530 if (IsUsingT32()) { 7531 // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 7532 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 7533 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7534 uint32_t amount_ = amount % 32; 7535 EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() | 7536 (operand.GetTypeEncodingValue() << 4) | 7537 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7538 AdvanceIT(); 7539 return; 7540 } 7541 } else { 7542 // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 7543 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7544 uint32_t amount_ = amount % 32; 7545 EmitA32(0x01e00000U | (cond.GetCondition() << 28) | 7546 (rd.GetCode() << 12) | rm.GetCode() | 7547 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7548 return; 7549 } 7550 } 7551 } 7552 if (operand.IsRegisterShiftedRegister()) { 7553 Register rm = operand.GetBaseRegister(); 7554 Shift shift = operand.GetShift(); 7555 Register rs = operand.GetShiftRegister(); 7556 if (IsUsingA32()) { 7557 // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7558 if (cond.IsNotNever() && 7559 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7560 EmitA32(0x01e00010U | (cond.GetCondition() << 28) | 7561 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7562 (rs.GetCode() << 8)); 7563 return; 7564 } 7565 } 7566 } 7567 Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand); 7568 } 7569 7570 void Assembler::mvns(Condition cond, 7571 EncodingSize size, 7572 Register rd, 7573 const Operand& operand) { 7574 VIXL_ASSERT(AllowAssembler()); 7575 CheckIT(cond); 7576 if (operand.IsImmediate()) { 7577 uint32_t imm = operand.GetImmediate(); 7578 if (IsUsingT32()) { 7579 ImmediateT32 immediate_t32(imm); 7580 // MVNS{<c>}{<q>} <Rd>, #<const> ; T1 7581 if (!size.IsNarrow() && immediate_t32.IsValid() && 7582 (!rd.IsPC() || AllowUnpredictable())) { 7583 EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) | 7584 (immediate_t32.GetEncodingValue() & 0xff) | 7585 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7586 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7587 AdvanceIT(); 7588 return; 7589 } 7590 } else { 7591 ImmediateA32 immediate_a32(imm); 7592 // MVNS{<c>}{<q>} <Rd>, #<const> ; A1 7593 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7594 EmitA32(0x03f00000U | (cond.GetCondition() << 28) | 7595 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 7596 return; 7597 } 7598 } 7599 } 7600 if (operand.IsImmediateShiftedRegister()) { 7601 Register rm = operand.GetBaseRegister(); 7602 if (operand.IsPlainRegister()) { 7603 if (IsUsingT32()) { 7604 // MVNS{<q>} <Rd>, <Rm> ; T1 7605 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) { 7606 EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3)); 7607 AdvanceIT(); 7608 return; 7609 } 7610 } 7611 } 7612 Shift shift = operand.GetShift(); 7613 uint32_t amount = operand.GetShiftAmount(); 7614 if (IsUsingT32()) { 7615 // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 7616 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 7617 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7618 uint32_t amount_ = amount % 32; 7619 EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() | 7620 (operand.GetTypeEncodingValue() << 4) | 7621 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7622 AdvanceIT(); 7623 return; 7624 } 7625 } else { 7626 // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 7627 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7628 uint32_t amount_ = amount % 32; 7629 EmitA32(0x01f00000U | (cond.GetCondition() << 28) | 7630 (rd.GetCode() << 12) | rm.GetCode() | 7631 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7632 return; 7633 } 7634 } 7635 } 7636 if (operand.IsRegisterShiftedRegister()) { 7637 Register rm = operand.GetBaseRegister(); 7638 Shift shift = operand.GetShift(); 7639 Register rs = operand.GetShiftRegister(); 7640 if (IsUsingA32()) { 7641 // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7642 if (cond.IsNotNever() && 7643 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 7644 EmitA32(0x01f00010U | (cond.GetCondition() << 28) | 7645 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7646 (rs.GetCode() << 8)); 7647 return; 7648 } 7649 } 7650 } 7651 Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand); 7652 } 7653 7654 void Assembler::nop(Condition cond, EncodingSize size) { 7655 VIXL_ASSERT(AllowAssembler()); 7656 CheckIT(cond); 7657 if (IsUsingT32()) { 7658 // NOP{<c>}{<q>} ; T1 7659 if (!size.IsWide()) { 7660 EmitT32_16(0xbf00); 7661 AdvanceIT(); 7662 return; 7663 } 7664 // NOP{<c>}.W ; T2 7665 if (!size.IsNarrow()) { 7666 EmitT32_32(0xf3af8000U); 7667 AdvanceIT(); 7668 return; 7669 } 7670 } else { 7671 // NOP{<c>}{<q>} ; A1 7672 if (cond.IsNotNever()) { 7673 EmitA32(0x0320f000U | (cond.GetCondition() << 28)); 7674 return; 7675 } 7676 } 7677 Delegate(kNop, &Assembler::nop, cond, size); 7678 } 7679 7680 void Assembler::orn(Condition cond, 7681 Register rd, 7682 Register rn, 7683 const Operand& operand) { 7684 VIXL_ASSERT(AllowAssembler()); 7685 CheckIT(cond); 7686 if (operand.IsImmediate()) { 7687 uint32_t imm = operand.GetImmediate(); 7688 if (IsUsingT32()) { 7689 ImmediateT32 immediate_t32(imm); 7690 // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7691 if (immediate_t32.IsValid() && !rn.Is(pc) && 7692 (!rd.IsPC() || AllowUnpredictable())) { 7693 EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7694 (immediate_t32.GetEncodingValue() & 0xff) | 7695 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7696 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7697 AdvanceIT(); 7698 return; 7699 } 7700 } 7701 } 7702 if (operand.IsImmediateShiftedRegister()) { 7703 Register rm = operand.GetBaseRegister(); 7704 Shift shift = operand.GetShift(); 7705 uint32_t amount = operand.GetShiftAmount(); 7706 if (IsUsingT32()) { 7707 // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 7708 if (shift.IsValidAmount(amount) && !rn.Is(pc) && 7709 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7710 uint32_t amount_ = amount % 32; 7711 EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7712 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7713 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7714 AdvanceIT(); 7715 return; 7716 } 7717 } 7718 } 7719 Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand); 7720 } 7721 7722 void Assembler::orns(Condition cond, 7723 Register rd, 7724 Register rn, 7725 const Operand& operand) { 7726 VIXL_ASSERT(AllowAssembler()); 7727 CheckIT(cond); 7728 if (operand.IsImmediate()) { 7729 uint32_t imm = operand.GetImmediate(); 7730 if (IsUsingT32()) { 7731 ImmediateT32 immediate_t32(imm); 7732 // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7733 if (immediate_t32.IsValid() && !rn.Is(pc) && 7734 (!rd.IsPC() || AllowUnpredictable())) { 7735 EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7736 (immediate_t32.GetEncodingValue() & 0xff) | 7737 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7738 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7739 AdvanceIT(); 7740 return; 7741 } 7742 } 7743 } 7744 if (operand.IsImmediateShiftedRegister()) { 7745 Register rm = operand.GetBaseRegister(); 7746 Shift shift = operand.GetShift(); 7747 uint32_t amount = operand.GetShiftAmount(); 7748 if (IsUsingT32()) { 7749 // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 7750 if (shift.IsValidAmount(amount) && !rn.Is(pc) && 7751 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7752 uint32_t amount_ = amount % 32; 7753 EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7754 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7755 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7756 AdvanceIT(); 7757 return; 7758 } 7759 } 7760 } 7761 Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand); 7762 } 7763 7764 void Assembler::orr(Condition cond, 7765 EncodingSize size, 7766 Register rd, 7767 Register rn, 7768 const Operand& operand) { 7769 VIXL_ASSERT(AllowAssembler()); 7770 CheckIT(cond); 7771 if (operand.IsImmediate()) { 7772 uint32_t imm = operand.GetImmediate(); 7773 if (IsUsingT32()) { 7774 ImmediateT32 immediate_t32(imm); 7775 // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7776 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) && 7777 (!rd.IsPC() || AllowUnpredictable())) { 7778 EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7779 (immediate_t32.GetEncodingValue() & 0xff) | 7780 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7781 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7782 AdvanceIT(); 7783 return; 7784 } 7785 } else { 7786 ImmediateA32 immediate_a32(imm); 7787 // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 7788 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7789 EmitA32(0x03800000U | (cond.GetCondition() << 28) | 7790 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 7791 immediate_a32.GetEncodingValue()); 7792 return; 7793 } 7794 } 7795 } 7796 if (operand.IsImmediateShiftedRegister()) { 7797 Register rm = operand.GetBaseRegister(); 7798 if (operand.IsPlainRegister()) { 7799 if (IsUsingT32()) { 7800 // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 7801 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 7802 rm.IsLow()) { 7803 EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3)); 7804 AdvanceIT(); 7805 return; 7806 } 7807 } 7808 } 7809 Shift shift = operand.GetShift(); 7810 uint32_t amount = operand.GetShiftAmount(); 7811 if (IsUsingT32()) { 7812 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 7813 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) && 7814 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7815 uint32_t amount_ = amount % 32; 7816 EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7817 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7818 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7819 AdvanceIT(); 7820 return; 7821 } 7822 } else { 7823 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 7824 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7825 uint32_t amount_ = amount % 32; 7826 EmitA32(0x01800000U | (cond.GetCondition() << 28) | 7827 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7828 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7829 return; 7830 } 7831 } 7832 } 7833 if (operand.IsRegisterShiftedRegister()) { 7834 Register rm = operand.GetBaseRegister(); 7835 Shift shift = operand.GetShift(); 7836 Register rs = operand.GetShiftRegister(); 7837 if (IsUsingA32()) { 7838 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 7839 if (cond.IsNotNever() && 7840 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 7841 AllowUnpredictable())) { 7842 EmitA32(0x01800010U | (cond.GetCondition() << 28) | 7843 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7844 (shift.GetType() << 5) | (rs.GetCode() << 8)); 7845 return; 7846 } 7847 } 7848 } 7849 Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand); 7850 } 7851 7852 void Assembler::orrs(Condition cond, 7853 EncodingSize size, 7854 Register rd, 7855 Register rn, 7856 const Operand& operand) { 7857 VIXL_ASSERT(AllowAssembler()); 7858 CheckIT(cond); 7859 if (operand.IsImmediate()) { 7860 uint32_t imm = operand.GetImmediate(); 7861 if (IsUsingT32()) { 7862 ImmediateT32 immediate_t32(imm); 7863 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7864 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) && 7865 (!rd.IsPC() || AllowUnpredictable())) { 7866 EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7867 (immediate_t32.GetEncodingValue() & 0xff) | 7868 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7869 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7870 AdvanceIT(); 7871 return; 7872 } 7873 } else { 7874 ImmediateA32 immediate_a32(imm); 7875 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 7876 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7877 EmitA32(0x03900000U | (cond.GetCondition() << 28) | 7878 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 7879 immediate_a32.GetEncodingValue()); 7880 return; 7881 } 7882 } 7883 } 7884 if (operand.IsImmediateShiftedRegister()) { 7885 Register rm = operand.GetBaseRegister(); 7886 if (operand.IsPlainRegister()) { 7887 if (IsUsingT32()) { 7888 // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 7889 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 7890 rm.IsLow()) { 7891 EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3)); 7892 AdvanceIT(); 7893 return; 7894 } 7895 } 7896 } 7897 Shift shift = operand.GetShift(); 7898 uint32_t amount = operand.GetShiftAmount(); 7899 if (IsUsingT32()) { 7900 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 7901 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) && 7902 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7903 uint32_t amount_ = amount % 32; 7904 EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7905 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7906 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7907 AdvanceIT(); 7908 return; 7909 } 7910 } else { 7911 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 7912 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7913 uint32_t amount_ = amount % 32; 7914 EmitA32(0x01900000U | (cond.GetCondition() << 28) | 7915 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7916 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7917 return; 7918 } 7919 } 7920 } 7921 if (operand.IsRegisterShiftedRegister()) { 7922 Register rm = operand.GetBaseRegister(); 7923 Shift shift = operand.GetShift(); 7924 Register rs = operand.GetShiftRegister(); 7925 if (IsUsingA32()) { 7926 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 7927 if (cond.IsNotNever() && 7928 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 7929 AllowUnpredictable())) { 7930 EmitA32(0x01900010U | (cond.GetCondition() << 28) | 7931 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7932 (shift.GetType() << 5) | (rs.GetCode() << 8)); 7933 return; 7934 } 7935 } 7936 } 7937 Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand); 7938 } 7939 7940 void Assembler::pkhbt(Condition cond, 7941 Register rd, 7942 Register rn, 7943 const Operand& operand) { 7944 VIXL_ASSERT(AllowAssembler()); 7945 CheckIT(cond); 7946 if (operand.IsImmediateShiftedRegister()) { 7947 Register rm = operand.GetBaseRegister(); 7948 Shift shift = operand.GetShift(); 7949 uint32_t amount = operand.GetShiftAmount(); 7950 if (IsUsingT32()) { 7951 // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1 7952 if (shift.IsLSL() && shift.IsValidAmount(amount) && 7953 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7954 EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7955 rm.GetCode() | ((amount & 0x3) << 6) | 7956 ((amount & 0x1c) << 10)); 7957 AdvanceIT(); 7958 return; 7959 } 7960 } else { 7961 // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1 7962 if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever() && 7963 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7964 EmitA32(0x06800010U | (cond.GetCondition() << 28) | 7965 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7966 (amount << 7)); 7967 return; 7968 } 7969 } 7970 } 7971 Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand); 7972 } 7973 7974 void Assembler::pkhtb(Condition cond, 7975 Register rd, 7976 Register rn, 7977 const Operand& operand) { 7978 VIXL_ASSERT(AllowAssembler()); 7979 CheckIT(cond); 7980 if (operand.IsImmediateShiftedRegister()) { 7981 Register rm = operand.GetBaseRegister(); 7982 Shift shift = operand.GetShift(); 7983 uint32_t amount = operand.GetShiftAmount(); 7984 if (IsUsingT32()) { 7985 // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1 7986 if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) && 7987 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 7988 uint32_t amount_ = amount % 32; 7989 EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7990 rm.GetCode() | ((amount_ & 0x3) << 6) | 7991 ((amount_ & 0x1c) << 10)); 7992 AdvanceIT(); 7993 return; 7994 } 7995 } else { 7996 // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1 7997 if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) && 7998 cond.IsNotNever() && 7999 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8000 uint32_t amount_ = amount % 32; 8001 EmitA32(0x06800050U | (cond.GetCondition() << 28) | 8002 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8003 (amount_ << 7)); 8004 return; 8005 } 8006 } 8007 } 8008 Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand); 8009 } 8010 8011 void Assembler::pld(Condition cond, Location* location) { 8012 VIXL_ASSERT(AllowAssembler()); 8013 CheckIT(cond); 8014 Location::Offset offset = 8015 location->IsBound() 8016 ? location->GetLocation() - 8017 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 8018 : 0; 8019 if (IsUsingT32()) { 8020 // PLD{<c>}{<q>} <label> ; T1 8021 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 8022 !location->IsBound())) { 8023 static class EmitOp : public Location::EmitOperator { 8024 public: 8025 EmitOp() : Location::EmitOperator(T32) {} 8026 virtual uint32_t Encode(uint32_t instr, 8027 Location::Offset pc, 8028 const Location* location) const VIXL_OVERRIDE { 8029 pc += kT32PcDelta; 8030 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 8031 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 8032 uint32_t U = (offset >= 0); 8033 int32_t target = abs(offset) | (U << 12); 8034 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 8035 } 8036 } immop; 8037 EmitT32_32(Link(0xf81ff000U, location, immop, &kT32FarDataInfo)); 8038 AdvanceIT(); 8039 return; 8040 } 8041 } else { 8042 // PLD{<c>}{<q>} <label> ; A1 8043 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 8044 !location->IsBound())) { 8045 if (cond.Is(al)) { 8046 static class EmitOp : public Location::EmitOperator { 8047 public: 8048 EmitOp() : Location::EmitOperator(A32) {} 8049 virtual uint32_t Encode(uint32_t instr, 8050 Location::Offset pc, 8051 const Location* location) const 8052 VIXL_OVERRIDE { 8053 pc += kA32PcDelta; 8054 Location::Offset offset = 8055 location->GetLocation() - AlignDown(pc, 4); 8056 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 8057 uint32_t U = (offset >= 0); 8058 int32_t target = abs(offset) | (U << 12); 8059 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 8060 } 8061 } immop; 8062 EmitA32(Link(0xf55ff000U, location, immop, &kA32FarDataInfo)); 8063 return; 8064 } 8065 } 8066 } 8067 Delegate(kPld, &Assembler::pld, cond, location); 8068 } 8069 8070 bool Assembler::pld_info(Condition cond, 8071 Location* location, 8072 const struct ReferenceInfo** info) { 8073 VIXL_ASSERT(!location->IsBound()); 8074 USE(location); 8075 USE(cond); 8076 if (IsUsingT32()) { 8077 // PLD{<c>}{<q>} <label> ; T1 8078 if (true) { 8079 *info = &kT32FarDataInfo; 8080 return true; 8081 } 8082 } else { 8083 // PLD{<c>}{<q>} <label> ; A1 8084 if (true) { 8085 *info = &kA32FarDataInfo; 8086 return true; 8087 } 8088 } 8089 return false; 8090 } 8091 8092 void Assembler::pld(Condition cond, const MemOperand& operand) { 8093 VIXL_ASSERT(AllowAssembler()); 8094 CheckIT(cond); 8095 if (operand.IsImmediate()) { 8096 Register rn = operand.GetBaseRegister(); 8097 int32_t offset = operand.GetOffsetImmediate(); 8098 if (IsUsingT32()) { 8099 // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1 8100 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 8101 operand.IsOffset()) { 8102 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8103 uint32_t offset_ = abs(offset); 8104 EmitT32_32(0xf81ff000U | offset_ | (sign << 23)); 8105 AdvanceIT(); 8106 return; 8107 } 8108 } else { 8109 // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1 8110 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 8111 operand.IsOffset()) { 8112 if (cond.Is(al)) { 8113 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8114 uint32_t offset_ = abs(offset); 8115 EmitA32(0xf55ff000U | offset_ | (sign << 23)); 8116 return; 8117 } 8118 } 8119 } 8120 } 8121 if (operand.IsImmediate()) { 8122 Register rn = operand.GetBaseRegister(); 8123 int32_t offset = operand.GetOffsetImmediate(); 8124 if (IsUsingT32()) { 8125 // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 8126 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 8127 ((rn.GetCode() & 0xf) != 0xf)) { 8128 EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 8129 AdvanceIT(); 8130 return; 8131 } 8132 // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 8133 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 8134 ((rn.GetCode() & 0xf) != 0xf)) { 8135 EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 8136 AdvanceIT(); 8137 return; 8138 } 8139 } else { 8140 // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1 8141 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 8142 ((rn.GetCode() & 0xf) != 0xf)) { 8143 if (cond.Is(al)) { 8144 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8145 uint32_t offset_ = abs(offset); 8146 EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 8147 return; 8148 } 8149 } 8150 } 8151 } 8152 if (operand.IsShiftedRegister()) { 8153 Register rn = operand.GetBaseRegister(); 8154 Sign sign = operand.GetSign(); 8155 Register rm = operand.GetOffsetRegister(); 8156 Shift shift = operand.GetShift(); 8157 uint32_t amount = operand.GetShiftAmount(); 8158 if (IsUsingT32()) { 8159 // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 8160 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 8161 ((rn.GetCode() & 0xf) != 0xf) && 8162 (!rm.IsPC() || AllowUnpredictable())) { 8163 EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() | 8164 (amount << 4)); 8165 AdvanceIT(); 8166 return; 8167 } 8168 } else { 8169 // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 8170 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() && 8171 (!rm.IsPC() || AllowUnpredictable())) { 8172 if (cond.Is(al)) { 8173 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8174 uint32_t amount_ = amount % 32; 8175 EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() | 8176 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 8177 return; 8178 } 8179 } 8180 // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 8181 if (shift.IsRRX() && operand.IsOffset() && 8182 (!rm.IsPC() || AllowUnpredictable())) { 8183 if (cond.Is(al)) { 8184 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8185 EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() | 8186 (sign_ << 23)); 8187 return; 8188 } 8189 } 8190 } 8191 } 8192 Delegate(kPld, &Assembler::pld, cond, operand); 8193 } 8194 8195 void Assembler::pldw(Condition cond, const MemOperand& operand) { 8196 VIXL_ASSERT(AllowAssembler()); 8197 CheckIT(cond); 8198 if (operand.IsImmediate()) { 8199 Register rn = operand.GetBaseRegister(); 8200 int32_t offset = operand.GetOffsetImmediate(); 8201 if (IsUsingT32()) { 8202 // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 8203 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 8204 ((rn.GetCode() & 0xf) != 0xf)) { 8205 EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 8206 AdvanceIT(); 8207 return; 8208 } 8209 // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 8210 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 8211 ((rn.GetCode() & 0xf) != 0xf)) { 8212 EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 8213 AdvanceIT(); 8214 return; 8215 } 8216 } else { 8217 // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1 8218 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 8219 ((rn.GetCode() & 0xf) != 0xf)) { 8220 if (cond.Is(al)) { 8221 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8222 uint32_t offset_ = abs(offset); 8223 EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 8224 return; 8225 } 8226 } 8227 } 8228 } 8229 if (operand.IsShiftedRegister()) { 8230 Register rn = operand.GetBaseRegister(); 8231 Sign sign = operand.GetSign(); 8232 Register rm = operand.GetOffsetRegister(); 8233 Shift shift = operand.GetShift(); 8234 uint32_t amount = operand.GetShiftAmount(); 8235 if (IsUsingT32()) { 8236 // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 8237 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 8238 ((rn.GetCode() & 0xf) != 0xf) && 8239 (!rm.IsPC() || AllowUnpredictable())) { 8240 EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() | 8241 (amount << 4)); 8242 AdvanceIT(); 8243 return; 8244 } 8245 } else { 8246 // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 8247 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() && 8248 (!rm.IsPC() || AllowUnpredictable())) { 8249 if (cond.Is(al)) { 8250 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8251 uint32_t amount_ = amount % 32; 8252 EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() | 8253 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 8254 return; 8255 } 8256 } 8257 // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 8258 if (shift.IsRRX() && operand.IsOffset() && 8259 (!rm.IsPC() || AllowUnpredictable())) { 8260 if (cond.Is(al)) { 8261 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8262 EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() | 8263 (sign_ << 23)); 8264 return; 8265 } 8266 } 8267 } 8268 } 8269 Delegate(kPldw, &Assembler::pldw, cond, operand); 8270 } 8271 8272 void Assembler::pli(Condition cond, const MemOperand& operand) { 8273 VIXL_ASSERT(AllowAssembler()); 8274 CheckIT(cond); 8275 if (operand.IsImmediate()) { 8276 Register rn = operand.GetBaseRegister(); 8277 int32_t offset = operand.GetOffsetImmediate(); 8278 if (IsUsingT32()) { 8279 // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 8280 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 8281 ((rn.GetCode() & 0xf) != 0xf)) { 8282 EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 8283 AdvanceIT(); 8284 return; 8285 } 8286 // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 8287 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 8288 ((rn.GetCode() & 0xf) != 0xf)) { 8289 EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 8290 AdvanceIT(); 8291 return; 8292 } 8293 } else { 8294 // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1 8295 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 8296 ((rn.GetCode() & 0xf) != 0xf)) { 8297 if (cond.Is(al)) { 8298 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8299 uint32_t offset_ = abs(offset); 8300 EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 8301 return; 8302 } 8303 } 8304 } 8305 } 8306 if (operand.IsImmediate()) { 8307 Register rn = operand.GetBaseRegister(); 8308 int32_t offset = operand.GetOffsetImmediate(); 8309 if (IsUsingT32()) { 8310 // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3 8311 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 8312 operand.IsOffset()) { 8313 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8314 uint32_t offset_ = abs(offset); 8315 EmitT32_32(0xf91ff000U | offset_ | (sign << 23)); 8316 AdvanceIT(); 8317 return; 8318 } 8319 } else { 8320 // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1 8321 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 8322 operand.IsOffset()) { 8323 if (cond.Is(al)) { 8324 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 8325 uint32_t offset_ = abs(offset); 8326 EmitA32(0xf45ff000U | offset_ | (sign << 23)); 8327 return; 8328 } 8329 } 8330 } 8331 } 8332 if (operand.IsShiftedRegister()) { 8333 Register rn = operand.GetBaseRegister(); 8334 Sign sign = operand.GetSign(); 8335 Register rm = operand.GetOffsetRegister(); 8336 Shift shift = operand.GetShift(); 8337 uint32_t amount = operand.GetShiftAmount(); 8338 if (IsUsingT32()) { 8339 // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 8340 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 8341 ((rn.GetCode() & 0xf) != 0xf) && 8342 (!rm.IsPC() || AllowUnpredictable())) { 8343 EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() | 8344 (amount << 4)); 8345 AdvanceIT(); 8346 return; 8347 } 8348 } else { 8349 // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 8350 if (shift.IsRRX() && operand.IsOffset() && 8351 (!rm.IsPC() || AllowUnpredictable())) { 8352 if (cond.Is(al)) { 8353 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8354 EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() | 8355 (sign_ << 23)); 8356 return; 8357 } 8358 } 8359 // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 8360 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() && 8361 (!rm.IsPC() || AllowUnpredictable())) { 8362 if (cond.Is(al)) { 8363 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 8364 uint32_t amount_ = amount % 32; 8365 EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() | 8366 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 8367 return; 8368 } 8369 } 8370 } 8371 } 8372 Delegate(kPli, &Assembler::pli, cond, operand); 8373 } 8374 8375 void Assembler::pli(Condition cond, Location* location) { 8376 VIXL_ASSERT(AllowAssembler()); 8377 CheckIT(cond); 8378 Location::Offset offset = 8379 location->IsBound() 8380 ? location->GetLocation() - 8381 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 8382 : 0; 8383 if (IsUsingT32()) { 8384 // PLI{<c>}{<q>} <label> ; T3 8385 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 8386 !location->IsBound())) { 8387 static class EmitOp : public Location::EmitOperator { 8388 public: 8389 EmitOp() : Location::EmitOperator(T32) {} 8390 virtual uint32_t Encode(uint32_t instr, 8391 Location::Offset pc, 8392 const Location* location) const VIXL_OVERRIDE { 8393 pc += kT32PcDelta; 8394 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 8395 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 8396 uint32_t U = (offset >= 0); 8397 int32_t target = abs(offset) | (U << 12); 8398 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 8399 } 8400 } immop; 8401 EmitT32_32(Link(0xf91ff000U, location, immop, &kT32FarDataInfo)); 8402 AdvanceIT(); 8403 return; 8404 } 8405 } else { 8406 // PLI{<c>}{<q>} <label> ; A1 8407 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) || 8408 !location->IsBound())) { 8409 if (cond.Is(al)) { 8410 static class EmitOp : public Location::EmitOperator { 8411 public: 8412 EmitOp() : Location::EmitOperator(A32) {} 8413 virtual uint32_t Encode(uint32_t instr, 8414 Location::Offset pc, 8415 const Location* location) const 8416 VIXL_OVERRIDE { 8417 pc += kA32PcDelta; 8418 Location::Offset offset = 8419 location->GetLocation() - AlignDown(pc, 4); 8420 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 8421 uint32_t U = (offset >= 0); 8422 int32_t target = abs(offset) | (U << 12); 8423 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 8424 } 8425 } immop; 8426 EmitA32(Link(0xf45ff000U, location, immop, &kA32FarDataInfo)); 8427 return; 8428 } 8429 } 8430 } 8431 Delegate(kPli, &Assembler::pli, cond, location); 8432 } 8433 8434 bool Assembler::pli_info(Condition cond, 8435 Location* location, 8436 const struct ReferenceInfo** info) { 8437 VIXL_ASSERT(!location->IsBound()); 8438 USE(location); 8439 USE(cond); 8440 if (IsUsingT32()) { 8441 // PLI{<c>}{<q>} <label> ; T3 8442 if (true) { 8443 *info = &kT32FarDataInfo; 8444 return true; 8445 } 8446 } else { 8447 // PLI{<c>}{<q>} <label> ; A1 8448 if (true) { 8449 *info = &kA32FarDataInfo; 8450 return true; 8451 } 8452 } 8453 return false; 8454 } 8455 8456 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) { 8457 VIXL_ASSERT(AllowAssembler()); 8458 CheckIT(cond); 8459 if (IsUsingT32()) { 8460 // POP{<c>}{<q>} <registers> ; T1 8461 if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) { 8462 EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) | 8463 GetRegisterListEncoding(registers, 0, 8)); 8464 AdvanceIT(); 8465 return; 8466 } 8467 // POP{<c>}{<q>} <registers> ; T2 8468 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) { 8469 EmitT32_32(0xe8bd0000U | 8470 (GetRegisterListEncoding(registers, 15, 1) << 15) | 8471 (GetRegisterListEncoding(registers, 14, 1) << 14) | 8472 GetRegisterListEncoding(registers, 0, 13)); 8473 AdvanceIT(); 8474 return; 8475 } 8476 } else { 8477 // POP{<c>}{<q>} <registers> ; A1 8478 if (cond.IsNotNever()) { 8479 EmitA32(0x08bd0000U | (cond.GetCondition() << 28) | 8480 GetRegisterListEncoding(registers, 0, 16)); 8481 return; 8482 } 8483 } 8484 Delegate(kPop, &Assembler::pop, cond, size, registers); 8485 } 8486 8487 void Assembler::pop(Condition cond, EncodingSize size, Register rt) { 8488 VIXL_ASSERT(AllowAssembler()); 8489 CheckIT(cond); 8490 if (IsUsingT32()) { 8491 // POP{<c>}{<q>} <single_register_list> ; T4 8492 if (!size.IsNarrow() && ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 8493 AllowUnpredictable())) { 8494 EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12)); 8495 AdvanceIT(); 8496 return; 8497 } 8498 } else { 8499 // POP{<c>}{<q>} <single_register_list> ; A1 8500 if (cond.IsNotNever()) { 8501 EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12)); 8502 return; 8503 } 8504 } 8505 Delegate(kPop, &Assembler::pop, cond, size, rt); 8506 } 8507 8508 void Assembler::push(Condition cond, 8509 EncodingSize size, 8510 RegisterList registers) { 8511 VIXL_ASSERT(AllowAssembler()); 8512 CheckIT(cond); 8513 if (IsUsingT32()) { 8514 // PUSH{<c>}{<q>} <registers> ; T1 8515 if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) { 8516 EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) | 8517 GetRegisterListEncoding(registers, 0, 8)); 8518 AdvanceIT(); 8519 return; 8520 } 8521 // PUSH{<c>}{<q>} <registers> ; T1 8522 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) { 8523 EmitT32_32(0xe92d0000U | 8524 (GetRegisterListEncoding(registers, 14, 1) << 14) | 8525 GetRegisterListEncoding(registers, 0, 13)); 8526 AdvanceIT(); 8527 return; 8528 } 8529 } else { 8530 // PUSH{<c>}{<q>} <registers> ; A1 8531 if (cond.IsNotNever()) { 8532 EmitA32(0x092d0000U | (cond.GetCondition() << 28) | 8533 GetRegisterListEncoding(registers, 0, 16)); 8534 return; 8535 } 8536 } 8537 Delegate(kPush, &Assembler::push, cond, size, registers); 8538 } 8539 8540 void Assembler::push(Condition cond, EncodingSize size, Register rt) { 8541 VIXL_ASSERT(AllowAssembler()); 8542 CheckIT(cond); 8543 if (IsUsingT32()) { 8544 // PUSH{<c>}{<q>} <single_register_list> ; T4 8545 if (!size.IsNarrow() && (!rt.IsPC() || AllowUnpredictable())) { 8546 EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12)); 8547 AdvanceIT(); 8548 return; 8549 } 8550 } else { 8551 // PUSH{<c>}{<q>} <single_register_list> ; A1 8552 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 8553 EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12)); 8554 return; 8555 } 8556 } 8557 Delegate(kPush, &Assembler::push, cond, size, rt); 8558 } 8559 8560 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) { 8561 VIXL_ASSERT(AllowAssembler()); 8562 CheckIT(cond); 8563 if (IsUsingT32()) { 8564 // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 8565 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8566 EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() | 8567 (rn.GetCode() << 16)); 8568 AdvanceIT(); 8569 return; 8570 } 8571 } else { 8572 // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 8573 if (cond.IsNotNever() && 8574 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8575 EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8576 rm.GetCode() | (rn.GetCode() << 16)); 8577 return; 8578 } 8579 } 8580 Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn); 8581 } 8582 8583 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) { 8584 VIXL_ASSERT(AllowAssembler()); 8585 CheckIT(cond); 8586 if (IsUsingT32()) { 8587 // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8588 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8589 EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8590 rm.GetCode()); 8591 AdvanceIT(); 8592 return; 8593 } 8594 } else { 8595 // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8596 if (cond.IsNotNever() && 8597 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8598 EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8599 (rn.GetCode() << 16) | rm.GetCode()); 8600 return; 8601 } 8602 } 8603 Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm); 8604 } 8605 8606 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) { 8607 VIXL_ASSERT(AllowAssembler()); 8608 CheckIT(cond); 8609 if (IsUsingT32()) { 8610 // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8611 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8612 EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8613 rm.GetCode()); 8614 AdvanceIT(); 8615 return; 8616 } 8617 } else { 8618 // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8619 if (cond.IsNotNever() && 8620 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8621 EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8622 (rn.GetCode() << 16) | rm.GetCode()); 8623 return; 8624 } 8625 } 8626 Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm); 8627 } 8628 8629 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) { 8630 VIXL_ASSERT(AllowAssembler()); 8631 CheckIT(cond); 8632 if (IsUsingT32()) { 8633 // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8634 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8635 EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8636 rm.GetCode()); 8637 AdvanceIT(); 8638 return; 8639 } 8640 } else { 8641 // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8642 if (cond.IsNotNever() && 8643 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8644 EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8645 (rn.GetCode() << 16) | rm.GetCode()); 8646 return; 8647 } 8648 } 8649 Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm); 8650 } 8651 8652 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) { 8653 VIXL_ASSERT(AllowAssembler()); 8654 CheckIT(cond); 8655 if (IsUsingT32()) { 8656 // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 8657 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8658 EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() | 8659 (rn.GetCode() << 16)); 8660 AdvanceIT(); 8661 return; 8662 } 8663 } else { 8664 // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 8665 if (cond.IsNotNever() && 8666 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8667 EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8668 rm.GetCode() | (rn.GetCode() << 16)); 8669 return; 8670 } 8671 } 8672 Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn); 8673 } 8674 8675 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) { 8676 VIXL_ASSERT(AllowAssembler()); 8677 CheckIT(cond); 8678 if (IsUsingT32()) { 8679 // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 8680 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8681 EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() | 8682 (rn.GetCode() << 16)); 8683 AdvanceIT(); 8684 return; 8685 } 8686 } else { 8687 // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 8688 if (cond.IsNotNever() && 8689 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8690 EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8691 rm.GetCode() | (rn.GetCode() << 16)); 8692 return; 8693 } 8694 } 8695 Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn); 8696 } 8697 8698 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) { 8699 VIXL_ASSERT(AllowAssembler()); 8700 CheckIT(cond); 8701 if (IsUsingT32()) { 8702 // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8703 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8704 EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8705 rm.GetCode()); 8706 AdvanceIT(); 8707 return; 8708 } 8709 } else { 8710 // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8711 if (cond.IsNotNever() && 8712 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8713 EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8714 (rn.GetCode() << 16) | rm.GetCode()); 8715 return; 8716 } 8717 } 8718 Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm); 8719 } 8720 8721 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) { 8722 VIXL_ASSERT(AllowAssembler()); 8723 CheckIT(cond); 8724 if (IsUsingT32()) { 8725 // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 8726 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8727 EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() | 8728 (rn.GetCode() << 16)); 8729 AdvanceIT(); 8730 return; 8731 } 8732 } else { 8733 // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 8734 if (cond.IsNotNever() && 8735 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8736 EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8737 rm.GetCode() | (rn.GetCode() << 16)); 8738 return; 8739 } 8740 } 8741 Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn); 8742 } 8743 8744 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) { 8745 VIXL_ASSERT(AllowAssembler()); 8746 CheckIT(cond); 8747 if (IsUsingT32()) { 8748 // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8749 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8750 EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8751 rm.GetCode()); 8752 AdvanceIT(); 8753 return; 8754 } 8755 } else { 8756 // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8757 if (cond.IsNotNever() && 8758 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8759 EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8760 (rn.GetCode() << 16) | rm.GetCode()); 8761 return; 8762 } 8763 } 8764 Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm); 8765 } 8766 8767 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) { 8768 VIXL_ASSERT(AllowAssembler()); 8769 CheckIT(cond); 8770 if (IsUsingT32()) { 8771 // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8772 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8773 EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8774 rm.GetCode()); 8775 AdvanceIT(); 8776 return; 8777 } 8778 } else { 8779 // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8780 if (cond.IsNotNever() && 8781 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8782 EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8783 (rn.GetCode() << 16) | rm.GetCode()); 8784 return; 8785 } 8786 } 8787 Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm); 8788 } 8789 8790 void Assembler::rbit(Condition cond, Register rd, Register rm) { 8791 VIXL_ASSERT(AllowAssembler()); 8792 CheckIT(cond); 8793 if (IsUsingT32()) { 8794 // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1 8795 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8796 EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() | 8797 (rm.GetCode() << 16)); 8798 AdvanceIT(); 8799 return; 8800 } 8801 } else { 8802 // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1 8803 if (cond.IsNotNever() && 8804 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8805 EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8806 rm.GetCode()); 8807 return; 8808 } 8809 } 8810 Delegate(kRbit, &Assembler::rbit, cond, rd, rm); 8811 } 8812 8813 void Assembler::rev(Condition cond, 8814 EncodingSize size, 8815 Register rd, 8816 Register rm) { 8817 VIXL_ASSERT(AllowAssembler()); 8818 CheckIT(cond); 8819 if (IsUsingT32()) { 8820 // REV{<c>}{<q>} <Rd>, <Rm> ; T1 8821 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8822 EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3)); 8823 AdvanceIT(); 8824 return; 8825 } 8826 // REV{<c>}{<q>} <Rd>, <Rm> ; T2 8827 if (!size.IsNarrow() && 8828 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8829 EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() | 8830 (rm.GetCode() << 16)); 8831 AdvanceIT(); 8832 return; 8833 } 8834 } else { 8835 // REV{<c>}{<q>} <Rd>, <Rm> ; A1 8836 if (cond.IsNotNever() && 8837 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8838 EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8839 rm.GetCode()); 8840 return; 8841 } 8842 } 8843 Delegate(kRev, &Assembler::rev, cond, size, rd, rm); 8844 } 8845 8846 void Assembler::rev16(Condition cond, 8847 EncodingSize size, 8848 Register rd, 8849 Register rm) { 8850 VIXL_ASSERT(AllowAssembler()); 8851 CheckIT(cond); 8852 if (IsUsingT32()) { 8853 // REV16{<c>}{<q>} <Rd>, <Rm> ; T1 8854 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8855 EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3)); 8856 AdvanceIT(); 8857 return; 8858 } 8859 // REV16{<c>}{<q>} <Rd>, <Rm> ; T2 8860 if (!size.IsNarrow() && 8861 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8862 EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() | 8863 (rm.GetCode() << 16)); 8864 AdvanceIT(); 8865 return; 8866 } 8867 } else { 8868 // REV16{<c>}{<q>} <Rd>, <Rm> ; A1 8869 if (cond.IsNotNever() && 8870 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8871 EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8872 rm.GetCode()); 8873 return; 8874 } 8875 } 8876 Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm); 8877 } 8878 8879 void Assembler::revsh(Condition cond, 8880 EncodingSize size, 8881 Register rd, 8882 Register rm) { 8883 VIXL_ASSERT(AllowAssembler()); 8884 CheckIT(cond); 8885 if (IsUsingT32()) { 8886 // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1 8887 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8888 EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3)); 8889 AdvanceIT(); 8890 return; 8891 } 8892 // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2 8893 if (!size.IsNarrow() && 8894 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8895 EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() | 8896 (rm.GetCode() << 16)); 8897 AdvanceIT(); 8898 return; 8899 } 8900 } else { 8901 // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1 8902 if (cond.IsNotNever() && 8903 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8904 EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8905 rm.GetCode()); 8906 return; 8907 } 8908 } 8909 Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm); 8910 } 8911 8912 void Assembler::ror(Condition cond, 8913 EncodingSize size, 8914 Register rd, 8915 Register rm, 8916 const Operand& operand) { 8917 VIXL_ASSERT(AllowAssembler()); 8918 CheckIT(cond); 8919 if (operand.IsImmediate()) { 8920 uint32_t imm = operand.GetImmediate(); 8921 if (IsUsingT32()) { 8922 // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 8923 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) && 8924 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8925 EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() | 8926 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 8927 AdvanceIT(); 8928 return; 8929 } 8930 } else { 8931 // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 8932 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 8933 EmitA32(0x01a00060U | (cond.GetCondition() << 28) | 8934 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 8935 return; 8936 } 8937 } 8938 } 8939 if (operand.IsPlainRegister()) { 8940 Register rs = operand.GetBaseRegister(); 8941 if (IsUsingT32()) { 8942 // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 8943 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 8944 rs.IsLow()) { 8945 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 8946 AdvanceIT(); 8947 return; 8948 } 8949 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 8950 if (!size.IsNarrow() && 8951 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 8952 EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 8953 rs.GetCode()); 8954 AdvanceIT(); 8955 return; 8956 } 8957 } else { 8958 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 8959 if (cond.IsNotNever() && 8960 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 8961 EmitA32(0x01a00070U | (cond.GetCondition() << 28) | 8962 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 8963 return; 8964 } 8965 } 8966 } 8967 Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand); 8968 } 8969 8970 void Assembler::rors(Condition cond, 8971 EncodingSize size, 8972 Register rd, 8973 Register rm, 8974 const Operand& operand) { 8975 VIXL_ASSERT(AllowAssembler()); 8976 CheckIT(cond); 8977 if (operand.IsImmediate()) { 8978 uint32_t imm = operand.GetImmediate(); 8979 if (IsUsingT32()) { 8980 // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 8981 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) && 8982 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 8983 EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() | 8984 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 8985 AdvanceIT(); 8986 return; 8987 } 8988 } else { 8989 // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 8990 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 8991 EmitA32(0x01b00060U | (cond.GetCondition() << 28) | 8992 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 8993 return; 8994 } 8995 } 8996 } 8997 if (operand.IsPlainRegister()) { 8998 Register rs = operand.GetBaseRegister(); 8999 if (IsUsingT32()) { 9000 // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 9001 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 9002 rs.IsLow()) { 9003 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 9004 AdvanceIT(); 9005 return; 9006 } 9007 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 9008 if (!size.IsNarrow() && 9009 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 9010 EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 9011 rs.GetCode()); 9012 AdvanceIT(); 9013 return; 9014 } 9015 } else { 9016 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 9017 if (cond.IsNotNever() && 9018 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 9019 EmitA32(0x01b00070U | (cond.GetCondition() << 28) | 9020 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 9021 return; 9022 } 9023 } 9024 } 9025 Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand); 9026 } 9027 9028 void Assembler::rrx(Condition cond, Register rd, Register rm) { 9029 VIXL_ASSERT(AllowAssembler()); 9030 CheckIT(cond); 9031 if (IsUsingT32()) { 9032 // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3 9033 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9034 EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode()); 9035 AdvanceIT(); 9036 return; 9037 } 9038 } else { 9039 // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1 9040 if (cond.IsNotNever()) { 9041 EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9042 rm.GetCode()); 9043 return; 9044 } 9045 } 9046 Delegate(kRrx, &Assembler::rrx, cond, rd, rm); 9047 } 9048 9049 void Assembler::rrxs(Condition cond, Register rd, Register rm) { 9050 VIXL_ASSERT(AllowAssembler()); 9051 CheckIT(cond); 9052 if (IsUsingT32()) { 9053 // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3 9054 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9055 EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode()); 9056 AdvanceIT(); 9057 return; 9058 } 9059 } else { 9060 // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1 9061 if (cond.IsNotNever()) { 9062 EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9063 rm.GetCode()); 9064 return; 9065 } 9066 } 9067 Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm); 9068 } 9069 9070 void Assembler::rsb(Condition cond, 9071 EncodingSize size, 9072 Register rd, 9073 Register rn, 9074 const Operand& operand) { 9075 VIXL_ASSERT(AllowAssembler()); 9076 CheckIT(cond); 9077 if (operand.IsImmediate()) { 9078 uint32_t imm = operand.GetImmediate(); 9079 if (IsUsingT32()) { 9080 ImmediateT32 immediate_t32(imm); 9081 // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1 9082 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 9083 (imm == 0)) { 9084 EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3)); 9085 AdvanceIT(); 9086 return; 9087 } 9088 // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2 9089 if (!size.IsNarrow() && immediate_t32.IsValid() && 9090 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 9091 EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9092 (immediate_t32.GetEncodingValue() & 0xff) | 9093 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 9094 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 9095 AdvanceIT(); 9096 return; 9097 } 9098 } else { 9099 ImmediateA32 immediate_a32(imm); 9100 // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9101 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9102 EmitA32(0x02600000U | (cond.GetCondition() << 28) | 9103 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9104 immediate_a32.GetEncodingValue()); 9105 return; 9106 } 9107 } 9108 } 9109 if (operand.IsImmediateShiftedRegister()) { 9110 Register rm = operand.GetBaseRegister(); 9111 Shift shift = operand.GetShift(); 9112 uint32_t amount = operand.GetShiftAmount(); 9113 if (IsUsingT32()) { 9114 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 9115 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 9116 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9117 uint32_t amount_ = amount % 32; 9118 EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9119 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 9120 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 9121 AdvanceIT(); 9122 return; 9123 } 9124 } else { 9125 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9126 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9127 uint32_t amount_ = amount % 32; 9128 EmitA32(0x00600000U | (cond.GetCondition() << 28) | 9129 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9130 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9131 return; 9132 } 9133 } 9134 } 9135 if (operand.IsRegisterShiftedRegister()) { 9136 Register rm = operand.GetBaseRegister(); 9137 Shift shift = operand.GetShift(); 9138 Register rs = operand.GetShiftRegister(); 9139 if (IsUsingA32()) { 9140 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9141 if (cond.IsNotNever() && 9142 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9143 AllowUnpredictable())) { 9144 EmitA32(0x00600010U | (cond.GetCondition() << 28) | 9145 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9146 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9147 return; 9148 } 9149 } 9150 } 9151 Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand); 9152 } 9153 9154 void Assembler::rsbs(Condition cond, 9155 EncodingSize size, 9156 Register rd, 9157 Register rn, 9158 const Operand& operand) { 9159 VIXL_ASSERT(AllowAssembler()); 9160 CheckIT(cond); 9161 if (operand.IsImmediate()) { 9162 uint32_t imm = operand.GetImmediate(); 9163 if (IsUsingT32()) { 9164 ImmediateT32 immediate_t32(imm); 9165 // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1 9166 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 9167 (imm == 0)) { 9168 EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3)); 9169 AdvanceIT(); 9170 return; 9171 } 9172 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2 9173 if (!size.IsNarrow() && immediate_t32.IsValid() && 9174 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 9175 EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9176 (immediate_t32.GetEncodingValue() & 0xff) | 9177 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 9178 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 9179 AdvanceIT(); 9180 return; 9181 } 9182 } else { 9183 ImmediateA32 immediate_a32(imm); 9184 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9185 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9186 EmitA32(0x02700000U | (cond.GetCondition() << 28) | 9187 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9188 immediate_a32.GetEncodingValue()); 9189 return; 9190 } 9191 } 9192 } 9193 if (operand.IsImmediateShiftedRegister()) { 9194 Register rm = operand.GetBaseRegister(); 9195 Shift shift = operand.GetShift(); 9196 uint32_t amount = operand.GetShiftAmount(); 9197 if (IsUsingT32()) { 9198 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 9199 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 9200 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9201 uint32_t amount_ = amount % 32; 9202 EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9203 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 9204 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 9205 AdvanceIT(); 9206 return; 9207 } 9208 } else { 9209 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9210 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9211 uint32_t amount_ = amount % 32; 9212 EmitA32(0x00700000U | (cond.GetCondition() << 28) | 9213 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9214 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9215 return; 9216 } 9217 } 9218 } 9219 if (operand.IsRegisterShiftedRegister()) { 9220 Register rm = operand.GetBaseRegister(); 9221 Shift shift = operand.GetShift(); 9222 Register rs = operand.GetShiftRegister(); 9223 if (IsUsingA32()) { 9224 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9225 if (cond.IsNotNever() && 9226 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9227 AllowUnpredictable())) { 9228 EmitA32(0x00700010U | (cond.GetCondition() << 28) | 9229 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9230 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9231 return; 9232 } 9233 } 9234 } 9235 Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand); 9236 } 9237 9238 void Assembler::rsc(Condition cond, 9239 Register rd, 9240 Register rn, 9241 const Operand& operand) { 9242 VIXL_ASSERT(AllowAssembler()); 9243 CheckIT(cond); 9244 if (operand.IsImmediate()) { 9245 uint32_t imm = operand.GetImmediate(); 9246 if (IsUsingA32()) { 9247 ImmediateA32 immediate_a32(imm); 9248 // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9249 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9250 EmitA32(0x02e00000U | (cond.GetCondition() << 28) | 9251 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9252 immediate_a32.GetEncodingValue()); 9253 return; 9254 } 9255 } 9256 } 9257 if (operand.IsImmediateShiftedRegister()) { 9258 Register rm = operand.GetBaseRegister(); 9259 Shift shift = operand.GetShift(); 9260 uint32_t amount = operand.GetShiftAmount(); 9261 if (IsUsingA32()) { 9262 // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9263 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9264 uint32_t amount_ = amount % 32; 9265 EmitA32(0x00e00000U | (cond.GetCondition() << 28) | 9266 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9267 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9268 return; 9269 } 9270 } 9271 } 9272 if (operand.IsRegisterShiftedRegister()) { 9273 Register rm = operand.GetBaseRegister(); 9274 Shift shift = operand.GetShift(); 9275 Register rs = operand.GetShiftRegister(); 9276 if (IsUsingA32()) { 9277 // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9278 if (cond.IsNotNever() && 9279 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9280 AllowUnpredictable())) { 9281 EmitA32(0x00e00010U | (cond.GetCondition() << 28) | 9282 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9283 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9284 return; 9285 } 9286 } 9287 } 9288 Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand); 9289 } 9290 9291 void Assembler::rscs(Condition cond, 9292 Register rd, 9293 Register rn, 9294 const Operand& operand) { 9295 VIXL_ASSERT(AllowAssembler()); 9296 CheckIT(cond); 9297 if (operand.IsImmediate()) { 9298 uint32_t imm = operand.GetImmediate(); 9299 if (IsUsingA32()) { 9300 ImmediateA32 immediate_a32(imm); 9301 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9302 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9303 EmitA32(0x02f00000U | (cond.GetCondition() << 28) | 9304 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9305 immediate_a32.GetEncodingValue()); 9306 return; 9307 } 9308 } 9309 } 9310 if (operand.IsImmediateShiftedRegister()) { 9311 Register rm = operand.GetBaseRegister(); 9312 Shift shift = operand.GetShift(); 9313 uint32_t amount = operand.GetShiftAmount(); 9314 if (IsUsingA32()) { 9315 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9316 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9317 uint32_t amount_ = amount % 32; 9318 EmitA32(0x00f00000U | (cond.GetCondition() << 28) | 9319 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9320 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9321 return; 9322 } 9323 } 9324 } 9325 if (operand.IsRegisterShiftedRegister()) { 9326 Register rm = operand.GetBaseRegister(); 9327 Shift shift = operand.GetShift(); 9328 Register rs = operand.GetShiftRegister(); 9329 if (IsUsingA32()) { 9330 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9331 if (cond.IsNotNever() && 9332 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9333 AllowUnpredictable())) { 9334 EmitA32(0x00f00010U | (cond.GetCondition() << 28) | 9335 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9336 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9337 return; 9338 } 9339 } 9340 } 9341 Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand); 9342 } 9343 9344 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) { 9345 VIXL_ASSERT(AllowAssembler()); 9346 CheckIT(cond); 9347 if (IsUsingT32()) { 9348 // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9349 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9350 EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9351 rm.GetCode()); 9352 AdvanceIT(); 9353 return; 9354 } 9355 } else { 9356 // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9357 if (cond.IsNotNever() && 9358 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9359 EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9360 (rn.GetCode() << 16) | rm.GetCode()); 9361 return; 9362 } 9363 } 9364 Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm); 9365 } 9366 9367 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) { 9368 VIXL_ASSERT(AllowAssembler()); 9369 CheckIT(cond); 9370 if (IsUsingT32()) { 9371 // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9372 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9373 EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9374 rm.GetCode()); 9375 AdvanceIT(); 9376 return; 9377 } 9378 } else { 9379 // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9380 if (cond.IsNotNever() && 9381 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9382 EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9383 (rn.GetCode() << 16) | rm.GetCode()); 9384 return; 9385 } 9386 } 9387 Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm); 9388 } 9389 9390 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) { 9391 VIXL_ASSERT(AllowAssembler()); 9392 CheckIT(cond); 9393 if (IsUsingT32()) { 9394 // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9395 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9396 EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9397 rm.GetCode()); 9398 AdvanceIT(); 9399 return; 9400 } 9401 } else { 9402 // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9403 if (cond.IsNotNever() && 9404 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9405 EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9406 (rn.GetCode() << 16) | rm.GetCode()); 9407 return; 9408 } 9409 } 9410 Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm); 9411 } 9412 9413 void Assembler::sbc(Condition cond, 9414 EncodingSize size, 9415 Register rd, 9416 Register rn, 9417 const Operand& operand) { 9418 VIXL_ASSERT(AllowAssembler()); 9419 CheckIT(cond); 9420 if (operand.IsImmediate()) { 9421 uint32_t imm = operand.GetImmediate(); 9422 if (IsUsingT32()) { 9423 ImmediateT32 immediate_t32(imm); 9424 // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 9425 if (!size.IsNarrow() && immediate_t32.IsValid() && 9426 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 9427 EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9428 (immediate_t32.GetEncodingValue() & 0xff) | 9429 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 9430 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 9431 AdvanceIT(); 9432 return; 9433 } 9434 } else { 9435 ImmediateA32 immediate_a32(imm); 9436 // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9437 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9438 EmitA32(0x02c00000U | (cond.GetCondition() << 28) | 9439 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9440 immediate_a32.GetEncodingValue()); 9441 return; 9442 } 9443 } 9444 } 9445 if (operand.IsImmediateShiftedRegister()) { 9446 Register rm = operand.GetBaseRegister(); 9447 if (operand.IsPlainRegister()) { 9448 if (IsUsingT32()) { 9449 // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 9450 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 9451 rm.IsLow()) { 9452 EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3)); 9453 AdvanceIT(); 9454 return; 9455 } 9456 } 9457 } 9458 Shift shift = operand.GetShift(); 9459 uint32_t amount = operand.GetShiftAmount(); 9460 if (IsUsingT32()) { 9461 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 9462 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 9463 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9464 uint32_t amount_ = amount % 32; 9465 EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9466 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 9467 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 9468 AdvanceIT(); 9469 return; 9470 } 9471 } else { 9472 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9473 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9474 uint32_t amount_ = amount % 32; 9475 EmitA32(0x00c00000U | (cond.GetCondition() << 28) | 9476 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9477 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9478 return; 9479 } 9480 } 9481 } 9482 if (operand.IsRegisterShiftedRegister()) { 9483 Register rm = operand.GetBaseRegister(); 9484 Shift shift = operand.GetShift(); 9485 Register rs = operand.GetShiftRegister(); 9486 if (IsUsingA32()) { 9487 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9488 if (cond.IsNotNever() && 9489 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9490 AllowUnpredictable())) { 9491 EmitA32(0x00c00010U | (cond.GetCondition() << 28) | 9492 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9493 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9494 return; 9495 } 9496 } 9497 } 9498 Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand); 9499 } 9500 9501 void Assembler::sbcs(Condition cond, 9502 EncodingSize size, 9503 Register rd, 9504 Register rn, 9505 const Operand& operand) { 9506 VIXL_ASSERT(AllowAssembler()); 9507 CheckIT(cond); 9508 if (operand.IsImmediate()) { 9509 uint32_t imm = operand.GetImmediate(); 9510 if (IsUsingT32()) { 9511 ImmediateT32 immediate_t32(imm); 9512 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 9513 if (!size.IsNarrow() && immediate_t32.IsValid() && 9514 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 9515 EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9516 (immediate_t32.GetEncodingValue() & 0xff) | 9517 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 9518 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 9519 AdvanceIT(); 9520 return; 9521 } 9522 } else { 9523 ImmediateA32 immediate_a32(imm); 9524 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 9525 if (immediate_a32.IsValid() && cond.IsNotNever()) { 9526 EmitA32(0x02d00000U | (cond.GetCondition() << 28) | 9527 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 9528 immediate_a32.GetEncodingValue()); 9529 return; 9530 } 9531 } 9532 } 9533 if (operand.IsImmediateShiftedRegister()) { 9534 Register rm = operand.GetBaseRegister(); 9535 if (operand.IsPlainRegister()) { 9536 if (IsUsingT32()) { 9537 // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 9538 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 9539 rm.IsLow()) { 9540 EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3)); 9541 AdvanceIT(); 9542 return; 9543 } 9544 } 9545 } 9546 Shift shift = operand.GetShift(); 9547 uint32_t amount = operand.GetShiftAmount(); 9548 if (IsUsingT32()) { 9549 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 9550 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 9551 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9552 uint32_t amount_ = amount % 32; 9553 EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9554 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 9555 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 9556 AdvanceIT(); 9557 return; 9558 } 9559 } else { 9560 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 9561 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 9562 uint32_t amount_ = amount % 32; 9563 EmitA32(0x00d00000U | (cond.GetCondition() << 28) | 9564 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9565 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 9566 return; 9567 } 9568 } 9569 } 9570 if (operand.IsRegisterShiftedRegister()) { 9571 Register rm = operand.GetBaseRegister(); 9572 Shift shift = operand.GetShift(); 9573 Register rs = operand.GetShiftRegister(); 9574 if (IsUsingA32()) { 9575 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 9576 if (cond.IsNotNever() && 9577 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 9578 AllowUnpredictable())) { 9579 EmitA32(0x00d00010U | (cond.GetCondition() << 28) | 9580 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 9581 (shift.GetType() << 5) | (rs.GetCode() << 8)); 9582 return; 9583 } 9584 } 9585 } 9586 Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand); 9587 } 9588 9589 void Assembler::sbfx( 9590 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) { 9591 VIXL_ASSERT(AllowAssembler()); 9592 CheckIT(cond); 9593 if (IsUsingT32()) { 9594 // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 9595 if ((lsb <= 31) && 9596 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) || 9597 AllowUnpredictable())) { 9598 uint32_t widthm1 = width - 1; 9599 EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9600 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1); 9601 AdvanceIT(); 9602 return; 9603 } 9604 } else { 9605 // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 9606 if ((lsb <= 31) && cond.IsNotNever() && 9607 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) || 9608 AllowUnpredictable())) { 9609 uint32_t widthm1 = width - 1; 9610 EmitA32(0x07a00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9611 rn.GetCode() | (lsb << 7) | (widthm1 << 16)); 9612 return; 9613 } 9614 } 9615 Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, width); 9616 } 9617 9618 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) { 9619 VIXL_ASSERT(AllowAssembler()); 9620 CheckIT(cond); 9621 if (IsUsingT32()) { 9622 // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9623 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9624 EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9625 rm.GetCode()); 9626 AdvanceIT(); 9627 return; 9628 } 9629 } else { 9630 // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9631 if (cond.IsNotNever() && 9632 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9633 EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9634 rn.GetCode() | (rm.GetCode() << 8)); 9635 return; 9636 } 9637 } 9638 Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm); 9639 } 9640 9641 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) { 9642 VIXL_ASSERT(AllowAssembler()); 9643 CheckIT(cond); 9644 if (IsUsingT32()) { 9645 // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9646 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9647 EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9648 rm.GetCode()); 9649 AdvanceIT(); 9650 return; 9651 } 9652 } else { 9653 // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9654 if (cond.IsNotNever() && 9655 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9656 EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9657 (rn.GetCode() << 16) | rm.GetCode()); 9658 return; 9659 } 9660 } 9661 Delegate(kSel, &Assembler::sel, cond, rd, rn, rm); 9662 } 9663 9664 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) { 9665 VIXL_ASSERT(AllowAssembler()); 9666 CheckIT(cond); 9667 if (IsUsingT32()) { 9668 // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9669 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9670 EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9671 rm.GetCode()); 9672 AdvanceIT(); 9673 return; 9674 } 9675 } else { 9676 // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9677 if (cond.IsNotNever() && 9678 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9679 EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9680 (rn.GetCode() << 16) | rm.GetCode()); 9681 return; 9682 } 9683 } 9684 Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm); 9685 } 9686 9687 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) { 9688 VIXL_ASSERT(AllowAssembler()); 9689 CheckIT(cond); 9690 if (IsUsingT32()) { 9691 // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9692 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9693 EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9694 rm.GetCode()); 9695 AdvanceIT(); 9696 return; 9697 } 9698 } else { 9699 // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9700 if (cond.IsNotNever() && 9701 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9702 EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9703 (rn.GetCode() << 16) | rm.GetCode()); 9704 return; 9705 } 9706 } 9707 Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm); 9708 } 9709 9710 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) { 9711 VIXL_ASSERT(AllowAssembler()); 9712 CheckIT(cond); 9713 if (IsUsingT32()) { 9714 // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9715 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9716 EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9717 rm.GetCode()); 9718 AdvanceIT(); 9719 return; 9720 } 9721 } else { 9722 // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9723 if (cond.IsNotNever() && 9724 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9725 EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9726 (rn.GetCode() << 16) | rm.GetCode()); 9727 return; 9728 } 9729 } 9730 Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm); 9731 } 9732 9733 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) { 9734 VIXL_ASSERT(AllowAssembler()); 9735 CheckIT(cond); 9736 if (IsUsingT32()) { 9737 // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9738 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9739 EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9740 rm.GetCode()); 9741 AdvanceIT(); 9742 return; 9743 } 9744 } else { 9745 // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9746 if (cond.IsNotNever() && 9747 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9748 EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9749 (rn.GetCode() << 16) | rm.GetCode()); 9750 return; 9751 } 9752 } 9753 Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm); 9754 } 9755 9756 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) { 9757 VIXL_ASSERT(AllowAssembler()); 9758 CheckIT(cond); 9759 if (IsUsingT32()) { 9760 // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9761 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9762 EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9763 rm.GetCode()); 9764 AdvanceIT(); 9765 return; 9766 } 9767 } else { 9768 // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9769 if (cond.IsNotNever() && 9770 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9771 EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9772 (rn.GetCode() << 16) | rm.GetCode()); 9773 return; 9774 } 9775 } 9776 Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm); 9777 } 9778 9779 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) { 9780 VIXL_ASSERT(AllowAssembler()); 9781 CheckIT(cond); 9782 if (IsUsingT32()) { 9783 // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9784 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9785 EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9786 rm.GetCode()); 9787 AdvanceIT(); 9788 return; 9789 } 9790 } else { 9791 // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9792 if (cond.IsNotNever() && 9793 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9794 EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9795 (rn.GetCode() << 16) | rm.GetCode()); 9796 return; 9797 } 9798 } 9799 Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm); 9800 } 9801 9802 void Assembler::smlabb( 9803 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9804 VIXL_ASSERT(AllowAssembler()); 9805 CheckIT(cond); 9806 if (IsUsingT32()) { 9807 // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9808 if (!ra.Is(pc) && 9809 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9810 EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9811 rm.GetCode() | (ra.GetCode() << 12)); 9812 AdvanceIT(); 9813 return; 9814 } 9815 } else { 9816 // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9817 if (cond.IsNotNever() && 9818 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 9819 AllowUnpredictable())) { 9820 EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9821 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9822 return; 9823 } 9824 } 9825 Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra); 9826 } 9827 9828 void Assembler::smlabt( 9829 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9830 VIXL_ASSERT(AllowAssembler()); 9831 CheckIT(cond); 9832 if (IsUsingT32()) { 9833 // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9834 if (!ra.Is(pc) && 9835 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9836 EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9837 rm.GetCode() | (ra.GetCode() << 12)); 9838 AdvanceIT(); 9839 return; 9840 } 9841 } else { 9842 // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9843 if (cond.IsNotNever() && 9844 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 9845 AllowUnpredictable())) { 9846 EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9847 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9848 return; 9849 } 9850 } 9851 Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra); 9852 } 9853 9854 void Assembler::smlad( 9855 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9856 VIXL_ASSERT(AllowAssembler()); 9857 CheckIT(cond); 9858 if (IsUsingT32()) { 9859 // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9860 if (!ra.Is(pc) && 9861 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9862 EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9863 rm.GetCode() | (ra.GetCode() << 12)); 9864 AdvanceIT(); 9865 return; 9866 } 9867 } else { 9868 // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9869 if (cond.IsNotNever() && !ra.Is(pc) && 9870 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9871 EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9872 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9873 return; 9874 } 9875 } 9876 Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra); 9877 } 9878 9879 void Assembler::smladx( 9880 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9881 VIXL_ASSERT(AllowAssembler()); 9882 CheckIT(cond); 9883 if (IsUsingT32()) { 9884 // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9885 if (!ra.Is(pc) && 9886 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9887 EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9888 rm.GetCode() | (ra.GetCode() << 12)); 9889 AdvanceIT(); 9890 return; 9891 } 9892 } else { 9893 // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9894 if (cond.IsNotNever() && !ra.Is(pc) && 9895 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 9896 EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9897 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9898 return; 9899 } 9900 } 9901 Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra); 9902 } 9903 9904 void Assembler::smlal( 9905 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9906 VIXL_ASSERT(AllowAssembler()); 9907 CheckIT(cond); 9908 if (IsUsingT32()) { 9909 // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9910 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9911 AllowUnpredictable())) { 9912 EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9913 (rn.GetCode() << 16) | rm.GetCode()); 9914 AdvanceIT(); 9915 return; 9916 } 9917 } else { 9918 // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9919 if (cond.IsNotNever() && 9920 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9921 AllowUnpredictable())) { 9922 EmitA32(0x00e00090U | (cond.GetCondition() << 28) | 9923 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9924 (rm.GetCode() << 8)); 9925 return; 9926 } 9927 } 9928 Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm); 9929 } 9930 9931 void Assembler::smlalbb( 9932 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9933 VIXL_ASSERT(AllowAssembler()); 9934 CheckIT(cond); 9935 if (IsUsingT32()) { 9936 // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9937 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9938 AllowUnpredictable())) { 9939 EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9940 (rn.GetCode() << 16) | rm.GetCode()); 9941 AdvanceIT(); 9942 return; 9943 } 9944 } else { 9945 // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9946 if (cond.IsNotNever() && 9947 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9948 AllowUnpredictable())) { 9949 EmitA32(0x01400080U | (cond.GetCondition() << 28) | 9950 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9951 (rm.GetCode() << 8)); 9952 return; 9953 } 9954 } 9955 Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm); 9956 } 9957 9958 void Assembler::smlalbt( 9959 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9960 VIXL_ASSERT(AllowAssembler()); 9961 CheckIT(cond); 9962 if (IsUsingT32()) { 9963 // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9964 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9965 AllowUnpredictable())) { 9966 EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9967 (rn.GetCode() << 16) | rm.GetCode()); 9968 AdvanceIT(); 9969 return; 9970 } 9971 } else { 9972 // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9973 if (cond.IsNotNever() && 9974 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9975 AllowUnpredictable())) { 9976 EmitA32(0x014000c0U | (cond.GetCondition() << 28) | 9977 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9978 (rm.GetCode() << 8)); 9979 return; 9980 } 9981 } 9982 Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm); 9983 } 9984 9985 void Assembler::smlald( 9986 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9987 VIXL_ASSERT(AllowAssembler()); 9988 CheckIT(cond); 9989 if (IsUsingT32()) { 9990 // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9991 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 9992 AllowUnpredictable())) { 9993 EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9994 (rn.GetCode() << 16) | rm.GetCode()); 9995 AdvanceIT(); 9996 return; 9997 } 9998 } else { 9999 // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10000 if (cond.IsNotNever() && 10001 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10002 AllowUnpredictable())) { 10003 EmitA32(0x07400010U | (cond.GetCondition() << 28) | 10004 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10005 (rm.GetCode() << 8)); 10006 return; 10007 } 10008 } 10009 Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm); 10010 } 10011 10012 void Assembler::smlaldx( 10013 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10014 VIXL_ASSERT(AllowAssembler()); 10015 CheckIT(cond); 10016 if (IsUsingT32()) { 10017 // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10018 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10019 AllowUnpredictable())) { 10020 EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10021 (rn.GetCode() << 16) | rm.GetCode()); 10022 AdvanceIT(); 10023 return; 10024 } 10025 } else { 10026 // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10027 if (cond.IsNotNever() && 10028 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10029 AllowUnpredictable())) { 10030 EmitA32(0x07400030U | (cond.GetCondition() << 28) | 10031 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10032 (rm.GetCode() << 8)); 10033 return; 10034 } 10035 } 10036 Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm); 10037 } 10038 10039 void Assembler::smlals( 10040 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10041 VIXL_ASSERT(AllowAssembler()); 10042 CheckIT(cond); 10043 if (IsUsingA32()) { 10044 // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10045 if (cond.IsNotNever() && 10046 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10047 AllowUnpredictable())) { 10048 EmitA32(0x00f00090U | (cond.GetCondition() << 28) | 10049 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10050 (rm.GetCode() << 8)); 10051 return; 10052 } 10053 } 10054 Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm); 10055 } 10056 10057 void Assembler::smlaltb( 10058 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10059 VIXL_ASSERT(AllowAssembler()); 10060 CheckIT(cond); 10061 if (IsUsingT32()) { 10062 // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10063 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10064 AllowUnpredictable())) { 10065 EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10066 (rn.GetCode() << 16) | rm.GetCode()); 10067 AdvanceIT(); 10068 return; 10069 } 10070 } else { 10071 // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10072 if (cond.IsNotNever() && 10073 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10074 AllowUnpredictable())) { 10075 EmitA32(0x014000a0U | (cond.GetCondition() << 28) | 10076 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10077 (rm.GetCode() << 8)); 10078 return; 10079 } 10080 } 10081 Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm); 10082 } 10083 10084 void Assembler::smlaltt( 10085 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10086 VIXL_ASSERT(AllowAssembler()); 10087 CheckIT(cond); 10088 if (IsUsingT32()) { 10089 // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10090 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10091 AllowUnpredictable())) { 10092 EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10093 (rn.GetCode() << 16) | rm.GetCode()); 10094 AdvanceIT(); 10095 return; 10096 } 10097 } else { 10098 // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10099 if (cond.IsNotNever() && 10100 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10101 AllowUnpredictable())) { 10102 EmitA32(0x014000e0U | (cond.GetCondition() << 28) | 10103 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10104 (rm.GetCode() << 8)); 10105 return; 10106 } 10107 } 10108 Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm); 10109 } 10110 10111 void Assembler::smlatb( 10112 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10113 VIXL_ASSERT(AllowAssembler()); 10114 CheckIT(cond); 10115 if (IsUsingT32()) { 10116 // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10117 if (!ra.Is(pc) && 10118 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10119 EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10120 rm.GetCode() | (ra.GetCode() << 12)); 10121 AdvanceIT(); 10122 return; 10123 } 10124 } else { 10125 // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10126 if (cond.IsNotNever() && 10127 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10128 AllowUnpredictable())) { 10129 EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10130 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10131 return; 10132 } 10133 } 10134 Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra); 10135 } 10136 10137 void Assembler::smlatt( 10138 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10139 VIXL_ASSERT(AllowAssembler()); 10140 CheckIT(cond); 10141 if (IsUsingT32()) { 10142 // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10143 if (!ra.Is(pc) && 10144 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10145 EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10146 rm.GetCode() | (ra.GetCode() << 12)); 10147 AdvanceIT(); 10148 return; 10149 } 10150 } else { 10151 // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10152 if (cond.IsNotNever() && 10153 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10154 AllowUnpredictable())) { 10155 EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10156 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10157 return; 10158 } 10159 } 10160 Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra); 10161 } 10162 10163 void Assembler::smlawb( 10164 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10165 VIXL_ASSERT(AllowAssembler()); 10166 CheckIT(cond); 10167 if (IsUsingT32()) { 10168 // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10169 if (!ra.Is(pc) && 10170 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10171 EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10172 rm.GetCode() | (ra.GetCode() << 12)); 10173 AdvanceIT(); 10174 return; 10175 } 10176 } else { 10177 // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10178 if (cond.IsNotNever() && 10179 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10180 AllowUnpredictable())) { 10181 EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10182 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10183 return; 10184 } 10185 } 10186 Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra); 10187 } 10188 10189 void Assembler::smlawt( 10190 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10191 VIXL_ASSERT(AllowAssembler()); 10192 CheckIT(cond); 10193 if (IsUsingT32()) { 10194 // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10195 if (!ra.Is(pc) && 10196 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10197 EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10198 rm.GetCode() | (ra.GetCode() << 12)); 10199 AdvanceIT(); 10200 return; 10201 } 10202 } else { 10203 // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10204 if (cond.IsNotNever() && 10205 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10206 AllowUnpredictable())) { 10207 EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10208 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10209 return; 10210 } 10211 } 10212 Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra); 10213 } 10214 10215 void Assembler::smlsd( 10216 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10217 VIXL_ASSERT(AllowAssembler()); 10218 CheckIT(cond); 10219 if (IsUsingT32()) { 10220 // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10221 if (!ra.Is(pc) && 10222 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10223 EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10224 rm.GetCode() | (ra.GetCode() << 12)); 10225 AdvanceIT(); 10226 return; 10227 } 10228 } else { 10229 // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10230 if (cond.IsNotNever() && !ra.Is(pc) && 10231 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10232 EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10233 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10234 return; 10235 } 10236 } 10237 Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra); 10238 } 10239 10240 void Assembler::smlsdx( 10241 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10242 VIXL_ASSERT(AllowAssembler()); 10243 CheckIT(cond); 10244 if (IsUsingT32()) { 10245 // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10246 if (!ra.Is(pc) && 10247 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10248 EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10249 rm.GetCode() | (ra.GetCode() << 12)); 10250 AdvanceIT(); 10251 return; 10252 } 10253 } else { 10254 // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10255 if (cond.IsNotNever() && !ra.Is(pc) && 10256 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10257 EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10258 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10259 return; 10260 } 10261 } 10262 Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra); 10263 } 10264 10265 void Assembler::smlsld( 10266 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10267 VIXL_ASSERT(AllowAssembler()); 10268 CheckIT(cond); 10269 if (IsUsingT32()) { 10270 // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10271 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10272 AllowUnpredictable())) { 10273 EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10274 (rn.GetCode() << 16) | rm.GetCode()); 10275 AdvanceIT(); 10276 return; 10277 } 10278 } else { 10279 // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10280 if (cond.IsNotNever() && 10281 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10282 AllowUnpredictable())) { 10283 EmitA32(0x07400050U | (cond.GetCondition() << 28) | 10284 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10285 (rm.GetCode() << 8)); 10286 return; 10287 } 10288 } 10289 Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm); 10290 } 10291 10292 void Assembler::smlsldx( 10293 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10294 VIXL_ASSERT(AllowAssembler()); 10295 CheckIT(cond); 10296 if (IsUsingT32()) { 10297 // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10298 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10299 AllowUnpredictable())) { 10300 EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10301 (rn.GetCode() << 16) | rm.GetCode()); 10302 AdvanceIT(); 10303 return; 10304 } 10305 } else { 10306 // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10307 if (cond.IsNotNever() && 10308 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10309 AllowUnpredictable())) { 10310 EmitA32(0x07400070U | (cond.GetCondition() << 28) | 10311 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10312 (rm.GetCode() << 8)); 10313 return; 10314 } 10315 } 10316 Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm); 10317 } 10318 10319 void Assembler::smmla( 10320 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10321 VIXL_ASSERT(AllowAssembler()); 10322 CheckIT(cond); 10323 if (IsUsingT32()) { 10324 // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10325 if (!ra.Is(pc) && 10326 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10327 EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10328 rm.GetCode() | (ra.GetCode() << 12)); 10329 AdvanceIT(); 10330 return; 10331 } 10332 } else { 10333 // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10334 if (cond.IsNotNever() && !ra.Is(pc) && 10335 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10336 EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10337 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10338 return; 10339 } 10340 } 10341 Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra); 10342 } 10343 10344 void Assembler::smmlar( 10345 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10346 VIXL_ASSERT(AllowAssembler()); 10347 CheckIT(cond); 10348 if (IsUsingT32()) { 10349 // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10350 if (!ra.Is(pc) && 10351 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10352 EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10353 rm.GetCode() | (ra.GetCode() << 12)); 10354 AdvanceIT(); 10355 return; 10356 } 10357 } else { 10358 // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10359 if (cond.IsNotNever() && !ra.Is(pc) && 10360 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10361 EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10362 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10363 return; 10364 } 10365 } 10366 Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra); 10367 } 10368 10369 void Assembler::smmls( 10370 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10371 VIXL_ASSERT(AllowAssembler()); 10372 CheckIT(cond); 10373 if (IsUsingT32()) { 10374 // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10375 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10376 AllowUnpredictable())) { 10377 EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10378 rm.GetCode() | (ra.GetCode() << 12)); 10379 AdvanceIT(); 10380 return; 10381 } 10382 } else { 10383 // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10384 if (cond.IsNotNever() && 10385 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10386 AllowUnpredictable())) { 10387 EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10388 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10389 return; 10390 } 10391 } 10392 Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra); 10393 } 10394 10395 void Assembler::smmlsr( 10396 Condition cond, Register rd, Register rn, Register rm, Register ra) { 10397 VIXL_ASSERT(AllowAssembler()); 10398 CheckIT(cond); 10399 if (IsUsingT32()) { 10400 // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 10401 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10402 AllowUnpredictable())) { 10403 EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10404 rm.GetCode() | (ra.GetCode() << 12)); 10405 AdvanceIT(); 10406 return; 10407 } 10408 } else { 10409 // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 10410 if (cond.IsNotNever() && 10411 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) || 10412 AllowUnpredictable())) { 10413 EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10414 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 10415 return; 10416 } 10417 } 10418 Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra); 10419 } 10420 10421 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) { 10422 VIXL_ASSERT(AllowAssembler()); 10423 CheckIT(cond); 10424 if (IsUsingT32()) { 10425 // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10426 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10427 EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10428 rm.GetCode()); 10429 AdvanceIT(); 10430 return; 10431 } 10432 } else { 10433 // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10434 if (cond.IsNotNever() && 10435 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10436 EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10437 rn.GetCode() | (rm.GetCode() << 8)); 10438 return; 10439 } 10440 } 10441 Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm); 10442 } 10443 10444 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) { 10445 VIXL_ASSERT(AllowAssembler()); 10446 CheckIT(cond); 10447 if (IsUsingT32()) { 10448 // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10449 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10450 EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10451 rm.GetCode()); 10452 AdvanceIT(); 10453 return; 10454 } 10455 } else { 10456 // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10457 if (cond.IsNotNever() && 10458 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10459 EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10460 rn.GetCode() | (rm.GetCode() << 8)); 10461 return; 10462 } 10463 } 10464 Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm); 10465 } 10466 10467 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) { 10468 VIXL_ASSERT(AllowAssembler()); 10469 CheckIT(cond); 10470 if (IsUsingT32()) { 10471 // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10472 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10473 EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10474 rm.GetCode()); 10475 AdvanceIT(); 10476 return; 10477 } 10478 } else { 10479 // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10480 if (cond.IsNotNever() && 10481 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10482 EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10483 rn.GetCode() | (rm.GetCode() << 8)); 10484 return; 10485 } 10486 } 10487 Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm); 10488 } 10489 10490 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) { 10491 VIXL_ASSERT(AllowAssembler()); 10492 CheckIT(cond); 10493 if (IsUsingT32()) { 10494 // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10495 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10496 EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10497 rm.GetCode()); 10498 AdvanceIT(); 10499 return; 10500 } 10501 } else { 10502 // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10503 if (cond.IsNotNever() && 10504 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10505 EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10506 rn.GetCode() | (rm.GetCode() << 8)); 10507 return; 10508 } 10509 } 10510 Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm); 10511 } 10512 10513 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) { 10514 VIXL_ASSERT(AllowAssembler()); 10515 CheckIT(cond); 10516 if (IsUsingT32()) { 10517 // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10518 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10519 EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10520 rm.GetCode()); 10521 AdvanceIT(); 10522 return; 10523 } 10524 } else { 10525 // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10526 if (cond.IsNotNever() && 10527 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10528 EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10529 rn.GetCode() | (rm.GetCode() << 8)); 10530 return; 10531 } 10532 } 10533 Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm); 10534 } 10535 10536 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) { 10537 VIXL_ASSERT(AllowAssembler()); 10538 CheckIT(cond); 10539 if (IsUsingT32()) { 10540 // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10541 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10542 EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10543 rm.GetCode()); 10544 AdvanceIT(); 10545 return; 10546 } 10547 } else { 10548 // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10549 if (cond.IsNotNever() && 10550 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10551 EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10552 rn.GetCode() | (rm.GetCode() << 8)); 10553 return; 10554 } 10555 } 10556 Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm); 10557 } 10558 10559 void Assembler::smull( 10560 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10561 VIXL_ASSERT(AllowAssembler()); 10562 CheckIT(cond); 10563 if (IsUsingT32()) { 10564 // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 10565 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10566 AllowUnpredictable())) { 10567 EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 10568 (rn.GetCode() << 16) | rm.GetCode()); 10569 AdvanceIT(); 10570 return; 10571 } 10572 } else { 10573 // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10574 if (cond.IsNotNever() && 10575 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10576 AllowUnpredictable())) { 10577 EmitA32(0x00c00090U | (cond.GetCondition() << 28) | 10578 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10579 (rm.GetCode() << 8)); 10580 return; 10581 } 10582 } 10583 Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm); 10584 } 10585 10586 void Assembler::smulls( 10587 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 10588 VIXL_ASSERT(AllowAssembler()); 10589 CheckIT(cond); 10590 if (IsUsingA32()) { 10591 // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 10592 if (cond.IsNotNever() && 10593 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 10594 AllowUnpredictable())) { 10595 EmitA32(0x00d00090U | (cond.GetCondition() << 28) | 10596 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 10597 (rm.GetCode() << 8)); 10598 return; 10599 } 10600 } 10601 Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm); 10602 } 10603 10604 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) { 10605 VIXL_ASSERT(AllowAssembler()); 10606 CheckIT(cond); 10607 if (IsUsingT32()) { 10608 // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10609 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10610 EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10611 rm.GetCode()); 10612 AdvanceIT(); 10613 return; 10614 } 10615 } else { 10616 // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10617 if (cond.IsNotNever() && 10618 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10619 EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10620 rn.GetCode() | (rm.GetCode() << 8)); 10621 return; 10622 } 10623 } 10624 Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm); 10625 } 10626 10627 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) { 10628 VIXL_ASSERT(AllowAssembler()); 10629 CheckIT(cond); 10630 if (IsUsingT32()) { 10631 // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10632 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10633 EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10634 rm.GetCode()); 10635 AdvanceIT(); 10636 return; 10637 } 10638 } else { 10639 // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10640 if (cond.IsNotNever() && 10641 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10642 EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10643 rn.GetCode() | (rm.GetCode() << 8)); 10644 return; 10645 } 10646 } 10647 Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm); 10648 } 10649 10650 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) { 10651 VIXL_ASSERT(AllowAssembler()); 10652 CheckIT(cond); 10653 if (IsUsingT32()) { 10654 // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10655 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10656 EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10657 rm.GetCode()); 10658 AdvanceIT(); 10659 return; 10660 } 10661 } else { 10662 // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10663 if (cond.IsNotNever() && 10664 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10665 EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10666 rn.GetCode() | (rm.GetCode() << 8)); 10667 return; 10668 } 10669 } 10670 Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm); 10671 } 10672 10673 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) { 10674 VIXL_ASSERT(AllowAssembler()); 10675 CheckIT(cond); 10676 if (IsUsingT32()) { 10677 // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10678 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10679 EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10680 rm.GetCode()); 10681 AdvanceIT(); 10682 return; 10683 } 10684 } else { 10685 // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10686 if (cond.IsNotNever() && 10687 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10688 EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10689 rn.GetCode() | (rm.GetCode() << 8)); 10690 return; 10691 } 10692 } 10693 Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm); 10694 } 10695 10696 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) { 10697 VIXL_ASSERT(AllowAssembler()); 10698 CheckIT(cond); 10699 if (IsUsingT32()) { 10700 // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10701 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10702 EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10703 rm.GetCode()); 10704 AdvanceIT(); 10705 return; 10706 } 10707 } else { 10708 // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10709 if (cond.IsNotNever() && 10710 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10711 EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10712 rn.GetCode() | (rm.GetCode() << 8)); 10713 return; 10714 } 10715 } 10716 Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm); 10717 } 10718 10719 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) { 10720 VIXL_ASSERT(AllowAssembler()); 10721 CheckIT(cond); 10722 if (IsUsingT32()) { 10723 // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10724 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10725 EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10726 rm.GetCode()); 10727 AdvanceIT(); 10728 return; 10729 } 10730 } else { 10731 // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10732 if (cond.IsNotNever() && 10733 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10734 EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 10735 rn.GetCode() | (rm.GetCode() << 8)); 10736 return; 10737 } 10738 } 10739 Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm); 10740 } 10741 10742 void Assembler::ssat(Condition cond, 10743 Register rd, 10744 uint32_t imm, 10745 const Operand& operand) { 10746 VIXL_ASSERT(AllowAssembler()); 10747 CheckIT(cond); 10748 if (operand.IsImmediateShiftedRegister()) { 10749 Register rn = operand.GetBaseRegister(); 10750 Shift shift = operand.GetShift(); 10751 uint32_t amount = operand.GetShiftAmount(); 10752 if (IsUsingT32()) { 10753 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1 10754 if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) && 10755 (amount <= 31) && 10756 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10757 uint32_t imm_ = imm - 1; 10758 EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ | 10759 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 10760 ((amount & 0x1c) << 10)); 10761 AdvanceIT(); 10762 return; 10763 } 10764 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1 10765 if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) && 10766 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10767 uint32_t imm_ = imm - 1; 10768 EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ | 10769 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 10770 ((amount & 0x1c) << 10)); 10771 AdvanceIT(); 10772 return; 10773 } 10774 } else { 10775 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1 10776 if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) && 10777 (amount <= 32) && cond.IsNotNever() && 10778 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10779 uint32_t imm_ = imm - 1; 10780 uint32_t amount_ = amount % 32; 10781 EmitA32(0x06a00050U | (cond.GetCondition() << 28) | 10782 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() | 10783 (amount_ << 7)); 10784 return; 10785 } 10786 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1 10787 if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) && 10788 cond.IsNotNever() && 10789 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10790 uint32_t imm_ = imm - 1; 10791 EmitA32(0x06a00010U | (cond.GetCondition() << 28) | 10792 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() | 10793 (amount << 7)); 10794 return; 10795 } 10796 } 10797 } 10798 Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand); 10799 } 10800 10801 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) { 10802 VIXL_ASSERT(AllowAssembler()); 10803 CheckIT(cond); 10804 if (IsUsingT32()) { 10805 // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1 10806 if ((imm >= 1) && (imm <= 16) && 10807 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10808 uint32_t imm_ = imm - 1; 10809 EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ | 10810 (rn.GetCode() << 16)); 10811 AdvanceIT(); 10812 return; 10813 } 10814 } else { 10815 // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1 10816 if ((imm >= 1) && (imm <= 16) && cond.IsNotNever() && 10817 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10818 uint32_t imm_ = imm - 1; 10819 EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 10820 (imm_ << 16) | rn.GetCode()); 10821 return; 10822 } 10823 } 10824 Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn); 10825 } 10826 10827 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) { 10828 VIXL_ASSERT(AllowAssembler()); 10829 CheckIT(cond); 10830 if (IsUsingT32()) { 10831 // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10832 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10833 EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10834 rm.GetCode()); 10835 AdvanceIT(); 10836 return; 10837 } 10838 } else { 10839 // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10840 if (cond.IsNotNever() && 10841 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10842 EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 10843 (rn.GetCode() << 16) | rm.GetCode()); 10844 return; 10845 } 10846 } 10847 Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm); 10848 } 10849 10850 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) { 10851 VIXL_ASSERT(AllowAssembler()); 10852 CheckIT(cond); 10853 if (IsUsingT32()) { 10854 // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10855 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10856 EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10857 rm.GetCode()); 10858 AdvanceIT(); 10859 return; 10860 } 10861 } else { 10862 // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10863 if (cond.IsNotNever() && 10864 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10865 EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 10866 (rn.GetCode() << 16) | rm.GetCode()); 10867 return; 10868 } 10869 } 10870 Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm); 10871 } 10872 10873 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) { 10874 VIXL_ASSERT(AllowAssembler()); 10875 CheckIT(cond); 10876 if (IsUsingT32()) { 10877 // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 10878 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10879 EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 10880 rm.GetCode()); 10881 AdvanceIT(); 10882 return; 10883 } 10884 } else { 10885 // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 10886 if (cond.IsNotNever() && 10887 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 10888 EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 10889 (rn.GetCode() << 16) | rm.GetCode()); 10890 return; 10891 } 10892 } 10893 Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm); 10894 } 10895 10896 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) { 10897 VIXL_ASSERT(AllowAssembler()); 10898 CheckIT(cond); 10899 if (operand.IsImmediateZero()) { 10900 Register rn = operand.GetBaseRegister(); 10901 if (IsUsingT32()) { 10902 // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1 10903 if (operand.IsOffset() && 10904 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10905 EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 10906 AdvanceIT(); 10907 return; 10908 } 10909 } else { 10910 // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1 10911 if (operand.IsOffset() && cond.IsNotNever() && 10912 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10913 EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 10914 (rn.GetCode() << 16)); 10915 return; 10916 } 10917 } 10918 } 10919 Delegate(kStl, &Assembler::stl, cond, rt, operand); 10920 } 10921 10922 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) { 10923 VIXL_ASSERT(AllowAssembler()); 10924 CheckIT(cond); 10925 if (operand.IsImmediateZero()) { 10926 Register rn = operand.GetBaseRegister(); 10927 if (IsUsingT32()) { 10928 // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1 10929 if (operand.IsOffset() && 10930 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10931 EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 10932 AdvanceIT(); 10933 return; 10934 } 10935 } else { 10936 // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1 10937 if (operand.IsOffset() && cond.IsNotNever() && 10938 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10939 EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 10940 (rn.GetCode() << 16)); 10941 return; 10942 } 10943 } 10944 } 10945 Delegate(kStlb, &Assembler::stlb, cond, rt, operand); 10946 } 10947 10948 void Assembler::stlex(Condition cond, 10949 Register rd, 10950 Register rt, 10951 const MemOperand& operand) { 10952 VIXL_ASSERT(AllowAssembler()); 10953 CheckIT(cond); 10954 if (operand.IsImmediateZero()) { 10955 Register rn = operand.GetBaseRegister(); 10956 if (IsUsingT32()) { 10957 // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 10958 if (operand.IsOffset() && 10959 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10960 EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) | 10961 (rn.GetCode() << 16)); 10962 AdvanceIT(); 10963 return; 10964 } 10965 } else { 10966 // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 10967 if (operand.IsOffset() && cond.IsNotNever() && 10968 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10969 EmitA32(0x01800e90U | (cond.GetCondition() << 28) | 10970 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10971 return; 10972 } 10973 } 10974 } 10975 Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand); 10976 } 10977 10978 void Assembler::stlexb(Condition cond, 10979 Register rd, 10980 Register rt, 10981 const MemOperand& operand) { 10982 VIXL_ASSERT(AllowAssembler()); 10983 CheckIT(cond); 10984 if (operand.IsImmediateZero()) { 10985 Register rn = operand.GetBaseRegister(); 10986 if (IsUsingT32()) { 10987 // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 10988 if (operand.IsOffset() && 10989 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10990 EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) | 10991 (rn.GetCode() << 16)); 10992 AdvanceIT(); 10993 return; 10994 } 10995 } else { 10996 // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 10997 if (operand.IsOffset() && cond.IsNotNever() && 10998 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 10999 EmitA32(0x01c00e90U | (cond.GetCondition() << 28) | 11000 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11001 return; 11002 } 11003 } 11004 } 11005 Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand); 11006 } 11007 11008 void Assembler::stlexd(Condition cond, 11009 Register rd, 11010 Register rt, 11011 Register rt2, 11012 const MemOperand& operand) { 11013 VIXL_ASSERT(AllowAssembler()); 11014 CheckIT(cond); 11015 if (operand.IsImmediateZero()) { 11016 Register rn = operand.GetBaseRegister(); 11017 if (IsUsingT32()) { 11018 // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1 11019 if (operand.IsOffset() && 11020 ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || 11021 AllowUnpredictable())) { 11022 EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) | 11023 (rt2.GetCode() << 8) | (rn.GetCode() << 16)); 11024 AdvanceIT(); 11025 return; 11026 } 11027 } else { 11028 // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1 11029 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11030 operand.IsOffset() && cond.IsNotNever() && 11031 ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() && 11032 !rn.IsPC()) || 11033 AllowUnpredictable())) { 11034 EmitA32(0x01a00e90U | (cond.GetCondition() << 28) | 11035 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11036 return; 11037 } 11038 } 11039 } 11040 Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand); 11041 } 11042 11043 void Assembler::stlexh(Condition cond, 11044 Register rd, 11045 Register rt, 11046 const MemOperand& operand) { 11047 VIXL_ASSERT(AllowAssembler()); 11048 CheckIT(cond); 11049 if (operand.IsImmediateZero()) { 11050 Register rn = operand.GetBaseRegister(); 11051 if (IsUsingT32()) { 11052 // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 11053 if (operand.IsOffset() && 11054 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11055 EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) | 11056 (rn.GetCode() << 16)); 11057 AdvanceIT(); 11058 return; 11059 } 11060 } else { 11061 // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 11062 if (operand.IsOffset() && cond.IsNotNever() && 11063 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11064 EmitA32(0x01e00e90U | (cond.GetCondition() << 28) | 11065 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11066 return; 11067 } 11068 } 11069 } 11070 Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand); 11071 } 11072 11073 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) { 11074 VIXL_ASSERT(AllowAssembler()); 11075 CheckIT(cond); 11076 if (operand.IsImmediateZero()) { 11077 Register rn = operand.GetBaseRegister(); 11078 if (IsUsingT32()) { 11079 // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1 11080 if (operand.IsOffset() && 11081 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11082 EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 11083 AdvanceIT(); 11084 return; 11085 } 11086 } else { 11087 // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1 11088 if (operand.IsOffset() && cond.IsNotNever() && 11089 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11090 EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 11091 (rn.GetCode() << 16)); 11092 return; 11093 } 11094 } 11095 } 11096 Delegate(kStlh, &Assembler::stlh, cond, rt, operand); 11097 } 11098 11099 void Assembler::stm(Condition cond, 11100 EncodingSize size, 11101 Register rn, 11102 WriteBack write_back, 11103 RegisterList registers) { 11104 VIXL_ASSERT(AllowAssembler()); 11105 CheckIT(cond); 11106 if (IsUsingT32()) { 11107 // STM{<c>}{<q>} <Rn>!, <registers> ; T1 11108 if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() && 11109 ((registers.GetList() & ~0xff) == 0)) { 11110 EmitT32_16(0xc000 | (rn.GetCode() << 8) | 11111 GetRegisterListEncoding(registers, 0, 8)); 11112 AdvanceIT(); 11113 return; 11114 } 11115 // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2 11116 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) && 11117 (!rn.IsPC() || AllowUnpredictable())) { 11118 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 11119 (write_back.GetWriteBackUint32() << 21) | 11120 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11121 GetRegisterListEncoding(registers, 0, 13)); 11122 AdvanceIT(); 11123 return; 11124 } 11125 } else { 11126 // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1 11127 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11128 EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11129 (write_back.GetWriteBackUint32() << 21) | 11130 GetRegisterListEncoding(registers, 0, 16)); 11131 return; 11132 } 11133 } 11134 Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers); 11135 } 11136 11137 void Assembler::stmda(Condition cond, 11138 Register rn, 11139 WriteBack write_back, 11140 RegisterList registers) { 11141 VIXL_ASSERT(AllowAssembler()); 11142 CheckIT(cond); 11143 if (IsUsingA32()) { 11144 // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1 11145 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11146 EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11147 (write_back.GetWriteBackUint32() << 21) | 11148 GetRegisterListEncoding(registers, 0, 16)); 11149 return; 11150 } 11151 } 11152 Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers); 11153 } 11154 11155 void Assembler::stmdb(Condition cond, 11156 EncodingSize size, 11157 Register rn, 11158 WriteBack write_back, 11159 RegisterList registers) { 11160 VIXL_ASSERT(AllowAssembler()); 11161 CheckIT(cond); 11162 if (IsUsingT32()) { 11163 // STMDB{<c>}{<q>} SP!, <registers> ; T1 11164 if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() && 11165 ((registers.GetList() & ~0x40ff) == 0)) { 11166 EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) | 11167 GetRegisterListEncoding(registers, 0, 8)); 11168 AdvanceIT(); 11169 return; 11170 } 11171 // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1 11172 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) && 11173 (!rn.IsPC() || AllowUnpredictable())) { 11174 EmitT32_32(0xe9000000U | (rn.GetCode() << 16) | 11175 (write_back.GetWriteBackUint32() << 21) | 11176 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11177 GetRegisterListEncoding(registers, 0, 13)); 11178 AdvanceIT(); 11179 return; 11180 } 11181 } else { 11182 // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1 11183 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11184 EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11185 (write_back.GetWriteBackUint32() << 21) | 11186 GetRegisterListEncoding(registers, 0, 16)); 11187 return; 11188 } 11189 } 11190 Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers); 11191 } 11192 11193 void Assembler::stmea(Condition cond, 11194 EncodingSize size, 11195 Register rn, 11196 WriteBack write_back, 11197 RegisterList registers) { 11198 VIXL_ASSERT(AllowAssembler()); 11199 CheckIT(cond); 11200 if (IsUsingT32()) { 11201 // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1 11202 if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() && 11203 ((registers.GetList() & ~0xff) == 0)) { 11204 EmitT32_16(0xc000 | (rn.GetCode() << 8) | 11205 GetRegisterListEncoding(registers, 0, 8)); 11206 AdvanceIT(); 11207 return; 11208 } 11209 // STMEA{<c>}.W <Rn>{!}, <registers> ; T2 11210 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) && 11211 (!rn.IsPC() || AllowUnpredictable())) { 11212 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 11213 (write_back.GetWriteBackUint32() << 21) | 11214 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11215 GetRegisterListEncoding(registers, 0, 13)); 11216 AdvanceIT(); 11217 return; 11218 } 11219 // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2 11220 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) && 11221 (!rn.IsPC() || AllowUnpredictable())) { 11222 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 11223 (write_back.GetWriteBackUint32() << 21) | 11224 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11225 GetRegisterListEncoding(registers, 0, 13)); 11226 AdvanceIT(); 11227 return; 11228 } 11229 } else { 11230 // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1 11231 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11232 EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11233 (write_back.GetWriteBackUint32() << 21) | 11234 GetRegisterListEncoding(registers, 0, 16)); 11235 return; 11236 } 11237 } 11238 Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers); 11239 } 11240 11241 void Assembler::stmed(Condition cond, 11242 Register rn, 11243 WriteBack write_back, 11244 RegisterList registers) { 11245 VIXL_ASSERT(AllowAssembler()); 11246 CheckIT(cond); 11247 if (IsUsingA32()) { 11248 // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1 11249 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11250 EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11251 (write_back.GetWriteBackUint32() << 21) | 11252 GetRegisterListEncoding(registers, 0, 16)); 11253 return; 11254 } 11255 } 11256 Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers); 11257 } 11258 11259 void Assembler::stmfa(Condition cond, 11260 Register rn, 11261 WriteBack write_back, 11262 RegisterList registers) { 11263 VIXL_ASSERT(AllowAssembler()); 11264 CheckIT(cond); 11265 if (IsUsingA32()) { 11266 // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1 11267 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11268 EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11269 (write_back.GetWriteBackUint32() << 21) | 11270 GetRegisterListEncoding(registers, 0, 16)); 11271 return; 11272 } 11273 } 11274 Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers); 11275 } 11276 11277 void Assembler::stmfd(Condition cond, 11278 Register rn, 11279 WriteBack write_back, 11280 RegisterList registers) { 11281 VIXL_ASSERT(AllowAssembler()); 11282 CheckIT(cond); 11283 if (IsUsingT32()) { 11284 // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1 11285 if (((registers.GetList() & ~0x5fff) == 0) && 11286 (!rn.IsPC() || AllowUnpredictable())) { 11287 EmitT32_32(0xe9000000U | (rn.GetCode() << 16) | 11288 (write_back.GetWriteBackUint32() << 21) | 11289 (GetRegisterListEncoding(registers, 14, 1) << 14) | 11290 GetRegisterListEncoding(registers, 0, 13)); 11291 AdvanceIT(); 11292 return; 11293 } 11294 } else { 11295 // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1 11296 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11297 EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11298 (write_back.GetWriteBackUint32() << 21) | 11299 GetRegisterListEncoding(registers, 0, 16)); 11300 return; 11301 } 11302 } 11303 Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers); 11304 } 11305 11306 void Assembler::stmib(Condition cond, 11307 Register rn, 11308 WriteBack write_back, 11309 RegisterList registers) { 11310 VIXL_ASSERT(AllowAssembler()); 11311 CheckIT(cond); 11312 if (IsUsingA32()) { 11313 // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1 11314 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) { 11315 EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 11316 (write_back.GetWriteBackUint32() << 21) | 11317 GetRegisterListEncoding(registers, 0, 16)); 11318 return; 11319 } 11320 } 11321 Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers); 11322 } 11323 11324 void Assembler::str(Condition cond, 11325 EncodingSize size, 11326 Register rt, 11327 const MemOperand& operand) { 11328 VIXL_ASSERT(AllowAssembler()); 11329 CheckIT(cond); 11330 if (operand.IsImmediate()) { 11331 Register rn = operand.GetBaseRegister(); 11332 int32_t offset = operand.GetOffsetImmediate(); 11333 if (IsUsingT32()) { 11334 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 11335 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 11336 (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) { 11337 int32_t offset_ = offset >> 2; 11338 EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) | 11339 ((offset_ & 0x1f) << 6)); 11340 AdvanceIT(); 11341 return; 11342 } 11343 // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2 11344 if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) && 11345 ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) { 11346 int32_t offset_ = offset >> 2; 11347 EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff)); 11348 AdvanceIT(); 11349 return; 11350 } 11351 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3 11352 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 11353 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11354 (!rt.IsPC() || AllowUnpredictable())) { 11355 EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11356 (offset & 0xfff)); 11357 AdvanceIT(); 11358 return; 11359 } 11360 // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4 11361 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 11362 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11363 (!rt.IsPC() || AllowUnpredictable())) { 11364 EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11365 (-offset & 0xff)); 11366 AdvanceIT(); 11367 return; 11368 } 11369 // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4 11370 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11371 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11372 (!rt.IsPC() || AllowUnpredictable())) { 11373 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11374 uint32_t offset_ = abs(offset); 11375 EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11376 offset_ | (sign << 9)); 11377 AdvanceIT(); 11378 return; 11379 } 11380 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4 11381 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11382 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11383 (!rt.IsPC() || AllowUnpredictable())) { 11384 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11385 uint32_t offset_ = abs(offset); 11386 EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11387 offset_ | (sign << 9)); 11388 AdvanceIT(); 11389 return; 11390 } 11391 } else { 11392 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 11393 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 11394 cond.IsNotNever()) { 11395 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11396 uint32_t offset_ = abs(offset); 11397 EmitA32(0x05000000U | (cond.GetCondition() << 28) | 11398 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11399 (sign << 23)); 11400 return; 11401 } 11402 // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 11403 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 11404 cond.IsNotNever()) { 11405 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11406 uint32_t offset_ = abs(offset); 11407 EmitA32(0x04000000U | (cond.GetCondition() << 28) | 11408 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11409 (sign << 23)); 11410 return; 11411 } 11412 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 11413 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 11414 cond.IsNotNever()) { 11415 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11416 uint32_t offset_ = abs(offset); 11417 EmitA32(0x05200000U | (cond.GetCondition() << 28) | 11418 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11419 (sign << 23)); 11420 return; 11421 } 11422 } 11423 } 11424 if (operand.IsPlainRegister()) { 11425 Register rn = operand.GetBaseRegister(); 11426 Sign sign = operand.GetSign(); 11427 Register rm = operand.GetOffsetRegister(); 11428 if (IsUsingT32()) { 11429 // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 11430 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 11431 sign.IsPlus() && operand.IsOffset()) { 11432 EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) | 11433 (rm.GetCode() << 6)); 11434 AdvanceIT(); 11435 return; 11436 } 11437 } 11438 } 11439 if (operand.IsShiftedRegister()) { 11440 Register rn = operand.GetBaseRegister(); 11441 Sign sign = operand.GetSign(); 11442 Register rm = operand.GetOffsetRegister(); 11443 Shift shift = operand.GetShift(); 11444 uint32_t amount = operand.GetShiftAmount(); 11445 if (IsUsingT32()) { 11446 // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 11447 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 11448 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11449 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11450 EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11451 rm.GetCode() | (amount << 4)); 11452 AdvanceIT(); 11453 return; 11454 } 11455 } else { 11456 // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 11457 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() && 11458 (!rm.IsPC() || AllowUnpredictable())) { 11459 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11460 uint32_t shift_ = TypeEncodingValue(shift); 11461 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11462 EmitA32(0x07000000U | (cond.GetCondition() << 28) | 11463 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11464 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11465 return; 11466 } 11467 // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 11468 if (operand.IsShiftValid() && operand.IsPostIndex() && 11469 cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) { 11470 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11471 uint32_t shift_ = TypeEncodingValue(shift); 11472 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11473 EmitA32(0x06000000U | (cond.GetCondition() << 28) | 11474 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11475 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11476 return; 11477 } 11478 // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 11479 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() && 11480 (!rm.IsPC() || AllowUnpredictable())) { 11481 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11482 uint32_t shift_ = TypeEncodingValue(shift); 11483 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11484 EmitA32(0x07200000U | (cond.GetCondition() << 28) | 11485 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11486 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11487 return; 11488 } 11489 } 11490 } 11491 Delegate(kStr, &Assembler::str, cond, size, rt, operand); 11492 } 11493 11494 void Assembler::strb(Condition cond, 11495 EncodingSize size, 11496 Register rt, 11497 const MemOperand& operand) { 11498 VIXL_ASSERT(AllowAssembler()); 11499 CheckIT(cond); 11500 if (operand.IsImmediate()) { 11501 Register rn = operand.GetBaseRegister(); 11502 int32_t offset = operand.GetOffsetImmediate(); 11503 if (IsUsingT32()) { 11504 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 11505 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 11506 (offset <= 31) && operand.IsOffset()) { 11507 EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) | 11508 ((offset & 0x1f) << 6)); 11509 AdvanceIT(); 11510 return; 11511 } 11512 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 11513 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 11514 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11515 (!rt.IsPC() || AllowUnpredictable())) { 11516 EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11517 (offset & 0xfff)); 11518 AdvanceIT(); 11519 return; 11520 } 11521 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 11522 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 11523 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11524 (!rt.IsPC() || AllowUnpredictable())) { 11525 EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11526 (-offset & 0xff)); 11527 AdvanceIT(); 11528 return; 11529 } 11530 // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 11531 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11532 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11533 (!rt.IsPC() || AllowUnpredictable())) { 11534 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11535 uint32_t offset_ = abs(offset); 11536 EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11537 offset_ | (sign << 9)); 11538 AdvanceIT(); 11539 return; 11540 } 11541 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 11542 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11543 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11544 (!rt.IsPC() || AllowUnpredictable())) { 11545 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11546 uint32_t offset_ = abs(offset); 11547 EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11548 offset_ | (sign << 9)); 11549 AdvanceIT(); 11550 return; 11551 } 11552 } else { 11553 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 11554 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 11555 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11556 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11557 uint32_t offset_ = abs(offset); 11558 EmitA32(0x05400000U | (cond.GetCondition() << 28) | 11559 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11560 (sign << 23)); 11561 return; 11562 } 11563 // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 11564 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 11565 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11566 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11567 uint32_t offset_ = abs(offset); 11568 EmitA32(0x04400000U | (cond.GetCondition() << 28) | 11569 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11570 (sign << 23)); 11571 return; 11572 } 11573 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 11574 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 11575 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11576 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11577 uint32_t offset_ = abs(offset); 11578 EmitA32(0x05600000U | (cond.GetCondition() << 28) | 11579 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 11580 (sign << 23)); 11581 return; 11582 } 11583 } 11584 } 11585 if (operand.IsPlainRegister()) { 11586 Register rn = operand.GetBaseRegister(); 11587 Sign sign = operand.GetSign(); 11588 Register rm = operand.GetOffsetRegister(); 11589 if (IsUsingT32()) { 11590 // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 11591 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 11592 sign.IsPlus() && operand.IsOffset()) { 11593 EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) | 11594 (rm.GetCode() << 6)); 11595 AdvanceIT(); 11596 return; 11597 } 11598 } 11599 } 11600 if (operand.IsShiftedRegister()) { 11601 Register rn = operand.GetBaseRegister(); 11602 Sign sign = operand.GetSign(); 11603 Register rm = operand.GetOffsetRegister(); 11604 Shift shift = operand.GetShift(); 11605 uint32_t amount = operand.GetShiftAmount(); 11606 if (IsUsingT32()) { 11607 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 11608 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 11609 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11610 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11611 EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11612 rm.GetCode() | (amount << 4)); 11613 AdvanceIT(); 11614 return; 11615 } 11616 } else { 11617 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 11618 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() && 11619 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11620 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11621 uint32_t shift_ = TypeEncodingValue(shift); 11622 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11623 EmitA32(0x07400000U | (cond.GetCondition() << 28) | 11624 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11625 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11626 return; 11627 } 11628 // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 11629 if (operand.IsShiftValid() && operand.IsPostIndex() && 11630 cond.IsNotNever() && 11631 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11632 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11633 uint32_t shift_ = TypeEncodingValue(shift); 11634 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11635 EmitA32(0x06400000U | (cond.GetCondition() << 28) | 11636 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11637 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11638 return; 11639 } 11640 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 11641 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() && 11642 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 11643 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11644 uint32_t shift_ = TypeEncodingValue(shift); 11645 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 11646 EmitA32(0x07600000U | (cond.GetCondition() << 28) | 11647 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11648 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 11649 return; 11650 } 11651 } 11652 } 11653 Delegate(kStrb, &Assembler::strb, cond, size, rt, operand); 11654 } 11655 11656 void Assembler::strd(Condition cond, 11657 Register rt, 11658 Register rt2, 11659 const MemOperand& operand) { 11660 VIXL_ASSERT(AllowAssembler()); 11661 CheckIT(cond); 11662 if (operand.IsImmediate()) { 11663 Register rn = operand.GetBaseRegister(); 11664 int32_t offset = operand.GetOffsetImmediate(); 11665 if (IsUsingT32()) { 11666 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1 11667 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 11668 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11669 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 11670 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11671 uint32_t offset_ = abs(offset) >> 2; 11672 EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 11673 (rn.GetCode() << 16) | offset_ | (sign << 23)); 11674 AdvanceIT(); 11675 return; 11676 } 11677 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1 11678 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 11679 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11680 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 11681 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11682 uint32_t offset_ = abs(offset) >> 2; 11683 EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 11684 (rn.GetCode() << 16) | offset_ | (sign << 23)); 11685 AdvanceIT(); 11686 return; 11687 } 11688 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1 11689 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 11690 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11691 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 11692 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11693 uint32_t offset_ = abs(offset) >> 2; 11694 EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 11695 (rn.GetCode() << 16) | offset_ | (sign << 23)); 11696 AdvanceIT(); 11697 return; 11698 } 11699 } else { 11700 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1 11701 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11702 (offset >= -255) && (offset <= 255) && operand.IsOffset() && 11703 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 11704 AllowUnpredictable())) { 11705 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11706 uint32_t offset_ = abs(offset); 11707 EmitA32(0x014000f0U | (cond.GetCondition() << 28) | 11708 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11709 ((offset_ & 0xf0) << 4) | (sign << 23)); 11710 return; 11711 } 11712 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1 11713 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11714 (offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 11715 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 11716 AllowUnpredictable())) { 11717 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11718 uint32_t offset_ = abs(offset); 11719 EmitA32(0x004000f0U | (cond.GetCondition() << 28) | 11720 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11721 ((offset_ & 0xf0) << 4) | (sign << 23)); 11722 return; 11723 } 11724 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1 11725 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11726 (offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 11727 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || 11728 AllowUnpredictable())) { 11729 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11730 uint32_t offset_ = abs(offset); 11731 EmitA32(0x016000f0U | (cond.GetCondition() << 28) | 11732 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11733 ((offset_ & 0xf0) << 4) | (sign << 23)); 11734 return; 11735 } 11736 } 11737 } 11738 if (operand.IsPlainRegister()) { 11739 Register rn = operand.GetBaseRegister(); 11740 Sign sign = operand.GetSign(); 11741 Register rm = operand.GetOffsetRegister(); 11742 if (IsUsingA32()) { 11743 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1 11744 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11745 operand.IsOffset() && cond.IsNotNever() && 11746 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 11747 AllowUnpredictable())) { 11748 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11749 EmitA32(0x010000f0U | (cond.GetCondition() << 28) | 11750 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11751 (sign_ << 23)); 11752 return; 11753 } 11754 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1 11755 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11756 operand.IsPostIndex() && cond.IsNotNever() && 11757 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 11758 AllowUnpredictable())) { 11759 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11760 EmitA32(0x000000f0U | (cond.GetCondition() << 28) | 11761 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11762 (sign_ << 23)); 11763 return; 11764 } 11765 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1 11766 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11767 operand.IsPreIndex() && cond.IsNotNever() && 11768 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) || 11769 AllowUnpredictable())) { 11770 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11771 EmitA32(0x012000f0U | (cond.GetCondition() << 28) | 11772 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11773 (sign_ << 23)); 11774 return; 11775 } 11776 } 11777 } 11778 Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand); 11779 } 11780 11781 void Assembler::strex(Condition cond, 11782 Register rd, 11783 Register rt, 11784 const MemOperand& operand) { 11785 VIXL_ASSERT(AllowAssembler()); 11786 CheckIT(cond); 11787 if (operand.IsImmediate()) { 11788 Register rn = operand.GetBaseRegister(); 11789 int32_t offset = operand.GetOffsetImmediate(); 11790 if (IsUsingT32()) { 11791 // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1 11792 if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) && 11793 operand.IsOffset() && 11794 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11795 int32_t offset_ = offset >> 2; 11796 EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) | 11797 (rn.GetCode() << 16) | (offset_ & 0xff)); 11798 AdvanceIT(); 11799 return; 11800 } 11801 } else { 11802 // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1 11803 if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() && 11804 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11805 EmitA32(0x01800f90U | (cond.GetCondition() << 28) | 11806 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11807 return; 11808 } 11809 } 11810 } 11811 Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand); 11812 } 11813 11814 void Assembler::strexb(Condition cond, 11815 Register rd, 11816 Register rt, 11817 const MemOperand& operand) { 11818 VIXL_ASSERT(AllowAssembler()); 11819 CheckIT(cond); 11820 if (operand.IsImmediateZero()) { 11821 Register rn = operand.GetBaseRegister(); 11822 if (IsUsingT32()) { 11823 // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 11824 if (operand.IsOffset() && 11825 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11826 EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) | 11827 (rn.GetCode() << 16)); 11828 AdvanceIT(); 11829 return; 11830 } 11831 } else { 11832 // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 11833 if (operand.IsOffset() && cond.IsNotNever() && 11834 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11835 EmitA32(0x01c00f90U | (cond.GetCondition() << 28) | 11836 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11837 return; 11838 } 11839 } 11840 } 11841 Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand); 11842 } 11843 11844 void Assembler::strexd(Condition cond, 11845 Register rd, 11846 Register rt, 11847 Register rt2, 11848 const MemOperand& operand) { 11849 VIXL_ASSERT(AllowAssembler()); 11850 CheckIT(cond); 11851 if (operand.IsImmediateZero()) { 11852 Register rn = operand.GetBaseRegister(); 11853 if (IsUsingT32()) { 11854 // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1 11855 if (operand.IsOffset() && 11856 ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || 11857 AllowUnpredictable())) { 11858 EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) | 11859 (rt2.GetCode() << 8) | (rn.GetCode() << 16)); 11860 AdvanceIT(); 11861 return; 11862 } 11863 } else { 11864 // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1 11865 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 11866 operand.IsOffset() && cond.IsNotNever() && 11867 ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() && 11868 !rn.IsPC()) || 11869 AllowUnpredictable())) { 11870 EmitA32(0x01a00f90U | (cond.GetCondition() << 28) | 11871 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11872 return; 11873 } 11874 } 11875 } 11876 Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand); 11877 } 11878 11879 void Assembler::strexh(Condition cond, 11880 Register rd, 11881 Register rt, 11882 const MemOperand& operand) { 11883 VIXL_ASSERT(AllowAssembler()); 11884 CheckIT(cond); 11885 if (operand.IsImmediateZero()) { 11886 Register rn = operand.GetBaseRegister(); 11887 if (IsUsingT32()) { 11888 // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 11889 if (operand.IsOffset() && 11890 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11891 EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) | 11892 (rn.GetCode() << 16)); 11893 AdvanceIT(); 11894 return; 11895 } 11896 } else { 11897 // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 11898 if (operand.IsOffset() && cond.IsNotNever() && 11899 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 11900 EmitA32(0x01e00f90U | (cond.GetCondition() << 28) | 11901 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 11902 return; 11903 } 11904 } 11905 } 11906 Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand); 11907 } 11908 11909 void Assembler::strh(Condition cond, 11910 EncodingSize size, 11911 Register rt, 11912 const MemOperand& operand) { 11913 VIXL_ASSERT(AllowAssembler()); 11914 CheckIT(cond); 11915 if (operand.IsImmediate()) { 11916 Register rn = operand.GetBaseRegister(); 11917 int32_t offset = operand.GetOffsetImmediate(); 11918 if (IsUsingT32()) { 11919 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 11920 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 11921 (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) { 11922 int32_t offset_ = offset >> 1; 11923 EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) | 11924 ((offset_ & 0x1f) << 6)); 11925 AdvanceIT(); 11926 return; 11927 } 11928 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 11929 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 11930 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11931 (!rt.IsPC() || AllowUnpredictable())) { 11932 EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11933 (offset & 0xfff)); 11934 AdvanceIT(); 11935 return; 11936 } 11937 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 11938 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 11939 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 11940 (!rt.IsPC() || AllowUnpredictable())) { 11941 EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11942 (-offset & 0xff)); 11943 AdvanceIT(); 11944 return; 11945 } 11946 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 11947 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11948 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11949 (!rt.IsPC() || AllowUnpredictable())) { 11950 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11951 uint32_t offset_ = abs(offset); 11952 EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11953 offset_ | (sign << 9)); 11954 AdvanceIT(); 11955 return; 11956 } 11957 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 11958 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 11959 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) && 11960 (!rt.IsPC() || AllowUnpredictable())) { 11961 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11962 uint32_t offset_ = abs(offset); 11963 EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11964 offset_ | (sign << 9)); 11965 AdvanceIT(); 11966 return; 11967 } 11968 } else { 11969 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 11970 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 11971 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11972 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11973 uint32_t offset_ = abs(offset); 11974 EmitA32(0x014000b0U | (cond.GetCondition() << 28) | 11975 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11976 ((offset_ & 0xf0) << 4) | (sign << 23)); 11977 return; 11978 } 11979 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 11980 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 11981 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11982 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11983 uint32_t offset_ = abs(offset); 11984 EmitA32(0x004000b0U | (cond.GetCondition() << 28) | 11985 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11986 ((offset_ & 0xf0) << 4) | (sign << 23)); 11987 return; 11988 } 11989 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 11990 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 11991 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 11992 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 11993 uint32_t offset_ = abs(offset); 11994 EmitA32(0x016000b0U | (cond.GetCondition() << 28) | 11995 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 11996 ((offset_ & 0xf0) << 4) | (sign << 23)); 11997 return; 11998 } 11999 } 12000 } 12001 if (operand.IsPlainRegister()) { 12002 Register rn = operand.GetBaseRegister(); 12003 Sign sign = operand.GetSign(); 12004 Register rm = operand.GetOffsetRegister(); 12005 if (IsUsingT32()) { 12006 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 12007 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 12008 sign.IsPlus() && operand.IsOffset()) { 12009 EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) | 12010 (rm.GetCode() << 6)); 12011 AdvanceIT(); 12012 return; 12013 } 12014 } else { 12015 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 12016 if (operand.IsOffset() && cond.IsNotNever() && 12017 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12018 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 12019 EmitA32(0x010000b0U | (cond.GetCondition() << 28) | 12020 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12021 (sign_ << 23)); 12022 return; 12023 } 12024 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 12025 if (operand.IsPostIndex() && cond.IsNotNever() && 12026 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12027 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 12028 EmitA32(0x000000b0U | (cond.GetCondition() << 28) | 12029 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12030 (sign_ << 23)); 12031 return; 12032 } 12033 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 12034 if (operand.IsPreIndex() && cond.IsNotNever() && 12035 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12036 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 12037 EmitA32(0x012000b0U | (cond.GetCondition() << 28) | 12038 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12039 (sign_ << 23)); 12040 return; 12041 } 12042 } 12043 } 12044 if (operand.IsShiftedRegister()) { 12045 Register rn = operand.GetBaseRegister(); 12046 Sign sign = operand.GetSign(); 12047 Register rm = operand.GetOffsetRegister(); 12048 Shift shift = operand.GetShift(); 12049 uint32_t amount = operand.GetShiftAmount(); 12050 if (IsUsingT32()) { 12051 // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 12052 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 12053 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && 12054 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12055 EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 12056 rm.GetCode() | (amount << 4)); 12057 AdvanceIT(); 12058 return; 12059 } 12060 } 12061 } 12062 Delegate(kStrh, &Assembler::strh, cond, size, rt, operand); 12063 } 12064 12065 void Assembler::sub(Condition cond, 12066 EncodingSize size, 12067 Register rd, 12068 Register rn, 12069 const Operand& operand) { 12070 VIXL_ASSERT(AllowAssembler()); 12071 CheckIT(cond); 12072 if (operand.IsImmediate()) { 12073 uint32_t imm = operand.GetImmediate(); 12074 if (IsUsingT32()) { 12075 ImmediateT32 immediate_t32(imm); 12076 // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1 12077 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 12078 (imm <= 7)) { 12079 EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 12080 AdvanceIT(); 12081 return; 12082 } 12083 // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 12084 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 12085 (imm <= 255)) { 12086 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 12087 AdvanceIT(); 12088 return; 12089 } 12090 // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1 12091 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && 12092 ((imm % 4) == 0)) { 12093 uint32_t imm_ = imm >> 2; 12094 EmitT32_16(0xb080 | imm_); 12095 AdvanceIT(); 12096 return; 12097 } 12098 // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2 12099 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && 12100 (!rd.IsPC() || AllowUnpredictable())) { 12101 EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) | 12102 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12103 AdvanceIT(); 12104 return; 12105 } 12106 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 12107 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 12108 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 12109 EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12110 (immediate_t32.GetEncodingValue() & 0xff) | 12111 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12112 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12113 AdvanceIT(); 12114 return; 12115 } 12116 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 12117 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 12118 (!rd.IsPC() || AllowUnpredictable())) { 12119 EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12120 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12121 AdvanceIT(); 12122 return; 12123 } 12124 // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2 12125 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 12126 (!rd.IsPC() || AllowUnpredictable())) { 12127 EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) | 12128 (immediate_t32.GetEncodingValue() & 0xff) | 12129 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12130 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12131 AdvanceIT(); 12132 return; 12133 } 12134 // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3 12135 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && 12136 (!rd.IsPC() || AllowUnpredictable())) { 12137 EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) | 12138 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12139 AdvanceIT(); 12140 return; 12141 } 12142 } else { 12143 ImmediateA32 immediate_a32(imm); 12144 // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2 12145 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { 12146 EmitA32(0x024f0000U | (cond.GetCondition() << 28) | 12147 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 12148 return; 12149 } 12150 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 12151 if (immediate_a32.IsValid() && cond.IsNotNever() && 12152 ((rn.GetCode() & 0xd) != 0xd)) { 12153 EmitA32(0x02400000U | (cond.GetCondition() << 28) | 12154 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 12155 immediate_a32.GetEncodingValue()); 12156 return; 12157 } 12158 // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 12159 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 12160 EmitA32(0x024d0000U | (cond.GetCondition() << 28) | 12161 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 12162 return; 12163 } 12164 } 12165 } 12166 if (operand.IsImmediateShiftedRegister()) { 12167 Register rm = operand.GetBaseRegister(); 12168 if (operand.IsPlainRegister()) { 12169 if (IsUsingT32()) { 12170 // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 12171 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 12172 rm.IsLow()) { 12173 EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) | 12174 (rm.GetCode() << 6)); 12175 AdvanceIT(); 12176 return; 12177 } 12178 // SUB{<c>} {<Rd>}, SP, <Rm> ; T1 12179 if (rn.Is(sp) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12180 EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode()); 12181 AdvanceIT(); 12182 return; 12183 } 12184 } 12185 } 12186 Shift shift = operand.GetShift(); 12187 uint32_t amount = operand.GetShiftAmount(); 12188 if (IsUsingT32()) { 12189 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 12190 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 12191 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12192 uint32_t amount_ = amount % 32; 12193 EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12194 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 12195 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12196 AdvanceIT(); 12197 return; 12198 } 12199 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 12200 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 12201 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12202 uint32_t amount_ = amount % 32; 12203 EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() | 12204 (operand.GetTypeEncodingValue() << 4) | 12205 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12206 AdvanceIT(); 12207 return; 12208 } 12209 } else { 12210 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 12211 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 12212 uint32_t amount_ = amount % 32; 12213 EmitA32(0x00400000U | (cond.GetCondition() << 28) | 12214 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12215 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12216 return; 12217 } 12218 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 12219 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 12220 uint32_t amount_ = amount % 32; 12221 EmitA32(0x004d0000U | (cond.GetCondition() << 28) | 12222 (rd.GetCode() << 12) | rm.GetCode() | 12223 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12224 return; 12225 } 12226 } 12227 } 12228 if (operand.IsRegisterShiftedRegister()) { 12229 Register rm = operand.GetBaseRegister(); 12230 Shift shift = operand.GetShift(); 12231 Register rs = operand.GetShiftRegister(); 12232 if (IsUsingA32()) { 12233 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 12234 if (cond.IsNotNever() && 12235 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 12236 AllowUnpredictable())) { 12237 EmitA32(0x00400010U | (cond.GetCondition() << 28) | 12238 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12239 (shift.GetType() << 5) | (rs.GetCode() << 8)); 12240 return; 12241 } 12242 } 12243 } 12244 Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand); 12245 } 12246 12247 void Assembler::sub(Condition cond, Register rd, const Operand& operand) { 12248 VIXL_ASSERT(AllowAssembler()); 12249 CheckIT(cond); 12250 if (operand.IsImmediate()) { 12251 uint32_t imm = operand.GetImmediate(); 12252 if (IsUsingT32()) { 12253 // SUB<c>{<q>} <Rdn>, #<imm8> ; T2 12254 if (InITBlock() && rd.IsLow() && (imm <= 255)) { 12255 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 12256 AdvanceIT(); 12257 return; 12258 } 12259 } 12260 } 12261 Delegate(kSub, &Assembler::sub, cond, rd, operand); 12262 } 12263 12264 void Assembler::subs(Condition cond, 12265 EncodingSize size, 12266 Register rd, 12267 Register rn, 12268 const Operand& operand) { 12269 VIXL_ASSERT(AllowAssembler()); 12270 CheckIT(cond); 12271 if (operand.IsImmediate()) { 12272 uint32_t imm = operand.GetImmediate(); 12273 if (IsUsingT32()) { 12274 ImmediateT32 immediate_t32(imm); 12275 // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1 12276 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 12277 (imm <= 7)) { 12278 EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 12279 AdvanceIT(); 12280 return; 12281 } 12282 // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 12283 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 12284 (imm <= 255)) { 12285 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 12286 AdvanceIT(); 12287 return; 12288 } 12289 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 12290 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 12291 !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { 12292 EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12293 (immediate_t32.GetEncodingValue() & 0xff) | 12294 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12295 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12296 AdvanceIT(); 12297 return; 12298 } 12299 // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5 12300 if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255) && 12301 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) { 12302 EmitT32_32(0xf3de8f00U | imm); 12303 AdvanceIT(); 12304 return; 12305 } 12306 // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2 12307 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 12308 !rd.Is(pc)) { 12309 EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) | 12310 (immediate_t32.GetEncodingValue() & 0xff) | 12311 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12312 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12313 AdvanceIT(); 12314 return; 12315 } 12316 } else { 12317 ImmediateA32 immediate_a32(imm); 12318 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 12319 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { 12320 EmitA32(0x02500000U | (cond.GetCondition() << 28) | 12321 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 12322 immediate_a32.GetEncodingValue()); 12323 return; 12324 } 12325 // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 12326 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 12327 EmitA32(0x025d0000U | (cond.GetCondition() << 28) | 12328 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 12329 return; 12330 } 12331 } 12332 } 12333 if (operand.IsImmediateShiftedRegister()) { 12334 Register rm = operand.GetBaseRegister(); 12335 if (operand.IsPlainRegister()) { 12336 if (IsUsingT32()) { 12337 // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12338 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 12339 rm.IsLow()) { 12340 EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) | 12341 (rm.GetCode() << 6)); 12342 AdvanceIT(); 12343 return; 12344 } 12345 } 12346 } 12347 Shift shift = operand.GetShift(); 12348 uint32_t amount = operand.GetShiftAmount(); 12349 if (IsUsingT32()) { 12350 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 12351 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 12352 !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12353 uint32_t amount_ = amount % 32; 12354 EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12355 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 12356 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12357 AdvanceIT(); 12358 return; 12359 } 12360 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 12361 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 12362 !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { 12363 uint32_t amount_ = amount % 32; 12364 EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() | 12365 (operand.GetTypeEncodingValue() << 4) | 12366 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12367 AdvanceIT(); 12368 return; 12369 } 12370 } else { 12371 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 12372 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 12373 uint32_t amount_ = amount % 32; 12374 EmitA32(0x00500000U | (cond.GetCondition() << 28) | 12375 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12376 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12377 return; 12378 } 12379 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 12380 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 12381 uint32_t amount_ = amount % 32; 12382 EmitA32(0x005d0000U | (cond.GetCondition() << 28) | 12383 (rd.GetCode() << 12) | rm.GetCode() | 12384 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12385 return; 12386 } 12387 } 12388 } 12389 if (operand.IsRegisterShiftedRegister()) { 12390 Register rm = operand.GetBaseRegister(); 12391 Shift shift = operand.GetShift(); 12392 Register rs = operand.GetShiftRegister(); 12393 if (IsUsingA32()) { 12394 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 12395 if (cond.IsNotNever() && 12396 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || 12397 AllowUnpredictable())) { 12398 EmitA32(0x00500010U | (cond.GetCondition() << 28) | 12399 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12400 (shift.GetType() << 5) | (rs.GetCode() << 8)); 12401 return; 12402 } 12403 } 12404 } 12405 Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand); 12406 } 12407 12408 void Assembler::subs(Register rd, const Operand& operand) { 12409 VIXL_ASSERT(AllowAssembler()); 12410 CheckIT(al); 12411 if (operand.IsImmediate()) { 12412 uint32_t imm = operand.GetImmediate(); 12413 if (IsUsingT32()) { 12414 // SUBS{<q>} <Rdn>, #<imm8> ; T2 12415 if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) { 12416 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 12417 AdvanceIT(); 12418 return; 12419 } 12420 } 12421 } 12422 Delegate(kSubs, &Assembler::subs, rd, operand); 12423 } 12424 12425 void Assembler::subw(Condition cond, 12426 Register rd, 12427 Register rn, 12428 const Operand& operand) { 12429 VIXL_ASSERT(AllowAssembler()); 12430 CheckIT(cond); 12431 if (operand.IsImmediate()) { 12432 uint32_t imm = operand.GetImmediate(); 12433 if (IsUsingT32()) { 12434 // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 12435 if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 12436 (!rd.IsPC() || AllowUnpredictable())) { 12437 EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12438 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12439 AdvanceIT(); 12440 return; 12441 } 12442 // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3 12443 if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 12444 EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) | 12445 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 12446 AdvanceIT(); 12447 return; 12448 } 12449 } 12450 } 12451 Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand); 12452 } 12453 12454 void Assembler::svc(Condition cond, uint32_t imm) { 12455 VIXL_ASSERT(AllowAssembler()); 12456 CheckIT(cond); 12457 if (IsUsingT32()) { 12458 // SVC{<c>}{<q>} {#}<imm> ; T1 12459 if ((imm <= 255)) { 12460 EmitT32_16(0xdf00 | imm); 12461 AdvanceIT(); 12462 return; 12463 } 12464 } else { 12465 // SVC{<c>}{<q>} {#}<imm> ; A1 12466 if ((imm <= 16777215) && cond.IsNotNever()) { 12467 EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm); 12468 return; 12469 } 12470 } 12471 Delegate(kSvc, &Assembler::svc, cond, imm); 12472 } 12473 12474 void Assembler::sxtab(Condition cond, 12475 Register rd, 12476 Register rn, 12477 const Operand& operand) { 12478 VIXL_ASSERT(AllowAssembler()); 12479 CheckIT(cond); 12480 if (operand.IsImmediateShiftedRegister()) { 12481 Register rm = operand.GetBaseRegister(); 12482 Shift shift = operand.GetShift(); 12483 uint32_t amount = operand.GetShiftAmount(); 12484 if (IsUsingT32()) { 12485 // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12486 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12487 ((amount % 8) == 0) && !rn.Is(pc) && 12488 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12489 uint32_t amount_ = amount / 8; 12490 EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12491 rm.GetCode() | (amount_ << 4)); 12492 AdvanceIT(); 12493 return; 12494 } 12495 } else { 12496 // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12497 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12498 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 12499 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12500 uint32_t amount_ = amount / 8; 12501 EmitA32(0x06a00070U | (cond.GetCondition() << 28) | 12502 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12503 (amount_ << 10)); 12504 return; 12505 } 12506 } 12507 } 12508 Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand); 12509 } 12510 12511 void Assembler::sxtab16(Condition cond, 12512 Register rd, 12513 Register rn, 12514 const Operand& operand) { 12515 VIXL_ASSERT(AllowAssembler()); 12516 CheckIT(cond); 12517 if (operand.IsImmediateShiftedRegister()) { 12518 Register rm = operand.GetBaseRegister(); 12519 Shift shift = operand.GetShift(); 12520 uint32_t amount = operand.GetShiftAmount(); 12521 if (IsUsingT32()) { 12522 // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12523 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12524 ((amount % 8) == 0) && !rn.Is(pc) && 12525 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12526 uint32_t amount_ = amount / 8; 12527 EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12528 rm.GetCode() | (amount_ << 4)); 12529 AdvanceIT(); 12530 return; 12531 } 12532 } else { 12533 // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12534 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12535 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 12536 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12537 uint32_t amount_ = amount / 8; 12538 EmitA32(0x06800070U | (cond.GetCondition() << 28) | 12539 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12540 (amount_ << 10)); 12541 return; 12542 } 12543 } 12544 } 12545 Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand); 12546 } 12547 12548 void Assembler::sxtah(Condition cond, 12549 Register rd, 12550 Register rn, 12551 const Operand& operand) { 12552 VIXL_ASSERT(AllowAssembler()); 12553 CheckIT(cond); 12554 if (operand.IsImmediateShiftedRegister()) { 12555 Register rm = operand.GetBaseRegister(); 12556 Shift shift = operand.GetShift(); 12557 uint32_t amount = operand.GetShiftAmount(); 12558 if (IsUsingT32()) { 12559 // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12560 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12561 ((amount % 8) == 0) && !rn.Is(pc) && 12562 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12563 uint32_t amount_ = amount / 8; 12564 EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12565 rm.GetCode() | (amount_ << 4)); 12566 AdvanceIT(); 12567 return; 12568 } 12569 } else { 12570 // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12571 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12572 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 12573 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12574 uint32_t amount_ = amount / 8; 12575 EmitA32(0x06b00070U | (cond.GetCondition() << 28) | 12576 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12577 (amount_ << 10)); 12578 return; 12579 } 12580 } 12581 } 12582 Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand); 12583 } 12584 12585 void Assembler::sxtb(Condition cond, 12586 EncodingSize size, 12587 Register rd, 12588 const Operand& operand) { 12589 VIXL_ASSERT(AllowAssembler()); 12590 CheckIT(cond); 12591 if (operand.IsImmediateShiftedRegister()) { 12592 Register rm = operand.GetBaseRegister(); 12593 if (operand.IsPlainRegister()) { 12594 if (IsUsingT32()) { 12595 // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1 12596 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 12597 EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3)); 12598 AdvanceIT(); 12599 return; 12600 } 12601 } 12602 } 12603 Shift shift = operand.GetShift(); 12604 uint32_t amount = operand.GetShiftAmount(); 12605 if (IsUsingT32()) { 12606 // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 12607 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 12608 (amount <= 24) && ((amount % 8) == 0) && 12609 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12610 uint32_t amount_ = amount / 8; 12611 EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12612 (amount_ << 4)); 12613 AdvanceIT(); 12614 return; 12615 } 12616 } else { 12617 // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12618 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12619 ((amount % 8) == 0) && cond.IsNotNever() && 12620 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12621 uint32_t amount_ = amount / 8; 12622 EmitA32(0x06af0070U | (cond.GetCondition() << 28) | 12623 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12624 return; 12625 } 12626 } 12627 } 12628 Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand); 12629 } 12630 12631 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) { 12632 VIXL_ASSERT(AllowAssembler()); 12633 CheckIT(cond); 12634 if (operand.IsImmediateShiftedRegister()) { 12635 Register rm = operand.GetBaseRegister(); 12636 Shift shift = operand.GetShift(); 12637 uint32_t amount = operand.GetShiftAmount(); 12638 if (IsUsingT32()) { 12639 // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1 12640 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12641 ((amount % 8) == 0) && 12642 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12643 uint32_t amount_ = amount / 8; 12644 EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12645 (amount_ << 4)); 12646 AdvanceIT(); 12647 return; 12648 } 12649 } else { 12650 // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12651 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12652 ((amount % 8) == 0) && cond.IsNotNever() && 12653 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12654 uint32_t amount_ = amount / 8; 12655 EmitA32(0x068f0070U | (cond.GetCondition() << 28) | 12656 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12657 return; 12658 } 12659 } 12660 } 12661 Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand); 12662 } 12663 12664 void Assembler::sxth(Condition cond, 12665 EncodingSize size, 12666 Register rd, 12667 const Operand& operand) { 12668 VIXL_ASSERT(AllowAssembler()); 12669 CheckIT(cond); 12670 if (operand.IsImmediateShiftedRegister()) { 12671 Register rm = operand.GetBaseRegister(); 12672 if (operand.IsPlainRegister()) { 12673 if (IsUsingT32()) { 12674 // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1 12675 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 12676 EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3)); 12677 AdvanceIT(); 12678 return; 12679 } 12680 } 12681 } 12682 Shift shift = operand.GetShift(); 12683 uint32_t amount = operand.GetShiftAmount(); 12684 if (IsUsingT32()) { 12685 // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 12686 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 12687 (amount <= 24) && ((amount % 8) == 0) && 12688 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12689 uint32_t amount_ = amount / 8; 12690 EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12691 (amount_ << 4)); 12692 AdvanceIT(); 12693 return; 12694 } 12695 } else { 12696 // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12697 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12698 ((amount % 8) == 0) && cond.IsNotNever() && 12699 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12700 uint32_t amount_ = amount / 8; 12701 EmitA32(0x06bf0070U | (cond.GetCondition() << 28) | 12702 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12703 return; 12704 } 12705 } 12706 } 12707 Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand); 12708 } 12709 12710 void Assembler::tbb(Condition cond, Register rn, Register rm) { 12711 VIXL_ASSERT(AllowAssembler()); 12712 CheckIT(cond); 12713 if (IsUsingT32()) { 12714 // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1 12715 if (OutsideITBlockAndAlOrLast(cond) && 12716 (!rm.IsPC() || AllowUnpredictable())) { 12717 EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode()); 12718 AdvanceIT(); 12719 return; 12720 } 12721 } 12722 Delegate(kTbb, &Assembler::tbb, cond, rn, rm); 12723 } 12724 12725 void Assembler::tbh(Condition cond, Register rn, Register rm) { 12726 VIXL_ASSERT(AllowAssembler()); 12727 CheckIT(cond); 12728 if (IsUsingT32()) { 12729 // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1 12730 if (OutsideITBlockAndAlOrLast(cond) && 12731 (!rm.IsPC() || AllowUnpredictable())) { 12732 EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode()); 12733 AdvanceIT(); 12734 return; 12735 } 12736 } 12737 Delegate(kTbh, &Assembler::tbh, cond, rn, rm); 12738 } 12739 12740 void Assembler::teq(Condition cond, Register rn, const Operand& operand) { 12741 VIXL_ASSERT(AllowAssembler()); 12742 CheckIT(cond); 12743 if (operand.IsImmediate()) { 12744 uint32_t imm = operand.GetImmediate(); 12745 if (IsUsingT32()) { 12746 ImmediateT32 immediate_t32(imm); 12747 // TEQ{<c>}{<q>} <Rn>, #<const> ; T1 12748 if (immediate_t32.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 12749 EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) | 12750 (immediate_t32.GetEncodingValue() & 0xff) | 12751 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12752 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12753 AdvanceIT(); 12754 return; 12755 } 12756 } else { 12757 ImmediateA32 immediate_a32(imm); 12758 // TEQ{<c>}{<q>} <Rn>, #<const> ; A1 12759 if (immediate_a32.IsValid() && cond.IsNotNever()) { 12760 EmitA32(0x03300000U | (cond.GetCondition() << 28) | 12761 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 12762 return; 12763 } 12764 } 12765 } 12766 if (operand.IsImmediateShiftedRegister()) { 12767 Register rm = operand.GetBaseRegister(); 12768 Shift shift = operand.GetShift(); 12769 uint32_t amount = operand.GetShiftAmount(); 12770 if (IsUsingT32()) { 12771 // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1 12772 if (shift.IsValidAmount(amount) && 12773 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12774 uint32_t amount_ = amount % 32; 12775 EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() | 12776 (operand.GetTypeEncodingValue() << 4) | 12777 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12778 AdvanceIT(); 12779 return; 12780 } 12781 } else { 12782 // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 12783 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 12784 uint32_t amount_ = amount % 32; 12785 EmitA32(0x01300000U | (cond.GetCondition() << 28) | 12786 (rn.GetCode() << 16) | rm.GetCode() | 12787 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12788 return; 12789 } 12790 } 12791 } 12792 if (operand.IsRegisterShiftedRegister()) { 12793 Register rm = operand.GetBaseRegister(); 12794 Shift shift = operand.GetShift(); 12795 Register rs = operand.GetShiftRegister(); 12796 if (IsUsingA32()) { 12797 // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 12798 if (cond.IsNotNever() && 12799 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 12800 EmitA32(0x01300010U | (cond.GetCondition() << 28) | 12801 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 12802 (rs.GetCode() << 8)); 12803 return; 12804 } 12805 } 12806 } 12807 Delegate(kTeq, &Assembler::teq, cond, rn, operand); 12808 } 12809 12810 void Assembler::tst(Condition cond, 12811 EncodingSize size, 12812 Register rn, 12813 const Operand& operand) { 12814 VIXL_ASSERT(AllowAssembler()); 12815 CheckIT(cond); 12816 if (operand.IsImmediate()) { 12817 uint32_t imm = operand.GetImmediate(); 12818 if (IsUsingT32()) { 12819 ImmediateT32 immediate_t32(imm); 12820 // TST{<c>}{<q>} <Rn>, #<const> ; T1 12821 if (!size.IsNarrow() && immediate_t32.IsValid() && 12822 (!rn.IsPC() || AllowUnpredictable())) { 12823 EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) | 12824 (immediate_t32.GetEncodingValue() & 0xff) | 12825 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 12826 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 12827 AdvanceIT(); 12828 return; 12829 } 12830 } else { 12831 ImmediateA32 immediate_a32(imm); 12832 // TST{<c>}{<q>} <Rn>, #<const> ; A1 12833 if (immediate_a32.IsValid() && cond.IsNotNever()) { 12834 EmitA32(0x03100000U | (cond.GetCondition() << 28) | 12835 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 12836 return; 12837 } 12838 } 12839 } 12840 if (operand.IsImmediateShiftedRegister()) { 12841 Register rm = operand.GetBaseRegister(); 12842 if (operand.IsPlainRegister()) { 12843 if (IsUsingT32()) { 12844 // TST{<c>}{<q>} <Rn>, <Rm> ; T1 12845 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 12846 EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3)); 12847 AdvanceIT(); 12848 return; 12849 } 12850 } 12851 } 12852 Shift shift = operand.GetShift(); 12853 uint32_t amount = operand.GetShiftAmount(); 12854 if (IsUsingT32()) { 12855 // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2 12856 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 12857 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12858 uint32_t amount_ = amount % 32; 12859 EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() | 12860 (operand.GetTypeEncodingValue() << 4) | 12861 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 12862 AdvanceIT(); 12863 return; 12864 } 12865 } else { 12866 // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 12867 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 12868 uint32_t amount_ = amount % 32; 12869 EmitA32(0x01100000U | (cond.GetCondition() << 28) | 12870 (rn.GetCode() << 16) | rm.GetCode() | 12871 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 12872 return; 12873 } 12874 } 12875 } 12876 if (operand.IsRegisterShiftedRegister()) { 12877 Register rm = operand.GetBaseRegister(); 12878 Shift shift = operand.GetShift(); 12879 Register rs = operand.GetShiftRegister(); 12880 if (IsUsingA32()) { 12881 // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 12882 if (cond.IsNotNever() && 12883 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) { 12884 EmitA32(0x01100010U | (cond.GetCondition() << 28) | 12885 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 12886 (rs.GetCode() << 8)); 12887 return; 12888 } 12889 } 12890 } 12891 Delegate(kTst, &Assembler::tst, cond, size, rn, operand); 12892 } 12893 12894 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) { 12895 VIXL_ASSERT(AllowAssembler()); 12896 CheckIT(cond); 12897 if (IsUsingT32()) { 12898 // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12899 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12900 EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12901 rm.GetCode()); 12902 AdvanceIT(); 12903 return; 12904 } 12905 } else { 12906 // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12907 if (cond.IsNotNever() && 12908 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12909 EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12910 (rn.GetCode() << 16) | rm.GetCode()); 12911 return; 12912 } 12913 } 12914 Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm); 12915 } 12916 12917 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) { 12918 VIXL_ASSERT(AllowAssembler()); 12919 CheckIT(cond); 12920 if (IsUsingT32()) { 12921 // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12922 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12923 EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12924 rm.GetCode()); 12925 AdvanceIT(); 12926 return; 12927 } 12928 } else { 12929 // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12930 if (cond.IsNotNever() && 12931 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12932 EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12933 (rn.GetCode() << 16) | rm.GetCode()); 12934 return; 12935 } 12936 } 12937 Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm); 12938 } 12939 12940 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) { 12941 VIXL_ASSERT(AllowAssembler()); 12942 CheckIT(cond); 12943 if (IsUsingT32()) { 12944 // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12945 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12946 EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12947 rm.GetCode()); 12948 AdvanceIT(); 12949 return; 12950 } 12951 } else { 12952 // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12953 if (cond.IsNotNever() && 12954 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 12955 EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12956 (rn.GetCode() << 16) | rm.GetCode()); 12957 return; 12958 } 12959 } 12960 Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm); 12961 } 12962 12963 void Assembler::ubfx( 12964 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) { 12965 VIXL_ASSERT(AllowAssembler()); 12966 CheckIT(cond); 12967 if (IsUsingT32()) { 12968 // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 12969 if ((lsb <= 31) && 12970 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) || 12971 AllowUnpredictable())) { 12972 uint32_t widthm1 = width - 1; 12973 EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12974 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1); 12975 AdvanceIT(); 12976 return; 12977 } 12978 } else { 12979 // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 12980 if ((lsb <= 31) && cond.IsNotNever() && 12981 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) || 12982 AllowUnpredictable())) { 12983 uint32_t widthm1 = width - 1; 12984 EmitA32(0x07e00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12985 rn.GetCode() | (lsb << 7) | (widthm1 << 16)); 12986 return; 12987 } 12988 } 12989 Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, width); 12990 } 12991 12992 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) { 12993 VIXL_ASSERT(AllowAssembler()); 12994 CheckIT(cond); 12995 if (IsUsingT32()) { 12996 // UDF{<c>}{<q>} {#}<imm> ; T1 12997 if (!size.IsWide() && (imm <= 255)) { 12998 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12999 EmitT32_16(0xde00 | imm); 13000 AdvanceIT(); 13001 return; 13002 } 13003 } 13004 // UDF{<c>}{<q>} {#}<imm> ; T2 13005 if (!size.IsNarrow() && (imm <= 65535)) { 13006 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13007 EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4)); 13008 AdvanceIT(); 13009 return; 13010 } 13011 } 13012 } else { 13013 // UDF{<c>}{<q>} {#}<imm> ; A1 13014 if ((imm <= 65535)) { 13015 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13016 EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4)); 13017 return; 13018 } 13019 } 13020 } 13021 Delegate(kUdf, &Assembler::udf, cond, size, imm); 13022 } 13023 13024 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) { 13025 VIXL_ASSERT(AllowAssembler()); 13026 CheckIT(cond); 13027 if (IsUsingT32()) { 13028 // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13029 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13030 EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13031 rm.GetCode()); 13032 AdvanceIT(); 13033 return; 13034 } 13035 } else { 13036 // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13037 if (cond.IsNotNever() && 13038 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13039 EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 13040 rn.GetCode() | (rm.GetCode() << 8)); 13041 return; 13042 } 13043 } 13044 Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm); 13045 } 13046 13047 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) { 13048 VIXL_ASSERT(AllowAssembler()); 13049 CheckIT(cond); 13050 if (IsUsingT32()) { 13051 // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13052 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13053 EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13054 rm.GetCode()); 13055 AdvanceIT(); 13056 return; 13057 } 13058 } else { 13059 // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13060 if (cond.IsNotNever() && 13061 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13062 EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13063 (rn.GetCode() << 16) | rm.GetCode()); 13064 return; 13065 } 13066 } 13067 Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm); 13068 } 13069 13070 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) { 13071 VIXL_ASSERT(AllowAssembler()); 13072 CheckIT(cond); 13073 if (IsUsingT32()) { 13074 // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13075 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13076 EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13077 rm.GetCode()); 13078 AdvanceIT(); 13079 return; 13080 } 13081 } else { 13082 // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13083 if (cond.IsNotNever() && 13084 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13085 EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13086 (rn.GetCode() << 16) | rm.GetCode()); 13087 return; 13088 } 13089 } 13090 Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm); 13091 } 13092 13093 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) { 13094 VIXL_ASSERT(AllowAssembler()); 13095 CheckIT(cond); 13096 if (IsUsingT32()) { 13097 // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13098 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13099 EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13100 rm.GetCode()); 13101 AdvanceIT(); 13102 return; 13103 } 13104 } else { 13105 // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13106 if (cond.IsNotNever() && 13107 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13108 EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13109 (rn.GetCode() << 16) | rm.GetCode()); 13110 return; 13111 } 13112 } 13113 Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm); 13114 } 13115 13116 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) { 13117 VIXL_ASSERT(AllowAssembler()); 13118 CheckIT(cond); 13119 if (IsUsingT32()) { 13120 // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13121 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13122 EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13123 rm.GetCode()); 13124 AdvanceIT(); 13125 return; 13126 } 13127 } else { 13128 // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13129 if (cond.IsNotNever() && 13130 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13131 EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13132 (rn.GetCode() << 16) | rm.GetCode()); 13133 return; 13134 } 13135 } 13136 Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm); 13137 } 13138 13139 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) { 13140 VIXL_ASSERT(AllowAssembler()); 13141 CheckIT(cond); 13142 if (IsUsingT32()) { 13143 // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13144 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13145 EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13146 rm.GetCode()); 13147 AdvanceIT(); 13148 return; 13149 } 13150 } else { 13151 // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13152 if (cond.IsNotNever() && 13153 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13154 EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13155 (rn.GetCode() << 16) | rm.GetCode()); 13156 return; 13157 } 13158 } 13159 Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm); 13160 } 13161 13162 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) { 13163 VIXL_ASSERT(AllowAssembler()); 13164 CheckIT(cond); 13165 if (IsUsingT32()) { 13166 // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13167 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13168 EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13169 rm.GetCode()); 13170 AdvanceIT(); 13171 return; 13172 } 13173 } else { 13174 // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13175 if (cond.IsNotNever() && 13176 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13177 EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13178 (rn.GetCode() << 16) | rm.GetCode()); 13179 return; 13180 } 13181 } 13182 Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm); 13183 } 13184 13185 void Assembler::umaal( 13186 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13187 VIXL_ASSERT(AllowAssembler()); 13188 CheckIT(cond); 13189 if (IsUsingT32()) { 13190 // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 13191 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13192 AllowUnpredictable())) { 13193 EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 13194 (rn.GetCode() << 16) | rm.GetCode()); 13195 AdvanceIT(); 13196 return; 13197 } 13198 } else { 13199 // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13200 if (cond.IsNotNever() && 13201 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13202 AllowUnpredictable())) { 13203 EmitA32(0x00400090U | (cond.GetCondition() << 28) | 13204 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13205 (rm.GetCode() << 8)); 13206 return; 13207 } 13208 } 13209 Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm); 13210 } 13211 13212 void Assembler::umlal( 13213 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13214 VIXL_ASSERT(AllowAssembler()); 13215 CheckIT(cond); 13216 if (IsUsingT32()) { 13217 // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 13218 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13219 AllowUnpredictable())) { 13220 EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 13221 (rn.GetCode() << 16) | rm.GetCode()); 13222 AdvanceIT(); 13223 return; 13224 } 13225 } else { 13226 // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13227 if (cond.IsNotNever() && 13228 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13229 AllowUnpredictable())) { 13230 EmitA32(0x00a00090U | (cond.GetCondition() << 28) | 13231 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13232 (rm.GetCode() << 8)); 13233 return; 13234 } 13235 } 13236 Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm); 13237 } 13238 13239 void Assembler::umlals( 13240 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13241 VIXL_ASSERT(AllowAssembler()); 13242 CheckIT(cond); 13243 if (IsUsingA32()) { 13244 // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13245 if (cond.IsNotNever() && 13246 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13247 AllowUnpredictable())) { 13248 EmitA32(0x00b00090U | (cond.GetCondition() << 28) | 13249 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13250 (rm.GetCode() << 8)); 13251 return; 13252 } 13253 } 13254 Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm); 13255 } 13256 13257 void Assembler::umull( 13258 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13259 VIXL_ASSERT(AllowAssembler()); 13260 CheckIT(cond); 13261 if (IsUsingT32()) { 13262 // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 13263 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13264 AllowUnpredictable())) { 13265 EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 13266 (rn.GetCode() << 16) | rm.GetCode()); 13267 AdvanceIT(); 13268 return; 13269 } 13270 } else { 13271 // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13272 if (cond.IsNotNever() && 13273 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13274 AllowUnpredictable())) { 13275 EmitA32(0x00800090U | (cond.GetCondition() << 28) | 13276 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13277 (rm.GetCode() << 8)); 13278 return; 13279 } 13280 } 13281 Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm); 13282 } 13283 13284 void Assembler::umulls( 13285 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 13286 VIXL_ASSERT(AllowAssembler()); 13287 CheckIT(cond); 13288 if (IsUsingA32()) { 13289 // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 13290 if (cond.IsNotNever() && 13291 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) || 13292 AllowUnpredictable())) { 13293 EmitA32(0x00900090U | (cond.GetCondition() << 28) | 13294 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 13295 (rm.GetCode() << 8)); 13296 return; 13297 } 13298 } 13299 Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm); 13300 } 13301 13302 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) { 13303 VIXL_ASSERT(AllowAssembler()); 13304 CheckIT(cond); 13305 if (IsUsingT32()) { 13306 // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13307 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13308 EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13309 rm.GetCode()); 13310 AdvanceIT(); 13311 return; 13312 } 13313 } else { 13314 // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13315 if (cond.IsNotNever() && 13316 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13317 EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13318 (rn.GetCode() << 16) | rm.GetCode()); 13319 return; 13320 } 13321 } 13322 Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm); 13323 } 13324 13325 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) { 13326 VIXL_ASSERT(AllowAssembler()); 13327 CheckIT(cond); 13328 if (IsUsingT32()) { 13329 // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13330 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13331 EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13332 rm.GetCode()); 13333 AdvanceIT(); 13334 return; 13335 } 13336 } else { 13337 // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13338 if (cond.IsNotNever() && 13339 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13340 EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13341 (rn.GetCode() << 16) | rm.GetCode()); 13342 return; 13343 } 13344 } 13345 Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm); 13346 } 13347 13348 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) { 13349 VIXL_ASSERT(AllowAssembler()); 13350 CheckIT(cond); 13351 if (IsUsingT32()) { 13352 // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13353 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13354 EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13355 rm.GetCode()); 13356 AdvanceIT(); 13357 return; 13358 } 13359 } else { 13360 // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13361 if (cond.IsNotNever() && 13362 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13363 EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13364 (rn.GetCode() << 16) | rm.GetCode()); 13365 return; 13366 } 13367 } 13368 Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm); 13369 } 13370 13371 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) { 13372 VIXL_ASSERT(AllowAssembler()); 13373 CheckIT(cond); 13374 if (IsUsingT32()) { 13375 // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13376 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13377 EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13378 rm.GetCode()); 13379 AdvanceIT(); 13380 return; 13381 } 13382 } else { 13383 // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13384 if (cond.IsNotNever() && 13385 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13386 EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13387 (rn.GetCode() << 16) | rm.GetCode()); 13388 return; 13389 } 13390 } 13391 Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm); 13392 } 13393 13394 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) { 13395 VIXL_ASSERT(AllowAssembler()); 13396 CheckIT(cond); 13397 if (IsUsingT32()) { 13398 // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13399 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13400 EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13401 rm.GetCode()); 13402 AdvanceIT(); 13403 return; 13404 } 13405 } else { 13406 // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13407 if (cond.IsNotNever() && 13408 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13409 EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13410 (rn.GetCode() << 16) | rm.GetCode()); 13411 return; 13412 } 13413 } 13414 Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm); 13415 } 13416 13417 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) { 13418 VIXL_ASSERT(AllowAssembler()); 13419 CheckIT(cond); 13420 if (IsUsingT32()) { 13421 // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13422 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13423 EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13424 rm.GetCode()); 13425 AdvanceIT(); 13426 return; 13427 } 13428 } else { 13429 // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13430 if (cond.IsNotNever() && 13431 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13432 EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13433 (rn.GetCode() << 16) | rm.GetCode()); 13434 return; 13435 } 13436 } 13437 Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm); 13438 } 13439 13440 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) { 13441 VIXL_ASSERT(AllowAssembler()); 13442 CheckIT(cond); 13443 if (IsUsingT32()) { 13444 // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13445 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13446 EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13447 rm.GetCode()); 13448 AdvanceIT(); 13449 return; 13450 } 13451 } else { 13452 // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13453 if (cond.IsNotNever() && 13454 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13455 EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 13456 rn.GetCode() | (rm.GetCode() << 8)); 13457 return; 13458 } 13459 } 13460 Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm); 13461 } 13462 13463 void Assembler::usada8( 13464 Condition cond, Register rd, Register rn, Register rm, Register ra) { 13465 VIXL_ASSERT(AllowAssembler()); 13466 CheckIT(cond); 13467 if (IsUsingT32()) { 13468 // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 13469 if (!ra.Is(pc) && 13470 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13471 EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13472 rm.GetCode() | (ra.GetCode() << 12)); 13473 AdvanceIT(); 13474 return; 13475 } 13476 } else { 13477 // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 13478 if (cond.IsNotNever() && !ra.Is(pc) && 13479 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13480 EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 13481 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 13482 return; 13483 } 13484 } 13485 Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra); 13486 } 13487 13488 void Assembler::usat(Condition cond, 13489 Register rd, 13490 uint32_t imm, 13491 const Operand& operand) { 13492 VIXL_ASSERT(AllowAssembler()); 13493 CheckIT(cond); 13494 if (operand.IsImmediateShiftedRegister()) { 13495 Register rn = operand.GetBaseRegister(); 13496 Shift shift = operand.GetShift(); 13497 uint32_t amount = operand.GetShiftAmount(); 13498 if (IsUsingT32()) { 13499 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1 13500 if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31) && 13501 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13502 EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm | 13503 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 13504 ((amount & 0x1c) << 10)); 13505 AdvanceIT(); 13506 return; 13507 } 13508 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1 13509 if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && 13510 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13511 EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm | 13512 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 13513 ((amount & 0x1c) << 10)); 13514 AdvanceIT(); 13515 return; 13516 } 13517 } else { 13518 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1 13519 if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) && 13520 cond.IsNotNever() && 13521 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13522 uint32_t amount_ = amount % 32; 13523 EmitA32(0x06e00050U | (cond.GetCondition() << 28) | 13524 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() | 13525 (amount_ << 7)); 13526 return; 13527 } 13528 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1 13529 if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever() && 13530 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13531 EmitA32(0x06e00010U | (cond.GetCondition() << 28) | 13532 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() | 13533 (amount << 7)); 13534 return; 13535 } 13536 } 13537 } 13538 Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand); 13539 } 13540 13541 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) { 13542 VIXL_ASSERT(AllowAssembler()); 13543 CheckIT(cond); 13544 if (IsUsingT32()) { 13545 // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1 13546 if ((imm <= 15) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13547 EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm | 13548 (rn.GetCode() << 16)); 13549 AdvanceIT(); 13550 return; 13551 } 13552 } else { 13553 // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1 13554 if ((imm <= 15) && cond.IsNotNever() && 13555 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 13556 EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13557 (imm << 16) | rn.GetCode()); 13558 return; 13559 } 13560 } 13561 Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn); 13562 } 13563 13564 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) { 13565 VIXL_ASSERT(AllowAssembler()); 13566 CheckIT(cond); 13567 if (IsUsingT32()) { 13568 // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13569 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13570 EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13571 rm.GetCode()); 13572 AdvanceIT(); 13573 return; 13574 } 13575 } else { 13576 // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13577 if (cond.IsNotNever() && 13578 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13579 EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13580 (rn.GetCode() << 16) | rm.GetCode()); 13581 return; 13582 } 13583 } 13584 Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm); 13585 } 13586 13587 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) { 13588 VIXL_ASSERT(AllowAssembler()); 13589 CheckIT(cond); 13590 if (IsUsingT32()) { 13591 // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13592 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13593 EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13594 rm.GetCode()); 13595 AdvanceIT(); 13596 return; 13597 } 13598 } else { 13599 // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13600 if (cond.IsNotNever() && 13601 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13602 EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13603 (rn.GetCode() << 16) | rm.GetCode()); 13604 return; 13605 } 13606 } 13607 Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm); 13608 } 13609 13610 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) { 13611 VIXL_ASSERT(AllowAssembler()); 13612 CheckIT(cond); 13613 if (IsUsingT32()) { 13614 // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 13615 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13616 EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13617 rm.GetCode()); 13618 AdvanceIT(); 13619 return; 13620 } 13621 } else { 13622 // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 13623 if (cond.IsNotNever() && 13624 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13625 EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 13626 (rn.GetCode() << 16) | rm.GetCode()); 13627 return; 13628 } 13629 } 13630 Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm); 13631 } 13632 13633 void Assembler::uxtab(Condition cond, 13634 Register rd, 13635 Register rn, 13636 const Operand& operand) { 13637 VIXL_ASSERT(AllowAssembler()); 13638 CheckIT(cond); 13639 if (operand.IsImmediateShiftedRegister()) { 13640 Register rm = operand.GetBaseRegister(); 13641 Shift shift = operand.GetShift(); 13642 uint32_t amount = operand.GetShiftAmount(); 13643 if (IsUsingT32()) { 13644 // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 13645 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13646 ((amount % 8) == 0) && !rn.Is(pc) && 13647 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13648 uint32_t amount_ = amount / 8; 13649 EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13650 rm.GetCode() | (amount_ << 4)); 13651 AdvanceIT(); 13652 return; 13653 } 13654 } else { 13655 // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 13656 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13657 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 13658 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13659 uint32_t amount_ = amount / 8; 13660 EmitA32(0x06e00070U | (cond.GetCondition() << 28) | 13661 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 13662 (amount_ << 10)); 13663 return; 13664 } 13665 } 13666 } 13667 Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand); 13668 } 13669 13670 void Assembler::uxtab16(Condition cond, 13671 Register rd, 13672 Register rn, 13673 const Operand& operand) { 13674 VIXL_ASSERT(AllowAssembler()); 13675 CheckIT(cond); 13676 if (operand.IsImmediateShiftedRegister()) { 13677 Register rm = operand.GetBaseRegister(); 13678 Shift shift = operand.GetShift(); 13679 uint32_t amount = operand.GetShiftAmount(); 13680 if (IsUsingT32()) { 13681 // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 13682 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13683 ((amount % 8) == 0) && !rn.Is(pc) && 13684 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13685 uint32_t amount_ = amount / 8; 13686 EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13687 rm.GetCode() | (amount_ << 4)); 13688 AdvanceIT(); 13689 return; 13690 } 13691 } else { 13692 // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 13693 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13694 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 13695 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13696 uint32_t amount_ = amount / 8; 13697 EmitA32(0x06c00070U | (cond.GetCondition() << 28) | 13698 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 13699 (amount_ << 10)); 13700 return; 13701 } 13702 } 13703 } 13704 Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand); 13705 } 13706 13707 void Assembler::uxtah(Condition cond, 13708 Register rd, 13709 Register rn, 13710 const Operand& operand) { 13711 VIXL_ASSERT(AllowAssembler()); 13712 CheckIT(cond); 13713 if (operand.IsImmediateShiftedRegister()) { 13714 Register rm = operand.GetBaseRegister(); 13715 Shift shift = operand.GetShift(); 13716 uint32_t amount = operand.GetShiftAmount(); 13717 if (IsUsingT32()) { 13718 // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 13719 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13720 ((amount % 8) == 0) && !rn.Is(pc) && 13721 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13722 uint32_t amount_ = amount / 8; 13723 EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 13724 rm.GetCode() | (amount_ << 4)); 13725 AdvanceIT(); 13726 return; 13727 } 13728 } else { 13729 // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 13730 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13731 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) && 13732 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13733 uint32_t amount_ = amount / 8; 13734 EmitA32(0x06f00070U | (cond.GetCondition() << 28) | 13735 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 13736 (amount_ << 10)); 13737 return; 13738 } 13739 } 13740 } 13741 Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand); 13742 } 13743 13744 void Assembler::uxtb(Condition cond, 13745 EncodingSize size, 13746 Register rd, 13747 const Operand& operand) { 13748 VIXL_ASSERT(AllowAssembler()); 13749 CheckIT(cond); 13750 if (operand.IsImmediateShiftedRegister()) { 13751 Register rm = operand.GetBaseRegister(); 13752 if (operand.IsPlainRegister()) { 13753 if (IsUsingT32()) { 13754 // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1 13755 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 13756 EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3)); 13757 AdvanceIT(); 13758 return; 13759 } 13760 } 13761 } 13762 Shift shift = operand.GetShift(); 13763 uint32_t amount = operand.GetShiftAmount(); 13764 if (IsUsingT32()) { 13765 // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 13766 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 13767 (amount <= 24) && ((amount % 8) == 0) && 13768 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13769 uint32_t amount_ = amount / 8; 13770 EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() | 13771 (amount_ << 4)); 13772 AdvanceIT(); 13773 return; 13774 } 13775 } else { 13776 // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 13777 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13778 ((amount % 8) == 0) && cond.IsNotNever() && 13779 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13780 uint32_t amount_ = amount / 8; 13781 EmitA32(0x06ef0070U | (cond.GetCondition() << 28) | 13782 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 13783 return; 13784 } 13785 } 13786 } 13787 Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand); 13788 } 13789 13790 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) { 13791 VIXL_ASSERT(AllowAssembler()); 13792 CheckIT(cond); 13793 if (operand.IsImmediateShiftedRegister()) { 13794 Register rm = operand.GetBaseRegister(); 13795 Shift shift = operand.GetShift(); 13796 uint32_t amount = operand.GetShiftAmount(); 13797 if (IsUsingT32()) { 13798 // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1 13799 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13800 ((amount % 8) == 0) && 13801 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13802 uint32_t amount_ = amount / 8; 13803 EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() | 13804 (amount_ << 4)); 13805 AdvanceIT(); 13806 return; 13807 } 13808 } else { 13809 // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 13810 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13811 ((amount % 8) == 0) && cond.IsNotNever() && 13812 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13813 uint32_t amount_ = amount / 8; 13814 EmitA32(0x06cf0070U | (cond.GetCondition() << 28) | 13815 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 13816 return; 13817 } 13818 } 13819 } 13820 Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand); 13821 } 13822 13823 void Assembler::uxth(Condition cond, 13824 EncodingSize size, 13825 Register rd, 13826 const Operand& operand) { 13827 VIXL_ASSERT(AllowAssembler()); 13828 CheckIT(cond); 13829 if (operand.IsImmediateShiftedRegister()) { 13830 Register rm = operand.GetBaseRegister(); 13831 if (operand.IsPlainRegister()) { 13832 if (IsUsingT32()) { 13833 // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1 13834 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 13835 EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3)); 13836 AdvanceIT(); 13837 return; 13838 } 13839 } 13840 } 13841 Shift shift = operand.GetShift(); 13842 uint32_t amount = operand.GetShiftAmount(); 13843 if (IsUsingT32()) { 13844 // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 13845 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 13846 (amount <= 24) && ((amount % 8) == 0) && 13847 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13848 uint32_t amount_ = amount / 8; 13849 EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() | 13850 (amount_ << 4)); 13851 AdvanceIT(); 13852 return; 13853 } 13854 } else { 13855 // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 13856 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 13857 ((amount % 8) == 0) && cond.IsNotNever() && 13858 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 13859 uint32_t amount_ = amount / 8; 13860 EmitA32(0x06ff0070U | (cond.GetCondition() << 28) | 13861 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 13862 return; 13863 } 13864 } 13865 } 13866 Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand); 13867 } 13868 13869 void Assembler::vaba( 13870 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13871 VIXL_ASSERT(AllowAssembler()); 13872 CheckIT(cond); 13873 Dt_U_size_1 encoded_dt(dt); 13874 if (IsUsingT32()) { 13875 // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1 13876 if (encoded_dt.IsValid()) { 13877 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13878 EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13879 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13880 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13881 AdvanceIT(); 13882 return; 13883 } 13884 } 13885 } else { 13886 // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1 13887 if (encoded_dt.IsValid()) { 13888 if (cond.Is(al)) { 13889 EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13890 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 13891 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13892 return; 13893 } 13894 } 13895 } 13896 Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm); 13897 } 13898 13899 void Assembler::vaba( 13900 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13901 VIXL_ASSERT(AllowAssembler()); 13902 CheckIT(cond); 13903 Dt_U_size_1 encoded_dt(dt); 13904 if (IsUsingT32()) { 13905 // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1 13906 if (encoded_dt.IsValid()) { 13907 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13908 EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13909 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13910 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13911 AdvanceIT(); 13912 return; 13913 } 13914 } 13915 } else { 13916 // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1 13917 if (encoded_dt.IsValid()) { 13918 if (cond.Is(al)) { 13919 EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13920 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 13921 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13922 return; 13923 } 13924 } 13925 } 13926 Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm); 13927 } 13928 13929 void Assembler::vabal( 13930 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 13931 VIXL_ASSERT(AllowAssembler()); 13932 CheckIT(cond); 13933 Dt_U_size_1 encoded_dt(dt); 13934 if (IsUsingT32()) { 13935 // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 13936 if (encoded_dt.IsValid()) { 13937 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13938 EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13939 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13940 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13941 AdvanceIT(); 13942 return; 13943 } 13944 } 13945 } else { 13946 // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 13947 if (encoded_dt.IsValid()) { 13948 if (cond.Is(al)) { 13949 EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13950 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 13951 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13952 return; 13953 } 13954 } 13955 } 13956 Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm); 13957 } 13958 13959 void Assembler::vabd( 13960 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13961 VIXL_ASSERT(AllowAssembler()); 13962 CheckIT(cond); 13963 Dt_U_size_1 encoded_dt(dt); 13964 if (IsUsingT32()) { 13965 // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 13966 if (dt.Is(F32)) { 13967 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13968 EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13969 rm.Encode(5, 0)); 13970 AdvanceIT(); 13971 return; 13972 } 13973 } 13974 // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 13975 if (encoded_dt.IsValid()) { 13976 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13977 EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13978 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13979 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13980 AdvanceIT(); 13981 return; 13982 } 13983 } 13984 } else { 13985 // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 13986 if (dt.Is(F32)) { 13987 if (cond.Is(al)) { 13988 EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13989 rm.Encode(5, 0)); 13990 return; 13991 } 13992 } 13993 // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 13994 if (encoded_dt.IsValid()) { 13995 if (cond.Is(al)) { 13996 EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13997 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 13998 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13999 return; 14000 } 14001 } 14002 } 14003 Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm); 14004 } 14005 14006 void Assembler::vabd( 14007 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14008 VIXL_ASSERT(AllowAssembler()); 14009 CheckIT(cond); 14010 Dt_U_size_1 encoded_dt(dt); 14011 if (IsUsingT32()) { 14012 // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14013 if (dt.Is(F32)) { 14014 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14015 EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14016 rm.Encode(5, 0)); 14017 AdvanceIT(); 14018 return; 14019 } 14020 } 14021 // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 14022 if (encoded_dt.IsValid()) { 14023 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14024 EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14025 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14026 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14027 AdvanceIT(); 14028 return; 14029 } 14030 } 14031 } else { 14032 // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14033 if (dt.Is(F32)) { 14034 if (cond.Is(al)) { 14035 EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14036 rm.Encode(5, 0)); 14037 return; 14038 } 14039 } 14040 // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14041 if (encoded_dt.IsValid()) { 14042 if (cond.Is(al)) { 14043 EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14044 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14045 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14046 return; 14047 } 14048 } 14049 } 14050 Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm); 14051 } 14052 14053 void Assembler::vabdl( 14054 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 14055 VIXL_ASSERT(AllowAssembler()); 14056 CheckIT(cond); 14057 Dt_U_size_1 encoded_dt(dt); 14058 if (IsUsingT32()) { 14059 // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 14060 if (encoded_dt.IsValid()) { 14061 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14062 EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14063 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14064 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14065 AdvanceIT(); 14066 return; 14067 } 14068 } 14069 } else { 14070 // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 14071 if (encoded_dt.IsValid()) { 14072 if (cond.Is(al)) { 14073 EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14074 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14075 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14076 return; 14077 } 14078 } 14079 } 14080 Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm); 14081 } 14082 14083 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) { 14084 VIXL_ASSERT(AllowAssembler()); 14085 CheckIT(cond); 14086 Dt_F_size_1 encoded_dt(dt); 14087 if (IsUsingT32()) { 14088 // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 14089 if (encoded_dt.IsValid()) { 14090 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14091 EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14092 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14093 rd.Encode(22, 12) | rm.Encode(5, 0)); 14094 AdvanceIT(); 14095 return; 14096 } 14097 } 14098 // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 14099 if (dt.Is(F64)) { 14100 EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14101 AdvanceIT(); 14102 return; 14103 } 14104 } else { 14105 // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 14106 if (encoded_dt.IsValid()) { 14107 if (cond.Is(al)) { 14108 EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14109 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14110 rd.Encode(22, 12) | rm.Encode(5, 0)); 14111 return; 14112 } 14113 } 14114 // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 14115 if (dt.Is(F64) && cond.IsNotNever()) { 14116 EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14117 rm.Encode(5, 0)); 14118 return; 14119 } 14120 } 14121 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 14122 } 14123 14124 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) { 14125 VIXL_ASSERT(AllowAssembler()); 14126 CheckIT(cond); 14127 Dt_F_size_1 encoded_dt(dt); 14128 if (IsUsingT32()) { 14129 // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 14130 if (encoded_dt.IsValid()) { 14131 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14132 EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14133 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14134 rd.Encode(22, 12) | rm.Encode(5, 0)); 14135 AdvanceIT(); 14136 return; 14137 } 14138 } 14139 } else { 14140 // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 14141 if (encoded_dt.IsValid()) { 14142 if (cond.Is(al)) { 14143 EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14144 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14145 rd.Encode(22, 12) | rm.Encode(5, 0)); 14146 return; 14147 } 14148 } 14149 } 14150 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 14151 } 14152 14153 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) { 14154 VIXL_ASSERT(AllowAssembler()); 14155 CheckIT(cond); 14156 if (IsUsingT32()) { 14157 // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 14158 if (dt.Is(F32)) { 14159 EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14160 AdvanceIT(); 14161 return; 14162 } 14163 } else { 14164 // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 14165 if (dt.Is(F32) && cond.IsNotNever()) { 14166 EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14167 rm.Encode(5, 0)); 14168 return; 14169 } 14170 } 14171 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 14172 } 14173 14174 void Assembler::vacge( 14175 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14176 VIXL_ASSERT(AllowAssembler()); 14177 CheckIT(cond); 14178 if (IsUsingT32()) { 14179 // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14180 if (dt.Is(F32)) { 14181 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14182 EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14183 rm.Encode(5, 0)); 14184 AdvanceIT(); 14185 return; 14186 } 14187 } 14188 } else { 14189 // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14190 if (dt.Is(F32)) { 14191 if (cond.Is(al)) { 14192 EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14193 rm.Encode(5, 0)); 14194 return; 14195 } 14196 } 14197 } 14198 Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm); 14199 } 14200 14201 void Assembler::vacge( 14202 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14203 VIXL_ASSERT(AllowAssembler()); 14204 CheckIT(cond); 14205 if (IsUsingT32()) { 14206 // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14207 if (dt.Is(F32)) { 14208 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14209 EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14210 rm.Encode(5, 0)); 14211 AdvanceIT(); 14212 return; 14213 } 14214 } 14215 } else { 14216 // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14217 if (dt.Is(F32)) { 14218 if (cond.Is(al)) { 14219 EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14220 rm.Encode(5, 0)); 14221 return; 14222 } 14223 } 14224 } 14225 Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm); 14226 } 14227 14228 void Assembler::vacgt( 14229 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14230 VIXL_ASSERT(AllowAssembler()); 14231 CheckIT(cond); 14232 if (IsUsingT32()) { 14233 // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14234 if (dt.Is(F32)) { 14235 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14236 EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14237 rm.Encode(5, 0)); 14238 AdvanceIT(); 14239 return; 14240 } 14241 } 14242 } else { 14243 // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14244 if (dt.Is(F32)) { 14245 if (cond.Is(al)) { 14246 EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14247 rm.Encode(5, 0)); 14248 return; 14249 } 14250 } 14251 } 14252 Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm); 14253 } 14254 14255 void Assembler::vacgt( 14256 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14257 VIXL_ASSERT(AllowAssembler()); 14258 CheckIT(cond); 14259 if (IsUsingT32()) { 14260 // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14261 if (dt.Is(F32)) { 14262 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14263 EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14264 rm.Encode(5, 0)); 14265 AdvanceIT(); 14266 return; 14267 } 14268 } 14269 } else { 14270 // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14271 if (dt.Is(F32)) { 14272 if (cond.Is(al)) { 14273 EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14274 rm.Encode(5, 0)); 14275 return; 14276 } 14277 } 14278 } 14279 Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm); 14280 } 14281 14282 void Assembler::vacle( 14283 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14284 VIXL_ASSERT(AllowAssembler()); 14285 CheckIT(cond); 14286 if (IsUsingT32()) { 14287 // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14288 if (dt.Is(F32)) { 14289 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14290 EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14291 rm.Encode(5, 0)); 14292 AdvanceIT(); 14293 return; 14294 } 14295 } 14296 } else { 14297 // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14298 if (dt.Is(F32)) { 14299 if (cond.Is(al)) { 14300 EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14301 rm.Encode(5, 0)); 14302 return; 14303 } 14304 } 14305 } 14306 Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm); 14307 } 14308 14309 void Assembler::vacle( 14310 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14311 VIXL_ASSERT(AllowAssembler()); 14312 CheckIT(cond); 14313 if (IsUsingT32()) { 14314 // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14315 if (dt.Is(F32)) { 14316 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14317 EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14318 rm.Encode(5, 0)); 14319 AdvanceIT(); 14320 return; 14321 } 14322 } 14323 } else { 14324 // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14325 if (dt.Is(F32)) { 14326 if (cond.Is(al)) { 14327 EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14328 rm.Encode(5, 0)); 14329 return; 14330 } 14331 } 14332 } 14333 Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm); 14334 } 14335 14336 void Assembler::vaclt( 14337 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14338 VIXL_ASSERT(AllowAssembler()); 14339 CheckIT(cond); 14340 if (IsUsingT32()) { 14341 // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14342 if (dt.Is(F32)) { 14343 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14344 EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14345 rm.Encode(5, 0)); 14346 AdvanceIT(); 14347 return; 14348 } 14349 } 14350 } else { 14351 // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14352 if (dt.Is(F32)) { 14353 if (cond.Is(al)) { 14354 EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14355 rm.Encode(5, 0)); 14356 return; 14357 } 14358 } 14359 } 14360 Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm); 14361 } 14362 14363 void Assembler::vaclt( 14364 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14365 VIXL_ASSERT(AllowAssembler()); 14366 CheckIT(cond); 14367 if (IsUsingT32()) { 14368 // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14369 if (dt.Is(F32)) { 14370 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14371 EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14372 rm.Encode(5, 0)); 14373 AdvanceIT(); 14374 return; 14375 } 14376 } 14377 } else { 14378 // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 14379 if (dt.Is(F32)) { 14380 if (cond.Is(al)) { 14381 EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14382 rm.Encode(5, 0)); 14383 return; 14384 } 14385 } 14386 } 14387 Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm); 14388 } 14389 14390 void Assembler::vadd( 14391 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14392 VIXL_ASSERT(AllowAssembler()); 14393 CheckIT(cond); 14394 Dt_size_2 encoded_dt(dt); 14395 if (IsUsingT32()) { 14396 // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 14397 if (dt.Is(F32)) { 14398 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14399 EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14400 rm.Encode(5, 0)); 14401 AdvanceIT(); 14402 return; 14403 } 14404 } 14405 // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 14406 if (dt.Is(F64)) { 14407 EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14408 rm.Encode(5, 0)); 14409 AdvanceIT(); 14410 return; 14411 } 14412 // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 14413 if (encoded_dt.IsValid()) { 14414 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14415 EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) | 14416 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14417 AdvanceIT(); 14418 return; 14419 } 14420 } 14421 } else { 14422 // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 14423 if (dt.Is(F32)) { 14424 if (cond.Is(al)) { 14425 EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14426 rm.Encode(5, 0)); 14427 return; 14428 } 14429 } 14430 // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 14431 if (dt.Is(F64) && cond.IsNotNever()) { 14432 EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14433 rn.Encode(7, 16) | rm.Encode(5, 0)); 14434 return; 14435 } 14436 // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 14437 if (encoded_dt.IsValid()) { 14438 if (cond.Is(al)) { 14439 EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) | 14440 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14441 return; 14442 } 14443 } 14444 } 14445 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 14446 } 14447 14448 void Assembler::vadd( 14449 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14450 VIXL_ASSERT(AllowAssembler()); 14451 CheckIT(cond); 14452 Dt_size_2 encoded_dt(dt); 14453 if (IsUsingT32()) { 14454 // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 14455 if (dt.Is(F32)) { 14456 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14457 EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14458 rm.Encode(5, 0)); 14459 AdvanceIT(); 14460 return; 14461 } 14462 } 14463 // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 14464 if (encoded_dt.IsValid()) { 14465 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14466 EmitT32_32(0xef000840U | (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 {<Qd>}, <Qn>, <Qm> ; A1 14474 if (dt.Is(F32)) { 14475 if (cond.Is(al)) { 14476 EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14477 rm.Encode(5, 0)); 14478 return; 14479 } 14480 } 14481 // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14482 if (encoded_dt.IsValid()) { 14483 if (cond.Is(al)) { 14484 EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) | 14485 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14486 return; 14487 } 14488 } 14489 } 14490 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 14491 } 14492 14493 void Assembler::vadd( 14494 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 14495 VIXL_ASSERT(AllowAssembler()); 14496 CheckIT(cond); 14497 if (IsUsingT32()) { 14498 // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 14499 if (dt.Is(F32)) { 14500 EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14501 rm.Encode(5, 0)); 14502 AdvanceIT(); 14503 return; 14504 } 14505 } else { 14506 // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 14507 if (dt.Is(F32) && cond.IsNotNever()) { 14508 EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14509 rn.Encode(7, 16) | rm.Encode(5, 0)); 14510 return; 14511 } 14512 } 14513 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 14514 } 14515 14516 void Assembler::vaddhn( 14517 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 14518 VIXL_ASSERT(AllowAssembler()); 14519 CheckIT(cond); 14520 Dt_size_3 encoded_dt(dt); 14521 if (IsUsingT32()) { 14522 // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 14523 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 14524 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14525 EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) | 14526 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14527 AdvanceIT(); 14528 return; 14529 } 14530 } 14531 } else { 14532 // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 14533 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 14534 if (cond.Is(al)) { 14535 EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) | 14536 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14537 return; 14538 } 14539 } 14540 } 14541 Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm); 14542 } 14543 14544 void Assembler::vaddl( 14545 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 14546 VIXL_ASSERT(AllowAssembler()); 14547 CheckIT(cond); 14548 Dt_U_size_1 encoded_dt(dt); 14549 if (IsUsingT32()) { 14550 // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 14551 if (encoded_dt.IsValid()) { 14552 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14553 EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14554 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14555 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14556 AdvanceIT(); 14557 return; 14558 } 14559 } 14560 } else { 14561 // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 14562 if (encoded_dt.IsValid()) { 14563 if (cond.Is(al)) { 14564 EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14565 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14566 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14567 return; 14568 } 14569 } 14570 } 14571 Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm); 14572 } 14573 14574 void Assembler::vaddw( 14575 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) { 14576 VIXL_ASSERT(AllowAssembler()); 14577 CheckIT(cond); 14578 Dt_U_size_1 encoded_dt(dt); 14579 if (IsUsingT32()) { 14580 // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1 14581 if (encoded_dt.IsValid()) { 14582 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14583 EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14584 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14585 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14586 AdvanceIT(); 14587 return; 14588 } 14589 } 14590 } else { 14591 // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1 14592 if (encoded_dt.IsValid()) { 14593 if (cond.Is(al)) { 14594 EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14595 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14596 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14597 return; 14598 } 14599 } 14600 } 14601 Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm); 14602 } 14603 14604 void Assembler::vand(Condition cond, 14605 DataType dt, 14606 DRegister rd, 14607 DRegister rn, 14608 const DOperand& operand) { 14609 VIXL_ASSERT(AllowAssembler()); 14610 CheckIT(cond); 14611 if (operand.IsImmediate()) { 14612 ImmediateVand encoded_dt(dt, operand.GetNeonImmediate()); 14613 if (IsUsingT32()) { 14614 // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 14615 if (encoded_dt.IsValid() && rd.Is(rn)) { 14616 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14617 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 14618 rd.Encode(22, 12) | 14619 (encoded_dt.GetEncodedImmediate() & 0xf) | 14620 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14621 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 14622 AdvanceIT(); 14623 return; 14624 } 14625 } 14626 } else { 14627 // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 14628 if (encoded_dt.IsValid() && rd.Is(rn)) { 14629 if (cond.Is(al)) { 14630 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 14631 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 14632 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14633 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 14634 return; 14635 } 14636 } 14637 } 14638 } 14639 if (operand.IsRegister()) { 14640 DRegister rm = operand.GetRegister(); 14641 USE(dt); 14642 if (IsUsingT32()) { 14643 // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14644 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14645 EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14646 rm.Encode(5, 0)); 14647 AdvanceIT(); 14648 return; 14649 } 14650 } else { 14651 // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14652 if (cond.Is(al)) { 14653 EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14654 rm.Encode(5, 0)); 14655 return; 14656 } 14657 } 14658 } 14659 Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand); 14660 } 14661 14662 void Assembler::vand(Condition cond, 14663 DataType dt, 14664 QRegister rd, 14665 QRegister rn, 14666 const QOperand& operand) { 14667 VIXL_ASSERT(AllowAssembler()); 14668 CheckIT(cond); 14669 if (operand.IsImmediate()) { 14670 ImmediateVand encoded_dt(dt, operand.GetNeonImmediate()); 14671 if (IsUsingT32()) { 14672 // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 14673 if (encoded_dt.IsValid() && rd.Is(rn)) { 14674 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14675 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 14676 rd.Encode(22, 12) | 14677 (encoded_dt.GetEncodedImmediate() & 0xf) | 14678 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14679 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 14680 AdvanceIT(); 14681 return; 14682 } 14683 } 14684 } else { 14685 // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 14686 if (encoded_dt.IsValid() && rd.Is(rn)) { 14687 if (cond.Is(al)) { 14688 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 14689 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 14690 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14691 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 14692 return; 14693 } 14694 } 14695 } 14696 } 14697 if (operand.IsRegister()) { 14698 QRegister rm = operand.GetRegister(); 14699 USE(dt); 14700 if (IsUsingT32()) { 14701 // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14702 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14703 EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14704 rm.Encode(5, 0)); 14705 AdvanceIT(); 14706 return; 14707 } 14708 } else { 14709 // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14710 if (cond.Is(al)) { 14711 EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14712 rm.Encode(5, 0)); 14713 return; 14714 } 14715 } 14716 } 14717 Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand); 14718 } 14719 14720 void Assembler::vbic(Condition cond, 14721 DataType dt, 14722 DRegister rd, 14723 DRegister rn, 14724 const DOperand& operand) { 14725 VIXL_ASSERT(AllowAssembler()); 14726 CheckIT(cond); 14727 if (operand.IsImmediate()) { 14728 ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate()); 14729 if (IsUsingT32()) { 14730 // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 14731 if (encoded_dt.IsValid() && rd.Is(rn)) { 14732 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14733 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 14734 rd.Encode(22, 12) | 14735 (encoded_dt.GetEncodedImmediate() & 0xf) | 14736 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14737 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 14738 AdvanceIT(); 14739 return; 14740 } 14741 } 14742 } else { 14743 // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 14744 if (encoded_dt.IsValid() && rd.Is(rn)) { 14745 if (cond.Is(al)) { 14746 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 14747 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 14748 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14749 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 14750 return; 14751 } 14752 } 14753 } 14754 } 14755 if (operand.IsRegister()) { 14756 DRegister rm = operand.GetRegister(); 14757 USE(dt); 14758 if (IsUsingT32()) { 14759 // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14760 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14761 EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14762 rm.Encode(5, 0)); 14763 AdvanceIT(); 14764 return; 14765 } 14766 } else { 14767 // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14768 if (cond.Is(al)) { 14769 EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14770 rm.Encode(5, 0)); 14771 return; 14772 } 14773 } 14774 } 14775 Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand); 14776 } 14777 14778 void Assembler::vbic(Condition cond, 14779 DataType dt, 14780 QRegister rd, 14781 QRegister rn, 14782 const QOperand& operand) { 14783 VIXL_ASSERT(AllowAssembler()); 14784 CheckIT(cond); 14785 if (operand.IsImmediate()) { 14786 ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate()); 14787 if (IsUsingT32()) { 14788 // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 14789 if (encoded_dt.IsValid() && rd.Is(rn)) { 14790 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14791 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 14792 rd.Encode(22, 12) | 14793 (encoded_dt.GetEncodedImmediate() & 0xf) | 14794 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14795 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 14796 AdvanceIT(); 14797 return; 14798 } 14799 } 14800 } else { 14801 // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 14802 if (encoded_dt.IsValid() && rd.Is(rn)) { 14803 if (cond.Is(al)) { 14804 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 14805 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 14806 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 14807 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 14808 return; 14809 } 14810 } 14811 } 14812 } 14813 if (operand.IsRegister()) { 14814 QRegister rm = operand.GetRegister(); 14815 USE(dt); 14816 if (IsUsingT32()) { 14817 // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14818 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14819 EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14820 rm.Encode(5, 0)); 14821 AdvanceIT(); 14822 return; 14823 } 14824 } else { 14825 // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14826 if (cond.Is(al)) { 14827 EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14828 rm.Encode(5, 0)); 14829 return; 14830 } 14831 } 14832 } 14833 Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand); 14834 } 14835 14836 void Assembler::vbif( 14837 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14838 VIXL_ASSERT(AllowAssembler()); 14839 CheckIT(cond); 14840 USE(dt); 14841 if (IsUsingT32()) { 14842 // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14843 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14844 EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14845 rm.Encode(5, 0)); 14846 AdvanceIT(); 14847 return; 14848 } 14849 } else { 14850 // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14851 if (cond.Is(al)) { 14852 EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14853 rm.Encode(5, 0)); 14854 return; 14855 } 14856 } 14857 Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm); 14858 } 14859 14860 void Assembler::vbif( 14861 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14862 VIXL_ASSERT(AllowAssembler()); 14863 CheckIT(cond); 14864 USE(dt); 14865 if (IsUsingT32()) { 14866 // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14867 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14868 EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14869 rm.Encode(5, 0)); 14870 AdvanceIT(); 14871 return; 14872 } 14873 } else { 14874 // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14875 if (cond.Is(al)) { 14876 EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14877 rm.Encode(5, 0)); 14878 return; 14879 } 14880 } 14881 Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm); 14882 } 14883 14884 void Assembler::vbit( 14885 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14886 VIXL_ASSERT(AllowAssembler()); 14887 CheckIT(cond); 14888 USE(dt); 14889 if (IsUsingT32()) { 14890 // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14891 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14892 EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14893 rm.Encode(5, 0)); 14894 AdvanceIT(); 14895 return; 14896 } 14897 } else { 14898 // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14899 if (cond.Is(al)) { 14900 EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14901 rm.Encode(5, 0)); 14902 return; 14903 } 14904 } 14905 Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm); 14906 } 14907 14908 void Assembler::vbit( 14909 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14910 VIXL_ASSERT(AllowAssembler()); 14911 CheckIT(cond); 14912 USE(dt); 14913 if (IsUsingT32()) { 14914 // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14915 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14916 EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14917 rm.Encode(5, 0)); 14918 AdvanceIT(); 14919 return; 14920 } 14921 } else { 14922 // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14923 if (cond.Is(al)) { 14924 EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14925 rm.Encode(5, 0)); 14926 return; 14927 } 14928 } 14929 Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm); 14930 } 14931 14932 void Assembler::vbsl( 14933 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14934 VIXL_ASSERT(AllowAssembler()); 14935 CheckIT(cond); 14936 USE(dt); 14937 if (IsUsingT32()) { 14938 // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 14939 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14940 EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14941 rm.Encode(5, 0)); 14942 AdvanceIT(); 14943 return; 14944 } 14945 } else { 14946 // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 14947 if (cond.Is(al)) { 14948 EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14949 rm.Encode(5, 0)); 14950 return; 14951 } 14952 } 14953 Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm); 14954 } 14955 14956 void Assembler::vbsl( 14957 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14958 VIXL_ASSERT(AllowAssembler()); 14959 CheckIT(cond); 14960 USE(dt); 14961 if (IsUsingT32()) { 14962 // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 14963 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14964 EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14965 rm.Encode(5, 0)); 14966 AdvanceIT(); 14967 return; 14968 } 14969 } else { 14970 // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 14971 if (cond.Is(al)) { 14972 EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14973 rm.Encode(5, 0)); 14974 return; 14975 } 14976 } 14977 Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm); 14978 } 14979 14980 void Assembler::vceq(Condition cond, 14981 DataType dt, 14982 DRegister rd, 14983 DRegister rm, 14984 const DOperand& operand) { 14985 VIXL_ASSERT(AllowAssembler()); 14986 CheckIT(cond); 14987 if (operand.IsImmediate()) { 14988 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14989 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14990 Dt_F_size_2 encoded_dt(dt); 14991 if (IsUsingT32()) { 14992 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 14993 if (encoded_dt.IsValid() && (imm == 0)) { 14994 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14995 EmitT32_32(0xffb10100U | 14996 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14997 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14998 rd.Encode(22, 12) | rm.Encode(5, 0)); 14999 AdvanceIT(); 15000 return; 15001 } 15002 } 15003 } else { 15004 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15005 if (encoded_dt.IsValid() && (imm == 0)) { 15006 if (cond.Is(al)) { 15007 EmitA32(0xf3b10100U | 15008 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15009 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15010 rd.Encode(22, 12) | rm.Encode(5, 0)); 15011 return; 15012 } 15013 } 15014 } 15015 } 15016 } 15017 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand); 15018 } 15019 15020 void Assembler::vceq(Condition cond, 15021 DataType dt, 15022 QRegister rd, 15023 QRegister rm, 15024 const QOperand& operand) { 15025 VIXL_ASSERT(AllowAssembler()); 15026 CheckIT(cond); 15027 if (operand.IsImmediate()) { 15028 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15029 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15030 Dt_F_size_2 encoded_dt(dt); 15031 if (IsUsingT32()) { 15032 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15033 if (encoded_dt.IsValid() && (imm == 0)) { 15034 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15035 EmitT32_32(0xffb10140U | 15036 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15037 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15038 rd.Encode(22, 12) | rm.Encode(5, 0)); 15039 AdvanceIT(); 15040 return; 15041 } 15042 } 15043 } else { 15044 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15045 if (encoded_dt.IsValid() && (imm == 0)) { 15046 if (cond.Is(al)) { 15047 EmitA32(0xf3b10140U | 15048 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15049 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15050 rd.Encode(22, 12) | rm.Encode(5, 0)); 15051 return; 15052 } 15053 } 15054 } 15055 } 15056 } 15057 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand); 15058 } 15059 15060 void Assembler::vceq( 15061 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15062 VIXL_ASSERT(AllowAssembler()); 15063 CheckIT(cond); 15064 Dt_size_4 encoded_dt(dt); 15065 Dt_sz_1 encoded_dt_2(dt); 15066 if (IsUsingT32()) { 15067 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15068 if (encoded_dt.IsValid()) { 15069 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15070 EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) | 15071 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15072 AdvanceIT(); 15073 return; 15074 } 15075 } 15076 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2 15077 if (encoded_dt_2.IsValid()) { 15078 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15079 EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) | 15080 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15081 AdvanceIT(); 15082 return; 15083 } 15084 } 15085 } else { 15086 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15087 if (encoded_dt.IsValid()) { 15088 if (cond.Is(al)) { 15089 EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) | 15090 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15091 return; 15092 } 15093 } 15094 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2 15095 if (encoded_dt_2.IsValid()) { 15096 if (cond.Is(al)) { 15097 EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) | 15098 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15099 return; 15100 } 15101 } 15102 } 15103 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm); 15104 } 15105 15106 void Assembler::vceq( 15107 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15108 VIXL_ASSERT(AllowAssembler()); 15109 CheckIT(cond); 15110 Dt_size_4 encoded_dt(dt); 15111 Dt_sz_1 encoded_dt_2(dt); 15112 if (IsUsingT32()) { 15113 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15114 if (encoded_dt.IsValid()) { 15115 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15116 EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) | 15117 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15118 AdvanceIT(); 15119 return; 15120 } 15121 } 15122 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2 15123 if (encoded_dt_2.IsValid()) { 15124 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15125 EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) | 15126 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15127 AdvanceIT(); 15128 return; 15129 } 15130 } 15131 } else { 15132 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15133 if (encoded_dt.IsValid()) { 15134 if (cond.Is(al)) { 15135 EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) | 15136 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15137 return; 15138 } 15139 } 15140 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2 15141 if (encoded_dt_2.IsValid()) { 15142 if (cond.Is(al)) { 15143 EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) | 15144 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15145 return; 15146 } 15147 } 15148 } 15149 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm); 15150 } 15151 15152 void Assembler::vcge(Condition cond, 15153 DataType dt, 15154 DRegister rd, 15155 DRegister rm, 15156 const DOperand& operand) { 15157 VIXL_ASSERT(AllowAssembler()); 15158 CheckIT(cond); 15159 if (operand.IsImmediate()) { 15160 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15161 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15162 Dt_F_size_1 encoded_dt(dt); 15163 if (IsUsingT32()) { 15164 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15165 if (encoded_dt.IsValid() && (imm == 0)) { 15166 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15167 EmitT32_32(0xffb10080U | 15168 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15169 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15170 rd.Encode(22, 12) | rm.Encode(5, 0)); 15171 AdvanceIT(); 15172 return; 15173 } 15174 } 15175 } else { 15176 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15177 if (encoded_dt.IsValid() && (imm == 0)) { 15178 if (cond.Is(al)) { 15179 EmitA32(0xf3b10080U | 15180 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15181 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15182 rd.Encode(22, 12) | rm.Encode(5, 0)); 15183 return; 15184 } 15185 } 15186 } 15187 } 15188 } 15189 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand); 15190 } 15191 15192 void Assembler::vcge(Condition cond, 15193 DataType dt, 15194 QRegister rd, 15195 QRegister rm, 15196 const QOperand& operand) { 15197 VIXL_ASSERT(AllowAssembler()); 15198 CheckIT(cond); 15199 if (operand.IsImmediate()) { 15200 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15201 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15202 Dt_F_size_1 encoded_dt(dt); 15203 if (IsUsingT32()) { 15204 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15205 if (encoded_dt.IsValid() && (imm == 0)) { 15206 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15207 EmitT32_32(0xffb100c0U | 15208 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15209 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15210 rd.Encode(22, 12) | rm.Encode(5, 0)); 15211 AdvanceIT(); 15212 return; 15213 } 15214 } 15215 } else { 15216 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15217 if (encoded_dt.IsValid() && (imm == 0)) { 15218 if (cond.Is(al)) { 15219 EmitA32(0xf3b100c0U | 15220 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15221 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15222 rd.Encode(22, 12) | rm.Encode(5, 0)); 15223 return; 15224 } 15225 } 15226 } 15227 } 15228 } 15229 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand); 15230 } 15231 15232 void Assembler::vcge( 15233 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15234 VIXL_ASSERT(AllowAssembler()); 15235 CheckIT(cond); 15236 Dt_U_size_1 encoded_dt(dt); 15237 if (IsUsingT32()) { 15238 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15239 if (encoded_dt.IsValid()) { 15240 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15241 EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15242 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15243 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15244 AdvanceIT(); 15245 return; 15246 } 15247 } 15248 // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 15249 if (dt.Is(F32)) { 15250 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15251 EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15252 rm.Encode(5, 0)); 15253 AdvanceIT(); 15254 return; 15255 } 15256 } 15257 } else { 15258 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15259 if (encoded_dt.IsValid()) { 15260 if (cond.Is(al)) { 15261 EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15262 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15263 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15264 return; 15265 } 15266 } 15267 // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 15268 if (dt.Is(F32)) { 15269 if (cond.Is(al)) { 15270 EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15271 rm.Encode(5, 0)); 15272 return; 15273 } 15274 } 15275 } 15276 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm); 15277 } 15278 15279 void Assembler::vcge( 15280 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15281 VIXL_ASSERT(AllowAssembler()); 15282 CheckIT(cond); 15283 Dt_U_size_1 encoded_dt(dt); 15284 if (IsUsingT32()) { 15285 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15286 if (encoded_dt.IsValid()) { 15287 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15288 EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15289 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15290 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15291 AdvanceIT(); 15292 return; 15293 } 15294 } 15295 // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 15296 if (dt.Is(F32)) { 15297 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15298 EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15299 rm.Encode(5, 0)); 15300 AdvanceIT(); 15301 return; 15302 } 15303 } 15304 } else { 15305 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15306 if (encoded_dt.IsValid()) { 15307 if (cond.Is(al)) { 15308 EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15309 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15310 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15311 return; 15312 } 15313 } 15314 // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 15315 if (dt.Is(F32)) { 15316 if (cond.Is(al)) { 15317 EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15318 rm.Encode(5, 0)); 15319 return; 15320 } 15321 } 15322 } 15323 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm); 15324 } 15325 15326 void Assembler::vcgt(Condition cond, 15327 DataType dt, 15328 DRegister rd, 15329 DRegister rm, 15330 const DOperand& operand) { 15331 VIXL_ASSERT(AllowAssembler()); 15332 CheckIT(cond); 15333 if (operand.IsImmediate()) { 15334 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15335 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15336 Dt_F_size_1 encoded_dt(dt); 15337 if (IsUsingT32()) { 15338 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15339 if (encoded_dt.IsValid() && (imm == 0)) { 15340 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15341 EmitT32_32(0xffb10000U | 15342 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15343 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15344 rd.Encode(22, 12) | rm.Encode(5, 0)); 15345 AdvanceIT(); 15346 return; 15347 } 15348 } 15349 } else { 15350 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15351 if (encoded_dt.IsValid() && (imm == 0)) { 15352 if (cond.Is(al)) { 15353 EmitA32(0xf3b10000U | 15354 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15355 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15356 rd.Encode(22, 12) | rm.Encode(5, 0)); 15357 return; 15358 } 15359 } 15360 } 15361 } 15362 } 15363 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand); 15364 } 15365 15366 void Assembler::vcgt(Condition cond, 15367 DataType dt, 15368 QRegister rd, 15369 QRegister rm, 15370 const QOperand& operand) { 15371 VIXL_ASSERT(AllowAssembler()); 15372 CheckIT(cond); 15373 if (operand.IsImmediate()) { 15374 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15375 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15376 Dt_F_size_1 encoded_dt(dt); 15377 if (IsUsingT32()) { 15378 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15379 if (encoded_dt.IsValid() && (imm == 0)) { 15380 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15381 EmitT32_32(0xffb10040U | 15382 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15383 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15384 rd.Encode(22, 12) | rm.Encode(5, 0)); 15385 AdvanceIT(); 15386 return; 15387 } 15388 } 15389 } else { 15390 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15391 if (encoded_dt.IsValid() && (imm == 0)) { 15392 if (cond.Is(al)) { 15393 EmitA32(0xf3b10040U | 15394 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15395 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15396 rd.Encode(22, 12) | rm.Encode(5, 0)); 15397 return; 15398 } 15399 } 15400 } 15401 } 15402 } 15403 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand); 15404 } 15405 15406 void Assembler::vcgt( 15407 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15408 VIXL_ASSERT(AllowAssembler()); 15409 CheckIT(cond); 15410 Dt_U_size_1 encoded_dt(dt); 15411 if (IsUsingT32()) { 15412 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15413 if (encoded_dt.IsValid()) { 15414 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15415 EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15416 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15417 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15418 AdvanceIT(); 15419 return; 15420 } 15421 } 15422 // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 15423 if (dt.Is(F32)) { 15424 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15425 EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15426 rm.Encode(5, 0)); 15427 AdvanceIT(); 15428 return; 15429 } 15430 } 15431 } else { 15432 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15433 if (encoded_dt.IsValid()) { 15434 if (cond.Is(al)) { 15435 EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15436 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15437 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15438 return; 15439 } 15440 } 15441 // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 15442 if (dt.Is(F32)) { 15443 if (cond.Is(al)) { 15444 EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15445 rm.Encode(5, 0)); 15446 return; 15447 } 15448 } 15449 } 15450 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm); 15451 } 15452 15453 void Assembler::vcgt( 15454 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15455 VIXL_ASSERT(AllowAssembler()); 15456 CheckIT(cond); 15457 Dt_U_size_1 encoded_dt(dt); 15458 if (IsUsingT32()) { 15459 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15460 if (encoded_dt.IsValid()) { 15461 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15462 EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15463 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15464 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15465 AdvanceIT(); 15466 return; 15467 } 15468 } 15469 // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 15470 if (dt.Is(F32)) { 15471 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15472 EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15473 rm.Encode(5, 0)); 15474 AdvanceIT(); 15475 return; 15476 } 15477 } 15478 } else { 15479 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15480 if (encoded_dt.IsValid()) { 15481 if (cond.Is(al)) { 15482 EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15483 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15484 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 15485 return; 15486 } 15487 } 15488 // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 15489 if (dt.Is(F32)) { 15490 if (cond.Is(al)) { 15491 EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 15492 rm.Encode(5, 0)); 15493 return; 15494 } 15495 } 15496 } 15497 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm); 15498 } 15499 15500 void Assembler::vcle(Condition cond, 15501 DataType dt, 15502 DRegister rd, 15503 DRegister rm, 15504 const DOperand& operand) { 15505 VIXL_ASSERT(AllowAssembler()); 15506 CheckIT(cond); 15507 if (operand.IsImmediate()) { 15508 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15509 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15510 Dt_F_size_1 encoded_dt(dt); 15511 if (IsUsingT32()) { 15512 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15513 if (encoded_dt.IsValid() && (imm == 0)) { 15514 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15515 EmitT32_32(0xffb10180U | 15516 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15517 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15518 rd.Encode(22, 12) | rm.Encode(5, 0)); 15519 AdvanceIT(); 15520 return; 15521 } 15522 } 15523 } else { 15524 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15525 if (encoded_dt.IsValid() && (imm == 0)) { 15526 if (cond.Is(al)) { 15527 EmitA32(0xf3b10180U | 15528 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15529 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15530 rd.Encode(22, 12) | rm.Encode(5, 0)); 15531 return; 15532 } 15533 } 15534 } 15535 } 15536 } 15537 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand); 15538 } 15539 15540 void Assembler::vcle(Condition cond, 15541 DataType dt, 15542 QRegister rd, 15543 QRegister rm, 15544 const QOperand& operand) { 15545 VIXL_ASSERT(AllowAssembler()); 15546 CheckIT(cond); 15547 if (operand.IsImmediate()) { 15548 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15549 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15550 Dt_F_size_1 encoded_dt(dt); 15551 if (IsUsingT32()) { 15552 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15553 if (encoded_dt.IsValid() && (imm == 0)) { 15554 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15555 EmitT32_32(0xffb101c0U | 15556 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15557 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15558 rd.Encode(22, 12) | rm.Encode(5, 0)); 15559 AdvanceIT(); 15560 return; 15561 } 15562 } 15563 } else { 15564 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15565 if (encoded_dt.IsValid() && (imm == 0)) { 15566 if (cond.Is(al)) { 15567 EmitA32(0xf3b101c0U | 15568 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15569 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15570 rd.Encode(22, 12) | rm.Encode(5, 0)); 15571 return; 15572 } 15573 } 15574 } 15575 } 15576 } 15577 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand); 15578 } 15579 15580 void Assembler::vcle( 15581 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15582 VIXL_ASSERT(AllowAssembler()); 15583 CheckIT(cond); 15584 Dt_U_size_1 encoded_dt(dt); 15585 if (IsUsingT32()) { 15586 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15587 if (encoded_dt.IsValid()) { 15588 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15589 EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15590 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15591 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15592 AdvanceIT(); 15593 return; 15594 } 15595 } 15596 // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 15597 if (dt.Is(F32)) { 15598 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15599 EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15600 rm.Encode(7, 16)); 15601 AdvanceIT(); 15602 return; 15603 } 15604 } 15605 } else { 15606 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15607 if (encoded_dt.IsValid()) { 15608 if (cond.Is(al)) { 15609 EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15610 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15611 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15612 return; 15613 } 15614 } 15615 // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 15616 if (dt.Is(F32)) { 15617 if (cond.Is(al)) { 15618 EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15619 rm.Encode(7, 16)); 15620 return; 15621 } 15622 } 15623 } 15624 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm); 15625 } 15626 15627 void Assembler::vcle( 15628 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15629 VIXL_ASSERT(AllowAssembler()); 15630 CheckIT(cond); 15631 Dt_U_size_1 encoded_dt(dt); 15632 if (IsUsingT32()) { 15633 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15634 if (encoded_dt.IsValid()) { 15635 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15636 EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15637 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15638 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15639 AdvanceIT(); 15640 return; 15641 } 15642 } 15643 // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 15644 if (dt.Is(F32)) { 15645 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15646 EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15647 rm.Encode(7, 16)); 15648 AdvanceIT(); 15649 return; 15650 } 15651 } 15652 } else { 15653 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15654 if (encoded_dt.IsValid()) { 15655 if (cond.Is(al)) { 15656 EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15657 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15658 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15659 return; 15660 } 15661 } 15662 // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 15663 if (dt.Is(F32)) { 15664 if (cond.Is(al)) { 15665 EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15666 rm.Encode(7, 16)); 15667 return; 15668 } 15669 } 15670 } 15671 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm); 15672 } 15673 15674 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) { 15675 VIXL_ASSERT(AllowAssembler()); 15676 CheckIT(cond); 15677 Dt_size_5 encoded_dt(dt); 15678 if (IsUsingT32()) { 15679 // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 15680 if (encoded_dt.IsValid()) { 15681 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15682 EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) | 15683 rd.Encode(22, 12) | rm.Encode(5, 0)); 15684 AdvanceIT(); 15685 return; 15686 } 15687 } 15688 } else { 15689 // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 15690 if (encoded_dt.IsValid()) { 15691 if (cond.Is(al)) { 15692 EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) | 15693 rd.Encode(22, 12) | rm.Encode(5, 0)); 15694 return; 15695 } 15696 } 15697 } 15698 Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm); 15699 } 15700 15701 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) { 15702 VIXL_ASSERT(AllowAssembler()); 15703 CheckIT(cond); 15704 Dt_size_5 encoded_dt(dt); 15705 if (IsUsingT32()) { 15706 // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 15707 if (encoded_dt.IsValid()) { 15708 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15709 EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) | 15710 rd.Encode(22, 12) | rm.Encode(5, 0)); 15711 AdvanceIT(); 15712 return; 15713 } 15714 } 15715 } else { 15716 // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 15717 if (encoded_dt.IsValid()) { 15718 if (cond.Is(al)) { 15719 EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) | 15720 rd.Encode(22, 12) | rm.Encode(5, 0)); 15721 return; 15722 } 15723 } 15724 } 15725 Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm); 15726 } 15727 15728 void Assembler::vclt(Condition cond, 15729 DataType dt, 15730 DRegister rd, 15731 DRegister rm, 15732 const DOperand& operand) { 15733 VIXL_ASSERT(AllowAssembler()); 15734 CheckIT(cond); 15735 if (operand.IsImmediate()) { 15736 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15737 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15738 Dt_F_size_1 encoded_dt(dt); 15739 if (IsUsingT32()) { 15740 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 15741 if (encoded_dt.IsValid() && (imm == 0)) { 15742 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15743 EmitT32_32(0xffb10200U | 15744 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15745 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15746 rd.Encode(22, 12) | rm.Encode(5, 0)); 15747 AdvanceIT(); 15748 return; 15749 } 15750 } 15751 } else { 15752 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 15753 if (encoded_dt.IsValid() && (imm == 0)) { 15754 if (cond.Is(al)) { 15755 EmitA32(0xf3b10200U | 15756 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15757 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15758 rd.Encode(22, 12) | rm.Encode(5, 0)); 15759 return; 15760 } 15761 } 15762 } 15763 } 15764 } 15765 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand); 15766 } 15767 15768 void Assembler::vclt(Condition cond, 15769 DataType dt, 15770 QRegister rd, 15771 QRegister rm, 15772 const QOperand& operand) { 15773 VIXL_ASSERT(AllowAssembler()); 15774 CheckIT(cond); 15775 if (operand.IsImmediate()) { 15776 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 15777 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 15778 Dt_F_size_1 encoded_dt(dt); 15779 if (IsUsingT32()) { 15780 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 15781 if (encoded_dt.IsValid() && (imm == 0)) { 15782 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15783 EmitT32_32(0xffb10240U | 15784 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15785 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15786 rd.Encode(22, 12) | rm.Encode(5, 0)); 15787 AdvanceIT(); 15788 return; 15789 } 15790 } 15791 } else { 15792 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 15793 if (encoded_dt.IsValid() && (imm == 0)) { 15794 if (cond.Is(al)) { 15795 EmitA32(0xf3b10240U | 15796 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 15797 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 15798 rd.Encode(22, 12) | rm.Encode(5, 0)); 15799 return; 15800 } 15801 } 15802 } 15803 } 15804 } 15805 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand); 15806 } 15807 15808 void Assembler::vclt( 15809 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 15810 VIXL_ASSERT(AllowAssembler()); 15811 CheckIT(cond); 15812 Dt_U_size_1 encoded_dt(dt); 15813 if (IsUsingT32()) { 15814 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 15815 if (encoded_dt.IsValid()) { 15816 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15817 EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15818 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15819 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15820 AdvanceIT(); 15821 return; 15822 } 15823 } 15824 // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 15825 if (dt.Is(F32)) { 15826 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15827 EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15828 rm.Encode(7, 16)); 15829 AdvanceIT(); 15830 return; 15831 } 15832 } 15833 } else { 15834 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 15835 if (encoded_dt.IsValid()) { 15836 if (cond.Is(al)) { 15837 EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15838 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15839 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15840 return; 15841 } 15842 } 15843 // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 15844 if (dt.Is(F32)) { 15845 if (cond.Is(al)) { 15846 EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15847 rm.Encode(7, 16)); 15848 return; 15849 } 15850 } 15851 } 15852 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm); 15853 } 15854 15855 void Assembler::vclt( 15856 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 15857 VIXL_ASSERT(AllowAssembler()); 15858 CheckIT(cond); 15859 Dt_U_size_1 encoded_dt(dt); 15860 if (IsUsingT32()) { 15861 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 15862 if (encoded_dt.IsValid()) { 15863 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15864 EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15865 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 15866 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15867 AdvanceIT(); 15868 return; 15869 } 15870 } 15871 // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 15872 if (dt.Is(F32)) { 15873 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15874 EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15875 rm.Encode(7, 16)); 15876 AdvanceIT(); 15877 return; 15878 } 15879 } 15880 } else { 15881 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 15882 if (encoded_dt.IsValid()) { 15883 if (cond.Is(al)) { 15884 EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 15885 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 15886 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 15887 return; 15888 } 15889 } 15890 // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 15891 if (dt.Is(F32)) { 15892 if (cond.Is(al)) { 15893 EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 15894 rm.Encode(7, 16)); 15895 return; 15896 } 15897 } 15898 } 15899 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm); 15900 } 15901 15902 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) { 15903 VIXL_ASSERT(AllowAssembler()); 15904 CheckIT(cond); 15905 Dt_size_4 encoded_dt(dt); 15906 if (IsUsingT32()) { 15907 // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 15908 if (encoded_dt.IsValid()) { 15909 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15910 EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) | 15911 rd.Encode(22, 12) | rm.Encode(5, 0)); 15912 AdvanceIT(); 15913 return; 15914 } 15915 } 15916 } else { 15917 // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 15918 if (encoded_dt.IsValid()) { 15919 if (cond.Is(al)) { 15920 EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) | 15921 rd.Encode(22, 12) | rm.Encode(5, 0)); 15922 return; 15923 } 15924 } 15925 } 15926 Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm); 15927 } 15928 15929 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) { 15930 VIXL_ASSERT(AllowAssembler()); 15931 CheckIT(cond); 15932 Dt_size_4 encoded_dt(dt); 15933 if (IsUsingT32()) { 15934 // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 15935 if (encoded_dt.IsValid()) { 15936 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15937 EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) | 15938 rd.Encode(22, 12) | rm.Encode(5, 0)); 15939 AdvanceIT(); 15940 return; 15941 } 15942 } 15943 } else { 15944 // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 15945 if (encoded_dt.IsValid()) { 15946 if (cond.Is(al)) { 15947 EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) | 15948 rd.Encode(22, 12) | rm.Encode(5, 0)); 15949 return; 15950 } 15951 } 15952 } 15953 Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm); 15954 } 15955 15956 void Assembler::vcmp(Condition cond, 15957 DataType dt, 15958 SRegister rd, 15959 const SOperand& operand) { 15960 VIXL_ASSERT(AllowAssembler()); 15961 CheckIT(cond); 15962 if (operand.IsRegister()) { 15963 SRegister rm = operand.GetRegister(); 15964 if (IsUsingT32()) { 15965 // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 15966 if (dt.Is(F32)) { 15967 EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15968 AdvanceIT(); 15969 return; 15970 } 15971 } else { 15972 // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 15973 if (dt.Is(F32) && cond.IsNotNever()) { 15974 EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15975 rm.Encode(5, 0)); 15976 return; 15977 } 15978 } 15979 } 15980 if (operand.IsImmediate()) { 15981 if (IsUsingT32()) { 15982 // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2 15983 if (dt.Is(F32) && (operand.IsFloatZero())) { 15984 EmitT32_32(0xeeb50a40U | rd.Encode(22, 12)); 15985 AdvanceIT(); 15986 return; 15987 } 15988 } else { 15989 // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2 15990 if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) { 15991 EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 15992 return; 15993 } 15994 } 15995 } 15996 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand); 15997 } 15998 15999 void Assembler::vcmp(Condition cond, 16000 DataType dt, 16001 DRegister rd, 16002 const DOperand& operand) { 16003 VIXL_ASSERT(AllowAssembler()); 16004 CheckIT(cond); 16005 if (operand.IsRegister()) { 16006 DRegister rm = operand.GetRegister(); 16007 if (IsUsingT32()) { 16008 // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 16009 if (dt.Is(F64)) { 16010 EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16011 AdvanceIT(); 16012 return; 16013 } 16014 } else { 16015 // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 16016 if (dt.Is(F64) && cond.IsNotNever()) { 16017 EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16018 rm.Encode(5, 0)); 16019 return; 16020 } 16021 } 16022 } 16023 if (operand.IsImmediate()) { 16024 if (IsUsingT32()) { 16025 // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2 16026 if (dt.Is(F64) && (operand.IsFloatZero())) { 16027 EmitT32_32(0xeeb50b40U | rd.Encode(22, 12)); 16028 AdvanceIT(); 16029 return; 16030 } 16031 } else { 16032 // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2 16033 if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) { 16034 EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 16035 return; 16036 } 16037 } 16038 } 16039 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand); 16040 } 16041 16042 void Assembler::vcmpe(Condition cond, 16043 DataType dt, 16044 SRegister rd, 16045 const SOperand& operand) { 16046 VIXL_ASSERT(AllowAssembler()); 16047 CheckIT(cond); 16048 if (operand.IsRegister()) { 16049 SRegister rm = operand.GetRegister(); 16050 if (IsUsingT32()) { 16051 // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 16052 if (dt.Is(F32)) { 16053 EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16054 AdvanceIT(); 16055 return; 16056 } 16057 } else { 16058 // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 16059 if (dt.Is(F32) && cond.IsNotNever()) { 16060 EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16061 rm.Encode(5, 0)); 16062 return; 16063 } 16064 } 16065 } 16066 if (operand.IsImmediate()) { 16067 if (IsUsingT32()) { 16068 // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2 16069 if (dt.Is(F32) && (operand.IsFloatZero())) { 16070 EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12)); 16071 AdvanceIT(); 16072 return; 16073 } 16074 } else { 16075 // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2 16076 if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) { 16077 EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 16078 return; 16079 } 16080 } 16081 } 16082 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand); 16083 } 16084 16085 void Assembler::vcmpe(Condition cond, 16086 DataType dt, 16087 DRegister rd, 16088 const DOperand& operand) { 16089 VIXL_ASSERT(AllowAssembler()); 16090 CheckIT(cond); 16091 if (operand.IsRegister()) { 16092 DRegister rm = operand.GetRegister(); 16093 if (IsUsingT32()) { 16094 // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 16095 if (dt.Is(F64)) { 16096 EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16097 AdvanceIT(); 16098 return; 16099 } 16100 } else { 16101 // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 16102 if (dt.Is(F64) && cond.IsNotNever()) { 16103 EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16104 rm.Encode(5, 0)); 16105 return; 16106 } 16107 } 16108 } 16109 if (operand.IsImmediate()) { 16110 if (IsUsingT32()) { 16111 // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2 16112 if (dt.Is(F64) && (operand.IsFloatZero())) { 16113 EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12)); 16114 AdvanceIT(); 16115 return; 16116 } 16117 } else { 16118 // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2 16119 if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) { 16120 EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 16121 return; 16122 } 16123 } 16124 } 16125 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand); 16126 } 16127 16128 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) { 16129 VIXL_ASSERT(AllowAssembler()); 16130 CheckIT(cond); 16131 if (IsUsingT32()) { 16132 // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1 16133 if (dt.Is(Untyped8)) { 16134 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16135 EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16136 AdvanceIT(); 16137 return; 16138 } 16139 } 16140 } else { 16141 // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1 16142 if (dt.Is(Untyped8)) { 16143 if (cond.Is(al)) { 16144 EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16145 return; 16146 } 16147 } 16148 } 16149 Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm); 16150 } 16151 16152 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) { 16153 VIXL_ASSERT(AllowAssembler()); 16154 CheckIT(cond); 16155 if (IsUsingT32()) { 16156 // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1 16157 if (dt.Is(Untyped8)) { 16158 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16159 EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16160 AdvanceIT(); 16161 return; 16162 } 16163 } 16164 } else { 16165 // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1 16166 if (dt.Is(Untyped8)) { 16167 if (cond.Is(al)) { 16168 EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16169 return; 16170 } 16171 } 16172 } 16173 Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm); 16174 } 16175 16176 void Assembler::vcvt( 16177 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 16178 VIXL_ASSERT(AllowAssembler()); 16179 CheckIT(cond); 16180 Dt_op_2 encoded_dt(dt2); 16181 if (IsUsingT32()) { 16182 // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1 16183 if (dt1.Is(F64) && dt2.Is(F32)) { 16184 EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16185 AdvanceIT(); 16186 return; 16187 } 16188 // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1 16189 if (dt1.Is(F64) && encoded_dt.IsValid()) { 16190 EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) | 16191 rd.Encode(22, 12) | rm.Encode(5, 0)); 16192 AdvanceIT(); 16193 return; 16194 } 16195 } else { 16196 // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1 16197 if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) { 16198 EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16199 rm.Encode(5, 0)); 16200 return; 16201 } 16202 // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1 16203 if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) { 16204 EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) | 16205 (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) | 16206 rm.Encode(5, 0)); 16207 return; 16208 } 16209 } 16210 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16211 } 16212 16213 void Assembler::vcvt( 16214 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16215 VIXL_ASSERT(AllowAssembler()); 16216 CheckIT(cond); 16217 if (IsUsingT32()) { 16218 // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1 16219 if (dt1.Is(F32) && dt2.Is(F64)) { 16220 EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16221 AdvanceIT(); 16222 return; 16223 } 16224 // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1 16225 if (dt1.Is(U32) && dt2.Is(F64)) { 16226 EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16227 AdvanceIT(); 16228 return; 16229 } 16230 // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1 16231 if (dt1.Is(S32) && dt2.Is(F64)) { 16232 EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16233 AdvanceIT(); 16234 return; 16235 } 16236 } else { 16237 // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1 16238 if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) { 16239 EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16240 rm.Encode(5, 0)); 16241 return; 16242 } 16243 // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1 16244 if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) { 16245 EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16246 rm.Encode(5, 0)); 16247 return; 16248 } 16249 // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1 16250 if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) { 16251 EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16252 rm.Encode(5, 0)); 16253 return; 16254 } 16255 } 16256 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16257 } 16258 16259 void Assembler::vcvt(Condition cond, 16260 DataType dt1, 16261 DataType dt2, 16262 DRegister rd, 16263 DRegister rm, 16264 int32_t fbits) { 16265 VIXL_ASSERT(AllowAssembler()); 16266 CheckIT(cond); 16267 Dt_op_U_1 encoded_dt(dt1, dt2); 16268 Dt_U_sx_1 encoded_dt_2(dt2); 16269 Dt_U_sx_1 encoded_dt_3(dt1); 16270 if (IsUsingT32()) { 16271 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1 16272 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 16273 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16274 uint32_t fbits_ = 64 - fbits; 16275 EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) | 16276 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 16277 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 16278 AdvanceIT(); 16279 return; 16280 } 16281 } 16282 // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1 16283 if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) && 16284 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 16285 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 16286 unsigned offset = 32; 16287 if (dt2.Is(S16) || dt2.Is(U16)) { 16288 offset = 16; 16289 } 16290 uint32_t fbits_ = offset - fbits; 16291 EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 16292 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 16293 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16294 ((fbits_ & 0x1e) >> 1)); 16295 AdvanceIT(); 16296 return; 16297 } 16298 // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1 16299 if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) && 16300 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 16301 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 16302 unsigned offset = 32; 16303 if (dt1.Is(S16) || dt1.Is(U16)) { 16304 offset = 16; 16305 } 16306 uint32_t fbits_ = offset - fbits; 16307 EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) | 16308 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) | 16309 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16310 ((fbits_ & 0x1e) >> 1)); 16311 AdvanceIT(); 16312 return; 16313 } 16314 } else { 16315 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1 16316 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 16317 if (cond.Is(al)) { 16318 uint32_t fbits_ = 64 - fbits; 16319 EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) | 16320 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 16321 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 16322 return; 16323 } 16324 } 16325 // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1 16326 if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) && 16327 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 16328 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 16329 cond.IsNotNever()) { 16330 unsigned offset = 32; 16331 if (dt2.Is(S16) || dt2.Is(U16)) { 16332 offset = 16; 16333 } 16334 uint32_t fbits_ = offset - fbits; 16335 EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) | 16336 ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 16337 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 16338 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16339 ((fbits_ & 0x1e) >> 1)); 16340 return; 16341 } 16342 // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1 16343 if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) && 16344 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 16345 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 16346 cond.IsNotNever()) { 16347 unsigned offset = 32; 16348 if (dt1.Is(S16) || dt1.Is(U16)) { 16349 offset = 16; 16350 } 16351 uint32_t fbits_ = offset - fbits; 16352 EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) | 16353 ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) | 16354 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) | 16355 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16356 ((fbits_ & 0x1e) >> 1)); 16357 return; 16358 } 16359 } 16360 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 16361 } 16362 16363 void Assembler::vcvt(Condition cond, 16364 DataType dt1, 16365 DataType dt2, 16366 QRegister rd, 16367 QRegister rm, 16368 int32_t fbits) { 16369 VIXL_ASSERT(AllowAssembler()); 16370 CheckIT(cond); 16371 Dt_op_U_1 encoded_dt(dt1, dt2); 16372 if (IsUsingT32()) { 16373 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1 16374 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 16375 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16376 uint32_t fbits_ = 64 - fbits; 16377 EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) | 16378 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 16379 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 16380 AdvanceIT(); 16381 return; 16382 } 16383 } 16384 } else { 16385 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1 16386 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 16387 if (cond.Is(al)) { 16388 uint32_t fbits_ = 64 - fbits; 16389 EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) | 16390 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 16391 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 16392 return; 16393 } 16394 } 16395 } 16396 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 16397 } 16398 16399 void Assembler::vcvt(Condition cond, 16400 DataType dt1, 16401 DataType dt2, 16402 SRegister rd, 16403 SRegister rm, 16404 int32_t fbits) { 16405 VIXL_ASSERT(AllowAssembler()); 16406 CheckIT(cond); 16407 Dt_U_sx_1 encoded_dt(dt2); 16408 Dt_U_sx_1 encoded_dt_2(dt1); 16409 if (IsUsingT32()) { 16410 // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1 16411 if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) && 16412 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 16413 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 16414 unsigned offset = 32; 16415 if (dt2.Is(S16) || dt2.Is(U16)) { 16416 offset = 16; 16417 } 16418 uint32_t fbits_ = offset - fbits; 16419 EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) | 16420 ((encoded_dt.GetEncodingValue() & 0x2) << 15) | 16421 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16422 ((fbits_ & 0x1e) >> 1)); 16423 AdvanceIT(); 16424 return; 16425 } 16426 // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1 16427 if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) && 16428 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 16429 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 16430 unsigned offset = 32; 16431 if (dt1.Is(S16) || dt1.Is(U16)) { 16432 offset = 16; 16433 } 16434 uint32_t fbits_ = offset - fbits; 16435 EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 16436 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 16437 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16438 ((fbits_ & 0x1e) >> 1)); 16439 AdvanceIT(); 16440 return; 16441 } 16442 } else { 16443 // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1 16444 if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) && 16445 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 16446 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 16447 cond.IsNotNever()) { 16448 unsigned offset = 32; 16449 if (dt2.Is(S16) || dt2.Is(U16)) { 16450 offset = 16; 16451 } 16452 uint32_t fbits_ = offset - fbits; 16453 EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) | 16454 ((encoded_dt.GetEncodingValue() & 0x1) << 7) | 16455 ((encoded_dt.GetEncodingValue() & 0x2) << 15) | 16456 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16457 ((fbits_ & 0x1e) >> 1)); 16458 return; 16459 } 16460 // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1 16461 if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) && 16462 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 16463 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 16464 cond.IsNotNever()) { 16465 unsigned offset = 32; 16466 if (dt1.Is(S16) || dt1.Is(U16)) { 16467 offset = 16; 16468 } 16469 uint32_t fbits_ = offset - fbits; 16470 EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) | 16471 ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 16472 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 16473 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 16474 ((fbits_ & 0x1e) >> 1)); 16475 return; 16476 } 16477 } 16478 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 16479 } 16480 16481 void Assembler::vcvt( 16482 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16483 VIXL_ASSERT(AllowAssembler()); 16484 CheckIT(cond); 16485 Dt_op_1 encoded_dt(dt1, dt2); 16486 if (IsUsingT32()) { 16487 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1 16488 if (encoded_dt.IsValid()) { 16489 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16490 EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) | 16491 rd.Encode(22, 12) | rm.Encode(5, 0)); 16492 AdvanceIT(); 16493 return; 16494 } 16495 } 16496 } else { 16497 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1 16498 if (encoded_dt.IsValid()) { 16499 if (cond.Is(al)) { 16500 EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) | 16501 rd.Encode(22, 12) | rm.Encode(5, 0)); 16502 return; 16503 } 16504 } 16505 } 16506 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16507 } 16508 16509 void Assembler::vcvt( 16510 Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 16511 VIXL_ASSERT(AllowAssembler()); 16512 CheckIT(cond); 16513 Dt_op_1 encoded_dt(dt1, dt2); 16514 if (IsUsingT32()) { 16515 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1 16516 if (encoded_dt.IsValid()) { 16517 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16518 EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) | 16519 rd.Encode(22, 12) | rm.Encode(5, 0)); 16520 AdvanceIT(); 16521 return; 16522 } 16523 } 16524 } else { 16525 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1 16526 if (encoded_dt.IsValid()) { 16527 if (cond.Is(al)) { 16528 EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) | 16529 rd.Encode(22, 12) | rm.Encode(5, 0)); 16530 return; 16531 } 16532 } 16533 } 16534 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16535 } 16536 16537 void Assembler::vcvt( 16538 Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) { 16539 VIXL_ASSERT(AllowAssembler()); 16540 CheckIT(cond); 16541 if (IsUsingT32()) { 16542 // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1 16543 if (dt1.Is(F16) && dt2.Is(F32)) { 16544 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16545 EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16546 AdvanceIT(); 16547 return; 16548 } 16549 } 16550 } else { 16551 // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1 16552 if (dt1.Is(F16) && dt2.Is(F32)) { 16553 if (cond.Is(al)) { 16554 EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16555 return; 16556 } 16557 } 16558 } 16559 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16560 } 16561 16562 void Assembler::vcvt( 16563 Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) { 16564 VIXL_ASSERT(AllowAssembler()); 16565 CheckIT(cond); 16566 if (IsUsingT32()) { 16567 // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1 16568 if (dt1.Is(F32) && dt2.Is(F16)) { 16569 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16570 EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16571 AdvanceIT(); 16572 return; 16573 } 16574 } 16575 } else { 16576 // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1 16577 if (dt1.Is(F32) && dt2.Is(F16)) { 16578 if (cond.Is(al)) { 16579 EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16580 return; 16581 } 16582 } 16583 } 16584 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16585 } 16586 16587 void Assembler::vcvt( 16588 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16589 VIXL_ASSERT(AllowAssembler()); 16590 CheckIT(cond); 16591 Dt_op_2 encoded_dt(dt2); 16592 if (IsUsingT32()) { 16593 // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1 16594 if (dt1.Is(U32) && dt2.Is(F32)) { 16595 EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16596 AdvanceIT(); 16597 return; 16598 } 16599 // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1 16600 if (dt1.Is(S32) && dt2.Is(F32)) { 16601 EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16602 AdvanceIT(); 16603 return; 16604 } 16605 // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1 16606 if (dt1.Is(F32) && encoded_dt.IsValid()) { 16607 EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) | 16608 rd.Encode(22, 12) | rm.Encode(5, 0)); 16609 AdvanceIT(); 16610 return; 16611 } 16612 } else { 16613 // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1 16614 if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) { 16615 EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16616 rm.Encode(5, 0)); 16617 return; 16618 } 16619 // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1 16620 if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) { 16621 EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16622 rm.Encode(5, 0)); 16623 return; 16624 } 16625 // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1 16626 if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) { 16627 EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) | 16628 (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) | 16629 rm.Encode(5, 0)); 16630 return; 16631 } 16632 } 16633 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 16634 } 16635 16636 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16637 VIXL_ASSERT(AllowAssembler()); 16638 CheckIT(al); 16639 Dt_op_3 encoded_dt(dt1); 16640 if (IsUsingT32()) { 16641 // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 16642 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16643 EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) | 16644 rd.Encode(22, 12) | rm.Encode(5, 0)); 16645 AdvanceIT(); 16646 return; 16647 } 16648 } else { 16649 // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 16650 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16651 EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) | 16652 rd.Encode(22, 12) | rm.Encode(5, 0)); 16653 return; 16654 } 16655 } 16656 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 16657 } 16658 16659 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 16660 VIXL_ASSERT(AllowAssembler()); 16661 CheckIT(al); 16662 Dt_op_3 encoded_dt(dt1); 16663 if (IsUsingT32()) { 16664 // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 16665 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16666 EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) | 16667 rd.Encode(22, 12) | rm.Encode(5, 0)); 16668 AdvanceIT(); 16669 return; 16670 } 16671 } else { 16672 // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 16673 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16674 EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) | 16675 rd.Encode(22, 12) | rm.Encode(5, 0)); 16676 return; 16677 } 16678 } 16679 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 16680 } 16681 16682 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16683 VIXL_ASSERT(AllowAssembler()); 16684 CheckIT(al); 16685 Dt_op_2 encoded_dt(dt1); 16686 if (IsUsingT32()) { 16687 // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 16688 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16689 EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) | 16690 rd.Encode(22, 12) | rm.Encode(5, 0)); 16691 AdvanceIT(); 16692 return; 16693 } 16694 } else { 16695 // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 16696 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16697 EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) | 16698 rd.Encode(22, 12) | rm.Encode(5, 0)); 16699 return; 16700 } 16701 } 16702 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 16703 } 16704 16705 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16706 VIXL_ASSERT(AllowAssembler()); 16707 CheckIT(al); 16708 Dt_op_2 encoded_dt(dt1); 16709 if (IsUsingT32()) { 16710 // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 16711 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16712 EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) | 16713 rd.Encode(22, 12) | rm.Encode(5, 0)); 16714 AdvanceIT(); 16715 return; 16716 } 16717 } else { 16718 // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 16719 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16720 EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) | 16721 rd.Encode(22, 12) | rm.Encode(5, 0)); 16722 return; 16723 } 16724 } 16725 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 16726 } 16727 16728 void Assembler::vcvtb( 16729 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16730 VIXL_ASSERT(AllowAssembler()); 16731 CheckIT(cond); 16732 if (IsUsingT32()) { 16733 // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1 16734 if (dt1.Is(F32) && dt2.Is(F16)) { 16735 EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16736 AdvanceIT(); 16737 return; 16738 } 16739 // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1 16740 if (dt1.Is(F16) && dt2.Is(F32)) { 16741 EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16742 AdvanceIT(); 16743 return; 16744 } 16745 } else { 16746 // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1 16747 if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) { 16748 EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16749 rm.Encode(5, 0)); 16750 return; 16751 } 16752 // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1 16753 if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) { 16754 EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16755 rm.Encode(5, 0)); 16756 return; 16757 } 16758 } 16759 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 16760 } 16761 16762 void Assembler::vcvtb( 16763 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 16764 VIXL_ASSERT(AllowAssembler()); 16765 CheckIT(cond); 16766 if (IsUsingT32()) { 16767 // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1 16768 if (dt1.Is(F64) && dt2.Is(F16)) { 16769 EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16770 AdvanceIT(); 16771 return; 16772 } 16773 } else { 16774 // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1 16775 if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) { 16776 EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16777 rm.Encode(5, 0)); 16778 return; 16779 } 16780 } 16781 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 16782 } 16783 16784 void Assembler::vcvtb( 16785 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16786 VIXL_ASSERT(AllowAssembler()); 16787 CheckIT(cond); 16788 if (IsUsingT32()) { 16789 // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1 16790 if (dt1.Is(F16) && dt2.Is(F64)) { 16791 EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16792 AdvanceIT(); 16793 return; 16794 } 16795 } else { 16796 // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1 16797 if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) { 16798 EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16799 rm.Encode(5, 0)); 16800 return; 16801 } 16802 } 16803 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 16804 } 16805 16806 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16807 VIXL_ASSERT(AllowAssembler()); 16808 CheckIT(al); 16809 Dt_op_3 encoded_dt(dt1); 16810 if (IsUsingT32()) { 16811 // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 16812 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16813 EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) | 16814 rd.Encode(22, 12) | rm.Encode(5, 0)); 16815 AdvanceIT(); 16816 return; 16817 } 16818 } else { 16819 // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 16820 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16821 EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) | 16822 rd.Encode(22, 12) | rm.Encode(5, 0)); 16823 return; 16824 } 16825 } 16826 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 16827 } 16828 16829 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 16830 VIXL_ASSERT(AllowAssembler()); 16831 CheckIT(al); 16832 Dt_op_3 encoded_dt(dt1); 16833 if (IsUsingT32()) { 16834 // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 16835 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16836 EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) | 16837 rd.Encode(22, 12) | rm.Encode(5, 0)); 16838 AdvanceIT(); 16839 return; 16840 } 16841 } else { 16842 // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 16843 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16844 EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) | 16845 rd.Encode(22, 12) | rm.Encode(5, 0)); 16846 return; 16847 } 16848 } 16849 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 16850 } 16851 16852 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16853 VIXL_ASSERT(AllowAssembler()); 16854 CheckIT(al); 16855 Dt_op_2 encoded_dt(dt1); 16856 if (IsUsingT32()) { 16857 // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 16858 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16859 EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) | 16860 rd.Encode(22, 12) | rm.Encode(5, 0)); 16861 AdvanceIT(); 16862 return; 16863 } 16864 } else { 16865 // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 16866 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16867 EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) | 16868 rd.Encode(22, 12) | rm.Encode(5, 0)); 16869 return; 16870 } 16871 } 16872 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 16873 } 16874 16875 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16876 VIXL_ASSERT(AllowAssembler()); 16877 CheckIT(al); 16878 Dt_op_2 encoded_dt(dt1); 16879 if (IsUsingT32()) { 16880 // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 16881 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16882 EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) | 16883 rd.Encode(22, 12) | rm.Encode(5, 0)); 16884 AdvanceIT(); 16885 return; 16886 } 16887 } else { 16888 // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 16889 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16890 EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) | 16891 rd.Encode(22, 12) | rm.Encode(5, 0)); 16892 return; 16893 } 16894 } 16895 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 16896 } 16897 16898 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16899 VIXL_ASSERT(AllowAssembler()); 16900 CheckIT(al); 16901 Dt_op_3 encoded_dt(dt1); 16902 if (IsUsingT32()) { 16903 // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 16904 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16905 EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) | 16906 rd.Encode(22, 12) | rm.Encode(5, 0)); 16907 AdvanceIT(); 16908 return; 16909 } 16910 } else { 16911 // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 16912 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16913 EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) | 16914 rd.Encode(22, 12) | rm.Encode(5, 0)); 16915 return; 16916 } 16917 } 16918 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 16919 } 16920 16921 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 16922 VIXL_ASSERT(AllowAssembler()); 16923 CheckIT(al); 16924 Dt_op_3 encoded_dt(dt1); 16925 if (IsUsingT32()) { 16926 // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 16927 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16928 EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) | 16929 rd.Encode(22, 12) | rm.Encode(5, 0)); 16930 AdvanceIT(); 16931 return; 16932 } 16933 } else { 16934 // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 16935 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16936 EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) | 16937 rd.Encode(22, 12) | rm.Encode(5, 0)); 16938 return; 16939 } 16940 } 16941 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 16942 } 16943 16944 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16945 VIXL_ASSERT(AllowAssembler()); 16946 CheckIT(al); 16947 Dt_op_2 encoded_dt(dt1); 16948 if (IsUsingT32()) { 16949 // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 16950 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16951 EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) | 16952 rd.Encode(22, 12) | rm.Encode(5, 0)); 16953 AdvanceIT(); 16954 return; 16955 } 16956 } else { 16957 // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 16958 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16959 EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) | 16960 rd.Encode(22, 12) | rm.Encode(5, 0)); 16961 return; 16962 } 16963 } 16964 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 16965 } 16966 16967 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16968 VIXL_ASSERT(AllowAssembler()); 16969 CheckIT(al); 16970 Dt_op_2 encoded_dt(dt1); 16971 if (IsUsingT32()) { 16972 // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 16973 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16974 EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) | 16975 rd.Encode(22, 12) | rm.Encode(5, 0)); 16976 AdvanceIT(); 16977 return; 16978 } 16979 } else { 16980 // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 16981 if (encoded_dt.IsValid() && dt2.Is(F64)) { 16982 EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) | 16983 rd.Encode(22, 12) | rm.Encode(5, 0)); 16984 return; 16985 } 16986 } 16987 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 16988 } 16989 16990 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 16991 VIXL_ASSERT(AllowAssembler()); 16992 CheckIT(al); 16993 Dt_op_3 encoded_dt(dt1); 16994 if (IsUsingT32()) { 16995 // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 16996 if (encoded_dt.IsValid() && dt2.Is(F32)) { 16997 EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) | 16998 rd.Encode(22, 12) | rm.Encode(5, 0)); 16999 AdvanceIT(); 17000 return; 17001 } 17002 } else { 17003 // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 17004 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17005 EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) | 17006 rd.Encode(22, 12) | rm.Encode(5, 0)); 17007 return; 17008 } 17009 } 17010 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 17011 } 17012 17013 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 17014 VIXL_ASSERT(AllowAssembler()); 17015 CheckIT(al); 17016 Dt_op_3 encoded_dt(dt1); 17017 if (IsUsingT32()) { 17018 // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 17019 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17020 EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) | 17021 rd.Encode(22, 12) | rm.Encode(5, 0)); 17022 AdvanceIT(); 17023 return; 17024 } 17025 } else { 17026 // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 17027 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17028 EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) | 17029 rd.Encode(22, 12) | rm.Encode(5, 0)); 17030 return; 17031 } 17032 } 17033 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 17034 } 17035 17036 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 17037 VIXL_ASSERT(AllowAssembler()); 17038 CheckIT(al); 17039 Dt_op_2 encoded_dt(dt1); 17040 if (IsUsingT32()) { 17041 // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 17042 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17043 EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) | 17044 rd.Encode(22, 12) | rm.Encode(5, 0)); 17045 AdvanceIT(); 17046 return; 17047 } 17048 } else { 17049 // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 17050 if (encoded_dt.IsValid() && dt2.Is(F32)) { 17051 EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) | 17052 rd.Encode(22, 12) | rm.Encode(5, 0)); 17053 return; 17054 } 17055 } 17056 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 17057 } 17058 17059 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 17060 VIXL_ASSERT(AllowAssembler()); 17061 CheckIT(al); 17062 Dt_op_2 encoded_dt(dt1); 17063 if (IsUsingT32()) { 17064 // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 17065 if (encoded_dt.IsValid() && dt2.Is(F64)) { 17066 EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) | 17067 rd.Encode(22, 12) | rm.Encode(5, 0)); 17068 AdvanceIT(); 17069 return; 17070 } 17071 } else { 17072 // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 17073 if (encoded_dt.IsValid() && dt2.Is(F64)) { 17074 EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) | 17075 rd.Encode(22, 12) | rm.Encode(5, 0)); 17076 return; 17077 } 17078 } 17079 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 17080 } 17081 17082 void Assembler::vcvtr( 17083 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 17084 VIXL_ASSERT(AllowAssembler()); 17085 CheckIT(cond); 17086 if (IsUsingT32()) { 17087 // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1 17088 if (dt1.Is(U32) && dt2.Is(F32)) { 17089 EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17090 AdvanceIT(); 17091 return; 17092 } 17093 // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1 17094 if (dt1.Is(S32) && dt2.Is(F32)) { 17095 EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17096 AdvanceIT(); 17097 return; 17098 } 17099 } else { 17100 // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1 17101 if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) { 17102 EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17103 rm.Encode(5, 0)); 17104 return; 17105 } 17106 // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1 17107 if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) { 17108 EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17109 rm.Encode(5, 0)); 17110 return; 17111 } 17112 } 17113 Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm); 17114 } 17115 17116 void Assembler::vcvtr( 17117 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 17118 VIXL_ASSERT(AllowAssembler()); 17119 CheckIT(cond); 17120 if (IsUsingT32()) { 17121 // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1 17122 if (dt1.Is(U32) && dt2.Is(F64)) { 17123 EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17124 AdvanceIT(); 17125 return; 17126 } 17127 // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1 17128 if (dt1.Is(S32) && dt2.Is(F64)) { 17129 EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17130 AdvanceIT(); 17131 return; 17132 } 17133 } else { 17134 // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1 17135 if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) { 17136 EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17137 rm.Encode(5, 0)); 17138 return; 17139 } 17140 // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1 17141 if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) { 17142 EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17143 rm.Encode(5, 0)); 17144 return; 17145 } 17146 } 17147 Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm); 17148 } 17149 17150 void Assembler::vcvtt( 17151 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 17152 VIXL_ASSERT(AllowAssembler()); 17153 CheckIT(cond); 17154 if (IsUsingT32()) { 17155 // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1 17156 if (dt1.Is(F32) && dt2.Is(F16)) { 17157 EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17158 AdvanceIT(); 17159 return; 17160 } 17161 // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1 17162 if (dt1.Is(F16) && dt2.Is(F32)) { 17163 EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17164 AdvanceIT(); 17165 return; 17166 } 17167 } else { 17168 // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1 17169 if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) { 17170 EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17171 rm.Encode(5, 0)); 17172 return; 17173 } 17174 // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1 17175 if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) { 17176 EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17177 rm.Encode(5, 0)); 17178 return; 17179 } 17180 } 17181 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 17182 } 17183 17184 void Assembler::vcvtt( 17185 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 17186 VIXL_ASSERT(AllowAssembler()); 17187 CheckIT(cond); 17188 if (IsUsingT32()) { 17189 // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1 17190 if (dt1.Is(F64) && dt2.Is(F16)) { 17191 EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17192 AdvanceIT(); 17193 return; 17194 } 17195 } else { 17196 // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1 17197 if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) { 17198 EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17199 rm.Encode(5, 0)); 17200 return; 17201 } 17202 } 17203 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 17204 } 17205 17206 void Assembler::vcvtt( 17207 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 17208 VIXL_ASSERT(AllowAssembler()); 17209 CheckIT(cond); 17210 if (IsUsingT32()) { 17211 // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1 17212 if (dt1.Is(F16) && dt2.Is(F64)) { 17213 EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 17214 AdvanceIT(); 17215 return; 17216 } 17217 } else { 17218 // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1 17219 if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) { 17220 EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17221 rm.Encode(5, 0)); 17222 return; 17223 } 17224 } 17225 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 17226 } 17227 17228 void Assembler::vdiv( 17229 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17230 VIXL_ASSERT(AllowAssembler()); 17231 CheckIT(cond); 17232 if (IsUsingT32()) { 17233 // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1 17234 if (dt.Is(F32)) { 17235 EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17236 rm.Encode(5, 0)); 17237 AdvanceIT(); 17238 return; 17239 } 17240 } else { 17241 // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1 17242 if (dt.Is(F32) && cond.IsNotNever()) { 17243 EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17244 rn.Encode(7, 16) | rm.Encode(5, 0)); 17245 return; 17246 } 17247 } 17248 Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm); 17249 } 17250 17251 void Assembler::vdiv( 17252 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17253 VIXL_ASSERT(AllowAssembler()); 17254 CheckIT(cond); 17255 if (IsUsingT32()) { 17256 // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1 17257 if (dt.Is(F64)) { 17258 EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17259 rm.Encode(5, 0)); 17260 AdvanceIT(); 17261 return; 17262 } 17263 } else { 17264 // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1 17265 if (dt.Is(F64) && cond.IsNotNever()) { 17266 EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17267 rn.Encode(7, 16) | rm.Encode(5, 0)); 17268 return; 17269 } 17270 } 17271 Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm); 17272 } 17273 17274 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) { 17275 VIXL_ASSERT(AllowAssembler()); 17276 CheckIT(cond); 17277 Dt_B_E_1 encoded_dt(dt); 17278 if (IsUsingT32()) { 17279 // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1 17280 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) { 17281 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17282 EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 17283 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 17284 rd.Encode(7, 16) | (rt.GetCode() << 12)); 17285 AdvanceIT(); 17286 return; 17287 } 17288 } 17289 } else { 17290 // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1 17291 if (encoded_dt.IsValid() && cond.IsNotNever() && 17292 (!rt.IsPC() || AllowUnpredictable())) { 17293 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17294 EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) | 17295 ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 17296 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 17297 rd.Encode(7, 16) | (rt.GetCode() << 12)); 17298 return; 17299 } 17300 } 17301 } 17302 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt); 17303 } 17304 17305 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) { 17306 VIXL_ASSERT(AllowAssembler()); 17307 CheckIT(cond); 17308 Dt_B_E_1 encoded_dt(dt); 17309 if (IsUsingT32()) { 17310 // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1 17311 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) { 17312 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17313 EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 17314 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 17315 rd.Encode(7, 16) | (rt.GetCode() << 12)); 17316 AdvanceIT(); 17317 return; 17318 } 17319 } 17320 } else { 17321 // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1 17322 if (encoded_dt.IsValid() && cond.IsNotNever() && 17323 (!rt.IsPC() || AllowUnpredictable())) { 17324 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17325 EmitA32(0x0e800b10U | (cond.GetCondition() << 28) | 17326 ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 17327 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 17328 rd.Encode(7, 16) | (rt.GetCode() << 12)); 17329 return; 17330 } 17331 } 17332 } 17333 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt); 17334 } 17335 17336 void Assembler::vdup(Condition cond, 17337 DataType dt, 17338 DRegister rd, 17339 DRegisterLane rm) { 17340 VIXL_ASSERT(AllowAssembler()); 17341 CheckIT(cond); 17342 Dt_imm4_1 encoded_dt(dt, rm); 17343 if (IsUsingT32()) { 17344 // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1 17345 if (encoded_dt.IsValid()) { 17346 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17347 EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) | 17348 rd.Encode(22, 12) | rm.Encode(5, 0)); 17349 AdvanceIT(); 17350 return; 17351 } 17352 } 17353 } else { 17354 // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1 17355 if (encoded_dt.IsValid()) { 17356 if (cond.Is(al)) { 17357 EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) | 17358 rd.Encode(22, 12) | rm.Encode(5, 0)); 17359 return; 17360 } 17361 } 17362 } 17363 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm); 17364 } 17365 17366 void Assembler::vdup(Condition cond, 17367 DataType dt, 17368 QRegister rd, 17369 DRegisterLane rm) { 17370 VIXL_ASSERT(AllowAssembler()); 17371 CheckIT(cond); 17372 Dt_imm4_1 encoded_dt(dt, rm); 17373 if (IsUsingT32()) { 17374 // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1 17375 if (encoded_dt.IsValid()) { 17376 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17377 EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) | 17378 rd.Encode(22, 12) | rm.Encode(5, 0)); 17379 AdvanceIT(); 17380 return; 17381 } 17382 } 17383 } else { 17384 // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1 17385 if (encoded_dt.IsValid()) { 17386 if (cond.Is(al)) { 17387 EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) | 17388 rd.Encode(22, 12) | rm.Encode(5, 0)); 17389 return; 17390 } 17391 } 17392 } 17393 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm); 17394 } 17395 17396 void Assembler::veor( 17397 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17398 VIXL_ASSERT(AllowAssembler()); 17399 CheckIT(cond); 17400 USE(dt); 17401 if (IsUsingT32()) { 17402 // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 17403 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17404 EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17405 rm.Encode(5, 0)); 17406 AdvanceIT(); 17407 return; 17408 } 17409 } else { 17410 // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 17411 if (cond.Is(al)) { 17412 EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17413 rm.Encode(5, 0)); 17414 return; 17415 } 17416 } 17417 Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm); 17418 } 17419 17420 void Assembler::veor( 17421 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17422 VIXL_ASSERT(AllowAssembler()); 17423 CheckIT(cond); 17424 USE(dt); 17425 if (IsUsingT32()) { 17426 // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 17427 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17428 EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17429 rm.Encode(5, 0)); 17430 AdvanceIT(); 17431 return; 17432 } 17433 } else { 17434 // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 17435 if (cond.Is(al)) { 17436 EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17437 rm.Encode(5, 0)); 17438 return; 17439 } 17440 } 17441 Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm); 17442 } 17443 17444 void Assembler::vext(Condition cond, 17445 DataType dt, 17446 DRegister rd, 17447 DRegister rn, 17448 DRegister rm, 17449 const DOperand& operand) { 17450 VIXL_ASSERT(AllowAssembler()); 17451 CheckIT(cond); 17452 if (operand.IsImmediate()) { 17453 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 17454 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 17455 if (IsUsingT32()) { 17456 // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1 17457 if (dt.Is(Untyped8) && (imm <= 7)) { 17458 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17459 EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17460 rm.Encode(5, 0) | (imm << 8)); 17461 AdvanceIT(); 17462 return; 17463 } 17464 } 17465 // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1 17466 if ((dt.Is(Untyped16) || dt.Is(Untyped32)) && 17467 (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 17468 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17469 uint32_t imm4 = imm / dt.GetSize(); 17470 EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17471 rm.Encode(5, 0) | (imm4 << 8)); 17472 AdvanceIT(); 17473 return; 17474 } 17475 } 17476 } else { 17477 // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1 17478 if (dt.Is(Untyped8) && (imm <= 7)) { 17479 if (cond.Is(al)) { 17480 EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17481 rm.Encode(5, 0) | (imm << 8)); 17482 return; 17483 } 17484 } 17485 // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1 17486 if ((dt.Is(Untyped16) || dt.Is(Untyped32)) && 17487 (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 17488 if (cond.Is(al)) { 17489 uint32_t imm4 = imm / dt.GetSize(); 17490 EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17491 rm.Encode(5, 0) | (imm4 << 8)); 17492 return; 17493 } 17494 } 17495 } 17496 } 17497 } 17498 Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand); 17499 } 17500 17501 void Assembler::vext(Condition cond, 17502 DataType dt, 17503 QRegister rd, 17504 QRegister rn, 17505 QRegister rm, 17506 const QOperand& operand) { 17507 VIXL_ASSERT(AllowAssembler()); 17508 CheckIT(cond); 17509 if (operand.IsImmediate()) { 17510 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 17511 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 17512 if (IsUsingT32()) { 17513 // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1 17514 if (dt.Is(Untyped8) && (imm <= 15)) { 17515 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17516 EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17517 rm.Encode(5, 0) | (imm << 8)); 17518 AdvanceIT(); 17519 return; 17520 } 17521 } 17522 // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1 17523 if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) && 17524 (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 17525 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17526 uint32_t imm4 = imm / dt.GetSize(); 17527 EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17528 rm.Encode(5, 0) | (imm4 << 8)); 17529 AdvanceIT(); 17530 return; 17531 } 17532 } 17533 } else { 17534 // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1 17535 if (dt.Is(Untyped8) && (imm <= 15)) { 17536 if (cond.Is(al)) { 17537 EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17538 rm.Encode(5, 0) | (imm << 8)); 17539 return; 17540 } 17541 } 17542 // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1 17543 if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) && 17544 (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 17545 if (cond.Is(al)) { 17546 uint32_t imm4 = imm / dt.GetSize(); 17547 EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17548 rm.Encode(5, 0) | (imm4 << 8)); 17549 return; 17550 } 17551 } 17552 } 17553 } 17554 } 17555 Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand); 17556 } 17557 17558 void Assembler::vfma( 17559 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17560 VIXL_ASSERT(AllowAssembler()); 17561 CheckIT(cond); 17562 if (IsUsingT32()) { 17563 // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 17564 if (dt.Is(F32)) { 17565 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17566 EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17567 rm.Encode(5, 0)); 17568 AdvanceIT(); 17569 return; 17570 } 17571 } 17572 // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 17573 if (dt.Is(F64)) { 17574 EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17575 rm.Encode(5, 0)); 17576 AdvanceIT(); 17577 return; 17578 } 17579 } else { 17580 // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 17581 if (dt.Is(F32)) { 17582 if (cond.Is(al)) { 17583 EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17584 rm.Encode(5, 0)); 17585 return; 17586 } 17587 } 17588 // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 17589 if (dt.Is(F64) && cond.IsNotNever()) { 17590 EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17591 rn.Encode(7, 16) | rm.Encode(5, 0)); 17592 return; 17593 } 17594 } 17595 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 17596 } 17597 17598 void Assembler::vfma( 17599 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17600 VIXL_ASSERT(AllowAssembler()); 17601 CheckIT(cond); 17602 if (IsUsingT32()) { 17603 // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 17604 if (dt.Is(F32)) { 17605 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17606 EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17607 rm.Encode(5, 0)); 17608 AdvanceIT(); 17609 return; 17610 } 17611 } 17612 } else { 17613 // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 17614 if (dt.Is(F32)) { 17615 if (cond.Is(al)) { 17616 EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17617 rm.Encode(5, 0)); 17618 return; 17619 } 17620 } 17621 } 17622 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 17623 } 17624 17625 void Assembler::vfma( 17626 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17627 VIXL_ASSERT(AllowAssembler()); 17628 CheckIT(cond); 17629 if (IsUsingT32()) { 17630 // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 17631 if (dt.Is(F32)) { 17632 EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17633 rm.Encode(5, 0)); 17634 AdvanceIT(); 17635 return; 17636 } 17637 } else { 17638 // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 17639 if (dt.Is(F32) && cond.IsNotNever()) { 17640 EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17641 rn.Encode(7, 16) | rm.Encode(5, 0)); 17642 return; 17643 } 17644 } 17645 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 17646 } 17647 17648 void Assembler::vfms( 17649 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17650 VIXL_ASSERT(AllowAssembler()); 17651 CheckIT(cond); 17652 if (IsUsingT32()) { 17653 // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 17654 if (dt.Is(F32)) { 17655 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17656 EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17657 rm.Encode(5, 0)); 17658 AdvanceIT(); 17659 return; 17660 } 17661 } 17662 // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 17663 if (dt.Is(F64)) { 17664 EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17665 rm.Encode(5, 0)); 17666 AdvanceIT(); 17667 return; 17668 } 17669 } else { 17670 // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 17671 if (dt.Is(F32)) { 17672 if (cond.Is(al)) { 17673 EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17674 rm.Encode(5, 0)); 17675 return; 17676 } 17677 } 17678 // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 17679 if (dt.Is(F64) && cond.IsNotNever()) { 17680 EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17681 rn.Encode(7, 16) | rm.Encode(5, 0)); 17682 return; 17683 } 17684 } 17685 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 17686 } 17687 17688 void Assembler::vfms( 17689 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17690 VIXL_ASSERT(AllowAssembler()); 17691 CheckIT(cond); 17692 if (IsUsingT32()) { 17693 // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 17694 if (dt.Is(F32)) { 17695 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17696 EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17697 rm.Encode(5, 0)); 17698 AdvanceIT(); 17699 return; 17700 } 17701 } 17702 } else { 17703 // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 17704 if (dt.Is(F32)) { 17705 if (cond.Is(al)) { 17706 EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17707 rm.Encode(5, 0)); 17708 return; 17709 } 17710 } 17711 } 17712 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 17713 } 17714 17715 void Assembler::vfms( 17716 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17717 VIXL_ASSERT(AllowAssembler()); 17718 CheckIT(cond); 17719 if (IsUsingT32()) { 17720 // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 17721 if (dt.Is(F32)) { 17722 EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17723 rm.Encode(5, 0)); 17724 AdvanceIT(); 17725 return; 17726 } 17727 } else { 17728 // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 17729 if (dt.Is(F32) && cond.IsNotNever()) { 17730 EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17731 rn.Encode(7, 16) | rm.Encode(5, 0)); 17732 return; 17733 } 17734 } 17735 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 17736 } 17737 17738 void Assembler::vfnma( 17739 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17740 VIXL_ASSERT(AllowAssembler()); 17741 CheckIT(cond); 17742 if (IsUsingT32()) { 17743 // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 17744 if (dt.Is(F32)) { 17745 EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17746 rm.Encode(5, 0)); 17747 AdvanceIT(); 17748 return; 17749 } 17750 } else { 17751 // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 17752 if (dt.Is(F32) && cond.IsNotNever()) { 17753 EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17754 rn.Encode(7, 16) | rm.Encode(5, 0)); 17755 return; 17756 } 17757 } 17758 Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm); 17759 } 17760 17761 void Assembler::vfnma( 17762 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17763 VIXL_ASSERT(AllowAssembler()); 17764 CheckIT(cond); 17765 if (IsUsingT32()) { 17766 // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 17767 if (dt.Is(F64)) { 17768 EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17769 rm.Encode(5, 0)); 17770 AdvanceIT(); 17771 return; 17772 } 17773 } else { 17774 // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 17775 if (dt.Is(F64) && cond.IsNotNever()) { 17776 EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17777 rn.Encode(7, 16) | rm.Encode(5, 0)); 17778 return; 17779 } 17780 } 17781 Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm); 17782 } 17783 17784 void Assembler::vfnms( 17785 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 17786 VIXL_ASSERT(AllowAssembler()); 17787 CheckIT(cond); 17788 if (IsUsingT32()) { 17789 // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 17790 if (dt.Is(F32)) { 17791 EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17792 rm.Encode(5, 0)); 17793 AdvanceIT(); 17794 return; 17795 } 17796 } else { 17797 // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 17798 if (dt.Is(F32) && cond.IsNotNever()) { 17799 EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17800 rn.Encode(7, 16) | rm.Encode(5, 0)); 17801 return; 17802 } 17803 } 17804 Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm); 17805 } 17806 17807 void Assembler::vfnms( 17808 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17809 VIXL_ASSERT(AllowAssembler()); 17810 CheckIT(cond); 17811 if (IsUsingT32()) { 17812 // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 17813 if (dt.Is(F64)) { 17814 EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 17815 rm.Encode(5, 0)); 17816 AdvanceIT(); 17817 return; 17818 } 17819 } else { 17820 // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 17821 if (dt.Is(F64) && cond.IsNotNever()) { 17822 EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 17823 rn.Encode(7, 16) | rm.Encode(5, 0)); 17824 return; 17825 } 17826 } 17827 Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm); 17828 } 17829 17830 void Assembler::vhadd( 17831 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17832 VIXL_ASSERT(AllowAssembler()); 17833 CheckIT(cond); 17834 Dt_U_size_1 encoded_dt(dt); 17835 if (IsUsingT32()) { 17836 // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 17837 if (encoded_dt.IsValid()) { 17838 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17839 EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17840 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 17841 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17842 AdvanceIT(); 17843 return; 17844 } 17845 } 17846 } else { 17847 // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 17848 if (encoded_dt.IsValid()) { 17849 if (cond.Is(al)) { 17850 EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17851 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 17852 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17853 return; 17854 } 17855 } 17856 } 17857 Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm); 17858 } 17859 17860 void Assembler::vhadd( 17861 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17862 VIXL_ASSERT(AllowAssembler()); 17863 CheckIT(cond); 17864 Dt_U_size_1 encoded_dt(dt); 17865 if (IsUsingT32()) { 17866 // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 17867 if (encoded_dt.IsValid()) { 17868 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17869 EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17870 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 17871 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17872 AdvanceIT(); 17873 return; 17874 } 17875 } 17876 } else { 17877 // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 17878 if (encoded_dt.IsValid()) { 17879 if (cond.Is(al)) { 17880 EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17881 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 17882 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17883 return; 17884 } 17885 } 17886 } 17887 Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm); 17888 } 17889 17890 void Assembler::vhsub( 17891 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 17892 VIXL_ASSERT(AllowAssembler()); 17893 CheckIT(cond); 17894 Dt_U_size_1 encoded_dt(dt); 17895 if (IsUsingT32()) { 17896 // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 17897 if (encoded_dt.IsValid()) { 17898 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17899 EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17900 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 17901 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17902 AdvanceIT(); 17903 return; 17904 } 17905 } 17906 } else { 17907 // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 17908 if (encoded_dt.IsValid()) { 17909 if (cond.Is(al)) { 17910 EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17911 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 17912 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17913 return; 17914 } 17915 } 17916 } 17917 Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm); 17918 } 17919 17920 void Assembler::vhsub( 17921 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 17922 VIXL_ASSERT(AllowAssembler()); 17923 CheckIT(cond); 17924 Dt_U_size_1 encoded_dt(dt); 17925 if (IsUsingT32()) { 17926 // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 17927 if (encoded_dt.IsValid()) { 17928 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17929 EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17930 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 17931 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17932 AdvanceIT(); 17933 return; 17934 } 17935 } 17936 } else { 17937 // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 17938 if (encoded_dt.IsValid()) { 17939 if (cond.Is(al)) { 17940 EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 17941 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 17942 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 17943 return; 17944 } 17945 } 17946 } 17947 Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm); 17948 } 17949 17950 void Assembler::vld1(Condition cond, 17951 DataType dt, 17952 const NeonRegisterList& nreglist, 17953 const AlignedMemOperand& operand) { 17954 VIXL_ASSERT(AllowAssembler()); 17955 CheckIT(cond); 17956 if (operand.IsImmediateZero()) { 17957 Register rn = operand.GetBaseRegister(); 17958 Alignment align = operand.GetAlignment(); 17959 Dt_size_6 encoded_dt(dt); 17960 Dt_size_7 encoded_dt_2(dt); 17961 Align_align_1 encoded_align_1(align, nreglist); 17962 Align_a_1 encoded_align_2(align, dt); 17963 Align_index_align_1 encoded_align_3(align, nreglist, dt); 17964 if (IsUsingT32()) { 17965 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 17966 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17967 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 17968 operand.IsOffset() && encoded_align_1.IsValid() && 17969 (!rn.IsPC() || AllowUnpredictable())) { 17970 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17971 const DRegister& first = nreglist.GetFirstDRegister(); 17972 uint32_t len_encoding; 17973 switch (nreglist.GetLength()) { 17974 default: 17975 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 17976 case 1: 17977 len_encoding = 0x7; 17978 break; 17979 case 2: 17980 len_encoding = 0xa; 17981 break; 17982 case 3: 17983 len_encoding = 0x6; 17984 break; 17985 case 4: 17986 len_encoding = 0x2; 17987 break; 17988 } 17989 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 17990 (encoded_align_1.GetEncodingValue() << 4) | 17991 first.Encode(22, 12) | (len_encoding << 8) | 17992 (rn.GetCode() << 16)); 17993 AdvanceIT(); 17994 return; 17995 } 17996 } 17997 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 17998 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17999 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18000 operand.IsPostIndex() && encoded_align_1.IsValid() && 18001 (!rn.IsPC() || AllowUnpredictable())) { 18002 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18003 const DRegister& first = nreglist.GetFirstDRegister(); 18004 uint32_t len_encoding; 18005 switch (nreglist.GetLength()) { 18006 default: 18007 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18008 case 1: 18009 len_encoding = 0x7; 18010 break; 18011 case 2: 18012 len_encoding = 0xa; 18013 break; 18014 case 3: 18015 len_encoding = 0x6; 18016 break; 18017 case 4: 18018 len_encoding = 0x2; 18019 break; 18020 } 18021 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 18022 (encoded_align_1.GetEncodingValue() << 4) | 18023 first.Encode(22, 12) | (len_encoding << 8) | 18024 (rn.GetCode() << 16)); 18025 AdvanceIT(); 18026 return; 18027 } 18028 } 18029 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18030 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18031 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18032 operand.IsOffset() && encoded_align_2.IsValid() && 18033 (!rn.IsPC() || AllowUnpredictable())) { 18034 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18035 const DRegister& first = nreglist.GetFirstDRegister(); 18036 uint32_t len_encoding = nreglist.GetLength() - 1; 18037 EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) | 18038 (encoded_align_2.GetEncodingValue() << 4) | 18039 first.Encode(22, 12) | (len_encoding << 5) | 18040 (rn.GetCode() << 16)); 18041 AdvanceIT(); 18042 return; 18043 } 18044 } 18045 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18046 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18047 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18048 operand.IsPostIndex() && encoded_align_2.IsValid() && 18049 (!rn.IsPC() || AllowUnpredictable())) { 18050 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18051 const DRegister& first = nreglist.GetFirstDRegister(); 18052 uint32_t len_encoding = nreglist.GetLength() - 1; 18053 EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) | 18054 (encoded_align_2.GetEncodingValue() << 4) | 18055 first.Encode(22, 12) | (len_encoding << 5) | 18056 (rn.GetCode() << 16)); 18057 AdvanceIT(); 18058 return; 18059 } 18060 } 18061 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18062 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18063 (nreglist.GetLength() == 1) && operand.IsOffset() && 18064 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 18065 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18066 const DRegister& first = nreglist.GetFirstDRegister(); 18067 EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) | 18068 (encoded_align_3.GetEncodingValue() << 4) | 18069 first.Encode(22, 12) | (rn.GetCode() << 16)); 18070 AdvanceIT(); 18071 return; 18072 } 18073 } 18074 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18075 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18076 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 18077 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 18078 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18079 const DRegister& first = nreglist.GetFirstDRegister(); 18080 EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) | 18081 (encoded_align_3.GetEncodingValue() << 4) | 18082 first.Encode(22, 12) | (rn.GetCode() << 16)); 18083 AdvanceIT(); 18084 return; 18085 } 18086 } 18087 } else { 18088 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18089 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18090 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18091 operand.IsOffset() && encoded_align_1.IsValid() && 18092 (!rn.IsPC() || AllowUnpredictable())) { 18093 if (cond.Is(al)) { 18094 const DRegister& first = nreglist.GetFirstDRegister(); 18095 uint32_t len_encoding; 18096 switch (nreglist.GetLength()) { 18097 default: 18098 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18099 case 1: 18100 len_encoding = 0x7; 18101 break; 18102 case 2: 18103 len_encoding = 0xa; 18104 break; 18105 case 3: 18106 len_encoding = 0x6; 18107 break; 18108 case 4: 18109 len_encoding = 0x2; 18110 break; 18111 } 18112 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 18113 (encoded_align_1.GetEncodingValue() << 4) | 18114 first.Encode(22, 12) | (len_encoding << 8) | 18115 (rn.GetCode() << 16)); 18116 return; 18117 } 18118 } 18119 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18120 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18121 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18122 operand.IsPostIndex() && encoded_align_1.IsValid() && 18123 (!rn.IsPC() || AllowUnpredictable())) { 18124 if (cond.Is(al)) { 18125 const DRegister& first = nreglist.GetFirstDRegister(); 18126 uint32_t len_encoding; 18127 switch (nreglist.GetLength()) { 18128 default: 18129 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18130 case 1: 18131 len_encoding = 0x7; 18132 break; 18133 case 2: 18134 len_encoding = 0xa; 18135 break; 18136 case 3: 18137 len_encoding = 0x6; 18138 break; 18139 case 4: 18140 len_encoding = 0x2; 18141 break; 18142 } 18143 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 18144 (encoded_align_1.GetEncodingValue() << 4) | 18145 first.Encode(22, 12) | (len_encoding << 8) | 18146 (rn.GetCode() << 16)); 18147 return; 18148 } 18149 } 18150 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18151 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18152 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18153 operand.IsOffset() && encoded_align_2.IsValid() && 18154 (!rn.IsPC() || AllowUnpredictable())) { 18155 if (cond.Is(al)) { 18156 const DRegister& first = nreglist.GetFirstDRegister(); 18157 uint32_t len_encoding = nreglist.GetLength() - 1; 18158 EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) | 18159 (encoded_align_2.GetEncodingValue() << 4) | 18160 first.Encode(22, 12) | (len_encoding << 5) | 18161 (rn.GetCode() << 16)); 18162 return; 18163 } 18164 } 18165 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18166 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18167 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18168 operand.IsPostIndex() && encoded_align_2.IsValid() && 18169 (!rn.IsPC() || AllowUnpredictable())) { 18170 if (cond.Is(al)) { 18171 const DRegister& first = nreglist.GetFirstDRegister(); 18172 uint32_t len_encoding = nreglist.GetLength() - 1; 18173 EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) | 18174 (encoded_align_2.GetEncodingValue() << 4) | 18175 first.Encode(22, 12) | (len_encoding << 5) | 18176 (rn.GetCode() << 16)); 18177 return; 18178 } 18179 } 18180 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18181 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18182 (nreglist.GetLength() == 1) && operand.IsOffset() && 18183 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 18184 if (cond.Is(al)) { 18185 const DRegister& first = nreglist.GetFirstDRegister(); 18186 EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) | 18187 (encoded_align_3.GetEncodingValue() << 4) | 18188 first.Encode(22, 12) | (rn.GetCode() << 16)); 18189 return; 18190 } 18191 } 18192 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18193 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18194 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 18195 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 18196 if (cond.Is(al)) { 18197 const DRegister& first = nreglist.GetFirstDRegister(); 18198 EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) | 18199 (encoded_align_3.GetEncodingValue() << 4) | 18200 first.Encode(22, 12) | (rn.GetCode() << 16)); 18201 return; 18202 } 18203 } 18204 } 18205 } 18206 if (operand.IsPlainRegister()) { 18207 Register rn = operand.GetBaseRegister(); 18208 Alignment align = operand.GetAlignment(); 18209 Register rm = operand.GetOffsetRegister(); 18210 Dt_size_6 encoded_dt(dt); 18211 Dt_size_7 encoded_dt_2(dt); 18212 Align_align_1 encoded_align_1(align, nreglist); 18213 Align_a_1 encoded_align_2(align, dt); 18214 Align_index_align_1 encoded_align_3(align, nreglist, dt); 18215 if (IsUsingT32()) { 18216 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18217 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18218 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18219 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18220 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18221 const DRegister& first = nreglist.GetFirstDRegister(); 18222 uint32_t len_encoding; 18223 switch (nreglist.GetLength()) { 18224 default: 18225 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18226 case 1: 18227 len_encoding = 0x7; 18228 break; 18229 case 2: 18230 len_encoding = 0xa; 18231 break; 18232 case 3: 18233 len_encoding = 0x6; 18234 break; 18235 case 4: 18236 len_encoding = 0x2; 18237 break; 18238 } 18239 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 18240 (encoded_align_1.GetEncodingValue() << 4) | 18241 first.Encode(22, 12) | (len_encoding << 8) | 18242 (rn.GetCode() << 16) | rm.GetCode()); 18243 AdvanceIT(); 18244 return; 18245 } 18246 } 18247 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18248 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18249 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18250 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18251 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18252 const DRegister& first = nreglist.GetFirstDRegister(); 18253 uint32_t len_encoding = nreglist.GetLength() - 1; 18254 EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) | 18255 (encoded_align_2.GetEncodingValue() << 4) | 18256 first.Encode(22, 12) | (len_encoding << 5) | 18257 (rn.GetCode() << 16) | rm.GetCode()); 18258 AdvanceIT(); 18259 return; 18260 } 18261 } 18262 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18263 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18264 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() && 18265 (!rn.IsPC() || AllowUnpredictable())) { 18266 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18267 const DRegister& first = nreglist.GetFirstDRegister(); 18268 EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) | 18269 (encoded_align_3.GetEncodingValue() << 4) | 18270 first.Encode(22, 12) | (rn.GetCode() << 16) | 18271 rm.GetCode()); 18272 AdvanceIT(); 18273 return; 18274 } 18275 } 18276 } else { 18277 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18278 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18279 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 18280 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18281 if (cond.Is(al)) { 18282 const DRegister& first = nreglist.GetFirstDRegister(); 18283 uint32_t len_encoding; 18284 switch (nreglist.GetLength()) { 18285 default: 18286 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 18287 case 1: 18288 len_encoding = 0x7; 18289 break; 18290 case 2: 18291 len_encoding = 0xa; 18292 break; 18293 case 3: 18294 len_encoding = 0x6; 18295 break; 18296 case 4: 18297 len_encoding = 0x2; 18298 break; 18299 } 18300 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 18301 (encoded_align_1.GetEncodingValue() << 4) | 18302 first.Encode(22, 12) | (len_encoding << 8) | 18303 (rn.GetCode() << 16) | rm.GetCode()); 18304 return; 18305 } 18306 } 18307 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18308 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18309 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 18310 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18311 if (cond.Is(al)) { 18312 const DRegister& first = nreglist.GetFirstDRegister(); 18313 uint32_t len_encoding = nreglist.GetLength() - 1; 18314 EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) | 18315 (encoded_align_2.GetEncodingValue() << 4) | 18316 first.Encode(22, 12) | (len_encoding << 5) | 18317 (rn.GetCode() << 16) | rm.GetCode()); 18318 return; 18319 } 18320 } 18321 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18322 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 18323 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() && 18324 (!rn.IsPC() || AllowUnpredictable())) { 18325 if (cond.Is(al)) { 18326 const DRegister& first = nreglist.GetFirstDRegister(); 18327 EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) | 18328 (encoded_align_3.GetEncodingValue() << 4) | 18329 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 18330 return; 18331 } 18332 } 18333 } 18334 } 18335 Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand); 18336 } 18337 18338 void Assembler::vld2(Condition cond, 18339 DataType dt, 18340 const NeonRegisterList& nreglist, 18341 const AlignedMemOperand& operand) { 18342 VIXL_ASSERT(AllowAssembler()); 18343 CheckIT(cond); 18344 if (operand.IsImmediateZero()) { 18345 Register rn = operand.GetBaseRegister(); 18346 Alignment align = operand.GetAlignment(); 18347 Dt_size_7 encoded_dt(dt); 18348 Align_align_2 encoded_align_1(align, nreglist); 18349 Align_a_2 encoded_align_2(align, dt); 18350 Align_index_align_2 encoded_align_3(align, nreglist, dt); 18351 if (IsUsingT32()) { 18352 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18353 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18354 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18355 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18356 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18357 operand.IsOffset() && encoded_align_1.IsValid() && 18358 (!rn.IsPC() || AllowUnpredictable())) { 18359 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18360 const DRegister& first = nreglist.GetFirstDRegister(); 18361 uint32_t len_encoding; 18362 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18363 len_encoding = 0x8; 18364 } 18365 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18366 len_encoding = 0x9; 18367 } 18368 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18369 len_encoding = 0x3; 18370 } 18371 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 18372 (encoded_align_1.GetEncodingValue() << 4) | 18373 first.Encode(22, 12) | (len_encoding << 8) | 18374 (rn.GetCode() << 16)); 18375 AdvanceIT(); 18376 return; 18377 } 18378 } 18379 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18380 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18381 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18382 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18383 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18384 operand.IsPostIndex() && encoded_align_1.IsValid() && 18385 (!rn.IsPC() || AllowUnpredictable())) { 18386 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18387 const DRegister& first = nreglist.GetFirstDRegister(); 18388 uint32_t len_encoding; 18389 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18390 len_encoding = 0x8; 18391 } 18392 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18393 len_encoding = 0x9; 18394 } 18395 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18396 len_encoding = 0x3; 18397 } 18398 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 18399 (encoded_align_1.GetEncodingValue() << 4) | 18400 first.Encode(22, 12) | (len_encoding << 8) | 18401 (rn.GetCode() << 16)); 18402 AdvanceIT(); 18403 return; 18404 } 18405 } 18406 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18407 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18408 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18409 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18410 operand.IsOffset() && encoded_align_2.IsValid() && 18411 (!rn.IsPC() || AllowUnpredictable())) { 18412 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18413 const DRegister& first = nreglist.GetFirstDRegister(); 18414 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18415 EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) | 18416 (encoded_align_2.GetEncodingValue() << 4) | 18417 first.Encode(22, 12) | (len_encoding << 5) | 18418 (rn.GetCode() << 16)); 18419 AdvanceIT(); 18420 return; 18421 } 18422 } 18423 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18424 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18425 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18426 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18427 operand.IsPostIndex() && encoded_align_2.IsValid() && 18428 (!rn.IsPC() || AllowUnpredictable())) { 18429 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18430 const DRegister& first = nreglist.GetFirstDRegister(); 18431 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18432 EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) | 18433 (encoded_align_2.GetEncodingValue() << 4) | 18434 first.Encode(22, 12) | (len_encoding << 5) | 18435 (rn.GetCode() << 16)); 18436 AdvanceIT(); 18437 return; 18438 } 18439 } 18440 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18441 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18442 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18443 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18444 operand.IsOffset() && encoded_align_3.IsValid() && 18445 (!rn.IsPC() || AllowUnpredictable())) { 18446 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18447 const DRegister& first = nreglist.GetFirstDRegister(); 18448 EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) | 18449 (encoded_align_3.GetEncodingValue() << 4) | 18450 first.Encode(22, 12) | (rn.GetCode() << 16)); 18451 AdvanceIT(); 18452 return; 18453 } 18454 } 18455 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18456 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18457 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18458 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18459 operand.IsPostIndex() && encoded_align_3.IsValid() && 18460 (!rn.IsPC() || AllowUnpredictable())) { 18461 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18462 const DRegister& first = nreglist.GetFirstDRegister(); 18463 EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) | 18464 (encoded_align_3.GetEncodingValue() << 4) | 18465 first.Encode(22, 12) | (rn.GetCode() << 16)); 18466 AdvanceIT(); 18467 return; 18468 } 18469 } 18470 } else { 18471 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18472 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18473 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18474 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18475 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18476 operand.IsOffset() && encoded_align_1.IsValid() && 18477 (!rn.IsPC() || AllowUnpredictable())) { 18478 if (cond.Is(al)) { 18479 const DRegister& first = nreglist.GetFirstDRegister(); 18480 uint32_t len_encoding; 18481 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18482 len_encoding = 0x8; 18483 } 18484 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18485 len_encoding = 0x9; 18486 } 18487 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18488 len_encoding = 0x3; 18489 } 18490 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 18491 (encoded_align_1.GetEncodingValue() << 4) | 18492 first.Encode(22, 12) | (len_encoding << 8) | 18493 (rn.GetCode() << 16)); 18494 return; 18495 } 18496 } 18497 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18498 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18499 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18500 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18501 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18502 operand.IsPostIndex() && encoded_align_1.IsValid() && 18503 (!rn.IsPC() || AllowUnpredictable())) { 18504 if (cond.Is(al)) { 18505 const DRegister& first = nreglist.GetFirstDRegister(); 18506 uint32_t len_encoding; 18507 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18508 len_encoding = 0x8; 18509 } 18510 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18511 len_encoding = 0x9; 18512 } 18513 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18514 len_encoding = 0x3; 18515 } 18516 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 18517 (encoded_align_1.GetEncodingValue() << 4) | 18518 first.Encode(22, 12) | (len_encoding << 8) | 18519 (rn.GetCode() << 16)); 18520 return; 18521 } 18522 } 18523 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18524 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18525 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18526 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18527 operand.IsOffset() && encoded_align_2.IsValid() && 18528 (!rn.IsPC() || AllowUnpredictable())) { 18529 if (cond.Is(al)) { 18530 const DRegister& first = nreglist.GetFirstDRegister(); 18531 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18532 EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) | 18533 (encoded_align_2.GetEncodingValue() << 4) | 18534 first.Encode(22, 12) | (len_encoding << 5) | 18535 (rn.GetCode() << 16)); 18536 return; 18537 } 18538 } 18539 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18540 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18541 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18542 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18543 operand.IsPostIndex() && encoded_align_2.IsValid() && 18544 (!rn.IsPC() || AllowUnpredictable())) { 18545 if (cond.Is(al)) { 18546 const DRegister& first = nreglist.GetFirstDRegister(); 18547 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18548 EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) | 18549 (encoded_align_2.GetEncodingValue() << 4) | 18550 first.Encode(22, 12) | (len_encoding << 5) | 18551 (rn.GetCode() << 16)); 18552 return; 18553 } 18554 } 18555 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18556 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18557 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18558 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18559 operand.IsOffset() && encoded_align_3.IsValid() && 18560 (!rn.IsPC() || AllowUnpredictable())) { 18561 if (cond.Is(al)) { 18562 const DRegister& first = nreglist.GetFirstDRegister(); 18563 EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) | 18564 (encoded_align_3.GetEncodingValue() << 4) | 18565 first.Encode(22, 12) | (rn.GetCode() << 16)); 18566 return; 18567 } 18568 } 18569 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18570 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18571 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18572 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18573 operand.IsPostIndex() && encoded_align_3.IsValid() && 18574 (!rn.IsPC() || AllowUnpredictable())) { 18575 if (cond.Is(al)) { 18576 const DRegister& first = nreglist.GetFirstDRegister(); 18577 EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) | 18578 (encoded_align_3.GetEncodingValue() << 4) | 18579 first.Encode(22, 12) | (rn.GetCode() << 16)); 18580 return; 18581 } 18582 } 18583 } 18584 } 18585 if (operand.IsPlainRegister()) { 18586 Register rn = operand.GetBaseRegister(); 18587 Alignment align = operand.GetAlignment(); 18588 Register rm = operand.GetOffsetRegister(); 18589 Dt_size_7 encoded_dt(dt); 18590 Align_align_2 encoded_align_1(align, nreglist); 18591 Align_a_2 encoded_align_2(align, dt); 18592 Align_index_align_2 encoded_align_3(align, nreglist, dt); 18593 if (IsUsingT32()) { 18594 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18595 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18596 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18597 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18598 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18599 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18600 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18601 const DRegister& first = nreglist.GetFirstDRegister(); 18602 uint32_t len_encoding; 18603 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18604 len_encoding = 0x8; 18605 } 18606 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18607 len_encoding = 0x9; 18608 } 18609 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18610 len_encoding = 0x3; 18611 } 18612 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 18613 (encoded_align_1.GetEncodingValue() << 4) | 18614 first.Encode(22, 12) | (len_encoding << 8) | 18615 (rn.GetCode() << 16) | rm.GetCode()); 18616 AdvanceIT(); 18617 return; 18618 } 18619 } 18620 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18621 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18622 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18623 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18624 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18625 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18626 const DRegister& first = nreglist.GetFirstDRegister(); 18627 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18628 EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) | 18629 (encoded_align_2.GetEncodingValue() << 4) | 18630 first.Encode(22, 12) | (len_encoding << 5) | 18631 (rn.GetCode() << 16) | rm.GetCode()); 18632 AdvanceIT(); 18633 return; 18634 } 18635 } 18636 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18637 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18638 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18639 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18640 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18641 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18642 const DRegister& first = nreglist.GetFirstDRegister(); 18643 EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) | 18644 (encoded_align_3.GetEncodingValue() << 4) | 18645 first.Encode(22, 12) | (rn.GetCode() << 16) | 18646 rm.GetCode()); 18647 AdvanceIT(); 18648 return; 18649 } 18650 } 18651 } else { 18652 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18653 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18654 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18655 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 18656 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 18657 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18658 if (cond.Is(al)) { 18659 const DRegister& first = nreglist.GetFirstDRegister(); 18660 uint32_t len_encoding; 18661 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 18662 len_encoding = 0x8; 18663 } 18664 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 18665 len_encoding = 0x9; 18666 } 18667 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 18668 len_encoding = 0x3; 18669 } 18670 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 18671 (encoded_align_1.GetEncodingValue() << 4) | 18672 first.Encode(22, 12) | (len_encoding << 8) | 18673 (rn.GetCode() << 16) | rm.GetCode()); 18674 return; 18675 } 18676 } 18677 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18678 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18679 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18680 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18681 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18682 if (cond.Is(al)) { 18683 const DRegister& first = nreglist.GetFirstDRegister(); 18684 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18685 EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) | 18686 (encoded_align_2.GetEncodingValue() << 4) | 18687 first.Encode(22, 12) | (len_encoding << 5) | 18688 (rn.GetCode() << 16) | rm.GetCode()); 18689 return; 18690 } 18691 } 18692 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18693 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18694 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 18695 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 18696 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18697 if (cond.Is(al)) { 18698 const DRegister& first = nreglist.GetFirstDRegister(); 18699 EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) | 18700 (encoded_align_3.GetEncodingValue() << 4) | 18701 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 18702 return; 18703 } 18704 } 18705 } 18706 } 18707 Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand); 18708 } 18709 18710 void Assembler::vld3(Condition cond, 18711 DataType dt, 18712 const NeonRegisterList& nreglist, 18713 const AlignedMemOperand& operand) { 18714 VIXL_ASSERT(AllowAssembler()); 18715 CheckIT(cond); 18716 if (operand.IsImmediateZero()) { 18717 Register rn = operand.GetBaseRegister(); 18718 Alignment align = operand.GetAlignment(); 18719 Dt_size_7 encoded_dt(dt); 18720 Align_align_3 encoded_align_1(align); 18721 if (IsUsingT32()) { 18722 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 18723 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18724 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18725 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18726 operand.IsOffset() && encoded_align_1.IsValid() && 18727 (!rn.IsPC() || AllowUnpredictable())) { 18728 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18729 const DRegister& first = nreglist.GetFirstDRegister(); 18730 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18731 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 18732 (encoded_align_1.GetEncodingValue() << 4) | 18733 first.Encode(22, 12) | (len_encoding << 8) | 18734 (rn.GetCode() << 16)); 18735 AdvanceIT(); 18736 return; 18737 } 18738 } 18739 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 18740 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18741 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18742 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18743 operand.IsPostIndex() && encoded_align_1.IsValid() && 18744 (!rn.IsPC() || AllowUnpredictable())) { 18745 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18746 const DRegister& first = nreglist.GetFirstDRegister(); 18747 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18748 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 18749 (encoded_align_1.GetEncodingValue() << 4) | 18750 first.Encode(22, 12) | (len_encoding << 8) | 18751 (rn.GetCode() << 16)); 18752 AdvanceIT(); 18753 return; 18754 } 18755 } 18756 } else { 18757 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18758 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18759 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18760 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18761 operand.IsOffset() && encoded_align_1.IsValid() && 18762 (!rn.IsPC() || AllowUnpredictable())) { 18763 if (cond.Is(al)) { 18764 const DRegister& first = nreglist.GetFirstDRegister(); 18765 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18766 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 18767 (encoded_align_1.GetEncodingValue() << 4) | 18768 first.Encode(22, 12) | (len_encoding << 8) | 18769 (rn.GetCode() << 16)); 18770 return; 18771 } 18772 } 18773 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18774 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18775 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18776 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18777 operand.IsPostIndex() && encoded_align_1.IsValid() && 18778 (!rn.IsPC() || AllowUnpredictable())) { 18779 if (cond.Is(al)) { 18780 const DRegister& first = nreglist.GetFirstDRegister(); 18781 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18782 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 18783 (encoded_align_1.GetEncodingValue() << 4) | 18784 first.Encode(22, 12) | (len_encoding << 8) | 18785 (rn.GetCode() << 16)); 18786 return; 18787 } 18788 } 18789 } 18790 } 18791 if (operand.IsPlainRegister()) { 18792 Register rn = operand.GetBaseRegister(); 18793 Alignment align = operand.GetAlignment(); 18794 Register rm = operand.GetOffsetRegister(); 18795 Dt_size_7 encoded_dt(dt); 18796 Align_align_3 encoded_align_1(align); 18797 if (IsUsingT32()) { 18798 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18799 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18800 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18801 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18802 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18803 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18804 const DRegister& first = nreglist.GetFirstDRegister(); 18805 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18806 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 18807 (encoded_align_1.GetEncodingValue() << 4) | 18808 first.Encode(22, 12) | (len_encoding << 8) | 18809 (rn.GetCode() << 16) | rm.GetCode()); 18810 AdvanceIT(); 18811 return; 18812 } 18813 } 18814 } else { 18815 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18816 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18817 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18818 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18819 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 18820 if (cond.Is(al)) { 18821 const DRegister& first = nreglist.GetFirstDRegister(); 18822 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 18823 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 18824 (encoded_align_1.GetEncodingValue() << 4) | 18825 first.Encode(22, 12) | (len_encoding << 8) | 18826 (rn.GetCode() << 16) | rm.GetCode()); 18827 return; 18828 } 18829 } 18830 } 18831 } 18832 Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand); 18833 } 18834 18835 void Assembler::vld3(Condition cond, 18836 DataType dt, 18837 const NeonRegisterList& nreglist, 18838 const MemOperand& operand) { 18839 VIXL_ASSERT(AllowAssembler()); 18840 CheckIT(cond); 18841 if (operand.IsImmediateZero()) { 18842 Register rn = operand.GetBaseRegister(); 18843 Dt_size_7 encoded_dt(dt); 18844 Index_1 encoded_align_1(nreglist, dt); 18845 if (IsUsingT32()) { 18846 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 18847 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18848 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18849 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18850 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 18851 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18852 const DRegister& first = nreglist.GetFirstDRegister(); 18853 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18854 EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) | 18855 first.Encode(22, 12) | (len_encoding << 5) | 18856 (rn.GetCode() << 16)); 18857 AdvanceIT(); 18858 return; 18859 } 18860 } 18861 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 18862 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18863 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18864 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18865 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 18866 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18867 const DRegister& first = nreglist.GetFirstDRegister(); 18868 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18869 EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) | 18870 first.Encode(22, 12) | (len_encoding << 5) | 18871 (rn.GetCode() << 16)); 18872 AdvanceIT(); 18873 return; 18874 } 18875 } 18876 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 18877 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18878 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18879 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18880 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 18881 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18882 const DRegister& first = nreglist.GetFirstDRegister(); 18883 EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) | 18884 (encoded_align_1.GetEncodingValue() << 4) | 18885 first.Encode(22, 12) | (rn.GetCode() << 16)); 18886 AdvanceIT(); 18887 return; 18888 } 18889 } 18890 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 18891 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18892 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18893 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18894 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 18895 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18896 const DRegister& first = nreglist.GetFirstDRegister(); 18897 EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) | 18898 (encoded_align_1.GetEncodingValue() << 4) | 18899 first.Encode(22, 12) | (rn.GetCode() << 16)); 18900 AdvanceIT(); 18901 return; 18902 } 18903 } 18904 } else { 18905 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 18906 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18907 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18908 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18909 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 18910 if (cond.Is(al)) { 18911 const DRegister& first = nreglist.GetFirstDRegister(); 18912 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18913 EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) | 18914 first.Encode(22, 12) | (len_encoding << 5) | 18915 (rn.GetCode() << 16)); 18916 return; 18917 } 18918 } 18919 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 18920 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18921 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18922 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18923 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 18924 if (cond.Is(al)) { 18925 const DRegister& first = nreglist.GetFirstDRegister(); 18926 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18927 EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) | 18928 first.Encode(22, 12) | (len_encoding << 5) | 18929 (rn.GetCode() << 16)); 18930 return; 18931 } 18932 } 18933 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 18934 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18935 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18936 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18937 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 18938 if (cond.Is(al)) { 18939 const DRegister& first = nreglist.GetFirstDRegister(); 18940 EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) | 18941 (encoded_align_1.GetEncodingValue() << 4) | 18942 first.Encode(22, 12) | (rn.GetCode() << 16)); 18943 return; 18944 } 18945 } 18946 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 18947 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18948 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18949 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18950 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 18951 if (cond.Is(al)) { 18952 const DRegister& first = nreglist.GetFirstDRegister(); 18953 EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) | 18954 (encoded_align_1.GetEncodingValue() << 4) | 18955 first.Encode(22, 12) | (rn.GetCode() << 16)); 18956 return; 18957 } 18958 } 18959 } 18960 } 18961 if (operand.IsPlainRegister()) { 18962 Register rn = operand.GetBaseRegister(); 18963 Sign sign = operand.GetSign(); 18964 Register rm = operand.GetOffsetRegister(); 18965 Dt_size_7 encoded_dt(dt); 18966 Index_1 encoded_align_1(nreglist, dt); 18967 if (IsUsingT32()) { 18968 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 18969 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 18970 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18971 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18972 sign.IsPlus() && operand.IsPostIndex() && 18973 (!rn.IsPC() || AllowUnpredictable())) { 18974 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18975 const DRegister& first = nreglist.GetFirstDRegister(); 18976 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18977 EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) | 18978 first.Encode(22, 12) | (len_encoding << 5) | 18979 (rn.GetCode() << 16) | rm.GetCode()); 18980 AdvanceIT(); 18981 return; 18982 } 18983 } 18984 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 18985 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18986 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 18987 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 18988 sign.IsPlus() && operand.IsPostIndex() && 18989 (!rn.IsPC() || AllowUnpredictable())) { 18990 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18991 const DRegister& first = nreglist.GetFirstDRegister(); 18992 EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) | 18993 (encoded_align_1.GetEncodingValue() << 4) | 18994 first.Encode(22, 12) | (rn.GetCode() << 16) | 18995 rm.GetCode()); 18996 AdvanceIT(); 18997 return; 18998 } 18999 } 19000 } else { 19001 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 19002 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 19003 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 19004 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 19005 sign.IsPlus() && operand.IsPostIndex() && 19006 (!rn.IsPC() || AllowUnpredictable())) { 19007 if (cond.Is(al)) { 19008 const DRegister& first = nreglist.GetFirstDRegister(); 19009 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19010 EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) | 19011 first.Encode(22, 12) | (len_encoding << 5) | 19012 (rn.GetCode() << 16) | rm.GetCode()); 19013 return; 19014 } 19015 } 19016 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 19017 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19018 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 19019 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 19020 sign.IsPlus() && operand.IsPostIndex() && 19021 (!rn.IsPC() || AllowUnpredictable())) { 19022 if (cond.Is(al)) { 19023 const DRegister& first = nreglist.GetFirstDRegister(); 19024 EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) | 19025 (encoded_align_1.GetEncodingValue() << 4) | 19026 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 19027 return; 19028 } 19029 } 19030 } 19031 } 19032 Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand); 19033 } 19034 19035 void Assembler::vld4(Condition cond, 19036 DataType dt, 19037 const NeonRegisterList& nreglist, 19038 const AlignedMemOperand& operand) { 19039 VIXL_ASSERT(AllowAssembler()); 19040 CheckIT(cond); 19041 if (operand.IsImmediateZero()) { 19042 Register rn = operand.GetBaseRegister(); 19043 Alignment align = operand.GetAlignment(); 19044 Dt_size_7 encoded_dt(dt); 19045 Dt_size_8 encoded_dt_2(dt, align); 19046 Align_align_4 encoded_align_1(align); 19047 Align_a_3 encoded_align_2(align, dt); 19048 Align_index_align_3 encoded_align_3(align, nreglist, dt); 19049 if (IsUsingT32()) { 19050 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 19051 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19052 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19053 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19054 operand.IsOffset() && encoded_align_1.IsValid() && 19055 (!rn.IsPC() || AllowUnpredictable())) { 19056 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19057 const DRegister& first = nreglist.GetFirstDRegister(); 19058 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19059 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 19060 (encoded_align_1.GetEncodingValue() << 4) | 19061 first.Encode(22, 12) | (len_encoding << 8) | 19062 (rn.GetCode() << 16)); 19063 AdvanceIT(); 19064 return; 19065 } 19066 } 19067 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 19068 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19069 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19070 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19071 operand.IsPostIndex() && encoded_align_1.IsValid() && 19072 (!rn.IsPC() || AllowUnpredictable())) { 19073 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19074 const DRegister& first = nreglist.GetFirstDRegister(); 19075 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19076 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 19077 (encoded_align_1.GetEncodingValue() << 4) | 19078 first.Encode(22, 12) | (len_encoding << 8) | 19079 (rn.GetCode() << 16)); 19080 AdvanceIT(); 19081 return; 19082 } 19083 } 19084 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 19085 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19086 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19087 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19088 operand.IsOffset() && encoded_align_2.IsValid() && 19089 (!rn.IsPC() || AllowUnpredictable())) { 19090 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19091 const DRegister& first = nreglist.GetFirstDRegister(); 19092 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19093 EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) | 19094 (encoded_align_2.GetEncodingValue() << 4) | 19095 first.Encode(22, 12) | (len_encoding << 5) | 19096 (rn.GetCode() << 16)); 19097 AdvanceIT(); 19098 return; 19099 } 19100 } 19101 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 19102 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19103 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19104 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19105 operand.IsPostIndex() && encoded_align_2.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(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) | 19111 (encoded_align_2.GetEncodingValue() << 4) | 19112 first.Encode(22, 12) | (len_encoding << 5) | 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.IsTransferOneLane() && 19120 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19121 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19122 operand.IsOffset() && encoded_align_3.IsValid() && 19123 (!rn.IsPC() || AllowUnpredictable())) { 19124 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19125 const DRegister& first = nreglist.GetFirstDRegister(); 19126 EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) | 19127 (encoded_align_3.GetEncodingValue() << 4) | 19128 first.Encode(22, 12) | (rn.GetCode() << 16)); 19129 AdvanceIT(); 19130 return; 19131 } 19132 } 19133 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 19134 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19135 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19136 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19137 operand.IsPostIndex() && encoded_align_3.IsValid() && 19138 (!rn.IsPC() || AllowUnpredictable())) { 19139 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19140 const DRegister& first = nreglist.GetFirstDRegister(); 19141 EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) | 19142 (encoded_align_3.GetEncodingValue() << 4) | 19143 first.Encode(22, 12) | (rn.GetCode() << 16)); 19144 AdvanceIT(); 19145 return; 19146 } 19147 } 19148 } else { 19149 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 19150 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19151 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19152 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19153 operand.IsOffset() && encoded_align_1.IsValid() && 19154 (!rn.IsPC() || AllowUnpredictable())) { 19155 if (cond.Is(al)) { 19156 const DRegister& first = nreglist.GetFirstDRegister(); 19157 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19158 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 19159 (encoded_align_1.GetEncodingValue() << 4) | 19160 first.Encode(22, 12) | (len_encoding << 8) | 19161 (rn.GetCode() << 16)); 19162 return; 19163 } 19164 } 19165 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 19166 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19167 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19168 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19169 operand.IsPostIndex() && encoded_align_1.IsValid() && 19170 (!rn.IsPC() || AllowUnpredictable())) { 19171 if (cond.Is(al)) { 19172 const DRegister& first = nreglist.GetFirstDRegister(); 19173 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19174 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 19175 (encoded_align_1.GetEncodingValue() << 4) | 19176 first.Encode(22, 12) | (len_encoding << 8) | 19177 (rn.GetCode() << 16)); 19178 return; 19179 } 19180 } 19181 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 19182 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19183 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19184 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19185 operand.IsOffset() && encoded_align_2.IsValid() && 19186 (!rn.IsPC() || AllowUnpredictable())) { 19187 if (cond.Is(al)) { 19188 const DRegister& first = nreglist.GetFirstDRegister(); 19189 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19190 EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) | 19191 (encoded_align_2.GetEncodingValue() << 4) | 19192 first.Encode(22, 12) | (len_encoding << 5) | 19193 (rn.GetCode() << 16)); 19194 return; 19195 } 19196 } 19197 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 19198 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19199 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19200 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19201 operand.IsPostIndex() && encoded_align_2.IsValid() && 19202 (!rn.IsPC() || AllowUnpredictable())) { 19203 if (cond.Is(al)) { 19204 const DRegister& first = nreglist.GetFirstDRegister(); 19205 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19206 EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) | 19207 (encoded_align_2.GetEncodingValue() << 4) | 19208 first.Encode(22, 12) | (len_encoding << 5) | 19209 (rn.GetCode() << 16)); 19210 return; 19211 } 19212 } 19213 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 19214 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19215 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19216 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19217 operand.IsOffset() && encoded_align_3.IsValid() && 19218 (!rn.IsPC() || AllowUnpredictable())) { 19219 if (cond.Is(al)) { 19220 const DRegister& first = nreglist.GetFirstDRegister(); 19221 EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) | 19222 (encoded_align_3.GetEncodingValue() << 4) | 19223 first.Encode(22, 12) | (rn.GetCode() << 16)); 19224 return; 19225 } 19226 } 19227 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 19228 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19229 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19230 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19231 operand.IsPostIndex() && encoded_align_3.IsValid() && 19232 (!rn.IsPC() || AllowUnpredictable())) { 19233 if (cond.Is(al)) { 19234 const DRegister& first = nreglist.GetFirstDRegister(); 19235 EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) | 19236 (encoded_align_3.GetEncodingValue() << 4) | 19237 first.Encode(22, 12) | (rn.GetCode() << 16)); 19238 return; 19239 } 19240 } 19241 } 19242 } 19243 if (operand.IsPlainRegister()) { 19244 Register rn = operand.GetBaseRegister(); 19245 Alignment align = operand.GetAlignment(); 19246 Register rm = operand.GetOffsetRegister(); 19247 Dt_size_7 encoded_dt(dt); 19248 Dt_size_8 encoded_dt_2(dt, align); 19249 Align_align_4 encoded_align_1(align); 19250 Align_a_3 encoded_align_2(align, dt); 19251 Align_index_align_3 encoded_align_3(align, nreglist, dt); 19252 if (IsUsingT32()) { 19253 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 19254 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19255 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19256 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19257 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19258 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19259 const DRegister& first = nreglist.GetFirstDRegister(); 19260 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19261 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 19262 (encoded_align_1.GetEncodingValue() << 4) | 19263 first.Encode(22, 12) | (len_encoding << 8) | 19264 (rn.GetCode() << 16) | rm.GetCode()); 19265 AdvanceIT(); 19266 return; 19267 } 19268 } 19269 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 19270 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19271 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19272 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19273 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19274 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19275 const DRegister& first = nreglist.GetFirstDRegister(); 19276 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19277 EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) | 19278 (encoded_align_2.GetEncodingValue() << 4) | 19279 first.Encode(22, 12) | (len_encoding << 5) | 19280 (rn.GetCode() << 16) | rm.GetCode()); 19281 AdvanceIT(); 19282 return; 19283 } 19284 } 19285 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 19286 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19287 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19288 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19289 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19290 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19291 const DRegister& first = nreglist.GetFirstDRegister(); 19292 EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) | 19293 (encoded_align_3.GetEncodingValue() << 4) | 19294 first.Encode(22, 12) | (rn.GetCode() << 16) | 19295 rm.GetCode()); 19296 AdvanceIT(); 19297 return; 19298 } 19299 } 19300 } else { 19301 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 19302 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 19303 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19304 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19305 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19306 if (cond.Is(al)) { 19307 const DRegister& first = nreglist.GetFirstDRegister(); 19308 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19309 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 19310 (encoded_align_1.GetEncodingValue() << 4) | 19311 first.Encode(22, 12) | (len_encoding << 8) | 19312 (rn.GetCode() << 16) | rm.GetCode()); 19313 return; 19314 } 19315 } 19316 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 19317 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 19318 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19319 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19320 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19321 if (cond.Is(al)) { 19322 const DRegister& first = nreglist.GetFirstDRegister(); 19323 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 19324 EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) | 19325 (encoded_align_2.GetEncodingValue() << 4) | 19326 first.Encode(22, 12) | (len_encoding << 5) | 19327 (rn.GetCode() << 16) | rm.GetCode()); 19328 return; 19329 } 19330 } 19331 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 19332 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 19333 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 19334 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 19335 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 19336 if (cond.Is(al)) { 19337 const DRegister& first = nreglist.GetFirstDRegister(); 19338 EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) | 19339 (encoded_align_3.GetEncodingValue() << 4) | 19340 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 19341 return; 19342 } 19343 } 19344 } 19345 } 19346 Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand); 19347 } 19348 19349 void Assembler::vldm(Condition cond, 19350 DataType dt, 19351 Register rn, 19352 WriteBack write_back, 19353 DRegisterList dreglist) { 19354 VIXL_ASSERT(AllowAssembler()); 19355 CheckIT(cond); 19356 USE(dt); 19357 if (IsUsingT32()) { 19358 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 19359 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) || 19360 AllowUnpredictable())) { 19361 const DRegister& dreg = dreglist.GetFirstDRegister(); 19362 unsigned len = dreglist.GetLength() * 2; 19363 EmitT32_32(0xec900b00U | (rn.GetCode() << 16) | 19364 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 19365 (len & 0xff)); 19366 AdvanceIT(); 19367 return; 19368 } 19369 } else { 19370 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 19371 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 19372 (!rn.IsPC() || !write_back.DoesWriteBack())) || 19373 AllowUnpredictable())) { 19374 const DRegister& dreg = dreglist.GetFirstDRegister(); 19375 unsigned len = dreglist.GetLength() * 2; 19376 EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19377 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 19378 (len & 0xff)); 19379 return; 19380 } 19381 } 19382 Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist); 19383 } 19384 19385 void Assembler::vldm(Condition cond, 19386 DataType dt, 19387 Register rn, 19388 WriteBack write_back, 19389 SRegisterList sreglist) { 19390 VIXL_ASSERT(AllowAssembler()); 19391 CheckIT(cond); 19392 USE(dt); 19393 if (IsUsingT32()) { 19394 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 19395 if ((!rn.IsPC() || AllowUnpredictable())) { 19396 const SRegister& sreg = sreglist.GetFirstSRegister(); 19397 unsigned len = sreglist.GetLength(); 19398 EmitT32_32(0xec900a00U | (rn.GetCode() << 16) | 19399 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 19400 (len & 0xff)); 19401 AdvanceIT(); 19402 return; 19403 } 19404 } else { 19405 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 19406 if (cond.IsNotNever() && 19407 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) { 19408 const SRegister& sreg = sreglist.GetFirstSRegister(); 19409 unsigned len = sreglist.GetLength(); 19410 EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19411 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 19412 (len & 0xff)); 19413 return; 19414 } 19415 } 19416 Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist); 19417 } 19418 19419 void Assembler::vldmdb(Condition cond, 19420 DataType dt, 19421 Register rn, 19422 WriteBack write_back, 19423 DRegisterList dreglist) { 19424 VIXL_ASSERT(AllowAssembler()); 19425 CheckIT(cond); 19426 USE(dt); 19427 if (IsUsingT32()) { 19428 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1 19429 if (write_back.DoesWriteBack() && 19430 (((dreglist.GetLength() <= 16) && !rn.IsPC()) || 19431 AllowUnpredictable())) { 19432 const DRegister& dreg = dreglist.GetFirstDRegister(); 19433 unsigned len = dreglist.GetLength() * 2; 19434 EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 19435 (len & 0xff)); 19436 AdvanceIT(); 19437 return; 19438 } 19439 } else { 19440 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1 19441 if (write_back.DoesWriteBack() && cond.IsNotNever() && 19442 (((dreglist.GetLength() <= 16) && !rn.IsPC()) || 19443 AllowUnpredictable())) { 19444 const DRegister& dreg = dreglist.GetFirstDRegister(); 19445 unsigned len = dreglist.GetLength() * 2; 19446 EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19447 dreg.Encode(22, 12) | (len & 0xff)); 19448 return; 19449 } 19450 } 19451 Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist); 19452 } 19453 19454 void Assembler::vldmdb(Condition cond, 19455 DataType dt, 19456 Register rn, 19457 WriteBack write_back, 19458 SRegisterList sreglist) { 19459 VIXL_ASSERT(AllowAssembler()); 19460 CheckIT(cond); 19461 USE(dt); 19462 if (IsUsingT32()) { 19463 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2 19464 if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) { 19465 const SRegister& sreg = sreglist.GetFirstSRegister(); 19466 unsigned len = sreglist.GetLength(); 19467 EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) | 19468 (len & 0xff)); 19469 AdvanceIT(); 19470 return; 19471 } 19472 } else { 19473 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2 19474 if (write_back.DoesWriteBack() && cond.IsNotNever() && 19475 (!rn.IsPC() || AllowUnpredictable())) { 19476 const SRegister& sreg = sreglist.GetFirstSRegister(); 19477 unsigned len = sreglist.GetLength(); 19478 EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19479 sreg.Encode(22, 12) | (len & 0xff)); 19480 return; 19481 } 19482 } 19483 Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist); 19484 } 19485 19486 void Assembler::vldmia(Condition cond, 19487 DataType dt, 19488 Register rn, 19489 WriteBack write_back, 19490 DRegisterList dreglist) { 19491 VIXL_ASSERT(AllowAssembler()); 19492 CheckIT(cond); 19493 USE(dt); 19494 if (IsUsingT32()) { 19495 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 19496 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) || 19497 AllowUnpredictable())) { 19498 const DRegister& dreg = dreglist.GetFirstDRegister(); 19499 unsigned len = dreglist.GetLength() * 2; 19500 EmitT32_32(0xec900b00U | (rn.GetCode() << 16) | 19501 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 19502 (len & 0xff)); 19503 AdvanceIT(); 19504 return; 19505 } 19506 } else { 19507 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 19508 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 19509 (!rn.IsPC() || !write_back.DoesWriteBack())) || 19510 AllowUnpredictable())) { 19511 const DRegister& dreg = dreglist.GetFirstDRegister(); 19512 unsigned len = dreglist.GetLength() * 2; 19513 EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19514 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 19515 (len & 0xff)); 19516 return; 19517 } 19518 } 19519 Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist); 19520 } 19521 19522 void Assembler::vldmia(Condition cond, 19523 DataType dt, 19524 Register rn, 19525 WriteBack write_back, 19526 SRegisterList sreglist) { 19527 VIXL_ASSERT(AllowAssembler()); 19528 CheckIT(cond); 19529 USE(dt); 19530 if (IsUsingT32()) { 19531 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 19532 if ((!rn.IsPC() || AllowUnpredictable())) { 19533 const SRegister& sreg = sreglist.GetFirstSRegister(); 19534 unsigned len = sreglist.GetLength(); 19535 EmitT32_32(0xec900a00U | (rn.GetCode() << 16) | 19536 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 19537 (len & 0xff)); 19538 AdvanceIT(); 19539 return; 19540 } 19541 } else { 19542 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 19543 if (cond.IsNotNever() && 19544 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) { 19545 const SRegister& sreg = sreglist.GetFirstSRegister(); 19546 unsigned len = sreglist.GetLength(); 19547 EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 19548 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 19549 (len & 0xff)); 19550 return; 19551 } 19552 } 19553 Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist); 19554 } 19555 19556 void Assembler::vldr(Condition cond, 19557 DataType dt, 19558 DRegister rd, 19559 Location* location) { 19560 VIXL_ASSERT(AllowAssembler()); 19561 CheckIT(cond); 19562 Location::Offset offset = 19563 location->IsBound() 19564 ? location->GetLocation() - 19565 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 19566 : 0; 19567 if (IsUsingT32()) { 19568 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1 19569 if (dt.IsNoneOr(Untyped64) && 19570 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 19571 ((offset & 0x3) == 0)) || 19572 !location->IsBound())) { 19573 static class EmitOp : public Location::EmitOperator { 19574 public: 19575 EmitOp() : Location::EmitOperator(T32) {} 19576 virtual uint32_t Encode(uint32_t instr, 19577 Location::Offset pc, 19578 const Location* location) const VIXL_OVERRIDE { 19579 pc += kT32PcDelta; 19580 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 19581 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 19582 ((offset & 0x3) == 0)); 19583 int32_t target = offset >> 2; 19584 uint32_t U = (target >= 0); 19585 target = abs(target) | (U << 8); 19586 return instr | (target & 0xff) | ((target & 0x100) << 15); 19587 } 19588 } immop; 19589 EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12), 19590 location, 19591 immop, 19592 &kT32DataInfo)); 19593 AdvanceIT(); 19594 return; 19595 } 19596 } else { 19597 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1 19598 if (dt.IsNoneOr(Untyped64) && 19599 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 19600 ((offset & 0x3) == 0)) || 19601 !location->IsBound()) && 19602 cond.IsNotNever()) { 19603 static class EmitOp : public Location::EmitOperator { 19604 public: 19605 EmitOp() : Location::EmitOperator(A32) {} 19606 virtual uint32_t Encode(uint32_t instr, 19607 Location::Offset pc, 19608 const Location* location) const VIXL_OVERRIDE { 19609 pc += kA32PcDelta; 19610 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 19611 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 19612 ((offset & 0x3) == 0)); 19613 int32_t target = offset >> 2; 19614 uint32_t U = (target >= 0); 19615 target = abs(target) | (U << 8); 19616 return instr | (target & 0xff) | ((target & 0x100) << 15); 19617 } 19618 } immop; 19619 EmitA32( 19620 Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12), 19621 location, 19622 immop, 19623 &kA32DataInfo)); 19624 return; 19625 } 19626 } 19627 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location); 19628 } 19629 19630 bool Assembler::vldr_info(Condition cond, 19631 DataType dt, 19632 DRegister rd, 19633 Location* location, 19634 const struct ReferenceInfo** info) { 19635 VIXL_ASSERT(!location->IsBound()); 19636 USE(location); 19637 USE(rd); 19638 if (IsUsingT32()) { 19639 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1 19640 if (dt.IsNoneOr(Untyped64)) { 19641 *info = &kT32DataInfo; 19642 return true; 19643 } 19644 } else { 19645 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1 19646 if (dt.IsNoneOr(Untyped64) && cond.IsNotNever()) { 19647 *info = &kA32DataInfo; 19648 return true; 19649 } 19650 } 19651 return false; 19652 } 19653 19654 void Assembler::vldr(Condition cond, 19655 DataType dt, 19656 DRegister rd, 19657 const MemOperand& operand) { 19658 VIXL_ASSERT(AllowAssembler()); 19659 CheckIT(cond); 19660 if (operand.IsImmediate()) { 19661 Register rn = operand.GetBaseRegister(); 19662 int32_t offset = operand.GetOffsetImmediate(); 19663 if (IsUsingT32()) { 19664 // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1 19665 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 19666 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) { 19667 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19668 uint32_t offset_ = abs(offset) >> 2; 19669 EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23)); 19670 AdvanceIT(); 19671 return; 19672 } 19673 // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1 19674 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 19675 ((offset % 4) == 0) && operand.IsOffset() && 19676 ((rn.GetCode() & 0xf) != 0xf)) { 19677 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19678 uint32_t offset_ = abs(offset) >> 2; 19679 EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 19680 offset_ | (sign << 23)); 19681 AdvanceIT(); 19682 return; 19683 } 19684 } else { 19685 // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1 19686 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 19687 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() && 19688 cond.IsNotNever()) { 19689 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19690 uint32_t offset_ = abs(offset) >> 2; 19691 EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19692 offset_ | (sign << 23)); 19693 return; 19694 } 19695 // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1 19696 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 19697 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() && 19698 ((rn.GetCode() & 0xf) != 0xf)) { 19699 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19700 uint32_t offset_ = abs(offset) >> 2; 19701 EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19702 (rn.GetCode() << 16) | offset_ | (sign << 23)); 19703 return; 19704 } 19705 } 19706 } 19707 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand); 19708 } 19709 19710 void Assembler::vldr(Condition cond, 19711 DataType dt, 19712 SRegister rd, 19713 Location* location) { 19714 VIXL_ASSERT(AllowAssembler()); 19715 CheckIT(cond); 19716 Location::Offset offset = 19717 location->IsBound() 19718 ? location->GetLocation() - 19719 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 19720 : 0; 19721 if (IsUsingT32()) { 19722 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2 19723 if (dt.IsNoneOr(Untyped32) && 19724 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 19725 ((offset & 0x3) == 0)) || 19726 !location->IsBound())) { 19727 static class EmitOp : public Location::EmitOperator { 19728 public: 19729 EmitOp() : Location::EmitOperator(T32) {} 19730 virtual uint32_t Encode(uint32_t instr, 19731 Location::Offset pc, 19732 const Location* location) const VIXL_OVERRIDE { 19733 pc += kT32PcDelta; 19734 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 19735 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 19736 ((offset & 0x3) == 0)); 19737 int32_t target = offset >> 2; 19738 uint32_t U = (target >= 0); 19739 target = abs(target) | (U << 8); 19740 return instr | (target & 0xff) | ((target & 0x100) << 15); 19741 } 19742 } immop; 19743 EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12), 19744 location, 19745 immop, 19746 &kT32DataInfo)); 19747 AdvanceIT(); 19748 return; 19749 } 19750 } else { 19751 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2 19752 if (dt.IsNoneOr(Untyped32) && 19753 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) && 19754 ((offset & 0x3) == 0)) || 19755 !location->IsBound()) && 19756 cond.IsNotNever()) { 19757 static class EmitOp : public Location::EmitOperator { 19758 public: 19759 EmitOp() : Location::EmitOperator(A32) {} 19760 virtual uint32_t Encode(uint32_t instr, 19761 Location::Offset pc, 19762 const Location* location) const VIXL_OVERRIDE { 19763 pc += kA32PcDelta; 19764 Location::Offset offset = location->GetLocation() - AlignDown(pc, 4); 19765 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 19766 ((offset & 0x3) == 0)); 19767 int32_t target = offset >> 2; 19768 uint32_t U = (target >= 0); 19769 target = abs(target) | (U << 8); 19770 return instr | (target & 0xff) | ((target & 0x100) << 15); 19771 } 19772 } immop; 19773 EmitA32( 19774 Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12), 19775 location, 19776 immop, 19777 &kA32DataInfo)); 19778 return; 19779 } 19780 } 19781 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location); 19782 } 19783 19784 bool Assembler::vldr_info(Condition cond, 19785 DataType dt, 19786 SRegister rd, 19787 Location* location, 19788 const struct ReferenceInfo** info) { 19789 VIXL_ASSERT(!location->IsBound()); 19790 USE(location); 19791 USE(rd); 19792 if (IsUsingT32()) { 19793 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2 19794 if (dt.IsNoneOr(Untyped32)) { 19795 *info = &kT32DataInfo; 19796 return true; 19797 } 19798 } else { 19799 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2 19800 if (dt.IsNoneOr(Untyped32) && cond.IsNotNever()) { 19801 *info = &kA32DataInfo; 19802 return true; 19803 } 19804 } 19805 return false; 19806 } 19807 19808 void Assembler::vldr(Condition cond, 19809 DataType dt, 19810 SRegister rd, 19811 const MemOperand& operand) { 19812 VIXL_ASSERT(AllowAssembler()); 19813 CheckIT(cond); 19814 if (operand.IsImmediate()) { 19815 Register rn = operand.GetBaseRegister(); 19816 int32_t offset = operand.GetOffsetImmediate(); 19817 if (IsUsingT32()) { 19818 // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2 19819 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 19820 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) { 19821 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19822 uint32_t offset_ = abs(offset) >> 2; 19823 EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23)); 19824 AdvanceIT(); 19825 return; 19826 } 19827 // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2 19828 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 19829 ((offset % 4) == 0) && operand.IsOffset() && 19830 ((rn.GetCode() & 0xf) != 0xf)) { 19831 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19832 uint32_t offset_ = abs(offset) >> 2; 19833 EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 19834 offset_ | (sign << 23)); 19835 AdvanceIT(); 19836 return; 19837 } 19838 } else { 19839 // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2 19840 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 19841 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() && 19842 cond.IsNotNever()) { 19843 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19844 uint32_t offset_ = abs(offset) >> 2; 19845 EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19846 offset_ | (sign << 23)); 19847 return; 19848 } 19849 // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2 19850 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 19851 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() && 19852 ((rn.GetCode() & 0xf) != 0xf)) { 19853 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 19854 uint32_t offset_ = abs(offset) >> 2; 19855 EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19856 (rn.GetCode() << 16) | offset_ | (sign << 23)); 19857 return; 19858 } 19859 } 19860 } 19861 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand); 19862 } 19863 19864 void Assembler::vmax( 19865 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 19866 VIXL_ASSERT(AllowAssembler()); 19867 CheckIT(cond); 19868 Dt_U_size_1 encoded_dt(dt); 19869 if (IsUsingT32()) { 19870 // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 19871 if (dt.Is(F32)) { 19872 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19873 EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19874 rm.Encode(5, 0)); 19875 AdvanceIT(); 19876 return; 19877 } 19878 } 19879 // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 19880 if (encoded_dt.IsValid()) { 19881 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19882 EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 19883 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 19884 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19885 AdvanceIT(); 19886 return; 19887 } 19888 } 19889 } else { 19890 // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 19891 if (dt.Is(F32)) { 19892 if (cond.Is(al)) { 19893 EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19894 rm.Encode(5, 0)); 19895 return; 19896 } 19897 } 19898 // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 19899 if (encoded_dt.IsValid()) { 19900 if (cond.Is(al)) { 19901 EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 19902 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 19903 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19904 return; 19905 } 19906 } 19907 } 19908 Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm); 19909 } 19910 19911 void Assembler::vmax( 19912 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 19913 VIXL_ASSERT(AllowAssembler()); 19914 CheckIT(cond); 19915 Dt_U_size_1 encoded_dt(dt); 19916 if (IsUsingT32()) { 19917 // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 19918 if (dt.Is(F32)) { 19919 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19920 EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19921 rm.Encode(5, 0)); 19922 AdvanceIT(); 19923 return; 19924 } 19925 } 19926 // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 19927 if (encoded_dt.IsValid()) { 19928 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19929 EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 19930 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 19931 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19932 AdvanceIT(); 19933 return; 19934 } 19935 } 19936 } else { 19937 // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 19938 if (dt.Is(F32)) { 19939 if (cond.Is(al)) { 19940 EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19941 rm.Encode(5, 0)); 19942 return; 19943 } 19944 } 19945 // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 19946 if (encoded_dt.IsValid()) { 19947 if (cond.Is(al)) { 19948 EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 19949 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 19950 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19951 return; 19952 } 19953 } 19954 } 19955 Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm); 19956 } 19957 19958 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 19959 VIXL_ASSERT(AllowAssembler()); 19960 CheckIT(al); 19961 if (IsUsingT32()) { 19962 // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 19963 if (OutsideITBlock() && dt.Is(F32)) { 19964 EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19965 rm.Encode(5, 0)); 19966 AdvanceIT(); 19967 return; 19968 } 19969 // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 19970 if (OutsideITBlock() && dt.Is(F64)) { 19971 EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19972 rm.Encode(5, 0)); 19973 AdvanceIT(); 19974 return; 19975 } 19976 } else { 19977 // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 19978 if (dt.Is(F32)) { 19979 EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19980 rm.Encode(5, 0)); 19981 return; 19982 } 19983 // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 19984 if (dt.Is(F64)) { 19985 EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19986 rm.Encode(5, 0)); 19987 return; 19988 } 19989 } 19990 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 19991 } 19992 19993 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) { 19994 VIXL_ASSERT(AllowAssembler()); 19995 CheckIT(al); 19996 if (IsUsingT32()) { 19997 // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 19998 if (OutsideITBlock() && dt.Is(F32)) { 19999 EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20000 rm.Encode(5, 0)); 20001 AdvanceIT(); 20002 return; 20003 } 20004 } else { 20005 // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 20006 if (dt.Is(F32)) { 20007 EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20008 rm.Encode(5, 0)); 20009 return; 20010 } 20011 } 20012 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 20013 } 20014 20015 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20016 VIXL_ASSERT(AllowAssembler()); 20017 CheckIT(al); 20018 if (IsUsingT32()) { 20019 // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 20020 if (OutsideITBlock() && dt.Is(F32)) { 20021 EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20022 rm.Encode(5, 0)); 20023 AdvanceIT(); 20024 return; 20025 } 20026 } else { 20027 // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 20028 if (dt.Is(F32)) { 20029 EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20030 rm.Encode(5, 0)); 20031 return; 20032 } 20033 } 20034 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 20035 } 20036 20037 void Assembler::vmin( 20038 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20039 VIXL_ASSERT(AllowAssembler()); 20040 CheckIT(cond); 20041 Dt_U_size_1 encoded_dt(dt); 20042 if (IsUsingT32()) { 20043 // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 20044 if (dt.Is(F32)) { 20045 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20046 EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20047 rm.Encode(5, 0)); 20048 AdvanceIT(); 20049 return; 20050 } 20051 } 20052 // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 20053 if (encoded_dt.IsValid()) { 20054 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20055 EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20056 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 20057 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20058 AdvanceIT(); 20059 return; 20060 } 20061 } 20062 } else { 20063 // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 20064 if (dt.Is(F32)) { 20065 if (cond.Is(al)) { 20066 EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20067 rm.Encode(5, 0)); 20068 return; 20069 } 20070 } 20071 // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 20072 if (encoded_dt.IsValid()) { 20073 if (cond.Is(al)) { 20074 EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20075 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20076 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20077 return; 20078 } 20079 } 20080 } 20081 Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm); 20082 } 20083 20084 void Assembler::vmin( 20085 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20086 VIXL_ASSERT(AllowAssembler()); 20087 CheckIT(cond); 20088 Dt_U_size_1 encoded_dt(dt); 20089 if (IsUsingT32()) { 20090 // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 20091 if (dt.Is(F32)) { 20092 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20093 EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20094 rm.Encode(5, 0)); 20095 AdvanceIT(); 20096 return; 20097 } 20098 } 20099 // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 20100 if (encoded_dt.IsValid()) { 20101 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20102 EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20103 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 20104 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20105 AdvanceIT(); 20106 return; 20107 } 20108 } 20109 } else { 20110 // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 20111 if (dt.Is(F32)) { 20112 if (cond.Is(al)) { 20113 EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20114 rm.Encode(5, 0)); 20115 return; 20116 } 20117 } 20118 // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 20119 if (encoded_dt.IsValid()) { 20120 if (cond.Is(al)) { 20121 EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20122 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20123 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20124 return; 20125 } 20126 } 20127 } 20128 Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm); 20129 } 20130 20131 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20132 VIXL_ASSERT(AllowAssembler()); 20133 CheckIT(al); 20134 if (IsUsingT32()) { 20135 // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 20136 if (OutsideITBlock() && dt.Is(F32)) { 20137 EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20138 rm.Encode(5, 0)); 20139 AdvanceIT(); 20140 return; 20141 } 20142 // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 20143 if (OutsideITBlock() && dt.Is(F64)) { 20144 EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20145 rm.Encode(5, 0)); 20146 AdvanceIT(); 20147 return; 20148 } 20149 } else { 20150 // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 20151 if (dt.Is(F32)) { 20152 EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20153 rm.Encode(5, 0)); 20154 return; 20155 } 20156 // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 20157 if (dt.Is(F64)) { 20158 EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20159 rm.Encode(5, 0)); 20160 return; 20161 } 20162 } 20163 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 20164 } 20165 20166 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20167 VIXL_ASSERT(AllowAssembler()); 20168 CheckIT(al); 20169 if (IsUsingT32()) { 20170 // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 20171 if (OutsideITBlock() && dt.Is(F32)) { 20172 EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20173 rm.Encode(5, 0)); 20174 AdvanceIT(); 20175 return; 20176 } 20177 } else { 20178 // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 20179 if (dt.Is(F32)) { 20180 EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20181 rm.Encode(5, 0)); 20182 return; 20183 } 20184 } 20185 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 20186 } 20187 20188 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20189 VIXL_ASSERT(AllowAssembler()); 20190 CheckIT(al); 20191 if (IsUsingT32()) { 20192 // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 20193 if (OutsideITBlock() && dt.Is(F32)) { 20194 EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20195 rm.Encode(5, 0)); 20196 AdvanceIT(); 20197 return; 20198 } 20199 } else { 20200 // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 20201 if (dt.Is(F32)) { 20202 EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20203 rm.Encode(5, 0)); 20204 return; 20205 } 20206 } 20207 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 20208 } 20209 20210 void Assembler::vmla( 20211 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 20212 VIXL_ASSERT(AllowAssembler()); 20213 CheckIT(cond); 20214 Dt_size_9 encoded_dt(dt); 20215 if (IsUsingT32()) { 20216 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1 20217 if (encoded_dt.IsValid() && 20218 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20219 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20220 (rm.GetLane() <= 1)))) { 20221 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20222 EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 20223 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20224 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20225 AdvanceIT(); 20226 return; 20227 } 20228 } 20229 } else { 20230 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1 20231 if (encoded_dt.IsValid() && 20232 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20233 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20234 (rm.GetLane() <= 1)))) { 20235 if (cond.Is(al)) { 20236 EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 20237 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20238 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20239 return; 20240 } 20241 } 20242 } 20243 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20244 } 20245 20246 void Assembler::vmla( 20247 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 20248 VIXL_ASSERT(AllowAssembler()); 20249 CheckIT(cond); 20250 Dt_size_9 encoded_dt(dt); 20251 if (IsUsingT32()) { 20252 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1 20253 if (encoded_dt.IsValid() && 20254 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20255 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20256 (rm.GetLane() <= 1)))) { 20257 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20258 EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 20259 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20260 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20261 AdvanceIT(); 20262 return; 20263 } 20264 } 20265 } else { 20266 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1 20267 if (encoded_dt.IsValid() && 20268 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20269 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20270 (rm.GetLane() <= 1)))) { 20271 if (cond.Is(al)) { 20272 EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 20273 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20274 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20275 return; 20276 } 20277 } 20278 } 20279 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20280 } 20281 20282 void Assembler::vmla( 20283 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20284 VIXL_ASSERT(AllowAssembler()); 20285 CheckIT(cond); 20286 Dt_size_10 encoded_dt(dt); 20287 if (IsUsingT32()) { 20288 // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 20289 if (dt.Is(F32)) { 20290 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20291 EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20292 rm.Encode(5, 0)); 20293 AdvanceIT(); 20294 return; 20295 } 20296 } 20297 // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 20298 if (dt.Is(F64)) { 20299 EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20300 rm.Encode(5, 0)); 20301 AdvanceIT(); 20302 return; 20303 } 20304 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1 20305 if (encoded_dt.IsValid()) { 20306 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20307 EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) | 20308 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20309 AdvanceIT(); 20310 return; 20311 } 20312 } 20313 } else { 20314 // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 20315 if (dt.Is(F32)) { 20316 if (cond.Is(al)) { 20317 EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20318 rm.Encode(5, 0)); 20319 return; 20320 } 20321 } 20322 // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 20323 if (dt.Is(F64) && cond.IsNotNever()) { 20324 EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20325 rn.Encode(7, 16) | rm.Encode(5, 0)); 20326 return; 20327 } 20328 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1 20329 if (encoded_dt.IsValid()) { 20330 if (cond.Is(al)) { 20331 EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) | 20332 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20333 return; 20334 } 20335 } 20336 } 20337 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20338 } 20339 20340 void Assembler::vmla( 20341 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20342 VIXL_ASSERT(AllowAssembler()); 20343 CheckIT(cond); 20344 Dt_size_10 encoded_dt(dt); 20345 if (IsUsingT32()) { 20346 // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 20347 if (dt.Is(F32)) { 20348 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20349 EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20350 rm.Encode(5, 0)); 20351 AdvanceIT(); 20352 return; 20353 } 20354 } 20355 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1 20356 if (encoded_dt.IsValid()) { 20357 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20358 EmitT32_32(0xef000940U | (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 <Qd>, <Qn>, <Qm> ; A1 20366 if (dt.Is(F32)) { 20367 if (cond.Is(al)) { 20368 EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20369 rm.Encode(5, 0)); 20370 return; 20371 } 20372 } 20373 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1 20374 if (encoded_dt.IsValid()) { 20375 if (cond.Is(al)) { 20376 EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) | 20377 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20378 return; 20379 } 20380 } 20381 } 20382 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20383 } 20384 20385 void Assembler::vmla( 20386 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20387 VIXL_ASSERT(AllowAssembler()); 20388 CheckIT(cond); 20389 if (IsUsingT32()) { 20390 // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 20391 if (dt.Is(F32)) { 20392 EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20393 rm.Encode(5, 0)); 20394 AdvanceIT(); 20395 return; 20396 } 20397 } else { 20398 // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 20399 if (dt.Is(F32) && cond.IsNotNever()) { 20400 EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20401 rn.Encode(7, 16) | rm.Encode(5, 0)); 20402 return; 20403 } 20404 } 20405 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 20406 } 20407 20408 void Assembler::vmlal( 20409 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 20410 VIXL_ASSERT(AllowAssembler()); 20411 CheckIT(cond); 20412 Dt_size_11 encoded_dt(dt); 20413 if (IsUsingT32()) { 20414 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1 20415 if (encoded_dt.IsValid() && 20416 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20417 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20418 (rm.GetLane() <= 1)))) { 20419 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20420 EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) | 20421 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20422 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20423 AdvanceIT(); 20424 return; 20425 } 20426 } 20427 } else { 20428 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1 20429 if (encoded_dt.IsValid() && 20430 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20431 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20432 (rm.GetLane() <= 1)))) { 20433 if (cond.Is(al)) { 20434 EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) | 20435 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20436 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20437 return; 20438 } 20439 } 20440 } 20441 Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm); 20442 } 20443 20444 void Assembler::vmlal( 20445 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 20446 VIXL_ASSERT(AllowAssembler()); 20447 CheckIT(cond); 20448 Dt_size_12 encoded_dt(dt); 20449 if (IsUsingT32()) { 20450 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1 20451 if (encoded_dt.IsValid()) { 20452 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20453 EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) | 20454 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20455 rn.Encode(7, 16) | rm.Encode(5, 0)); 20456 AdvanceIT(); 20457 return; 20458 } 20459 } 20460 } else { 20461 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1 20462 if (encoded_dt.IsValid()) { 20463 if (cond.Is(al)) { 20464 EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) | 20465 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20466 rn.Encode(7, 16) | rm.Encode(5, 0)); 20467 return; 20468 } 20469 } 20470 } 20471 Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm); 20472 } 20473 20474 void Assembler::vmls( 20475 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 20476 VIXL_ASSERT(AllowAssembler()); 20477 CheckIT(cond); 20478 Dt_size_9 encoded_dt(dt); 20479 if (IsUsingT32()) { 20480 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1 20481 if (encoded_dt.IsValid() && 20482 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20483 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20484 (rm.GetLane() <= 1)))) { 20485 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20486 EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 20487 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20488 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20489 AdvanceIT(); 20490 return; 20491 } 20492 } 20493 } else { 20494 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1 20495 if (encoded_dt.IsValid() && 20496 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20497 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20498 (rm.GetLane() <= 1)))) { 20499 if (cond.Is(al)) { 20500 EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 20501 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20502 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20503 return; 20504 } 20505 } 20506 } 20507 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20508 } 20509 20510 void Assembler::vmls( 20511 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 20512 VIXL_ASSERT(AllowAssembler()); 20513 CheckIT(cond); 20514 Dt_size_9 encoded_dt(dt); 20515 if (IsUsingT32()) { 20516 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1 20517 if (encoded_dt.IsValid() && 20518 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20519 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20520 (rm.GetLane() <= 1)))) { 20521 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20522 EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 20523 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20524 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20525 AdvanceIT(); 20526 return; 20527 } 20528 } 20529 } else { 20530 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1 20531 if (encoded_dt.IsValid() && 20532 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20533 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20534 (rm.GetLane() <= 1)))) { 20535 if (cond.Is(al)) { 20536 EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 20537 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20538 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20539 return; 20540 } 20541 } 20542 } 20543 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20544 } 20545 20546 void Assembler::vmls( 20547 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20548 VIXL_ASSERT(AllowAssembler()); 20549 CheckIT(cond); 20550 Dt_size_10 encoded_dt(dt); 20551 if (IsUsingT32()) { 20552 // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 20553 if (dt.Is(F32)) { 20554 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20555 EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20556 rm.Encode(5, 0)); 20557 AdvanceIT(); 20558 return; 20559 } 20560 } 20561 // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 20562 if (dt.Is(F64)) { 20563 EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20564 rm.Encode(5, 0)); 20565 AdvanceIT(); 20566 return; 20567 } 20568 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1 20569 if (encoded_dt.IsValid()) { 20570 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20571 EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) | 20572 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20573 AdvanceIT(); 20574 return; 20575 } 20576 } 20577 } else { 20578 // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 20579 if (dt.Is(F32)) { 20580 if (cond.Is(al)) { 20581 EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20582 rm.Encode(5, 0)); 20583 return; 20584 } 20585 } 20586 // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 20587 if (dt.Is(F64) && cond.IsNotNever()) { 20588 EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20589 rn.Encode(7, 16) | rm.Encode(5, 0)); 20590 return; 20591 } 20592 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1 20593 if (encoded_dt.IsValid()) { 20594 if (cond.Is(al)) { 20595 EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) | 20596 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20597 return; 20598 } 20599 } 20600 } 20601 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20602 } 20603 20604 void Assembler::vmls( 20605 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20606 VIXL_ASSERT(AllowAssembler()); 20607 CheckIT(cond); 20608 Dt_size_10 encoded_dt(dt); 20609 if (IsUsingT32()) { 20610 // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 20611 if (dt.Is(F32)) { 20612 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20613 EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20614 rm.Encode(5, 0)); 20615 AdvanceIT(); 20616 return; 20617 } 20618 } 20619 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1 20620 if (encoded_dt.IsValid()) { 20621 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20622 EmitT32_32(0xff000940U | (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 <Qd>, <Qn>, <Qm> ; A1 20630 if (dt.Is(F32)) { 20631 if (cond.Is(al)) { 20632 EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20633 rm.Encode(5, 0)); 20634 return; 20635 } 20636 } 20637 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1 20638 if (encoded_dt.IsValid()) { 20639 if (cond.Is(al)) { 20640 EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) | 20641 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20642 return; 20643 } 20644 } 20645 } 20646 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20647 } 20648 20649 void Assembler::vmls( 20650 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20651 VIXL_ASSERT(AllowAssembler()); 20652 CheckIT(cond); 20653 if (IsUsingT32()) { 20654 // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 20655 if (dt.Is(F32)) { 20656 EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20657 rm.Encode(5, 0)); 20658 AdvanceIT(); 20659 return; 20660 } 20661 } else { 20662 // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 20663 if (dt.Is(F32) && cond.IsNotNever()) { 20664 EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20665 rn.Encode(7, 16) | rm.Encode(5, 0)); 20666 return; 20667 } 20668 } 20669 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 20670 } 20671 20672 void Assembler::vmlsl( 20673 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 20674 VIXL_ASSERT(AllowAssembler()); 20675 CheckIT(cond); 20676 Dt_size_11 encoded_dt(dt); 20677 if (IsUsingT32()) { 20678 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1 20679 if (encoded_dt.IsValid() && 20680 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20681 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20682 (rm.GetLane() <= 1)))) { 20683 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20684 EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) | 20685 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20686 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20687 AdvanceIT(); 20688 return; 20689 } 20690 } 20691 } else { 20692 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1 20693 if (encoded_dt.IsValid() && 20694 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 20695 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 20696 (rm.GetLane() <= 1)))) { 20697 if (cond.Is(al)) { 20698 EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) | 20699 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20700 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 20701 return; 20702 } 20703 } 20704 } 20705 Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm); 20706 } 20707 20708 void Assembler::vmlsl( 20709 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 20710 VIXL_ASSERT(AllowAssembler()); 20711 CheckIT(cond); 20712 Dt_size_12 encoded_dt(dt); 20713 if (IsUsingT32()) { 20714 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1 20715 if (encoded_dt.IsValid()) { 20716 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20717 EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) | 20718 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20719 rn.Encode(7, 16) | rm.Encode(5, 0)); 20720 AdvanceIT(); 20721 return; 20722 } 20723 } 20724 } else { 20725 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1 20726 if (encoded_dt.IsValid()) { 20727 if (cond.Is(al)) { 20728 EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) | 20729 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 20730 rn.Encode(7, 16) | rm.Encode(5, 0)); 20731 return; 20732 } 20733 } 20734 } 20735 Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm); 20736 } 20737 20738 void Assembler::vmov(Condition cond, Register rt, SRegister rn) { 20739 VIXL_ASSERT(AllowAssembler()); 20740 CheckIT(cond); 20741 if (IsUsingT32()) { 20742 // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1 20743 if ((!rt.IsPC() || AllowUnpredictable())) { 20744 EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16)); 20745 AdvanceIT(); 20746 return; 20747 } 20748 } else { 20749 // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1 20750 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 20751 EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 20752 rn.Encode(7, 16)); 20753 return; 20754 } 20755 } 20756 Delegate(kVmov, &Assembler::vmov, cond, rt, rn); 20757 } 20758 20759 void Assembler::vmov(Condition cond, SRegister rn, Register rt) { 20760 VIXL_ASSERT(AllowAssembler()); 20761 CheckIT(cond); 20762 if (IsUsingT32()) { 20763 // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1 20764 if ((!rt.IsPC() || AllowUnpredictable())) { 20765 EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12)); 20766 AdvanceIT(); 20767 return; 20768 } 20769 } else { 20770 // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1 20771 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 20772 EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) | 20773 (rt.GetCode() << 12)); 20774 return; 20775 } 20776 } 20777 Delegate(kVmov, &Assembler::vmov, cond, rn, rt); 20778 } 20779 20780 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) { 20781 VIXL_ASSERT(AllowAssembler()); 20782 CheckIT(cond); 20783 if (IsUsingT32()) { 20784 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1 20785 if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20786 EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) | 20787 rm.Encode(5, 0)); 20788 AdvanceIT(); 20789 return; 20790 } 20791 } else { 20792 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1 20793 if (cond.IsNotNever() && 20794 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20795 EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 20796 (rt2.GetCode() << 16) | rm.Encode(5, 0)); 20797 return; 20798 } 20799 } 20800 Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm); 20801 } 20802 20803 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) { 20804 VIXL_ASSERT(AllowAssembler()); 20805 CheckIT(cond); 20806 if (IsUsingT32()) { 20807 // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1 20808 if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20809 EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) | 20810 (rt2.GetCode() << 16)); 20811 AdvanceIT(); 20812 return; 20813 } 20814 } else { 20815 // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1 20816 if (cond.IsNotNever() && 20817 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20818 EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) | 20819 (rt.GetCode() << 12) | (rt2.GetCode() << 16)); 20820 return; 20821 } 20822 } 20823 Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2); 20824 } 20825 20826 void Assembler::vmov( 20827 Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) { 20828 VIXL_ASSERT(AllowAssembler()); 20829 CheckIT(cond); 20830 if (IsUsingT32()) { 20831 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1 20832 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 20833 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20834 EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) | 20835 rm.Encode(5, 0)); 20836 AdvanceIT(); 20837 return; 20838 } 20839 } else { 20840 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1 20841 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 20842 cond.IsNotNever() && 20843 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20844 EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 20845 (rt2.GetCode() << 16) | rm.Encode(5, 0)); 20846 return; 20847 } 20848 } 20849 Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1); 20850 } 20851 20852 void Assembler::vmov( 20853 Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) { 20854 VIXL_ASSERT(AllowAssembler()); 20855 CheckIT(cond); 20856 if (IsUsingT32()) { 20857 // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1 20858 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 20859 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20860 EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) | 20861 (rt2.GetCode() << 16)); 20862 AdvanceIT(); 20863 return; 20864 } 20865 } else { 20866 // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1 20867 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 20868 cond.IsNotNever() && 20869 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) { 20870 EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) | 20871 (rt.GetCode() << 12) | (rt2.GetCode() << 16)); 20872 return; 20873 } 20874 } 20875 Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2); 20876 } 20877 20878 void Assembler::vmov(Condition cond, 20879 DataType dt, 20880 DRegisterLane rd, 20881 Register rt) { 20882 VIXL_ASSERT(AllowAssembler()); 20883 CheckIT(cond); 20884 Dt_opc1_opc2_1 encoded_dt(dt, rd); 20885 if (IsUsingT32()) { 20886 // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1 20887 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) { 20888 EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 20889 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 20890 rd.Encode(7, 16) | (rt.GetCode() << 12)); 20891 AdvanceIT(); 20892 return; 20893 } 20894 } else { 20895 // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1 20896 if (encoded_dt.IsValid() && cond.IsNotNever() && 20897 (!rt.IsPC() || AllowUnpredictable())) { 20898 EmitA32(0x0e000b10U | (cond.GetCondition() << 28) | 20899 ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 20900 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) | 20901 (rt.GetCode() << 12)); 20902 return; 20903 } 20904 } 20905 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt); 20906 } 20907 20908 void Assembler::vmov(Condition cond, 20909 DataType dt, 20910 DRegister rd, 20911 const DOperand& operand) { 20912 VIXL_ASSERT(AllowAssembler()); 20913 CheckIT(cond); 20914 if (operand.IsImmediate()) { 20915 ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate()); 20916 if (IsUsingT32()) { 20917 // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 20918 if (encoded_dt.IsValid()) { 20919 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20920 EmitT32_32( 20921 0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 20922 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 20923 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20924 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20925 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 20926 AdvanceIT(); 20927 return; 20928 } 20929 } 20930 } else { 20931 // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 20932 if (encoded_dt.IsValid()) { 20933 if (cond.Is(al)) { 20934 EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 20935 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 20936 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20937 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20938 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 20939 return; 20940 } 20941 } 20942 } 20943 } 20944 if (operand.IsImmediate()) { 20945 ImmediateVFP vfp(operand.GetNeonImmediate()); 20946 if (IsUsingT32()) { 20947 // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2 20948 if (dt.Is(F64) && vfp.IsValid()) { 20949 EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) | 20950 (vfp.GetEncodingValue() & 0xf) | 20951 ((vfp.GetEncodingValue() & 0xf0) << 12)); 20952 AdvanceIT(); 20953 return; 20954 } 20955 } else { 20956 // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2 20957 if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) { 20958 EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20959 (vfp.GetEncodingValue() & 0xf) | 20960 ((vfp.GetEncodingValue() & 0xf0) << 12)); 20961 return; 20962 } 20963 } 20964 } 20965 if (operand.IsRegister()) { 20966 DRegister rm = operand.GetRegister(); 20967 if (IsUsingT32()) { 20968 // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 20969 if (dt.Is(F64)) { 20970 EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 20971 AdvanceIT(); 20972 return; 20973 } 20974 // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 20975 if (!dt.Is(F64)) { 20976 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20977 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 20978 rm.Encode(5, 0)); 20979 AdvanceIT(); 20980 return; 20981 } 20982 } 20983 } else { 20984 // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 20985 if (dt.Is(F64) && cond.IsNotNever()) { 20986 EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20987 rm.Encode(5, 0)); 20988 return; 20989 } 20990 // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 20991 if (!dt.Is(F64)) { 20992 if (cond.Is(al)) { 20993 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 20994 rm.Encode(5, 0)); 20995 return; 20996 } 20997 } 20998 } 20999 } 21000 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 21001 } 21002 21003 void Assembler::vmov(Condition cond, 21004 DataType dt, 21005 QRegister rd, 21006 const QOperand& operand) { 21007 VIXL_ASSERT(AllowAssembler()); 21008 CheckIT(cond); 21009 if (operand.IsImmediate()) { 21010 ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate()); 21011 if (IsUsingT32()) { 21012 // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 21013 if (encoded_dt.IsValid()) { 21014 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21015 EmitT32_32( 21016 0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 21017 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 21018 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21019 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21020 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21021 AdvanceIT(); 21022 return; 21023 } 21024 } 21025 } else { 21026 // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 21027 if (encoded_dt.IsValid()) { 21028 if (cond.Is(al)) { 21029 EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 21030 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 21031 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21032 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21033 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21034 return; 21035 } 21036 } 21037 } 21038 } 21039 if (operand.IsRegister()) { 21040 QRegister rm = operand.GetRegister(); 21041 if (IsUsingT32()) { 21042 // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 21043 if (!dt.Is(F64)) { 21044 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21045 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 21046 rm.Encode(5, 0)); 21047 AdvanceIT(); 21048 return; 21049 } 21050 } 21051 } else { 21052 // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 21053 if (!dt.Is(F64)) { 21054 if (cond.Is(al)) { 21055 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 21056 rm.Encode(5, 0)); 21057 return; 21058 } 21059 } 21060 } 21061 } 21062 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 21063 } 21064 21065 void Assembler::vmov(Condition cond, 21066 DataType dt, 21067 SRegister rd, 21068 const SOperand& operand) { 21069 VIXL_ASSERT(AllowAssembler()); 21070 CheckIT(cond); 21071 if (operand.IsImmediate()) { 21072 ImmediateVFP vfp(operand.GetNeonImmediate()); 21073 if (IsUsingT32()) { 21074 // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2 21075 if (dt.Is(F32) && vfp.IsValid()) { 21076 EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) | 21077 (vfp.GetEncodingValue() & 0xf) | 21078 ((vfp.GetEncodingValue() & 0xf0) << 12)); 21079 AdvanceIT(); 21080 return; 21081 } 21082 } else { 21083 // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2 21084 if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) { 21085 EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21086 (vfp.GetEncodingValue() & 0xf) | 21087 ((vfp.GetEncodingValue() & 0xf0) << 12)); 21088 return; 21089 } 21090 } 21091 } 21092 if (operand.IsRegister()) { 21093 SRegister rm = operand.GetRegister(); 21094 if (IsUsingT32()) { 21095 // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 21096 if (dt.Is(F32)) { 21097 EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21098 AdvanceIT(); 21099 return; 21100 } 21101 } else { 21102 // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 21103 if (dt.Is(F32) && cond.IsNotNever()) { 21104 EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21105 rm.Encode(5, 0)); 21106 return; 21107 } 21108 } 21109 } 21110 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 21111 } 21112 21113 void Assembler::vmov(Condition cond, 21114 DataType dt, 21115 Register rt, 21116 DRegisterLane rn) { 21117 VIXL_ASSERT(AllowAssembler()); 21118 CheckIT(cond); 21119 Dt_U_opc1_opc2_1 encoded_dt(dt, rn); 21120 if (IsUsingT32()) { 21121 // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1 21122 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) { 21123 EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 21124 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 21125 ((encoded_dt.GetEncodingValue() & 0x10) << 19) | 21126 (rt.GetCode() << 12) | rn.Encode(7, 16)); 21127 AdvanceIT(); 21128 return; 21129 } 21130 } else { 21131 // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1 21132 if (encoded_dt.IsValid() && cond.IsNotNever() && 21133 (!rt.IsPC() || AllowUnpredictable())) { 21134 EmitA32(0x0e100b10U | (cond.GetCondition() << 28) | 21135 ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 21136 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 21137 ((encoded_dt.GetEncodingValue() & 0x10) << 19) | 21138 (rt.GetCode() << 12) | rn.Encode(7, 16)); 21139 return; 21140 } 21141 } 21142 Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn); 21143 } 21144 21145 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) { 21146 VIXL_ASSERT(AllowAssembler()); 21147 CheckIT(cond); 21148 Dt_U_imm3H_1 encoded_dt(dt); 21149 if (IsUsingT32()) { 21150 // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1 21151 if (encoded_dt.IsValid()) { 21152 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21153 EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 21154 ((encoded_dt.GetEncodingValue() & 0x8) << 25) | 21155 rd.Encode(22, 12) | rm.Encode(5, 0)); 21156 AdvanceIT(); 21157 return; 21158 } 21159 } 21160 } else { 21161 // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1 21162 if (encoded_dt.IsValid()) { 21163 if (cond.Is(al)) { 21164 EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 21165 ((encoded_dt.GetEncodingValue() & 0x8) << 21) | 21166 rd.Encode(22, 12) | rm.Encode(5, 0)); 21167 return; 21168 } 21169 } 21170 } 21171 Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm); 21172 } 21173 21174 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) { 21175 VIXL_ASSERT(AllowAssembler()); 21176 CheckIT(cond); 21177 Dt_size_3 encoded_dt(dt); 21178 if (IsUsingT32()) { 21179 // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 21180 if (encoded_dt.IsValid()) { 21181 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21182 EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) | 21183 rd.Encode(22, 12) | rm.Encode(5, 0)); 21184 AdvanceIT(); 21185 return; 21186 } 21187 } 21188 } else { 21189 // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 21190 if (encoded_dt.IsValid()) { 21191 if (cond.Is(al)) { 21192 EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) | 21193 rd.Encode(22, 12) | rm.Encode(5, 0)); 21194 return; 21195 } 21196 } 21197 } 21198 Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm); 21199 } 21200 21201 void Assembler::vmrs(Condition cond, 21202 RegisterOrAPSR_nzcv rt, 21203 SpecialFPRegister spec_reg) { 21204 VIXL_ASSERT(AllowAssembler()); 21205 CheckIT(cond); 21206 if (IsUsingT32()) { 21207 // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1 21208 EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16)); 21209 AdvanceIT(); 21210 return; 21211 } else { 21212 // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1 21213 if (cond.IsNotNever()) { 21214 EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 21215 (spec_reg.GetReg() << 16)); 21216 return; 21217 } 21218 } 21219 Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg); 21220 } 21221 21222 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) { 21223 VIXL_ASSERT(AllowAssembler()); 21224 CheckIT(cond); 21225 if (IsUsingT32()) { 21226 // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1 21227 if ((!rt.IsPC() || AllowUnpredictable())) { 21228 EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) | 21229 (rt.GetCode() << 12)); 21230 AdvanceIT(); 21231 return; 21232 } 21233 } else { 21234 // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1 21235 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 21236 EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) | 21237 (spec_reg.GetReg() << 16) | (rt.GetCode() << 12)); 21238 return; 21239 } 21240 } 21241 Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt); 21242 } 21243 21244 void Assembler::vmul(Condition cond, 21245 DataType dt, 21246 DRegister rd, 21247 DRegister rn, 21248 DRegister dm, 21249 unsigned index) { 21250 VIXL_ASSERT(AllowAssembler()); 21251 CheckIT(cond); 21252 Dt_F_size_3 encoded_dt(dt); 21253 if (IsUsingT32()) { 21254 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1 21255 if (encoded_dt.IsValid() && 21256 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 21257 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) { 21258 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21259 uint32_t shift = 4; 21260 if (dt.Is(I16)) { 21261 shift = 3; 21262 } 21263 uint32_t mvm = dm.GetCode() | index << shift; 21264 EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21265 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 21266 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21267 ((mvm & 0x10) << 1)); 21268 AdvanceIT(); 21269 return; 21270 } 21271 } 21272 } else { 21273 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1 21274 if (encoded_dt.IsValid() && 21275 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 21276 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) { 21277 if (cond.Is(al)) { 21278 uint32_t shift = 4; 21279 if (dt.Is(I16)) { 21280 shift = 3; 21281 } 21282 uint32_t mvm = dm.GetCode() | index << shift; 21283 EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21284 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 21285 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21286 ((mvm & 0x10) << 1)); 21287 return; 21288 } 21289 } 21290 } 21291 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index); 21292 } 21293 21294 void Assembler::vmul(Condition cond, 21295 DataType dt, 21296 QRegister rd, 21297 QRegister rn, 21298 DRegister dm, 21299 unsigned index) { 21300 VIXL_ASSERT(AllowAssembler()); 21301 CheckIT(cond); 21302 Dt_F_size_3 encoded_dt(dt); 21303 if (IsUsingT32()) { 21304 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1 21305 if (encoded_dt.IsValid() && 21306 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 21307 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) { 21308 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21309 uint32_t shift = 4; 21310 if (dt.Is(I16)) { 21311 shift = 3; 21312 } 21313 uint32_t mvm = dm.GetCode() | index << shift; 21314 EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21315 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 21316 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21317 ((mvm & 0x10) << 1)); 21318 AdvanceIT(); 21319 return; 21320 } 21321 } 21322 } else { 21323 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1 21324 if (encoded_dt.IsValid() && 21325 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 21326 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) { 21327 if (cond.Is(al)) { 21328 uint32_t shift = 4; 21329 if (dt.Is(I16)) { 21330 shift = 3; 21331 } 21332 uint32_t mvm = dm.GetCode() | index << shift; 21333 EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21334 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 21335 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21336 ((mvm & 0x10) << 1)); 21337 return; 21338 } 21339 } 21340 } 21341 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index); 21342 } 21343 21344 void Assembler::vmul( 21345 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21346 VIXL_ASSERT(AllowAssembler()); 21347 CheckIT(cond); 21348 Dt_op_size_1 encoded_dt(dt); 21349 if (IsUsingT32()) { 21350 // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 21351 if (dt.Is(F32)) { 21352 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21353 EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21354 rm.Encode(5, 0)); 21355 AdvanceIT(); 21356 return; 21357 } 21358 } 21359 // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 21360 if (dt.Is(F64)) { 21361 EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21362 rm.Encode(5, 0)); 21363 AdvanceIT(); 21364 return; 21365 } 21366 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 21367 if (encoded_dt.IsValid()) { 21368 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21369 EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21370 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21371 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21372 AdvanceIT(); 21373 return; 21374 } 21375 } 21376 } else { 21377 // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 21378 if (dt.Is(F32)) { 21379 if (cond.Is(al)) { 21380 EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21381 rm.Encode(5, 0)); 21382 return; 21383 } 21384 } 21385 // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 21386 if (dt.Is(F64) && cond.IsNotNever()) { 21387 EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21388 rn.Encode(7, 16) | rm.Encode(5, 0)); 21389 return; 21390 } 21391 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 21392 if (encoded_dt.IsValid()) { 21393 if (cond.Is(al)) { 21394 EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21395 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21396 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21397 return; 21398 } 21399 } 21400 } 21401 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 21402 } 21403 21404 void Assembler::vmul( 21405 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 21406 VIXL_ASSERT(AllowAssembler()); 21407 CheckIT(cond); 21408 Dt_op_size_1 encoded_dt(dt); 21409 if (IsUsingT32()) { 21410 // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 21411 if (dt.Is(F32)) { 21412 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21413 EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21414 rm.Encode(5, 0)); 21415 AdvanceIT(); 21416 return; 21417 } 21418 } 21419 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 21420 if (encoded_dt.IsValid()) { 21421 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21422 EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21423 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21424 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21425 AdvanceIT(); 21426 return; 21427 } 21428 } 21429 } else { 21430 // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 21431 if (dt.Is(F32)) { 21432 if (cond.Is(al)) { 21433 EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21434 rm.Encode(5, 0)); 21435 return; 21436 } 21437 } 21438 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 21439 if (encoded_dt.IsValid()) { 21440 if (cond.Is(al)) { 21441 EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21442 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21443 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21444 return; 21445 } 21446 } 21447 } 21448 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 21449 } 21450 21451 void Assembler::vmul( 21452 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 21453 VIXL_ASSERT(AllowAssembler()); 21454 CheckIT(cond); 21455 if (IsUsingT32()) { 21456 // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 21457 if (dt.Is(F32)) { 21458 EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21459 rm.Encode(5, 0)); 21460 AdvanceIT(); 21461 return; 21462 } 21463 } else { 21464 // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 21465 if (dt.Is(F32) && cond.IsNotNever()) { 21466 EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21467 rn.Encode(7, 16) | rm.Encode(5, 0)); 21468 return; 21469 } 21470 } 21471 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 21472 } 21473 21474 void Assembler::vmull(Condition cond, 21475 DataType dt, 21476 QRegister rd, 21477 DRegister rn, 21478 DRegister dm, 21479 unsigned index) { 21480 VIXL_ASSERT(AllowAssembler()); 21481 CheckIT(cond); 21482 Dt_U_size_2 encoded_dt(dt); 21483 if (IsUsingT32()) { 21484 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1 21485 if (encoded_dt.IsValid() && 21486 (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) || 21487 (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) && 21488 (dm.GetCode() <= 15)))) { 21489 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21490 uint32_t shift = 4; 21491 if (dt.Is(S16) || dt.Is(U16)) { 21492 shift = 3; 21493 } 21494 uint32_t mvm = dm.GetCode() | index << shift; 21495 EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21496 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21497 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21498 ((mvm & 0x10) << 1)); 21499 AdvanceIT(); 21500 return; 21501 } 21502 } 21503 } else { 21504 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1 21505 if (encoded_dt.IsValid() && 21506 (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) || 21507 (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) && 21508 (dm.GetCode() <= 15)))) { 21509 if (cond.Is(al)) { 21510 uint32_t shift = 4; 21511 if (dt.Is(S16) || dt.Is(U16)) { 21512 shift = 3; 21513 } 21514 uint32_t mvm = dm.GetCode() | index << shift; 21515 EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21516 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21517 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21518 ((mvm & 0x10) << 1)); 21519 return; 21520 } 21521 } 21522 } 21523 Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index); 21524 } 21525 21526 void Assembler::vmull( 21527 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 21528 VIXL_ASSERT(AllowAssembler()); 21529 CheckIT(cond); 21530 Dt_op_U_size_1 encoded_dt(dt); 21531 if (IsUsingT32()) { 21532 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 21533 if (encoded_dt.IsValid()) { 21534 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21535 EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21536 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21537 ((encoded_dt.GetEncodingValue() & 0x8) << 6) | 21538 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21539 AdvanceIT(); 21540 return; 21541 } 21542 } 21543 } else { 21544 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 21545 if (encoded_dt.IsValid()) { 21546 if (cond.Is(al)) { 21547 EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21548 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21549 ((encoded_dt.GetEncodingValue() & 0x8) << 6) | 21550 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21551 return; 21552 } 21553 } 21554 } 21555 Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm); 21556 } 21557 21558 void Assembler::vmvn(Condition cond, 21559 DataType dt, 21560 DRegister rd, 21561 const DOperand& operand) { 21562 VIXL_ASSERT(AllowAssembler()); 21563 CheckIT(cond); 21564 if (operand.IsImmediate()) { 21565 ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate()); 21566 if (IsUsingT32()) { 21567 // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 21568 if (encoded_dt.IsValid()) { 21569 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21570 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 21571 rd.Encode(22, 12) | 21572 (encoded_dt.GetEncodedImmediate() & 0xf) | 21573 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21574 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21575 AdvanceIT(); 21576 return; 21577 } 21578 } 21579 } else { 21580 // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 21581 if (encoded_dt.IsValid()) { 21582 if (cond.Is(al)) { 21583 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 21584 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21585 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21586 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21587 return; 21588 } 21589 } 21590 } 21591 } 21592 if (operand.IsRegister()) { 21593 DRegister rm = operand.GetRegister(); 21594 USE(dt); 21595 if (IsUsingT32()) { 21596 // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 21597 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21598 EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21599 AdvanceIT(); 21600 return; 21601 } 21602 } else { 21603 // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 21604 if (cond.Is(al)) { 21605 EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21606 return; 21607 } 21608 } 21609 } 21610 Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand); 21611 } 21612 21613 void Assembler::vmvn(Condition cond, 21614 DataType dt, 21615 QRegister rd, 21616 const QOperand& operand) { 21617 VIXL_ASSERT(AllowAssembler()); 21618 CheckIT(cond); 21619 if (operand.IsImmediate()) { 21620 ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate()); 21621 if (IsUsingT32()) { 21622 // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 21623 if (encoded_dt.IsValid()) { 21624 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21625 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 21626 rd.Encode(22, 12) | 21627 (encoded_dt.GetEncodedImmediate() & 0xf) | 21628 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21629 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21630 AdvanceIT(); 21631 return; 21632 } 21633 } 21634 } else { 21635 // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 21636 if (encoded_dt.IsValid()) { 21637 if (cond.Is(al)) { 21638 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 21639 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21640 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21641 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21642 return; 21643 } 21644 } 21645 } 21646 } 21647 if (operand.IsRegister()) { 21648 QRegister rm = operand.GetRegister(); 21649 USE(dt); 21650 if (IsUsingT32()) { 21651 // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 21652 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21653 EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21654 AdvanceIT(); 21655 return; 21656 } 21657 } else { 21658 // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 21659 if (cond.Is(al)) { 21660 EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21661 return; 21662 } 21663 } 21664 } 21665 Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand); 21666 } 21667 21668 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) { 21669 VIXL_ASSERT(AllowAssembler()); 21670 CheckIT(cond); 21671 Dt_F_size_1 encoded_dt(dt); 21672 if (IsUsingT32()) { 21673 // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 21674 if (encoded_dt.IsValid()) { 21675 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21676 EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21677 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 21678 rd.Encode(22, 12) | rm.Encode(5, 0)); 21679 AdvanceIT(); 21680 return; 21681 } 21682 } 21683 // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 21684 if (dt.Is(F64)) { 21685 EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21686 AdvanceIT(); 21687 return; 21688 } 21689 } else { 21690 // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 21691 if (encoded_dt.IsValid()) { 21692 if (cond.Is(al)) { 21693 EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21694 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 21695 rd.Encode(22, 12) | rm.Encode(5, 0)); 21696 return; 21697 } 21698 } 21699 // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 21700 if (dt.Is(F64) && cond.IsNotNever()) { 21701 EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21702 rm.Encode(5, 0)); 21703 return; 21704 } 21705 } 21706 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 21707 } 21708 21709 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) { 21710 VIXL_ASSERT(AllowAssembler()); 21711 CheckIT(cond); 21712 Dt_F_size_1 encoded_dt(dt); 21713 if (IsUsingT32()) { 21714 // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 21715 if (encoded_dt.IsValid()) { 21716 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21717 EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21718 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 21719 rd.Encode(22, 12) | rm.Encode(5, 0)); 21720 AdvanceIT(); 21721 return; 21722 } 21723 } 21724 } else { 21725 // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 21726 if (encoded_dt.IsValid()) { 21727 if (cond.Is(al)) { 21728 EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21729 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 21730 rd.Encode(22, 12) | rm.Encode(5, 0)); 21731 return; 21732 } 21733 } 21734 } 21735 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 21736 } 21737 21738 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) { 21739 VIXL_ASSERT(AllowAssembler()); 21740 CheckIT(cond); 21741 if (IsUsingT32()) { 21742 // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 21743 if (dt.Is(F32)) { 21744 EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 21745 AdvanceIT(); 21746 return; 21747 } 21748 } else { 21749 // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 21750 if (dt.Is(F32) && cond.IsNotNever()) { 21751 EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21752 rm.Encode(5, 0)); 21753 return; 21754 } 21755 } 21756 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 21757 } 21758 21759 void Assembler::vnmla( 21760 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 21761 VIXL_ASSERT(AllowAssembler()); 21762 CheckIT(cond); 21763 if (IsUsingT32()) { 21764 // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 21765 if (dt.Is(F32)) { 21766 EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21767 rm.Encode(5, 0)); 21768 AdvanceIT(); 21769 return; 21770 } 21771 } else { 21772 // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 21773 if (dt.Is(F32) && cond.IsNotNever()) { 21774 EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21775 rn.Encode(7, 16) | rm.Encode(5, 0)); 21776 return; 21777 } 21778 } 21779 Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm); 21780 } 21781 21782 void Assembler::vnmla( 21783 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21784 VIXL_ASSERT(AllowAssembler()); 21785 CheckIT(cond); 21786 if (IsUsingT32()) { 21787 // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 21788 if (dt.Is(F64)) { 21789 EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21790 rm.Encode(5, 0)); 21791 AdvanceIT(); 21792 return; 21793 } 21794 } else { 21795 // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 21796 if (dt.Is(F64) && cond.IsNotNever()) { 21797 EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21798 rn.Encode(7, 16) | rm.Encode(5, 0)); 21799 return; 21800 } 21801 } 21802 Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm); 21803 } 21804 21805 void Assembler::vnmls( 21806 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 21807 VIXL_ASSERT(AllowAssembler()); 21808 CheckIT(cond); 21809 if (IsUsingT32()) { 21810 // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 21811 if (dt.Is(F32)) { 21812 EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21813 rm.Encode(5, 0)); 21814 AdvanceIT(); 21815 return; 21816 } 21817 } else { 21818 // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 21819 if (dt.Is(F32) && cond.IsNotNever()) { 21820 EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21821 rn.Encode(7, 16) | rm.Encode(5, 0)); 21822 return; 21823 } 21824 } 21825 Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm); 21826 } 21827 21828 void Assembler::vnmls( 21829 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21830 VIXL_ASSERT(AllowAssembler()); 21831 CheckIT(cond); 21832 if (IsUsingT32()) { 21833 // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 21834 if (dt.Is(F64)) { 21835 EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21836 rm.Encode(5, 0)); 21837 AdvanceIT(); 21838 return; 21839 } 21840 } else { 21841 // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 21842 if (dt.Is(F64) && cond.IsNotNever()) { 21843 EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21844 rn.Encode(7, 16) | rm.Encode(5, 0)); 21845 return; 21846 } 21847 } 21848 Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm); 21849 } 21850 21851 void Assembler::vnmul( 21852 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 21853 VIXL_ASSERT(AllowAssembler()); 21854 CheckIT(cond); 21855 if (IsUsingT32()) { 21856 // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1 21857 if (dt.Is(F32)) { 21858 EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21859 rm.Encode(5, 0)); 21860 AdvanceIT(); 21861 return; 21862 } 21863 } else { 21864 // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1 21865 if (dt.Is(F32) && cond.IsNotNever()) { 21866 EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21867 rn.Encode(7, 16) | rm.Encode(5, 0)); 21868 return; 21869 } 21870 } 21871 Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm); 21872 } 21873 21874 void Assembler::vnmul( 21875 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21876 VIXL_ASSERT(AllowAssembler()); 21877 CheckIT(cond); 21878 if (IsUsingT32()) { 21879 // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1 21880 if (dt.Is(F64)) { 21881 EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21882 rm.Encode(5, 0)); 21883 AdvanceIT(); 21884 return; 21885 } 21886 } else { 21887 // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1 21888 if (dt.Is(F64) && cond.IsNotNever()) { 21889 EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 21890 rn.Encode(7, 16) | rm.Encode(5, 0)); 21891 return; 21892 } 21893 } 21894 Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm); 21895 } 21896 21897 void Assembler::vorn(Condition cond, 21898 DataType dt, 21899 DRegister rd, 21900 DRegister rn, 21901 const DOperand& operand) { 21902 VIXL_ASSERT(AllowAssembler()); 21903 CheckIT(cond); 21904 if (operand.IsImmediate()) { 21905 ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate()); 21906 if (IsUsingT32()) { 21907 // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 21908 if (encoded_dt.IsValid() && rd.Is(rn)) { 21909 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21910 EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) | 21911 rd.Encode(22, 12) | 21912 (encoded_dt.GetEncodedImmediate() & 0xf) | 21913 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21914 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21915 AdvanceIT(); 21916 return; 21917 } 21918 } 21919 } else { 21920 // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 21921 if (encoded_dt.IsValid() && rd.Is(rn)) { 21922 if (cond.Is(al)) { 21923 EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) | 21924 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21925 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21926 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21927 return; 21928 } 21929 } 21930 } 21931 } 21932 if (operand.IsRegister()) { 21933 DRegister rm = operand.GetRegister(); 21934 USE(dt); 21935 if (IsUsingT32()) { 21936 // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 21937 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21938 EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21939 rm.Encode(5, 0)); 21940 AdvanceIT(); 21941 return; 21942 } 21943 } else { 21944 // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 21945 if (cond.Is(al)) { 21946 EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21947 rm.Encode(5, 0)); 21948 return; 21949 } 21950 } 21951 } 21952 Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand); 21953 } 21954 21955 void Assembler::vorn(Condition cond, 21956 DataType dt, 21957 QRegister rd, 21958 QRegister rn, 21959 const QOperand& operand) { 21960 VIXL_ASSERT(AllowAssembler()); 21961 CheckIT(cond); 21962 if (operand.IsImmediate()) { 21963 ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate()); 21964 if (IsUsingT32()) { 21965 // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 21966 if (encoded_dt.IsValid() && rd.Is(rn)) { 21967 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21968 EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) | 21969 rd.Encode(22, 12) | 21970 (encoded_dt.GetEncodedImmediate() & 0xf) | 21971 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21972 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 21973 AdvanceIT(); 21974 return; 21975 } 21976 } 21977 } else { 21978 // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 21979 if (encoded_dt.IsValid() && rd.Is(rn)) { 21980 if (cond.Is(al)) { 21981 EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) | 21982 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 21983 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 21984 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 21985 return; 21986 } 21987 } 21988 } 21989 } 21990 if (operand.IsRegister()) { 21991 QRegister rm = operand.GetRegister(); 21992 USE(dt); 21993 if (IsUsingT32()) { 21994 // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 21995 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21996 EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21997 rm.Encode(5, 0)); 21998 AdvanceIT(); 21999 return; 22000 } 22001 } else { 22002 // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 22003 if (cond.Is(al)) { 22004 EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22005 rm.Encode(5, 0)); 22006 return; 22007 } 22008 } 22009 } 22010 Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand); 22011 } 22012 22013 void Assembler::vorr(Condition cond, 22014 DataType dt, 22015 DRegister rd, 22016 DRegister rn, 22017 const DOperand& operand) { 22018 VIXL_ASSERT(AllowAssembler()); 22019 CheckIT(cond); 22020 if (operand.IsRegister()) { 22021 DRegister rm = operand.GetRegister(); 22022 USE(dt); 22023 if (IsUsingT32()) { 22024 // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 22025 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22026 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22027 rm.Encode(5, 0)); 22028 AdvanceIT(); 22029 return; 22030 } 22031 } else { 22032 // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 22033 if (cond.Is(al)) { 22034 EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22035 rm.Encode(5, 0)); 22036 return; 22037 } 22038 } 22039 } 22040 if (operand.IsImmediate()) { 22041 ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate()); 22042 if (IsUsingT32()) { 22043 // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 22044 if (encoded_dt.IsValid() && rd.Is(rn)) { 22045 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22046 EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) | 22047 rd.Encode(22, 12) | 22048 (encoded_dt.GetEncodedImmediate() & 0xf) | 22049 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22050 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 22051 AdvanceIT(); 22052 return; 22053 } 22054 } 22055 } else { 22056 // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 22057 if (encoded_dt.IsValid() && rd.Is(rn)) { 22058 if (cond.Is(al)) { 22059 EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) | 22060 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 22061 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22062 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 22063 return; 22064 } 22065 } 22066 } 22067 } 22068 Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand); 22069 } 22070 22071 void Assembler::vorr(Condition cond, 22072 DataType dt, 22073 QRegister rd, 22074 QRegister rn, 22075 const QOperand& operand) { 22076 VIXL_ASSERT(AllowAssembler()); 22077 CheckIT(cond); 22078 if (operand.IsRegister()) { 22079 QRegister rm = operand.GetRegister(); 22080 USE(dt); 22081 if (IsUsingT32()) { 22082 // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 22083 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22084 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22085 rm.Encode(5, 0)); 22086 AdvanceIT(); 22087 return; 22088 } 22089 } else { 22090 // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 22091 if (cond.Is(al)) { 22092 EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22093 rm.Encode(5, 0)); 22094 return; 22095 } 22096 } 22097 } 22098 if (operand.IsImmediate()) { 22099 ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate()); 22100 if (IsUsingT32()) { 22101 // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 22102 if (encoded_dt.IsValid() && rd.Is(rn)) { 22103 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22104 EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) | 22105 rd.Encode(22, 12) | 22106 (encoded_dt.GetEncodedImmediate() & 0xf) | 22107 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22108 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 22109 AdvanceIT(); 22110 return; 22111 } 22112 } 22113 } else { 22114 // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 22115 if (encoded_dt.IsValid() && rd.Is(rn)) { 22116 if (cond.Is(al)) { 22117 EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) | 22118 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 22119 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 22120 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 22121 return; 22122 } 22123 } 22124 } 22125 } 22126 Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand); 22127 } 22128 22129 void Assembler::vpadal(Condition cond, 22130 DataType dt, 22131 DRegister rd, 22132 DRegister rm) { 22133 VIXL_ASSERT(AllowAssembler()); 22134 CheckIT(cond); 22135 Dt_op_size_2 encoded_dt(dt); 22136 if (IsUsingT32()) { 22137 // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22138 if (encoded_dt.IsValid()) { 22139 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22140 EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22141 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22142 rd.Encode(22, 12) | rm.Encode(5, 0)); 22143 AdvanceIT(); 22144 return; 22145 } 22146 } 22147 } else { 22148 // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22149 if (encoded_dt.IsValid()) { 22150 if (cond.Is(al)) { 22151 EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22152 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22153 rd.Encode(22, 12) | rm.Encode(5, 0)); 22154 return; 22155 } 22156 } 22157 } 22158 Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm); 22159 } 22160 22161 void Assembler::vpadal(Condition cond, 22162 DataType dt, 22163 QRegister rd, 22164 QRegister rm) { 22165 VIXL_ASSERT(AllowAssembler()); 22166 CheckIT(cond); 22167 Dt_op_size_2 encoded_dt(dt); 22168 if (IsUsingT32()) { 22169 // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22170 if (encoded_dt.IsValid()) { 22171 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22172 EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22173 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22174 rd.Encode(22, 12) | rm.Encode(5, 0)); 22175 AdvanceIT(); 22176 return; 22177 } 22178 } 22179 } else { 22180 // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22181 if (encoded_dt.IsValid()) { 22182 if (cond.Is(al)) { 22183 EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22184 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22185 rd.Encode(22, 12) | rm.Encode(5, 0)); 22186 return; 22187 } 22188 } 22189 } 22190 Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm); 22191 } 22192 22193 void Assembler::vpadd( 22194 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22195 VIXL_ASSERT(AllowAssembler()); 22196 CheckIT(cond); 22197 Dt_size_4 encoded_dt(dt); 22198 if (IsUsingT32()) { 22199 // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 22200 if (dt.Is(F32)) { 22201 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22202 EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22203 rm.Encode(5, 0)); 22204 AdvanceIT(); 22205 return; 22206 } 22207 } 22208 // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22209 if (encoded_dt.IsValid()) { 22210 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22211 EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) | 22212 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22213 AdvanceIT(); 22214 return; 22215 } 22216 } 22217 } else { 22218 // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 22219 if (dt.Is(F32)) { 22220 if (cond.Is(al)) { 22221 EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22222 rm.Encode(5, 0)); 22223 return; 22224 } 22225 } 22226 // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22227 if (encoded_dt.IsValid()) { 22228 if (cond.Is(al)) { 22229 EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) | 22230 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22231 return; 22232 } 22233 } 22234 } 22235 Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm); 22236 } 22237 22238 void Assembler::vpaddl(Condition cond, 22239 DataType dt, 22240 DRegister rd, 22241 DRegister rm) { 22242 VIXL_ASSERT(AllowAssembler()); 22243 CheckIT(cond); 22244 Dt_op_size_2 encoded_dt(dt); 22245 if (IsUsingT32()) { 22246 // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22247 if (encoded_dt.IsValid()) { 22248 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22249 EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22250 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22251 rd.Encode(22, 12) | rm.Encode(5, 0)); 22252 AdvanceIT(); 22253 return; 22254 } 22255 } 22256 } else { 22257 // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22258 if (encoded_dt.IsValid()) { 22259 if (cond.Is(al)) { 22260 EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22261 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22262 rd.Encode(22, 12) | rm.Encode(5, 0)); 22263 return; 22264 } 22265 } 22266 } 22267 Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm); 22268 } 22269 22270 void Assembler::vpaddl(Condition cond, 22271 DataType dt, 22272 QRegister rd, 22273 QRegister rm) { 22274 VIXL_ASSERT(AllowAssembler()); 22275 CheckIT(cond); 22276 Dt_op_size_2 encoded_dt(dt); 22277 if (IsUsingT32()) { 22278 // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22279 if (encoded_dt.IsValid()) { 22280 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22281 EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22282 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22283 rd.Encode(22, 12) | rm.Encode(5, 0)); 22284 AdvanceIT(); 22285 return; 22286 } 22287 } 22288 } else { 22289 // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22290 if (encoded_dt.IsValid()) { 22291 if (cond.Is(al)) { 22292 EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22293 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 22294 rd.Encode(22, 12) | rm.Encode(5, 0)); 22295 return; 22296 } 22297 } 22298 } 22299 Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm); 22300 } 22301 22302 void Assembler::vpmax( 22303 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22304 VIXL_ASSERT(AllowAssembler()); 22305 CheckIT(cond); 22306 Dt_U_size_1 encoded_dt(dt); 22307 if (IsUsingT32()) { 22308 // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 22309 if (dt.Is(F32)) { 22310 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22311 EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22312 rm.Encode(5, 0)); 22313 AdvanceIT(); 22314 return; 22315 } 22316 } 22317 // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22318 if (encoded_dt.IsValid()) { 22319 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22320 EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22321 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22322 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22323 AdvanceIT(); 22324 return; 22325 } 22326 } 22327 } else { 22328 // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 22329 if (dt.Is(F32)) { 22330 if (cond.Is(al)) { 22331 EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22332 rm.Encode(5, 0)); 22333 return; 22334 } 22335 } 22336 // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22337 if (encoded_dt.IsValid()) { 22338 if (cond.Is(al)) { 22339 EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22340 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22341 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22342 return; 22343 } 22344 } 22345 } 22346 Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm); 22347 } 22348 22349 void Assembler::vpmin( 22350 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22351 VIXL_ASSERT(AllowAssembler()); 22352 CheckIT(cond); 22353 Dt_U_size_1 encoded_dt(dt); 22354 if (IsUsingT32()) { 22355 // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 22356 if (dt.Is(F32)) { 22357 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22358 EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22359 rm.Encode(5, 0)); 22360 AdvanceIT(); 22361 return; 22362 } 22363 } 22364 // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22365 if (encoded_dt.IsValid()) { 22366 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22367 EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22368 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22369 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22370 AdvanceIT(); 22371 return; 22372 } 22373 } 22374 } else { 22375 // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 22376 if (dt.Is(F32)) { 22377 if (cond.Is(al)) { 22378 EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22379 rm.Encode(5, 0)); 22380 return; 22381 } 22382 } 22383 // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22384 if (encoded_dt.IsValid()) { 22385 if (cond.Is(al)) { 22386 EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22387 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22388 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22389 return; 22390 } 22391 } 22392 } 22393 Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm); 22394 } 22395 22396 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) { 22397 VIXL_ASSERT(AllowAssembler()); 22398 CheckIT(cond); 22399 USE(dt); 22400 if (IsUsingT32()) { 22401 // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1 22402 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 22403 const DRegister& dreg = dreglist.GetFirstDRegister(); 22404 unsigned len = dreglist.GetLength() * 2; 22405 EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff)); 22406 AdvanceIT(); 22407 return; 22408 } 22409 } else { 22410 // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1 22411 if (cond.IsNotNever() && 22412 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 22413 const DRegister& dreg = dreglist.GetFirstDRegister(); 22414 unsigned len = dreglist.GetLength() * 2; 22415 EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) | 22416 (len & 0xff)); 22417 return; 22418 } 22419 } 22420 Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist); 22421 } 22422 22423 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) { 22424 VIXL_ASSERT(AllowAssembler()); 22425 CheckIT(cond); 22426 USE(dt); 22427 if (IsUsingT32()) { 22428 // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2 22429 const SRegister& sreg = sreglist.GetFirstSRegister(); 22430 unsigned len = sreglist.GetLength(); 22431 EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff)); 22432 AdvanceIT(); 22433 return; 22434 } else { 22435 // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2 22436 if (cond.IsNotNever()) { 22437 const SRegister& sreg = sreglist.GetFirstSRegister(); 22438 unsigned len = sreglist.GetLength(); 22439 EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) | 22440 (len & 0xff)); 22441 return; 22442 } 22443 } 22444 Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist); 22445 } 22446 22447 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) { 22448 VIXL_ASSERT(AllowAssembler()); 22449 CheckIT(cond); 22450 USE(dt); 22451 if (IsUsingT32()) { 22452 // VPUSH{<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(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff)); 22457 AdvanceIT(); 22458 return; 22459 } 22460 } else { 22461 // VPUSH{<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(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) | 22467 (len & 0xff)); 22468 return; 22469 } 22470 } 22471 Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist); 22472 } 22473 22474 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) { 22475 VIXL_ASSERT(AllowAssembler()); 22476 CheckIT(cond); 22477 USE(dt); 22478 if (IsUsingT32()) { 22479 // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2 22480 const SRegister& sreg = sreglist.GetFirstSRegister(); 22481 unsigned len = sreglist.GetLength(); 22482 EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff)); 22483 AdvanceIT(); 22484 return; 22485 } else { 22486 // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2 22487 if (cond.IsNotNever()) { 22488 const SRegister& sreg = sreglist.GetFirstSRegister(); 22489 unsigned len = sreglist.GetLength(); 22490 EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) | 22491 (len & 0xff)); 22492 return; 22493 } 22494 } 22495 Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist); 22496 } 22497 22498 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) { 22499 VIXL_ASSERT(AllowAssembler()); 22500 CheckIT(cond); 22501 Dt_size_5 encoded_dt(dt); 22502 if (IsUsingT32()) { 22503 // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22504 if (encoded_dt.IsValid()) { 22505 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22506 EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) | 22507 rd.Encode(22, 12) | rm.Encode(5, 0)); 22508 AdvanceIT(); 22509 return; 22510 } 22511 } 22512 } else { 22513 // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22514 if (encoded_dt.IsValid()) { 22515 if (cond.Is(al)) { 22516 EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) | 22517 rd.Encode(22, 12) | rm.Encode(5, 0)); 22518 return; 22519 } 22520 } 22521 } 22522 Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm); 22523 } 22524 22525 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) { 22526 VIXL_ASSERT(AllowAssembler()); 22527 CheckIT(cond); 22528 Dt_size_5 encoded_dt(dt); 22529 if (IsUsingT32()) { 22530 // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22531 if (encoded_dt.IsValid()) { 22532 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22533 EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) | 22534 rd.Encode(22, 12) | rm.Encode(5, 0)); 22535 AdvanceIT(); 22536 return; 22537 } 22538 } 22539 } else { 22540 // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22541 if (encoded_dt.IsValid()) { 22542 if (cond.Is(al)) { 22543 EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) | 22544 rd.Encode(22, 12) | rm.Encode(5, 0)); 22545 return; 22546 } 22547 } 22548 } 22549 Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm); 22550 } 22551 22552 void Assembler::vqadd( 22553 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22554 VIXL_ASSERT(AllowAssembler()); 22555 CheckIT(cond); 22556 Dt_U_size_3 encoded_dt(dt); 22557 if (IsUsingT32()) { 22558 // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22559 if (encoded_dt.IsValid()) { 22560 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22561 EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22562 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22563 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22564 AdvanceIT(); 22565 return; 22566 } 22567 } 22568 } else { 22569 // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22570 if (encoded_dt.IsValid()) { 22571 if (cond.Is(al)) { 22572 EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22573 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22574 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22575 return; 22576 } 22577 } 22578 } 22579 Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm); 22580 } 22581 22582 void Assembler::vqadd( 22583 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 22584 VIXL_ASSERT(AllowAssembler()); 22585 CheckIT(cond); 22586 Dt_U_size_3 encoded_dt(dt); 22587 if (IsUsingT32()) { 22588 // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 22589 if (encoded_dt.IsValid()) { 22590 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22591 EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22592 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22593 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22594 AdvanceIT(); 22595 return; 22596 } 22597 } 22598 } else { 22599 // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 22600 if (encoded_dt.IsValid()) { 22601 if (cond.Is(al)) { 22602 EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22603 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22604 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22605 return; 22606 } 22607 } 22608 } 22609 Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm); 22610 } 22611 22612 void Assembler::vqdmlal( 22613 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 22614 VIXL_ASSERT(AllowAssembler()); 22615 CheckIT(cond); 22616 Dt_size_13 encoded_dt(dt); 22617 if (IsUsingT32()) { 22618 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 22619 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22620 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22621 EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) | 22622 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22623 AdvanceIT(); 22624 return; 22625 } 22626 } 22627 } else { 22628 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 22629 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22630 if (cond.Is(al)) { 22631 EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) | 22632 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22633 return; 22634 } 22635 } 22636 } 22637 Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm); 22638 } 22639 22640 void Assembler::vqdmlal(Condition cond, 22641 DataType dt, 22642 QRegister rd, 22643 DRegister rn, 22644 DRegister dm, 22645 unsigned index) { 22646 VIXL_ASSERT(AllowAssembler()); 22647 CheckIT(cond); 22648 Dt_size_13 encoded_dt(dt); 22649 if (IsUsingT32()) { 22650 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2 22651 if (encoded_dt.IsValid() && 22652 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 22653 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) && 22654 (dt.Is(S16) || dt.Is(S32))) { 22655 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22656 uint32_t shift = 4; 22657 if (dt.Is(S16)) { 22658 shift = 3; 22659 } 22660 uint32_t mvm = dm.GetCode() | index << shift; 22661 EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) | 22662 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 22663 ((mvm & 0x10) << 1)); 22664 AdvanceIT(); 22665 return; 22666 } 22667 } 22668 } else { 22669 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2 22670 if (encoded_dt.IsValid() && 22671 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 22672 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) && 22673 (dt.Is(S16) || dt.Is(S32))) { 22674 if (cond.Is(al)) { 22675 uint32_t shift = 4; 22676 if (dt.Is(S16)) { 22677 shift = 3; 22678 } 22679 uint32_t mvm = dm.GetCode() | index << shift; 22680 EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) | 22681 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 22682 ((mvm & 0x10) << 1)); 22683 return; 22684 } 22685 } 22686 } 22687 Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index); 22688 } 22689 22690 void Assembler::vqdmlsl( 22691 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 22692 VIXL_ASSERT(AllowAssembler()); 22693 CheckIT(cond); 22694 Dt_size_13 encoded_dt(dt); 22695 if (IsUsingT32()) { 22696 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 22697 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22698 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22699 EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) | 22700 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22701 AdvanceIT(); 22702 return; 22703 } 22704 } 22705 } else { 22706 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 22707 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22708 if (cond.Is(al)) { 22709 EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) | 22710 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22711 return; 22712 } 22713 } 22714 } 22715 Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm); 22716 } 22717 22718 void Assembler::vqdmlsl(Condition cond, 22719 DataType dt, 22720 QRegister rd, 22721 DRegister rn, 22722 DRegister dm, 22723 unsigned index) { 22724 VIXL_ASSERT(AllowAssembler()); 22725 CheckIT(cond); 22726 Dt_size_13 encoded_dt(dt); 22727 if (IsUsingT32()) { 22728 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2 22729 if (encoded_dt.IsValid() && 22730 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 22731 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) && 22732 (dt.Is(S16) || dt.Is(S32))) { 22733 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22734 uint32_t shift = 4; 22735 if (dt.Is(S16)) { 22736 shift = 3; 22737 } 22738 uint32_t mvm = dm.GetCode() | index << shift; 22739 EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) | 22740 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 22741 ((mvm & 0x10) << 1)); 22742 AdvanceIT(); 22743 return; 22744 } 22745 } 22746 } else { 22747 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2 22748 if (encoded_dt.IsValid() && 22749 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 22750 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) && 22751 (dt.Is(S16) || dt.Is(S32))) { 22752 if (cond.Is(al)) { 22753 uint32_t shift = 4; 22754 if (dt.Is(S16)) { 22755 shift = 3; 22756 } 22757 uint32_t mvm = dm.GetCode() | index << shift; 22758 EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) | 22759 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 22760 ((mvm & 0x10) << 1)); 22761 return; 22762 } 22763 } 22764 } 22765 Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index); 22766 } 22767 22768 void Assembler::vqdmulh( 22769 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22770 VIXL_ASSERT(AllowAssembler()); 22771 CheckIT(cond); 22772 Dt_size_13 encoded_dt(dt); 22773 if (IsUsingT32()) { 22774 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22775 if (encoded_dt.IsValid()) { 22776 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22777 EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) | 22778 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22779 AdvanceIT(); 22780 return; 22781 } 22782 } 22783 } else { 22784 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22785 if (encoded_dt.IsValid()) { 22786 if (cond.Is(al)) { 22787 EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) | 22788 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22789 return; 22790 } 22791 } 22792 } 22793 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 22794 } 22795 22796 void Assembler::vqdmulh( 22797 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 22798 VIXL_ASSERT(AllowAssembler()); 22799 CheckIT(cond); 22800 Dt_size_13 encoded_dt(dt); 22801 if (IsUsingT32()) { 22802 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 22803 if (encoded_dt.IsValid()) { 22804 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22805 EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) | 22806 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22807 AdvanceIT(); 22808 return; 22809 } 22810 } 22811 } else { 22812 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 22813 if (encoded_dt.IsValid()) { 22814 if (cond.Is(al)) { 22815 EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) | 22816 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22817 return; 22818 } 22819 } 22820 } 22821 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 22822 } 22823 22824 void Assembler::vqdmulh( 22825 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 22826 VIXL_ASSERT(AllowAssembler()); 22827 CheckIT(cond); 22828 Dt_size_13 encoded_dt(dt); 22829 if (IsUsingT32()) { 22830 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2 22831 if (encoded_dt.IsValid() && 22832 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22833 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22834 (rm.GetLane() <= 1))) && 22835 (dt.Is(S16) || dt.Is(S32))) { 22836 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22837 EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) | 22838 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22839 AdvanceIT(); 22840 return; 22841 } 22842 } 22843 } else { 22844 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2 22845 if (encoded_dt.IsValid() && 22846 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22847 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22848 (rm.GetLane() <= 1))) && 22849 (dt.Is(S16) || dt.Is(S32))) { 22850 if (cond.Is(al)) { 22851 EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) | 22852 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22853 return; 22854 } 22855 } 22856 } 22857 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 22858 } 22859 22860 void Assembler::vqdmulh( 22861 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 22862 VIXL_ASSERT(AllowAssembler()); 22863 CheckIT(cond); 22864 Dt_size_13 encoded_dt(dt); 22865 if (IsUsingT32()) { 22866 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2 22867 if (encoded_dt.IsValid() && 22868 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22869 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22870 (rm.GetLane() <= 1))) && 22871 (dt.Is(S16) || dt.Is(S32))) { 22872 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22873 EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) | 22874 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22875 AdvanceIT(); 22876 return; 22877 } 22878 } 22879 } else { 22880 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2 22881 if (encoded_dt.IsValid() && 22882 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22883 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22884 (rm.GetLane() <= 1))) && 22885 (dt.Is(S16) || dt.Is(S32))) { 22886 if (cond.Is(al)) { 22887 EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) | 22888 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22889 return; 22890 } 22891 } 22892 } 22893 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 22894 } 22895 22896 void Assembler::vqdmull( 22897 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 22898 VIXL_ASSERT(AllowAssembler()); 22899 CheckIT(cond); 22900 Dt_size_13 encoded_dt(dt); 22901 if (IsUsingT32()) { 22902 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 22903 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22904 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22905 EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) | 22906 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22907 AdvanceIT(); 22908 return; 22909 } 22910 } 22911 } else { 22912 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 22913 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 22914 if (cond.Is(al)) { 22915 EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) | 22916 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22917 return; 22918 } 22919 } 22920 } 22921 Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm); 22922 } 22923 22924 void Assembler::vqdmull( 22925 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 22926 VIXL_ASSERT(AllowAssembler()); 22927 CheckIT(cond); 22928 Dt_size_13 encoded_dt(dt); 22929 if (IsUsingT32()) { 22930 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2 22931 if (encoded_dt.IsValid() && 22932 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22933 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22934 (rm.GetLane() <= 1))) && 22935 (dt.Is(S16) || dt.Is(S32))) { 22936 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22937 EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) | 22938 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22939 AdvanceIT(); 22940 return; 22941 } 22942 } 22943 } else { 22944 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2 22945 if (encoded_dt.IsValid() && 22946 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 22947 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 22948 (rm.GetLane() <= 1))) && 22949 (dt.Is(S16) || dt.Is(S32))) { 22950 if (cond.Is(al)) { 22951 EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) | 22952 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 22953 return; 22954 } 22955 } 22956 } 22957 Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm); 22958 } 22959 22960 void Assembler::vqmovn(Condition cond, 22961 DataType dt, 22962 DRegister rd, 22963 QRegister rm) { 22964 VIXL_ASSERT(AllowAssembler()); 22965 CheckIT(cond); 22966 Dt_op_size_3 encoded_dt(dt); 22967 if (IsUsingT32()) { 22968 // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 22969 if (encoded_dt.IsValid()) { 22970 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22971 EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22972 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 22973 rd.Encode(22, 12) | rm.Encode(5, 0)); 22974 AdvanceIT(); 22975 return; 22976 } 22977 } 22978 } else { 22979 // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 22980 if (encoded_dt.IsValid()) { 22981 if (cond.Is(al)) { 22982 EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22983 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 22984 rd.Encode(22, 12) | rm.Encode(5, 0)); 22985 return; 22986 } 22987 } 22988 } 22989 Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm); 22990 } 22991 22992 void Assembler::vqmovun(Condition cond, 22993 DataType dt, 22994 DRegister rd, 22995 QRegister rm) { 22996 VIXL_ASSERT(AllowAssembler()); 22997 CheckIT(cond); 22998 Dt_size_14 encoded_dt(dt); 22999 if (IsUsingT32()) { 23000 // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 23001 if (encoded_dt.IsValid()) { 23002 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23003 EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) | 23004 rd.Encode(22, 12) | rm.Encode(5, 0)); 23005 AdvanceIT(); 23006 return; 23007 } 23008 } 23009 } else { 23010 // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 23011 if (encoded_dt.IsValid()) { 23012 if (cond.Is(al)) { 23013 EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) | 23014 rd.Encode(22, 12) | rm.Encode(5, 0)); 23015 return; 23016 } 23017 } 23018 } 23019 Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm); 23020 } 23021 23022 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) { 23023 VIXL_ASSERT(AllowAssembler()); 23024 CheckIT(cond); 23025 Dt_size_5 encoded_dt(dt); 23026 if (IsUsingT32()) { 23027 // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 23028 if (encoded_dt.IsValid()) { 23029 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23030 EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) | 23031 rd.Encode(22, 12) | rm.Encode(5, 0)); 23032 AdvanceIT(); 23033 return; 23034 } 23035 } 23036 } else { 23037 // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 23038 if (encoded_dt.IsValid()) { 23039 if (cond.Is(al)) { 23040 EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) | 23041 rd.Encode(22, 12) | rm.Encode(5, 0)); 23042 return; 23043 } 23044 } 23045 } 23046 Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm); 23047 } 23048 23049 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) { 23050 VIXL_ASSERT(AllowAssembler()); 23051 CheckIT(cond); 23052 Dt_size_5 encoded_dt(dt); 23053 if (IsUsingT32()) { 23054 // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 23055 if (encoded_dt.IsValid()) { 23056 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23057 EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) | 23058 rd.Encode(22, 12) | rm.Encode(5, 0)); 23059 AdvanceIT(); 23060 return; 23061 } 23062 } 23063 } else { 23064 // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 23065 if (encoded_dt.IsValid()) { 23066 if (cond.Is(al)) { 23067 EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) | 23068 rd.Encode(22, 12) | rm.Encode(5, 0)); 23069 return; 23070 } 23071 } 23072 } 23073 Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm); 23074 } 23075 23076 void Assembler::vqrdmulh( 23077 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23078 VIXL_ASSERT(AllowAssembler()); 23079 CheckIT(cond); 23080 Dt_size_13 encoded_dt(dt); 23081 if (IsUsingT32()) { 23082 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 23083 if (encoded_dt.IsValid()) { 23084 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23085 EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) | 23086 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23087 AdvanceIT(); 23088 return; 23089 } 23090 } 23091 } else { 23092 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 23093 if (encoded_dt.IsValid()) { 23094 if (cond.Is(al)) { 23095 EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) | 23096 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23097 return; 23098 } 23099 } 23100 } 23101 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 23102 } 23103 23104 void Assembler::vqrdmulh( 23105 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 23106 VIXL_ASSERT(AllowAssembler()); 23107 CheckIT(cond); 23108 Dt_size_13 encoded_dt(dt); 23109 if (IsUsingT32()) { 23110 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 23111 if (encoded_dt.IsValid()) { 23112 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23113 EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) | 23114 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23115 AdvanceIT(); 23116 return; 23117 } 23118 } 23119 } else { 23120 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 23121 if (encoded_dt.IsValid()) { 23122 if (cond.Is(al)) { 23123 EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) | 23124 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23125 return; 23126 } 23127 } 23128 } 23129 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 23130 } 23131 23132 void Assembler::vqrdmulh( 23133 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 23134 VIXL_ASSERT(AllowAssembler()); 23135 CheckIT(cond); 23136 Dt_size_13 encoded_dt(dt); 23137 if (IsUsingT32()) { 23138 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2 23139 if (encoded_dt.IsValid() && 23140 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 23141 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 23142 (rm.GetLane() <= 1))) && 23143 (dt.Is(S16) || dt.Is(S32))) { 23144 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23145 EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) | 23146 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23147 AdvanceIT(); 23148 return; 23149 } 23150 } 23151 } else { 23152 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2 23153 if (encoded_dt.IsValid() && 23154 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 23155 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 23156 (rm.GetLane() <= 1))) && 23157 (dt.Is(S16) || dt.Is(S32))) { 23158 if (cond.Is(al)) { 23159 EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) | 23160 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23161 return; 23162 } 23163 } 23164 } 23165 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 23166 } 23167 23168 void Assembler::vqrdmulh( 23169 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 23170 VIXL_ASSERT(AllowAssembler()); 23171 CheckIT(cond); 23172 Dt_size_13 encoded_dt(dt); 23173 if (IsUsingT32()) { 23174 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2 23175 if (encoded_dt.IsValid() && 23176 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 23177 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 23178 (rm.GetLane() <= 1))) && 23179 (dt.Is(S16) || dt.Is(S32))) { 23180 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23181 EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) | 23182 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23183 AdvanceIT(); 23184 return; 23185 } 23186 } 23187 } else { 23188 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2 23189 if (encoded_dt.IsValid() && 23190 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 23191 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 23192 (rm.GetLane() <= 1))) && 23193 (dt.Is(S16) || dt.Is(S32))) { 23194 if (cond.Is(al)) { 23195 EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) | 23196 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 23197 return; 23198 } 23199 } 23200 } 23201 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 23202 } 23203 23204 void Assembler::vqrshl( 23205 Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) { 23206 VIXL_ASSERT(AllowAssembler()); 23207 CheckIT(cond); 23208 Dt_U_size_3 encoded_dt(dt); 23209 if (IsUsingT32()) { 23210 // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 23211 if (encoded_dt.IsValid()) { 23212 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23213 EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23214 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23215 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23216 AdvanceIT(); 23217 return; 23218 } 23219 } 23220 } else { 23221 // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 23222 if (encoded_dt.IsValid()) { 23223 if (cond.Is(al)) { 23224 EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23225 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23226 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23227 return; 23228 } 23229 } 23230 } 23231 Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn); 23232 } 23233 23234 void Assembler::vqrshl( 23235 Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) { 23236 VIXL_ASSERT(AllowAssembler()); 23237 CheckIT(cond); 23238 Dt_U_size_3 encoded_dt(dt); 23239 if (IsUsingT32()) { 23240 // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 23241 if (encoded_dt.IsValid()) { 23242 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23243 EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23244 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23245 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23246 AdvanceIT(); 23247 return; 23248 } 23249 } 23250 } else { 23251 // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 23252 if (encoded_dt.IsValid()) { 23253 if (cond.Is(al)) { 23254 EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23255 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23256 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23257 return; 23258 } 23259 } 23260 } 23261 Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn); 23262 } 23263 23264 void Assembler::vqrshrn(Condition cond, 23265 DataType dt, 23266 DRegister rd, 23267 QRegister rm, 23268 const QOperand& operand) { 23269 VIXL_ASSERT(AllowAssembler()); 23270 CheckIT(cond); 23271 if (operand.IsImmediate()) { 23272 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23273 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23274 Dt_op_size_3 encoded_dt(dt); 23275 Dt_imm6_1 encoded_dt_2(dt); 23276 if (IsUsingT32()) { 23277 // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23278 if (encoded_dt.IsValid() && (imm == 0)) { 23279 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23280 EmitT32_32(0xffb20280U | 23281 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23282 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23283 rd.Encode(22, 12) | rm.Encode(5, 0)); 23284 AdvanceIT(); 23285 return; 23286 } 23287 } 23288 // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 23289 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23290 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23291 uint32_t imm6 = dt.GetSize() / 2 - imm; 23292 EmitT32_32(0xef800950U | 23293 (encoded_dt_2.GetTypeEncodingValue() << 28) | 23294 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 23295 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23296 AdvanceIT(); 23297 return; 23298 } 23299 } 23300 } else { 23301 // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23302 if (encoded_dt.IsValid() && (imm == 0)) { 23303 if (cond.Is(al)) { 23304 EmitA32(0xf3b20280U | 23305 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23306 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23307 rd.Encode(22, 12) | rm.Encode(5, 0)); 23308 return; 23309 } 23310 } 23311 // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 23312 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23313 if (cond.Is(al)) { 23314 uint32_t imm6 = dt.GetSize() / 2 - imm; 23315 EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) | 23316 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 23317 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23318 return; 23319 } 23320 } 23321 } 23322 } 23323 } 23324 Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand); 23325 } 23326 23327 void Assembler::vqrshrun(Condition cond, 23328 DataType dt, 23329 DRegister rd, 23330 QRegister rm, 23331 const QOperand& operand) { 23332 VIXL_ASSERT(AllowAssembler()); 23333 CheckIT(cond); 23334 if (operand.IsImmediate()) { 23335 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23336 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23337 Dt_imm6_2 encoded_dt(dt); 23338 Dt_size_14 encoded_dt_2(dt); 23339 if (IsUsingT32()) { 23340 // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 23341 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23342 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23343 uint32_t imm6 = dt.GetSize() / 2 - imm; 23344 EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) | 23345 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23346 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23347 AdvanceIT(); 23348 return; 23349 } 23350 } 23351 // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23352 if (encoded_dt_2.IsValid() && (imm == 0)) { 23353 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23354 EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) | 23355 rd.Encode(22, 12) | rm.Encode(5, 0)); 23356 AdvanceIT(); 23357 return; 23358 } 23359 } 23360 } else { 23361 // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 23362 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23363 if (cond.Is(al)) { 23364 uint32_t imm6 = dt.GetSize() / 2 - imm; 23365 EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) | 23366 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23367 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23368 return; 23369 } 23370 } 23371 // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23372 if (encoded_dt_2.IsValid() && (imm == 0)) { 23373 if (cond.Is(al)) { 23374 EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) | 23375 rd.Encode(22, 12) | rm.Encode(5, 0)); 23376 return; 23377 } 23378 } 23379 } 23380 } 23381 } 23382 Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand); 23383 } 23384 23385 void Assembler::vqshl(Condition cond, 23386 DataType dt, 23387 DRegister rd, 23388 DRegister rm, 23389 const DOperand& operand) { 23390 VIXL_ASSERT(AllowAssembler()); 23391 CheckIT(cond); 23392 if (operand.IsRegister()) { 23393 DRegister rn = operand.GetRegister(); 23394 Dt_U_size_3 encoded_dt(dt); 23395 if (IsUsingT32()) { 23396 // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 23397 if (encoded_dt.IsValid()) { 23398 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23399 EmitT32_32(0xef000410U | 23400 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23401 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23402 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23403 AdvanceIT(); 23404 return; 23405 } 23406 } 23407 } else { 23408 // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 23409 if (encoded_dt.IsValid()) { 23410 if (cond.Is(al)) { 23411 EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23412 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23413 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23414 return; 23415 } 23416 } 23417 } 23418 } 23419 if (operand.IsImmediate()) { 23420 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23421 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23422 Dt_L_imm6_1 encoded_dt(dt); 23423 if (IsUsingT32()) { 23424 // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 23425 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23426 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23427 uint32_t imm6 = imm; 23428 EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) | 23429 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23430 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23431 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23432 AdvanceIT(); 23433 return; 23434 } 23435 } 23436 } else { 23437 // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 23438 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23439 if (cond.Is(al)) { 23440 uint32_t imm6 = imm; 23441 EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) | 23442 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23443 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23444 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23445 return; 23446 } 23447 } 23448 } 23449 } 23450 } 23451 Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand); 23452 } 23453 23454 void Assembler::vqshl(Condition cond, 23455 DataType dt, 23456 QRegister rd, 23457 QRegister rm, 23458 const QOperand& operand) { 23459 VIXL_ASSERT(AllowAssembler()); 23460 CheckIT(cond); 23461 if (operand.IsRegister()) { 23462 QRegister rn = operand.GetRegister(); 23463 Dt_U_size_3 encoded_dt(dt); 23464 if (IsUsingT32()) { 23465 // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 23466 if (encoded_dt.IsValid()) { 23467 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23468 EmitT32_32(0xef000450U | 23469 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23470 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23471 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23472 AdvanceIT(); 23473 return; 23474 } 23475 } 23476 } else { 23477 // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 23478 if (encoded_dt.IsValid()) { 23479 if (cond.Is(al)) { 23480 EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23481 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23482 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23483 return; 23484 } 23485 } 23486 } 23487 } 23488 if (operand.IsImmediate()) { 23489 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23490 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23491 Dt_L_imm6_1 encoded_dt(dt); 23492 if (IsUsingT32()) { 23493 // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 23494 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23495 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23496 uint32_t imm6 = imm; 23497 EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) | 23498 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23499 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23500 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23501 AdvanceIT(); 23502 return; 23503 } 23504 } 23505 } else { 23506 // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 23507 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23508 if (cond.Is(al)) { 23509 uint32_t imm6 = imm; 23510 EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) | 23511 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23512 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23513 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23514 return; 23515 } 23516 } 23517 } 23518 } 23519 } 23520 Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand); 23521 } 23522 23523 void Assembler::vqshlu(Condition cond, 23524 DataType dt, 23525 DRegister rd, 23526 DRegister rm, 23527 const DOperand& operand) { 23528 VIXL_ASSERT(AllowAssembler()); 23529 CheckIT(cond); 23530 if (operand.IsImmediate()) { 23531 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23532 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23533 Dt_L_imm6_2 encoded_dt(dt); 23534 if (IsUsingT32()) { 23535 // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 23536 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23537 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23538 uint32_t imm6 = imm; 23539 EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) | 23540 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23541 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23542 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23543 AdvanceIT(); 23544 return; 23545 } 23546 } 23547 } else { 23548 // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 23549 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23550 if (cond.Is(al)) { 23551 uint32_t imm6 = imm; 23552 EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) | 23553 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23554 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23555 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23556 return; 23557 } 23558 } 23559 } 23560 } 23561 } 23562 Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand); 23563 } 23564 23565 void Assembler::vqshlu(Condition cond, 23566 DataType dt, 23567 QRegister rd, 23568 QRegister rm, 23569 const QOperand& operand) { 23570 VIXL_ASSERT(AllowAssembler()); 23571 CheckIT(cond); 23572 if (operand.IsImmediate()) { 23573 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23574 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23575 Dt_L_imm6_2 encoded_dt(dt); 23576 if (IsUsingT32()) { 23577 // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 23578 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23579 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23580 uint32_t imm6 = imm; 23581 EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) | 23582 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23583 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23584 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23585 AdvanceIT(); 23586 return; 23587 } 23588 } 23589 } else { 23590 // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 23591 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 23592 if (cond.Is(al)) { 23593 uint32_t imm6 = imm; 23594 EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) | 23595 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23596 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23597 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23598 return; 23599 } 23600 } 23601 } 23602 } 23603 } 23604 Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand); 23605 } 23606 23607 void Assembler::vqshrn(Condition cond, 23608 DataType dt, 23609 DRegister rd, 23610 QRegister rm, 23611 const QOperand& operand) { 23612 VIXL_ASSERT(AllowAssembler()); 23613 CheckIT(cond); 23614 if (operand.IsImmediate()) { 23615 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23616 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23617 Dt_op_size_3 encoded_dt(dt); 23618 Dt_imm6_1 encoded_dt_2(dt); 23619 if (IsUsingT32()) { 23620 // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23621 if (encoded_dt.IsValid() && (imm == 0)) { 23622 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23623 EmitT32_32(0xffb20280U | 23624 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23625 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23626 rd.Encode(22, 12) | rm.Encode(5, 0)); 23627 AdvanceIT(); 23628 return; 23629 } 23630 } 23631 // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 23632 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23633 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23634 uint32_t imm6 = dt.GetSize() / 2 - imm; 23635 EmitT32_32(0xef800910U | 23636 (encoded_dt_2.GetTypeEncodingValue() << 28) | 23637 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 23638 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23639 AdvanceIT(); 23640 return; 23641 } 23642 } 23643 } else { 23644 // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23645 if (encoded_dt.IsValid() && (imm == 0)) { 23646 if (cond.Is(al)) { 23647 EmitA32(0xf3b20280U | 23648 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23649 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 23650 rd.Encode(22, 12) | rm.Encode(5, 0)); 23651 return; 23652 } 23653 } 23654 // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 23655 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23656 if (cond.Is(al)) { 23657 uint32_t imm6 = dt.GetSize() / 2 - imm; 23658 EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) | 23659 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 23660 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23661 return; 23662 } 23663 } 23664 } 23665 } 23666 } 23667 Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand); 23668 } 23669 23670 void Assembler::vqshrun(Condition cond, 23671 DataType dt, 23672 DRegister rd, 23673 QRegister rm, 23674 const QOperand& operand) { 23675 VIXL_ASSERT(AllowAssembler()); 23676 CheckIT(cond); 23677 if (operand.IsImmediate()) { 23678 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23679 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23680 Dt_imm6_2 encoded_dt(dt); 23681 Dt_size_14 encoded_dt_2(dt); 23682 if (IsUsingT32()) { 23683 // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 23684 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23685 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23686 uint32_t imm6 = dt.GetSize() / 2 - imm; 23687 EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) | 23688 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23689 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23690 AdvanceIT(); 23691 return; 23692 } 23693 } 23694 // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23695 if (encoded_dt_2.IsValid() && (imm == 0)) { 23696 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23697 EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) | 23698 rd.Encode(22, 12) | rm.Encode(5, 0)); 23699 AdvanceIT(); 23700 return; 23701 } 23702 } 23703 } else { 23704 // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 23705 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23706 if (cond.Is(al)) { 23707 uint32_t imm6 = dt.GetSize() / 2 - imm; 23708 EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) | 23709 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23710 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23711 return; 23712 } 23713 } 23714 // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23715 if (encoded_dt_2.IsValid() && (imm == 0)) { 23716 if (cond.Is(al)) { 23717 EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) | 23718 rd.Encode(22, 12) | rm.Encode(5, 0)); 23719 return; 23720 } 23721 } 23722 } 23723 } 23724 } 23725 Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand); 23726 } 23727 23728 void Assembler::vqsub( 23729 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23730 VIXL_ASSERT(AllowAssembler()); 23731 CheckIT(cond); 23732 Dt_U_size_3 encoded_dt(dt); 23733 if (IsUsingT32()) { 23734 // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 23735 if (encoded_dt.IsValid()) { 23736 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23737 EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23738 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23739 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23740 AdvanceIT(); 23741 return; 23742 } 23743 } 23744 } else { 23745 // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 23746 if (encoded_dt.IsValid()) { 23747 if (cond.Is(al)) { 23748 EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23749 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23750 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23751 return; 23752 } 23753 } 23754 } 23755 Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm); 23756 } 23757 23758 void Assembler::vqsub( 23759 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 23760 VIXL_ASSERT(AllowAssembler()); 23761 CheckIT(cond); 23762 Dt_U_size_3 encoded_dt(dt); 23763 if (IsUsingT32()) { 23764 // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 23765 if (encoded_dt.IsValid()) { 23766 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23767 EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23768 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23769 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23770 AdvanceIT(); 23771 return; 23772 } 23773 } 23774 } else { 23775 // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 23776 if (encoded_dt.IsValid()) { 23777 if (cond.Is(al)) { 23778 EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23779 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23780 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23781 return; 23782 } 23783 } 23784 } 23785 Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm); 23786 } 23787 23788 void Assembler::vraddhn( 23789 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 23790 VIXL_ASSERT(AllowAssembler()); 23791 CheckIT(cond); 23792 Dt_size_3 encoded_dt(dt); 23793 if (IsUsingT32()) { 23794 // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 23795 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 23796 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23797 EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) | 23798 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23799 AdvanceIT(); 23800 return; 23801 } 23802 } 23803 } else { 23804 // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 23805 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 23806 if (cond.Is(al)) { 23807 EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) | 23808 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23809 return; 23810 } 23811 } 23812 } 23813 Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm); 23814 } 23815 23816 void Assembler::vrecpe(Condition cond, 23817 DataType dt, 23818 DRegister rd, 23819 DRegister rm) { 23820 VIXL_ASSERT(AllowAssembler()); 23821 CheckIT(cond); 23822 Dt_F_size_4 encoded_dt(dt); 23823 if (IsUsingT32()) { 23824 // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 23825 if (encoded_dt.IsValid()) { 23826 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23827 EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23828 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23829 rd.Encode(22, 12) | rm.Encode(5, 0)); 23830 AdvanceIT(); 23831 return; 23832 } 23833 } 23834 } else { 23835 // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 23836 if (encoded_dt.IsValid()) { 23837 if (cond.Is(al)) { 23838 EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23839 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23840 rd.Encode(22, 12) | rm.Encode(5, 0)); 23841 return; 23842 } 23843 } 23844 } 23845 Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm); 23846 } 23847 23848 void Assembler::vrecpe(Condition cond, 23849 DataType dt, 23850 QRegister rd, 23851 QRegister rm) { 23852 VIXL_ASSERT(AllowAssembler()); 23853 CheckIT(cond); 23854 Dt_F_size_4 encoded_dt(dt); 23855 if (IsUsingT32()) { 23856 // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 23857 if (encoded_dt.IsValid()) { 23858 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23859 EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23860 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23861 rd.Encode(22, 12) | rm.Encode(5, 0)); 23862 AdvanceIT(); 23863 return; 23864 } 23865 } 23866 } else { 23867 // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 23868 if (encoded_dt.IsValid()) { 23869 if (cond.Is(al)) { 23870 EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23871 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23872 rd.Encode(22, 12) | rm.Encode(5, 0)); 23873 return; 23874 } 23875 } 23876 } 23877 Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm); 23878 } 23879 23880 void Assembler::vrecps( 23881 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23882 VIXL_ASSERT(AllowAssembler()); 23883 CheckIT(cond); 23884 if (IsUsingT32()) { 23885 // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 23886 if (dt.Is(F32)) { 23887 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23888 EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23889 rm.Encode(5, 0)); 23890 AdvanceIT(); 23891 return; 23892 } 23893 } 23894 } else { 23895 // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 23896 if (dt.Is(F32)) { 23897 if (cond.Is(al)) { 23898 EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23899 rm.Encode(5, 0)); 23900 return; 23901 } 23902 } 23903 } 23904 Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm); 23905 } 23906 23907 void Assembler::vrecps( 23908 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 23909 VIXL_ASSERT(AllowAssembler()); 23910 CheckIT(cond); 23911 if (IsUsingT32()) { 23912 // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 23913 if (dt.Is(F32)) { 23914 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23915 EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23916 rm.Encode(5, 0)); 23917 AdvanceIT(); 23918 return; 23919 } 23920 } 23921 } else { 23922 // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 23923 if (dt.Is(F32)) { 23924 if (cond.Is(al)) { 23925 EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23926 rm.Encode(5, 0)); 23927 return; 23928 } 23929 } 23930 } 23931 Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm); 23932 } 23933 23934 void Assembler::vrev16(Condition cond, 23935 DataType dt, 23936 DRegister rd, 23937 DRegister rm) { 23938 VIXL_ASSERT(AllowAssembler()); 23939 CheckIT(cond); 23940 Dt_size_1 encoded_dt(dt); 23941 if (IsUsingT32()) { 23942 // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 23943 if (encoded_dt.IsValid()) { 23944 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23945 EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) | 23946 rd.Encode(22, 12) | rm.Encode(5, 0)); 23947 AdvanceIT(); 23948 return; 23949 } 23950 } 23951 } else { 23952 // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 23953 if (encoded_dt.IsValid()) { 23954 if (cond.Is(al)) { 23955 EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) | 23956 rd.Encode(22, 12) | rm.Encode(5, 0)); 23957 return; 23958 } 23959 } 23960 } 23961 Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm); 23962 } 23963 23964 void Assembler::vrev16(Condition cond, 23965 DataType dt, 23966 QRegister rd, 23967 QRegister rm) { 23968 VIXL_ASSERT(AllowAssembler()); 23969 CheckIT(cond); 23970 Dt_size_1 encoded_dt(dt); 23971 if (IsUsingT32()) { 23972 // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 23973 if (encoded_dt.IsValid()) { 23974 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23975 EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) | 23976 rd.Encode(22, 12) | rm.Encode(5, 0)); 23977 AdvanceIT(); 23978 return; 23979 } 23980 } 23981 } else { 23982 // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 23983 if (encoded_dt.IsValid()) { 23984 if (cond.Is(al)) { 23985 EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) | 23986 rd.Encode(22, 12) | rm.Encode(5, 0)); 23987 return; 23988 } 23989 } 23990 } 23991 Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm); 23992 } 23993 23994 void Assembler::vrev32(Condition cond, 23995 DataType dt, 23996 DRegister rd, 23997 DRegister rm) { 23998 VIXL_ASSERT(AllowAssembler()); 23999 CheckIT(cond); 24000 Dt_size_15 encoded_dt(dt); 24001 if (IsUsingT32()) { 24002 // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 24003 if (encoded_dt.IsValid()) { 24004 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24005 EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) | 24006 rd.Encode(22, 12) | rm.Encode(5, 0)); 24007 AdvanceIT(); 24008 return; 24009 } 24010 } 24011 } else { 24012 // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 24013 if (encoded_dt.IsValid()) { 24014 if (cond.Is(al)) { 24015 EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) | 24016 rd.Encode(22, 12) | rm.Encode(5, 0)); 24017 return; 24018 } 24019 } 24020 } 24021 Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm); 24022 } 24023 24024 void Assembler::vrev32(Condition cond, 24025 DataType dt, 24026 QRegister rd, 24027 QRegister rm) { 24028 VIXL_ASSERT(AllowAssembler()); 24029 CheckIT(cond); 24030 Dt_size_15 encoded_dt(dt); 24031 if (IsUsingT32()) { 24032 // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 24033 if (encoded_dt.IsValid()) { 24034 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24035 EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) | 24036 rd.Encode(22, 12) | rm.Encode(5, 0)); 24037 AdvanceIT(); 24038 return; 24039 } 24040 } 24041 } else { 24042 // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 24043 if (encoded_dt.IsValid()) { 24044 if (cond.Is(al)) { 24045 EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) | 24046 rd.Encode(22, 12) | rm.Encode(5, 0)); 24047 return; 24048 } 24049 } 24050 } 24051 Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm); 24052 } 24053 24054 void Assembler::vrev64(Condition cond, 24055 DataType dt, 24056 DRegister rd, 24057 DRegister rm) { 24058 VIXL_ASSERT(AllowAssembler()); 24059 CheckIT(cond); 24060 Dt_size_7 encoded_dt(dt); 24061 if (IsUsingT32()) { 24062 // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 24063 if (encoded_dt.IsValid()) { 24064 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24065 EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) | 24066 rd.Encode(22, 12) | rm.Encode(5, 0)); 24067 AdvanceIT(); 24068 return; 24069 } 24070 } 24071 } else { 24072 // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 24073 if (encoded_dt.IsValid()) { 24074 if (cond.Is(al)) { 24075 EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) | 24076 rd.Encode(22, 12) | rm.Encode(5, 0)); 24077 return; 24078 } 24079 } 24080 } 24081 Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm); 24082 } 24083 24084 void Assembler::vrev64(Condition cond, 24085 DataType dt, 24086 QRegister rd, 24087 QRegister rm) { 24088 VIXL_ASSERT(AllowAssembler()); 24089 CheckIT(cond); 24090 Dt_size_7 encoded_dt(dt); 24091 if (IsUsingT32()) { 24092 // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 24093 if (encoded_dt.IsValid()) { 24094 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24095 EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) | 24096 rd.Encode(22, 12) | rm.Encode(5, 0)); 24097 AdvanceIT(); 24098 return; 24099 } 24100 } 24101 } else { 24102 // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 24103 if (encoded_dt.IsValid()) { 24104 if (cond.Is(al)) { 24105 EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) | 24106 rd.Encode(22, 12) | rm.Encode(5, 0)); 24107 return; 24108 } 24109 } 24110 } 24111 Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm); 24112 } 24113 24114 void Assembler::vrhadd( 24115 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 24116 VIXL_ASSERT(AllowAssembler()); 24117 CheckIT(cond); 24118 Dt_U_size_1 encoded_dt(dt); 24119 if (IsUsingT32()) { 24120 // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 24121 if (encoded_dt.IsValid()) { 24122 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24123 EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24124 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24125 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 24126 AdvanceIT(); 24127 return; 24128 } 24129 } 24130 } else { 24131 // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 24132 if (encoded_dt.IsValid()) { 24133 if (cond.Is(al)) { 24134 EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24135 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24136 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 24137 return; 24138 } 24139 } 24140 } 24141 Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm); 24142 } 24143 24144 void Assembler::vrhadd( 24145 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 24146 VIXL_ASSERT(AllowAssembler()); 24147 CheckIT(cond); 24148 Dt_U_size_1 encoded_dt(dt); 24149 if (IsUsingT32()) { 24150 // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 24151 if (encoded_dt.IsValid()) { 24152 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24153 EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24154 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24155 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 24156 AdvanceIT(); 24157 return; 24158 } 24159 } 24160 } else { 24161 // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 24162 if (encoded_dt.IsValid()) { 24163 if (cond.Is(al)) { 24164 EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24165 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24166 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 24167 return; 24168 } 24169 } 24170 } 24171 Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm); 24172 } 24173 24174 void Assembler::vrinta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 24175 VIXL_ASSERT(AllowAssembler()); 24176 CheckIT(al); 24177 if (IsUsingT32()) { 24178 // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; T1 24179 if (dt1.Is(F32) && dt2.Is(F32)) { 24180 EmitT32_32(0xffba0500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24181 AdvanceIT(); 24182 return; 24183 } 24184 // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; T1 24185 if (dt1.Is(F64) && dt2.Is(F64)) { 24186 EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24187 AdvanceIT(); 24188 return; 24189 } 24190 } else { 24191 // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; A1 24192 if (dt1.Is(F32) && dt2.Is(F32)) { 24193 EmitA32(0xf3ba0500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24194 return; 24195 } 24196 // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; A1 24197 if (dt1.Is(F64) && dt2.Is(F64)) { 24198 EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24199 return; 24200 } 24201 } 24202 Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm); 24203 } 24204 24205 void Assembler::vrinta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 24206 VIXL_ASSERT(AllowAssembler()); 24207 CheckIT(al); 24208 if (IsUsingT32()) { 24209 // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; T1 24210 if (dt1.Is(F32) && dt2.Is(F32)) { 24211 EmitT32_32(0xffba0540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24212 AdvanceIT(); 24213 return; 24214 } 24215 } else { 24216 // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; A1 24217 if (dt1.Is(F32) && dt2.Is(F32)) { 24218 EmitA32(0xf3ba0540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24219 return; 24220 } 24221 } 24222 Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm); 24223 } 24224 24225 void Assembler::vrinta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 24226 VIXL_ASSERT(AllowAssembler()); 24227 CheckIT(al); 24228 if (IsUsingT32()) { 24229 // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; T1 24230 if (dt1.Is(F32) && dt2.Is(F32)) { 24231 EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24232 AdvanceIT(); 24233 return; 24234 } 24235 } else { 24236 // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; A1 24237 if (dt1.Is(F32) && dt2.Is(F32)) { 24238 EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24239 return; 24240 } 24241 } 24242 Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm); 24243 } 24244 24245 void Assembler::vrintm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 24246 VIXL_ASSERT(AllowAssembler()); 24247 CheckIT(al); 24248 if (IsUsingT32()) { 24249 // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; T1 24250 if (dt1.Is(F32) && dt2.Is(F32)) { 24251 EmitT32_32(0xffba0680U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24252 AdvanceIT(); 24253 return; 24254 } 24255 // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; T1 24256 if (dt1.Is(F64) && dt2.Is(F64)) { 24257 EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24258 AdvanceIT(); 24259 return; 24260 } 24261 } else { 24262 // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; A1 24263 if (dt1.Is(F32) && dt2.Is(F32)) { 24264 EmitA32(0xf3ba0680U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24265 return; 24266 } 24267 // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; A1 24268 if (dt1.Is(F64) && dt2.Is(F64)) { 24269 EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24270 return; 24271 } 24272 } 24273 Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm); 24274 } 24275 24276 void Assembler::vrintm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 24277 VIXL_ASSERT(AllowAssembler()); 24278 CheckIT(al); 24279 if (IsUsingT32()) { 24280 // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; T1 24281 if (dt1.Is(F32) && dt2.Is(F32)) { 24282 EmitT32_32(0xffba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24283 AdvanceIT(); 24284 return; 24285 } 24286 } else { 24287 // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; A1 24288 if (dt1.Is(F32) && dt2.Is(F32)) { 24289 EmitA32(0xf3ba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24290 return; 24291 } 24292 } 24293 Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm); 24294 } 24295 24296 void Assembler::vrintm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 24297 VIXL_ASSERT(AllowAssembler()); 24298 CheckIT(al); 24299 if (IsUsingT32()) { 24300 // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; T1 24301 if (dt1.Is(F32) && dt2.Is(F32)) { 24302 EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24303 AdvanceIT(); 24304 return; 24305 } 24306 } else { 24307 // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; A1 24308 if (dt1.Is(F32) && dt2.Is(F32)) { 24309 EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24310 return; 24311 } 24312 } 24313 Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm); 24314 } 24315 24316 void Assembler::vrintn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 24317 VIXL_ASSERT(AllowAssembler()); 24318 CheckIT(al); 24319 if (IsUsingT32()) { 24320 // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; T1 24321 if (dt1.Is(F32) && dt2.Is(F32)) { 24322 EmitT32_32(0xffba0400U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24323 AdvanceIT(); 24324 return; 24325 } 24326 // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; T1 24327 if (dt1.Is(F64) && dt2.Is(F64)) { 24328 EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24329 AdvanceIT(); 24330 return; 24331 } 24332 } else { 24333 // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; A1 24334 if (dt1.Is(F32) && dt2.Is(F32)) { 24335 EmitA32(0xf3ba0400U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24336 return; 24337 } 24338 // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; A1 24339 if (dt1.Is(F64) && dt2.Is(F64)) { 24340 EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24341 return; 24342 } 24343 } 24344 Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm); 24345 } 24346 24347 void Assembler::vrintn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 24348 VIXL_ASSERT(AllowAssembler()); 24349 CheckIT(al); 24350 if (IsUsingT32()) { 24351 // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; T1 24352 if (dt1.Is(F32) && dt2.Is(F32)) { 24353 EmitT32_32(0xffba0440U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24354 AdvanceIT(); 24355 return; 24356 } 24357 } else { 24358 // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; A1 24359 if (dt1.Is(F32) && dt2.Is(F32)) { 24360 EmitA32(0xf3ba0440U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24361 return; 24362 } 24363 } 24364 Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm); 24365 } 24366 24367 void Assembler::vrintn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 24368 VIXL_ASSERT(AllowAssembler()); 24369 CheckIT(al); 24370 if (IsUsingT32()) { 24371 // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; T1 24372 if (dt1.Is(F32) && dt2.Is(F32)) { 24373 EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24374 AdvanceIT(); 24375 return; 24376 } 24377 } else { 24378 // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; A1 24379 if (dt1.Is(F32) && dt2.Is(F32)) { 24380 EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24381 return; 24382 } 24383 } 24384 Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm); 24385 } 24386 24387 void Assembler::vrintp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 24388 VIXL_ASSERT(AllowAssembler()); 24389 CheckIT(al); 24390 if (IsUsingT32()) { 24391 // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; T1 24392 if (dt1.Is(F32) && dt2.Is(F32)) { 24393 EmitT32_32(0xffba0780U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24394 AdvanceIT(); 24395 return; 24396 } 24397 // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; T1 24398 if (dt1.Is(F64) && dt2.Is(F64)) { 24399 EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24400 AdvanceIT(); 24401 return; 24402 } 24403 } else { 24404 // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; A1 24405 if (dt1.Is(F32) && dt2.Is(F32)) { 24406 EmitA32(0xf3ba0780U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24407 return; 24408 } 24409 // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; A1 24410 if (dt1.Is(F64) && dt2.Is(F64)) { 24411 EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24412 return; 24413 } 24414 } 24415 Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm); 24416 } 24417 24418 void Assembler::vrintp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 24419 VIXL_ASSERT(AllowAssembler()); 24420 CheckIT(al); 24421 if (IsUsingT32()) { 24422 // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; T1 24423 if (dt1.Is(F32) && dt2.Is(F32)) { 24424 EmitT32_32(0xffba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24425 AdvanceIT(); 24426 return; 24427 } 24428 } else { 24429 // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; A1 24430 if (dt1.Is(F32) && dt2.Is(F32)) { 24431 EmitA32(0xf3ba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24432 return; 24433 } 24434 } 24435 Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm); 24436 } 24437 24438 void Assembler::vrintp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 24439 VIXL_ASSERT(AllowAssembler()); 24440 CheckIT(al); 24441 if (IsUsingT32()) { 24442 // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; T1 24443 if (dt1.Is(F32) && dt2.Is(F32)) { 24444 EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24445 AdvanceIT(); 24446 return; 24447 } 24448 } else { 24449 // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; A1 24450 if (dt1.Is(F32) && dt2.Is(F32)) { 24451 EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24452 return; 24453 } 24454 } 24455 Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm); 24456 } 24457 24458 void Assembler::vrintr( 24459 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 24460 VIXL_ASSERT(AllowAssembler()); 24461 CheckIT(cond); 24462 if (IsUsingT32()) { 24463 // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1 24464 if (dt1.Is(F32) && dt2.Is(F32)) { 24465 EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24466 AdvanceIT(); 24467 return; 24468 } 24469 } else { 24470 // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1 24471 if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) { 24472 EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24473 rm.Encode(5, 0)); 24474 return; 24475 } 24476 } 24477 Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm); 24478 } 24479 24480 void Assembler::vrintr( 24481 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 24482 VIXL_ASSERT(AllowAssembler()); 24483 CheckIT(cond); 24484 if (IsUsingT32()) { 24485 // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1 24486 if (dt1.Is(F64) && dt2.Is(F64)) { 24487 EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24488 AdvanceIT(); 24489 return; 24490 } 24491 } else { 24492 // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1 24493 if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) { 24494 EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24495 rm.Encode(5, 0)); 24496 return; 24497 } 24498 } 24499 Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm); 24500 } 24501 24502 void Assembler::vrintx( 24503 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 24504 VIXL_ASSERT(AllowAssembler()); 24505 CheckIT(cond); 24506 if (IsUsingT32()) { 24507 // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; T1 24508 if (dt1.Is(F32) && dt2.Is(F32)) { 24509 EmitT32_32(0xffba0480U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24510 AdvanceIT(); 24511 return; 24512 } 24513 // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1 24514 if (dt1.Is(F64) && dt2.Is(F64)) { 24515 EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24516 AdvanceIT(); 24517 return; 24518 } 24519 } else { 24520 // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; A1 24521 if (dt1.Is(F32) && dt2.Is(F32)) { 24522 EmitA32(0xf3ba0480U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24523 return; 24524 } 24525 // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1 24526 if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) { 24527 EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24528 rm.Encode(5, 0)); 24529 return; 24530 } 24531 } 24532 Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm); 24533 } 24534 24535 void Assembler::vrintx(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 24536 VIXL_ASSERT(AllowAssembler()); 24537 CheckIT(al); 24538 if (IsUsingT32()) { 24539 // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; T1 24540 if (dt1.Is(F32) && dt2.Is(F32)) { 24541 EmitT32_32(0xffba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24542 AdvanceIT(); 24543 return; 24544 } 24545 } else { 24546 // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; A1 24547 if (dt1.Is(F32) && dt2.Is(F32)) { 24548 EmitA32(0xf3ba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24549 return; 24550 } 24551 } 24552 Delegate(kVrintx, &Assembler::vrintx, dt1, dt2, rd, rm); 24553 } 24554 24555 void Assembler::vrintx( 24556 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 24557 VIXL_ASSERT(AllowAssembler()); 24558 CheckIT(cond); 24559 if (IsUsingT32()) { 24560 // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1 24561 if (dt1.Is(F32) && dt2.Is(F32)) { 24562 EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24563 AdvanceIT(); 24564 return; 24565 } 24566 } else { 24567 // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1 24568 if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) { 24569 EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24570 rm.Encode(5, 0)); 24571 return; 24572 } 24573 } 24574 Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm); 24575 } 24576 24577 void Assembler::vrintz( 24578 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 24579 VIXL_ASSERT(AllowAssembler()); 24580 CheckIT(cond); 24581 if (IsUsingT32()) { 24582 // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; T1 24583 if (dt1.Is(F32) && dt2.Is(F32)) { 24584 EmitT32_32(0xffba0580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24585 AdvanceIT(); 24586 return; 24587 } 24588 // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1 24589 if (dt1.Is(F64) && dt2.Is(F64)) { 24590 EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24591 AdvanceIT(); 24592 return; 24593 } 24594 } else { 24595 // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; A1 24596 if (dt1.Is(F32) && dt2.Is(F32)) { 24597 EmitA32(0xf3ba0580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24598 return; 24599 } 24600 // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1 24601 if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) { 24602 EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24603 rm.Encode(5, 0)); 24604 return; 24605 } 24606 } 24607 Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm); 24608 } 24609 24610 void Assembler::vrintz(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 24611 VIXL_ASSERT(AllowAssembler()); 24612 CheckIT(al); 24613 if (IsUsingT32()) { 24614 // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; T1 24615 if (dt1.Is(F32) && dt2.Is(F32)) { 24616 EmitT32_32(0xffba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24617 AdvanceIT(); 24618 return; 24619 } 24620 } else { 24621 // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; A1 24622 if (dt1.Is(F32) && dt2.Is(F32)) { 24623 EmitA32(0xf3ba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24624 return; 24625 } 24626 } 24627 Delegate(kVrintz, &Assembler::vrintz, dt1, dt2, rd, rm); 24628 } 24629 24630 void Assembler::vrintz( 24631 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 24632 VIXL_ASSERT(AllowAssembler()); 24633 CheckIT(cond); 24634 if (IsUsingT32()) { 24635 // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1 24636 if (dt1.Is(F32) && dt2.Is(F32)) { 24637 EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24638 AdvanceIT(); 24639 return; 24640 } 24641 } else { 24642 // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1 24643 if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) { 24644 EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24645 rm.Encode(5, 0)); 24646 return; 24647 } 24648 } 24649 Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm); 24650 } 24651 24652 void Assembler::vrshl( 24653 Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) { 24654 VIXL_ASSERT(AllowAssembler()); 24655 CheckIT(cond); 24656 Dt_U_size_3 encoded_dt(dt); 24657 if (IsUsingT32()) { 24658 // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 24659 if (encoded_dt.IsValid()) { 24660 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24661 EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24662 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24663 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24664 AdvanceIT(); 24665 return; 24666 } 24667 } 24668 } else { 24669 // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 24670 if (encoded_dt.IsValid()) { 24671 if (cond.Is(al)) { 24672 EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24673 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24674 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24675 return; 24676 } 24677 } 24678 } 24679 Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn); 24680 } 24681 24682 void Assembler::vrshl( 24683 Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) { 24684 VIXL_ASSERT(AllowAssembler()); 24685 CheckIT(cond); 24686 Dt_U_size_3 encoded_dt(dt); 24687 if (IsUsingT32()) { 24688 // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 24689 if (encoded_dt.IsValid()) { 24690 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24691 EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24692 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24693 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24694 AdvanceIT(); 24695 return; 24696 } 24697 } 24698 } else { 24699 // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 24700 if (encoded_dt.IsValid()) { 24701 if (cond.Is(al)) { 24702 EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24703 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24704 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24705 return; 24706 } 24707 } 24708 } 24709 Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn); 24710 } 24711 24712 void Assembler::vrshr(Condition cond, 24713 DataType dt, 24714 DRegister rd, 24715 DRegister rm, 24716 const DOperand& operand) { 24717 VIXL_ASSERT(AllowAssembler()); 24718 CheckIT(cond); 24719 if (operand.IsImmediate()) { 24720 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24721 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24722 Dt_L_imm6_1 encoded_dt(dt); 24723 if (IsUsingT32()) { 24724 // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 24725 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24726 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24727 uint32_t imm6 = dt.GetSize() - imm; 24728 EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) | 24729 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24730 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24731 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24732 AdvanceIT(); 24733 return; 24734 } 24735 } 24736 // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1 24737 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24738 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24739 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24740 rm.Encode(5, 0)); 24741 AdvanceIT(); 24742 return; 24743 } 24744 } 24745 } else { 24746 // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 24747 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24748 if (cond.Is(al)) { 24749 uint32_t imm6 = dt.GetSize() - imm; 24750 EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) | 24751 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24752 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24753 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24754 return; 24755 } 24756 } 24757 // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1 24758 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24759 if (cond.Is(al)) { 24760 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24761 rm.Encode(5, 0)); 24762 return; 24763 } 24764 } 24765 } 24766 } 24767 } 24768 Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand); 24769 } 24770 24771 void Assembler::vrshr(Condition cond, 24772 DataType dt, 24773 QRegister rd, 24774 QRegister rm, 24775 const QOperand& operand) { 24776 VIXL_ASSERT(AllowAssembler()); 24777 CheckIT(cond); 24778 if (operand.IsImmediate()) { 24779 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24780 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24781 Dt_L_imm6_1 encoded_dt(dt); 24782 if (IsUsingT32()) { 24783 // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 24784 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24785 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24786 uint32_t imm6 = dt.GetSize() - imm; 24787 EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) | 24788 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24789 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24790 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24791 AdvanceIT(); 24792 return; 24793 } 24794 } 24795 // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1 24796 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24797 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24798 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24799 rm.Encode(5, 0)); 24800 AdvanceIT(); 24801 return; 24802 } 24803 } 24804 } else { 24805 // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 24806 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24807 if (cond.Is(al)) { 24808 uint32_t imm6 = dt.GetSize() - imm; 24809 EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) | 24810 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24811 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24812 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24813 return; 24814 } 24815 } 24816 // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1 24817 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24818 if (cond.Is(al)) { 24819 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24820 rm.Encode(5, 0)); 24821 return; 24822 } 24823 } 24824 } 24825 } 24826 } 24827 Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand); 24828 } 24829 24830 void Assembler::vrshrn(Condition cond, 24831 DataType dt, 24832 DRegister rd, 24833 QRegister rm, 24834 const QOperand& operand) { 24835 VIXL_ASSERT(AllowAssembler()); 24836 CheckIT(cond); 24837 if (operand.IsImmediate()) { 24838 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24839 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24840 Dt_imm6_3 encoded_dt(dt); 24841 Dt_size_3 encoded_dt_2(dt); 24842 if (IsUsingT32()) { 24843 // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 24844 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 24845 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24846 uint32_t imm6 = dt.GetSize() / 2 - imm; 24847 EmitT32_32(0xef800850U | 24848 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24849 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24850 AdvanceIT(); 24851 return; 24852 } 24853 } 24854 // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 24855 if (encoded_dt_2.IsValid() && (imm == 0)) { 24856 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24857 EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) | 24858 rd.Encode(22, 12) | rm.Encode(5, 0)); 24859 AdvanceIT(); 24860 return; 24861 } 24862 } 24863 } else { 24864 // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 24865 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 24866 if (cond.Is(al)) { 24867 uint32_t imm6 = dt.GetSize() / 2 - imm; 24868 EmitA32(0xf2800850U | 24869 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24870 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24871 return; 24872 } 24873 } 24874 // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 24875 if (encoded_dt_2.IsValid() && (imm == 0)) { 24876 if (cond.Is(al)) { 24877 EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) | 24878 rd.Encode(22, 12) | rm.Encode(5, 0)); 24879 return; 24880 } 24881 } 24882 } 24883 } 24884 } 24885 Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand); 24886 } 24887 24888 void Assembler::vrsqrte(Condition cond, 24889 DataType dt, 24890 DRegister rd, 24891 DRegister rm) { 24892 VIXL_ASSERT(AllowAssembler()); 24893 CheckIT(cond); 24894 Dt_F_size_4 encoded_dt(dt); 24895 if (IsUsingT32()) { 24896 // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 24897 if (encoded_dt.IsValid()) { 24898 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24899 EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 24900 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 24901 rd.Encode(22, 12) | rm.Encode(5, 0)); 24902 AdvanceIT(); 24903 return; 24904 } 24905 } 24906 } else { 24907 // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 24908 if (encoded_dt.IsValid()) { 24909 if (cond.Is(al)) { 24910 EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 24911 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 24912 rd.Encode(22, 12) | rm.Encode(5, 0)); 24913 return; 24914 } 24915 } 24916 } 24917 Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm); 24918 } 24919 24920 void Assembler::vrsqrte(Condition cond, 24921 DataType dt, 24922 QRegister rd, 24923 QRegister rm) { 24924 VIXL_ASSERT(AllowAssembler()); 24925 CheckIT(cond); 24926 Dt_F_size_4 encoded_dt(dt); 24927 if (IsUsingT32()) { 24928 // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 24929 if (encoded_dt.IsValid()) { 24930 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24931 EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 24932 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 24933 rd.Encode(22, 12) | rm.Encode(5, 0)); 24934 AdvanceIT(); 24935 return; 24936 } 24937 } 24938 } else { 24939 // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 24940 if (encoded_dt.IsValid()) { 24941 if (cond.Is(al)) { 24942 EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 24943 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 24944 rd.Encode(22, 12) | rm.Encode(5, 0)); 24945 return; 24946 } 24947 } 24948 } 24949 Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm); 24950 } 24951 24952 void Assembler::vrsqrts( 24953 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 24954 VIXL_ASSERT(AllowAssembler()); 24955 CheckIT(cond); 24956 if (IsUsingT32()) { 24957 // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 24958 if (dt.Is(F32)) { 24959 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24960 EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 24961 rm.Encode(5, 0)); 24962 AdvanceIT(); 24963 return; 24964 } 24965 } 24966 } else { 24967 // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 24968 if (dt.Is(F32)) { 24969 if (cond.Is(al)) { 24970 EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 24971 rm.Encode(5, 0)); 24972 return; 24973 } 24974 } 24975 } 24976 Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm); 24977 } 24978 24979 void Assembler::vrsqrts( 24980 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 24981 VIXL_ASSERT(AllowAssembler()); 24982 CheckIT(cond); 24983 if (IsUsingT32()) { 24984 // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 24985 if (dt.Is(F32)) { 24986 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24987 EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 24988 rm.Encode(5, 0)); 24989 AdvanceIT(); 24990 return; 24991 } 24992 } 24993 } else { 24994 // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 24995 if (dt.Is(F32)) { 24996 if (cond.Is(al)) { 24997 EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 24998 rm.Encode(5, 0)); 24999 return; 25000 } 25001 } 25002 } 25003 Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm); 25004 } 25005 25006 void Assembler::vrsra(Condition cond, 25007 DataType dt, 25008 DRegister rd, 25009 DRegister rm, 25010 const DOperand& operand) { 25011 VIXL_ASSERT(AllowAssembler()); 25012 CheckIT(cond); 25013 if (operand.IsImmediate()) { 25014 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25015 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25016 Dt_L_imm6_1 encoded_dt(dt); 25017 if (IsUsingT32()) { 25018 // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 25019 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25020 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25021 uint32_t imm6 = dt.GetSize() - imm; 25022 EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) | 25023 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25024 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25025 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25026 AdvanceIT(); 25027 return; 25028 } 25029 } 25030 } else { 25031 // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 25032 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25033 if (cond.Is(al)) { 25034 uint32_t imm6 = dt.GetSize() - imm; 25035 EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) | 25036 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25037 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25038 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25039 return; 25040 } 25041 } 25042 } 25043 } 25044 } 25045 Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand); 25046 } 25047 25048 void Assembler::vrsra(Condition cond, 25049 DataType dt, 25050 QRegister rd, 25051 QRegister rm, 25052 const QOperand& operand) { 25053 VIXL_ASSERT(AllowAssembler()); 25054 CheckIT(cond); 25055 if (operand.IsImmediate()) { 25056 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25057 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25058 Dt_L_imm6_1 encoded_dt(dt); 25059 if (IsUsingT32()) { 25060 // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 25061 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25062 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25063 uint32_t imm6 = dt.GetSize() - imm; 25064 EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) | 25065 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25066 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25067 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25068 AdvanceIT(); 25069 return; 25070 } 25071 } 25072 } else { 25073 // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 25074 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25075 if (cond.Is(al)) { 25076 uint32_t imm6 = dt.GetSize() - imm; 25077 EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) | 25078 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25079 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25080 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25081 return; 25082 } 25083 } 25084 } 25085 } 25086 } 25087 Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand); 25088 } 25089 25090 void Assembler::vrsubhn( 25091 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 25092 VIXL_ASSERT(AllowAssembler()); 25093 CheckIT(cond); 25094 Dt_size_3 encoded_dt(dt); 25095 if (IsUsingT32()) { 25096 // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 25097 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 25098 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25099 EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) | 25100 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 25101 AdvanceIT(); 25102 return; 25103 } 25104 } 25105 } else { 25106 // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 25107 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 25108 if (cond.Is(al)) { 25109 EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) | 25110 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 25111 return; 25112 } 25113 } 25114 } 25115 Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm); 25116 } 25117 25118 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25119 VIXL_ASSERT(AllowAssembler()); 25120 CheckIT(al); 25121 if (IsUsingT32()) { 25122 // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1 25123 if (OutsideITBlock() && dt.Is(F64)) { 25124 EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25125 rm.Encode(5, 0)); 25126 AdvanceIT(); 25127 return; 25128 } 25129 } else { 25130 // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1 25131 if (dt.Is(F64)) { 25132 EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25133 rm.Encode(5, 0)); 25134 return; 25135 } 25136 } 25137 Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm); 25138 } 25139 25140 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 25141 VIXL_ASSERT(AllowAssembler()); 25142 CheckIT(al); 25143 if (IsUsingT32()) { 25144 // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1 25145 if (OutsideITBlock() && dt.Is(F32)) { 25146 EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25147 rm.Encode(5, 0)); 25148 AdvanceIT(); 25149 return; 25150 } 25151 } else { 25152 // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1 25153 if (dt.Is(F32)) { 25154 EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25155 rm.Encode(5, 0)); 25156 return; 25157 } 25158 } 25159 Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm); 25160 } 25161 25162 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25163 VIXL_ASSERT(AllowAssembler()); 25164 CheckIT(al); 25165 if (IsUsingT32()) { 25166 // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1 25167 if (OutsideITBlock() && dt.Is(F64)) { 25168 EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25169 rm.Encode(5, 0)); 25170 AdvanceIT(); 25171 return; 25172 } 25173 } else { 25174 // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1 25175 if (dt.Is(F64)) { 25176 EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25177 rm.Encode(5, 0)); 25178 return; 25179 } 25180 } 25181 Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm); 25182 } 25183 25184 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 25185 VIXL_ASSERT(AllowAssembler()); 25186 CheckIT(al); 25187 if (IsUsingT32()) { 25188 // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1 25189 if (OutsideITBlock() && dt.Is(F32)) { 25190 EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25191 rm.Encode(5, 0)); 25192 AdvanceIT(); 25193 return; 25194 } 25195 } else { 25196 // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1 25197 if (dt.Is(F32)) { 25198 EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25199 rm.Encode(5, 0)); 25200 return; 25201 } 25202 } 25203 Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm); 25204 } 25205 25206 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25207 VIXL_ASSERT(AllowAssembler()); 25208 CheckIT(al); 25209 if (IsUsingT32()) { 25210 // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1 25211 if (OutsideITBlock() && dt.Is(F64)) { 25212 EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25213 rm.Encode(5, 0)); 25214 AdvanceIT(); 25215 return; 25216 } 25217 } else { 25218 // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1 25219 if (dt.Is(F64)) { 25220 EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25221 rm.Encode(5, 0)); 25222 return; 25223 } 25224 } 25225 Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm); 25226 } 25227 25228 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 25229 VIXL_ASSERT(AllowAssembler()); 25230 CheckIT(al); 25231 if (IsUsingT32()) { 25232 // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1 25233 if (OutsideITBlock() && dt.Is(F32)) { 25234 EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25235 rm.Encode(5, 0)); 25236 AdvanceIT(); 25237 return; 25238 } 25239 } else { 25240 // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1 25241 if (dt.Is(F32)) { 25242 EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25243 rm.Encode(5, 0)); 25244 return; 25245 } 25246 } 25247 Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm); 25248 } 25249 25250 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25251 VIXL_ASSERT(AllowAssembler()); 25252 CheckIT(al); 25253 if (IsUsingT32()) { 25254 // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1 25255 if (OutsideITBlock() && dt.Is(F64)) { 25256 EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25257 rm.Encode(5, 0)); 25258 AdvanceIT(); 25259 return; 25260 } 25261 } else { 25262 // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1 25263 if (dt.Is(F64)) { 25264 EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25265 rm.Encode(5, 0)); 25266 return; 25267 } 25268 } 25269 Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm); 25270 } 25271 25272 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 25273 VIXL_ASSERT(AllowAssembler()); 25274 CheckIT(al); 25275 if (IsUsingT32()) { 25276 // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1 25277 if (OutsideITBlock() && dt.Is(F32)) { 25278 EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25279 rm.Encode(5, 0)); 25280 AdvanceIT(); 25281 return; 25282 } 25283 } else { 25284 // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1 25285 if (dt.Is(F32)) { 25286 EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25287 rm.Encode(5, 0)); 25288 return; 25289 } 25290 } 25291 Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm); 25292 } 25293 25294 void Assembler::vshl(Condition cond, 25295 DataType dt, 25296 DRegister rd, 25297 DRegister rm, 25298 const DOperand& operand) { 25299 VIXL_ASSERT(AllowAssembler()); 25300 CheckIT(cond); 25301 if (operand.IsImmediate()) { 25302 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25303 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25304 Dt_L_imm6_3 encoded_dt(dt); 25305 if (IsUsingT32()) { 25306 // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1 25307 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25308 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25309 uint32_t imm6 = imm; 25310 EmitT32_32(0xef800510U | 25311 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25312 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25313 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25314 AdvanceIT(); 25315 return; 25316 } 25317 } 25318 } else { 25319 // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1 25320 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25321 if (cond.Is(al)) { 25322 uint32_t imm6 = imm; 25323 EmitA32(0xf2800510U | 25324 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25325 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25326 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25327 return; 25328 } 25329 } 25330 } 25331 } 25332 } 25333 if (operand.IsRegister()) { 25334 DRegister rn = operand.GetRegister(); 25335 Dt_U_size_3 encoded_dt(dt); 25336 if (IsUsingT32()) { 25337 // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 25338 if (encoded_dt.IsValid()) { 25339 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25340 EmitT32_32(0xef000400U | 25341 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 25342 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 25343 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 25344 AdvanceIT(); 25345 return; 25346 } 25347 } 25348 } else { 25349 // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 25350 if (encoded_dt.IsValid()) { 25351 if (cond.Is(al)) { 25352 EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 25353 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 25354 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 25355 return; 25356 } 25357 } 25358 } 25359 } 25360 Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand); 25361 } 25362 25363 void Assembler::vshl(Condition cond, 25364 DataType dt, 25365 QRegister rd, 25366 QRegister rm, 25367 const QOperand& operand) { 25368 VIXL_ASSERT(AllowAssembler()); 25369 CheckIT(cond); 25370 if (operand.IsImmediate()) { 25371 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25372 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25373 Dt_L_imm6_3 encoded_dt(dt); 25374 if (IsUsingT32()) { 25375 // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1 25376 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25377 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25378 uint32_t imm6 = imm; 25379 EmitT32_32(0xef800550U | 25380 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25381 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25382 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25383 AdvanceIT(); 25384 return; 25385 } 25386 } 25387 } else { 25388 // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1 25389 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25390 if (cond.Is(al)) { 25391 uint32_t imm6 = imm; 25392 EmitA32(0xf2800550U | 25393 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25394 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25395 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25396 return; 25397 } 25398 } 25399 } 25400 } 25401 } 25402 if (operand.IsRegister()) { 25403 QRegister rn = operand.GetRegister(); 25404 Dt_U_size_3 encoded_dt(dt); 25405 if (IsUsingT32()) { 25406 // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 25407 if (encoded_dt.IsValid()) { 25408 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25409 EmitT32_32(0xef000440U | 25410 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 25411 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 25412 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 25413 AdvanceIT(); 25414 return; 25415 } 25416 } 25417 } else { 25418 // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 25419 if (encoded_dt.IsValid()) { 25420 if (cond.Is(al)) { 25421 EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 25422 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 25423 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 25424 return; 25425 } 25426 } 25427 } 25428 } 25429 Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand); 25430 } 25431 25432 void Assembler::vshll(Condition cond, 25433 DataType dt, 25434 QRegister rd, 25435 DRegister rm, 25436 const DOperand& operand) { 25437 VIXL_ASSERT(AllowAssembler()); 25438 CheckIT(cond); 25439 if (operand.IsImmediate()) { 25440 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25441 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25442 Dt_imm6_4 encoded_dt(dt); 25443 Dt_size_16 encoded_dt_2(dt); 25444 if (IsUsingT32()) { 25445 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 25446 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) { 25447 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25448 uint32_t imm6 = dt.GetSize() + imm; 25449 EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) | 25450 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25451 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25452 AdvanceIT(); 25453 return; 25454 } 25455 } 25456 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2 25457 if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) { 25458 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25459 EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) | 25460 rd.Encode(22, 12) | rm.Encode(5, 0)); 25461 AdvanceIT(); 25462 return; 25463 } 25464 } 25465 } else { 25466 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 25467 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) { 25468 if (cond.Is(al)) { 25469 uint32_t imm6 = dt.GetSize() + imm; 25470 EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) | 25471 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25472 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25473 return; 25474 } 25475 } 25476 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2 25477 if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) { 25478 if (cond.Is(al)) { 25479 EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) | 25480 rd.Encode(22, 12) | rm.Encode(5, 0)); 25481 return; 25482 } 25483 } 25484 } 25485 } 25486 } 25487 Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand); 25488 } 25489 25490 void Assembler::vshr(Condition cond, 25491 DataType dt, 25492 DRegister rd, 25493 DRegister rm, 25494 const DOperand& operand) { 25495 VIXL_ASSERT(AllowAssembler()); 25496 CheckIT(cond); 25497 if (operand.IsImmediate()) { 25498 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25499 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25500 Dt_L_imm6_1 encoded_dt(dt); 25501 if (IsUsingT32()) { 25502 // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 25503 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25504 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25505 uint32_t imm6 = dt.GetSize() - imm; 25506 EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) | 25507 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25508 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25509 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25510 AdvanceIT(); 25511 return; 25512 } 25513 } 25514 // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1 25515 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 25516 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25517 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 25518 rm.Encode(5, 0)); 25519 AdvanceIT(); 25520 return; 25521 } 25522 } 25523 } else { 25524 // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 25525 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25526 if (cond.Is(al)) { 25527 uint32_t imm6 = dt.GetSize() - imm; 25528 EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) | 25529 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25530 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25531 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25532 return; 25533 } 25534 } 25535 // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1 25536 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 25537 if (cond.Is(al)) { 25538 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 25539 rm.Encode(5, 0)); 25540 return; 25541 } 25542 } 25543 } 25544 } 25545 } 25546 Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand); 25547 } 25548 25549 void Assembler::vshr(Condition cond, 25550 DataType dt, 25551 QRegister rd, 25552 QRegister rm, 25553 const QOperand& operand) { 25554 VIXL_ASSERT(AllowAssembler()); 25555 CheckIT(cond); 25556 if (operand.IsImmediate()) { 25557 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25558 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25559 Dt_L_imm6_1 encoded_dt(dt); 25560 if (IsUsingT32()) { 25561 // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 25562 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25563 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25564 uint32_t imm6 = dt.GetSize() - imm; 25565 EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) | 25566 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25567 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25568 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25569 AdvanceIT(); 25570 return; 25571 } 25572 } 25573 // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1 25574 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 25575 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25576 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 25577 rm.Encode(5, 0)); 25578 AdvanceIT(); 25579 return; 25580 } 25581 } 25582 } else { 25583 // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 25584 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25585 if (cond.Is(al)) { 25586 uint32_t imm6 = dt.GetSize() - imm; 25587 EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) | 25588 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25589 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25590 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25591 return; 25592 } 25593 } 25594 // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1 25595 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 25596 if (cond.Is(al)) { 25597 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 25598 rm.Encode(5, 0)); 25599 return; 25600 } 25601 } 25602 } 25603 } 25604 } 25605 Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand); 25606 } 25607 25608 void Assembler::vshrn(Condition cond, 25609 DataType dt, 25610 DRegister rd, 25611 QRegister rm, 25612 const QOperand& operand) { 25613 VIXL_ASSERT(AllowAssembler()); 25614 CheckIT(cond); 25615 if (operand.IsImmediate()) { 25616 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25617 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25618 Dt_imm6_3 encoded_dt(dt); 25619 Dt_size_3 encoded_dt_2(dt); 25620 if (IsUsingT32()) { 25621 // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 25622 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 25623 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25624 uint32_t imm6 = dt.GetSize() / 2 - imm; 25625 EmitT32_32(0xef800810U | 25626 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25627 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25628 AdvanceIT(); 25629 return; 25630 } 25631 } 25632 // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 25633 if (encoded_dt_2.IsValid() && (imm == 0)) { 25634 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25635 EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) | 25636 rd.Encode(22, 12) | rm.Encode(5, 0)); 25637 AdvanceIT(); 25638 return; 25639 } 25640 } 25641 } else { 25642 // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 25643 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 25644 if (cond.Is(al)) { 25645 uint32_t imm6 = dt.GetSize() / 2 - imm; 25646 EmitA32(0xf2800810U | 25647 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25648 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25649 return; 25650 } 25651 } 25652 // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 25653 if (encoded_dt_2.IsValid() && (imm == 0)) { 25654 if (cond.Is(al)) { 25655 EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) | 25656 rd.Encode(22, 12) | rm.Encode(5, 0)); 25657 return; 25658 } 25659 } 25660 } 25661 } 25662 } 25663 Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand); 25664 } 25665 25666 void Assembler::vsli(Condition cond, 25667 DataType dt, 25668 DRegister rd, 25669 DRegister rm, 25670 const DOperand& operand) { 25671 VIXL_ASSERT(AllowAssembler()); 25672 CheckIT(cond); 25673 if (operand.IsImmediate()) { 25674 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25675 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25676 Dt_L_imm6_4 encoded_dt(dt); 25677 if (IsUsingT32()) { 25678 // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1 25679 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25680 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25681 uint32_t imm6 = imm; 25682 EmitT32_32(0xff800510U | 25683 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25684 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25685 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25686 AdvanceIT(); 25687 return; 25688 } 25689 } 25690 } else { 25691 // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1 25692 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25693 if (cond.Is(al)) { 25694 uint32_t imm6 = imm; 25695 EmitA32(0xf3800510U | 25696 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25697 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25698 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25699 return; 25700 } 25701 } 25702 } 25703 } 25704 } 25705 Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand); 25706 } 25707 25708 void Assembler::vsli(Condition cond, 25709 DataType dt, 25710 QRegister rd, 25711 QRegister rm, 25712 const QOperand& operand) { 25713 VIXL_ASSERT(AllowAssembler()); 25714 CheckIT(cond); 25715 if (operand.IsImmediate()) { 25716 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25717 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25718 Dt_L_imm6_4 encoded_dt(dt); 25719 if (IsUsingT32()) { 25720 // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1 25721 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25722 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25723 uint32_t imm6 = imm; 25724 EmitT32_32(0xff800550U | 25725 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25726 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25727 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25728 AdvanceIT(); 25729 return; 25730 } 25731 } 25732 } else { 25733 // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1 25734 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 25735 if (cond.Is(al)) { 25736 uint32_t imm6 = imm; 25737 EmitA32(0xf3800550U | 25738 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25739 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25740 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25741 return; 25742 } 25743 } 25744 } 25745 } 25746 } 25747 Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand); 25748 } 25749 25750 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) { 25751 VIXL_ASSERT(AllowAssembler()); 25752 CheckIT(cond); 25753 if (IsUsingT32()) { 25754 // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 25755 if (dt.Is(F32)) { 25756 EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 25757 AdvanceIT(); 25758 return; 25759 } 25760 } else { 25761 // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 25762 if (dt.Is(F32) && cond.IsNotNever()) { 25763 EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 25764 rm.Encode(5, 0)); 25765 return; 25766 } 25767 } 25768 Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm); 25769 } 25770 25771 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) { 25772 VIXL_ASSERT(AllowAssembler()); 25773 CheckIT(cond); 25774 if (IsUsingT32()) { 25775 // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 25776 if (dt.Is(F64)) { 25777 EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 25778 AdvanceIT(); 25779 return; 25780 } 25781 } else { 25782 // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 25783 if (dt.Is(F64) && cond.IsNotNever()) { 25784 EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 25785 rm.Encode(5, 0)); 25786 return; 25787 } 25788 } 25789 Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm); 25790 } 25791 25792 void Assembler::vsra(Condition cond, 25793 DataType dt, 25794 DRegister rd, 25795 DRegister rm, 25796 const DOperand& operand) { 25797 VIXL_ASSERT(AllowAssembler()); 25798 CheckIT(cond); 25799 if (operand.IsImmediate()) { 25800 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25801 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25802 Dt_L_imm6_1 encoded_dt(dt); 25803 if (IsUsingT32()) { 25804 // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 25805 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25806 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25807 uint32_t imm6 = dt.GetSize() - imm; 25808 EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) | 25809 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25810 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25811 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25812 AdvanceIT(); 25813 return; 25814 } 25815 } 25816 } else { 25817 // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 25818 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25819 if (cond.Is(al)) { 25820 uint32_t imm6 = dt.GetSize() - imm; 25821 EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) | 25822 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25823 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25824 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25825 return; 25826 } 25827 } 25828 } 25829 } 25830 } 25831 Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand); 25832 } 25833 25834 void Assembler::vsra(Condition cond, 25835 DataType dt, 25836 QRegister rd, 25837 QRegister rm, 25838 const QOperand& operand) { 25839 VIXL_ASSERT(AllowAssembler()); 25840 CheckIT(cond); 25841 if (operand.IsImmediate()) { 25842 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25843 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25844 Dt_L_imm6_1 encoded_dt(dt); 25845 if (IsUsingT32()) { 25846 // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 25847 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25848 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25849 uint32_t imm6 = dt.GetSize() - imm; 25850 EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) | 25851 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25852 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25853 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25854 AdvanceIT(); 25855 return; 25856 } 25857 } 25858 } else { 25859 // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 25860 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25861 if (cond.Is(al)) { 25862 uint32_t imm6 = dt.GetSize() - imm; 25863 EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) | 25864 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25865 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25866 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25867 return; 25868 } 25869 } 25870 } 25871 } 25872 } 25873 Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand); 25874 } 25875 25876 void Assembler::vsri(Condition cond, 25877 DataType dt, 25878 DRegister rd, 25879 DRegister rm, 25880 const DOperand& operand) { 25881 VIXL_ASSERT(AllowAssembler()); 25882 CheckIT(cond); 25883 if (operand.IsImmediate()) { 25884 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25885 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25886 Dt_L_imm6_4 encoded_dt(dt); 25887 if (IsUsingT32()) { 25888 // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1 25889 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25890 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25891 uint32_t imm6 = dt.GetSize() - imm; 25892 EmitT32_32(0xff800410U | 25893 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25894 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25895 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25896 AdvanceIT(); 25897 return; 25898 } 25899 } 25900 } else { 25901 // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1 25902 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25903 if (cond.Is(al)) { 25904 uint32_t imm6 = dt.GetSize() - imm; 25905 EmitA32(0xf3800410U | 25906 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25907 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25908 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25909 return; 25910 } 25911 } 25912 } 25913 } 25914 } 25915 Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand); 25916 } 25917 25918 void Assembler::vsri(Condition cond, 25919 DataType dt, 25920 QRegister rd, 25921 QRegister rm, 25922 const QOperand& operand) { 25923 VIXL_ASSERT(AllowAssembler()); 25924 CheckIT(cond); 25925 if (operand.IsImmediate()) { 25926 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 25927 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 25928 Dt_L_imm6_4 encoded_dt(dt); 25929 if (IsUsingT32()) { 25930 // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1 25931 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25932 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25933 uint32_t imm6 = dt.GetSize() - imm; 25934 EmitT32_32(0xff800450U | 25935 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25936 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25937 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25938 AdvanceIT(); 25939 return; 25940 } 25941 } 25942 } else { 25943 // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1 25944 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 25945 if (cond.Is(al)) { 25946 uint32_t imm6 = dt.GetSize() - imm; 25947 EmitA32(0xf3800450U | 25948 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 25949 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 25950 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 25951 return; 25952 } 25953 } 25954 } 25955 } 25956 } 25957 Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand); 25958 } 25959 25960 void Assembler::vst1(Condition cond, 25961 DataType dt, 25962 const NeonRegisterList& nreglist, 25963 const AlignedMemOperand& operand) { 25964 VIXL_ASSERT(AllowAssembler()); 25965 CheckIT(cond); 25966 if (operand.IsImmediateZero()) { 25967 Register rn = operand.GetBaseRegister(); 25968 Alignment align = operand.GetAlignment(); 25969 Dt_size_6 encoded_dt(dt); 25970 Dt_size_7 encoded_dt_2(dt); 25971 Align_align_5 encoded_align_1(align, nreglist); 25972 Align_index_align_1 encoded_align_2(align, nreglist, dt); 25973 if (IsUsingT32()) { 25974 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 25975 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25976 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 25977 operand.IsOffset() && encoded_align_1.IsValid() && 25978 (!rn.IsPC() || AllowUnpredictable())) { 25979 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25980 const DRegister& first = nreglist.GetFirstDRegister(); 25981 uint32_t len_encoding; 25982 switch (nreglist.GetLength()) { 25983 default: 25984 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 25985 case 1: 25986 len_encoding = 0x7; 25987 break; 25988 case 2: 25989 len_encoding = 0xa; 25990 break; 25991 case 3: 25992 len_encoding = 0x6; 25993 break; 25994 case 4: 25995 len_encoding = 0x2; 25996 break; 25997 } 25998 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 25999 (encoded_align_1.GetEncodingValue() << 4) | 26000 first.Encode(22, 12) | (len_encoding << 8) | 26001 (rn.GetCode() << 16)); 26002 AdvanceIT(); 26003 return; 26004 } 26005 } 26006 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26007 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26008 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26009 operand.IsPostIndex() && encoded_align_1.IsValid() && 26010 (!rn.IsPC() || AllowUnpredictable())) { 26011 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26012 const DRegister& first = nreglist.GetFirstDRegister(); 26013 uint32_t len_encoding; 26014 switch (nreglist.GetLength()) { 26015 default: 26016 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26017 case 1: 26018 len_encoding = 0x7; 26019 break; 26020 case 2: 26021 len_encoding = 0xa; 26022 break; 26023 case 3: 26024 len_encoding = 0x6; 26025 break; 26026 case 4: 26027 len_encoding = 0x2; 26028 break; 26029 } 26030 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 26031 (encoded_align_1.GetEncodingValue() << 4) | 26032 first.Encode(22, 12) | (len_encoding << 8) | 26033 (rn.GetCode() << 16)); 26034 AdvanceIT(); 26035 return; 26036 } 26037 } 26038 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26039 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26040 (nreglist.GetLength() == 1) && operand.IsOffset() && 26041 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 26042 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26043 const DRegister& first = nreglist.GetFirstDRegister(); 26044 EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) | 26045 (encoded_align_2.GetEncodingValue() << 4) | 26046 first.Encode(22, 12) | (rn.GetCode() << 16)); 26047 AdvanceIT(); 26048 return; 26049 } 26050 } 26051 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26052 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26053 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 26054 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 26055 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26056 const DRegister& first = nreglist.GetFirstDRegister(); 26057 EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) | 26058 (encoded_align_2.GetEncodingValue() << 4) | 26059 first.Encode(22, 12) | (rn.GetCode() << 16)); 26060 AdvanceIT(); 26061 return; 26062 } 26063 } 26064 } else { 26065 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26066 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26067 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26068 operand.IsOffset() && encoded_align_1.IsValid() && 26069 (!rn.IsPC() || AllowUnpredictable())) { 26070 if (cond.Is(al)) { 26071 const DRegister& first = nreglist.GetFirstDRegister(); 26072 uint32_t len_encoding; 26073 switch (nreglist.GetLength()) { 26074 default: 26075 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26076 case 1: 26077 len_encoding = 0x7; 26078 break; 26079 case 2: 26080 len_encoding = 0xa; 26081 break; 26082 case 3: 26083 len_encoding = 0x6; 26084 break; 26085 case 4: 26086 len_encoding = 0x2; 26087 break; 26088 } 26089 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 26090 (encoded_align_1.GetEncodingValue() << 4) | 26091 first.Encode(22, 12) | (len_encoding << 8) | 26092 (rn.GetCode() << 16)); 26093 return; 26094 } 26095 } 26096 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26097 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26098 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26099 operand.IsPostIndex() && encoded_align_1.IsValid() && 26100 (!rn.IsPC() || AllowUnpredictable())) { 26101 if (cond.Is(al)) { 26102 const DRegister& first = nreglist.GetFirstDRegister(); 26103 uint32_t len_encoding; 26104 switch (nreglist.GetLength()) { 26105 default: 26106 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26107 case 1: 26108 len_encoding = 0x7; 26109 break; 26110 case 2: 26111 len_encoding = 0xa; 26112 break; 26113 case 3: 26114 len_encoding = 0x6; 26115 break; 26116 case 4: 26117 len_encoding = 0x2; 26118 break; 26119 } 26120 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 26121 (encoded_align_1.GetEncodingValue() << 4) | 26122 first.Encode(22, 12) | (len_encoding << 8) | 26123 (rn.GetCode() << 16)); 26124 return; 26125 } 26126 } 26127 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26128 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26129 (nreglist.GetLength() == 1) && operand.IsOffset() && 26130 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 26131 if (cond.Is(al)) { 26132 const DRegister& first = nreglist.GetFirstDRegister(); 26133 EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) | 26134 (encoded_align_2.GetEncodingValue() << 4) | 26135 first.Encode(22, 12) | (rn.GetCode() << 16)); 26136 return; 26137 } 26138 } 26139 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26140 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26141 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 26142 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 26143 if (cond.Is(al)) { 26144 const DRegister& first = nreglist.GetFirstDRegister(); 26145 EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) | 26146 (encoded_align_2.GetEncodingValue() << 4) | 26147 first.Encode(22, 12) | (rn.GetCode() << 16)); 26148 return; 26149 } 26150 } 26151 } 26152 } 26153 if (operand.IsPlainRegister()) { 26154 Register rn = operand.GetBaseRegister(); 26155 Alignment align = operand.GetAlignment(); 26156 Register rm = operand.GetOffsetRegister(); 26157 Dt_size_6 encoded_dt(dt); 26158 Dt_size_7 encoded_dt_2(dt); 26159 Align_align_5 encoded_align_1(align, nreglist); 26160 Align_index_align_1 encoded_align_2(align, nreglist, dt); 26161 if (IsUsingT32()) { 26162 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26163 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26164 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26165 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26166 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26167 const DRegister& first = nreglist.GetFirstDRegister(); 26168 uint32_t len_encoding; 26169 switch (nreglist.GetLength()) { 26170 default: 26171 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26172 case 1: 26173 len_encoding = 0x7; 26174 break; 26175 case 2: 26176 len_encoding = 0xa; 26177 break; 26178 case 3: 26179 len_encoding = 0x6; 26180 break; 26181 case 4: 26182 len_encoding = 0x2; 26183 break; 26184 } 26185 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 26186 (encoded_align_1.GetEncodingValue() << 4) | 26187 first.Encode(22, 12) | (len_encoding << 8) | 26188 (rn.GetCode() << 16) | rm.GetCode()); 26189 AdvanceIT(); 26190 return; 26191 } 26192 } 26193 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26194 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26195 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() && 26196 (!rn.IsPC() || AllowUnpredictable())) { 26197 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26198 const DRegister& first = nreglist.GetFirstDRegister(); 26199 EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) | 26200 (encoded_align_2.GetEncodingValue() << 4) | 26201 first.Encode(22, 12) | (rn.GetCode() << 16) | 26202 rm.GetCode()); 26203 AdvanceIT(); 26204 return; 26205 } 26206 } 26207 } else { 26208 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26209 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26210 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 26211 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26212 if (cond.Is(al)) { 26213 const DRegister& first = nreglist.GetFirstDRegister(); 26214 uint32_t len_encoding; 26215 switch (nreglist.GetLength()) { 26216 default: 26217 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 26218 case 1: 26219 len_encoding = 0x7; 26220 break; 26221 case 2: 26222 len_encoding = 0xa; 26223 break; 26224 case 3: 26225 len_encoding = 0x6; 26226 break; 26227 case 4: 26228 len_encoding = 0x2; 26229 break; 26230 } 26231 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 26232 (encoded_align_1.GetEncodingValue() << 4) | 26233 first.Encode(22, 12) | (len_encoding << 8) | 26234 (rn.GetCode() << 16) | rm.GetCode()); 26235 return; 26236 } 26237 } 26238 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26239 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 26240 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() && 26241 (!rn.IsPC() || AllowUnpredictable())) { 26242 if (cond.Is(al)) { 26243 const DRegister& first = nreglist.GetFirstDRegister(); 26244 EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) | 26245 (encoded_align_2.GetEncodingValue() << 4) | 26246 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 26247 return; 26248 } 26249 } 26250 } 26251 } 26252 Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand); 26253 } 26254 26255 void Assembler::vst2(Condition cond, 26256 DataType dt, 26257 const NeonRegisterList& nreglist, 26258 const AlignedMemOperand& operand) { 26259 VIXL_ASSERT(AllowAssembler()); 26260 CheckIT(cond); 26261 if (operand.IsImmediateZero()) { 26262 Register rn = operand.GetBaseRegister(); 26263 Alignment align = operand.GetAlignment(); 26264 Dt_size_7 encoded_dt(dt); 26265 Align_align_2 encoded_align_1(align, nreglist); 26266 Align_index_align_2 encoded_align_2(align, nreglist, dt); 26267 if (IsUsingT32()) { 26268 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26269 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26270 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26271 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26272 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26273 operand.IsOffset() && encoded_align_1.IsValid() && 26274 (!rn.IsPC() || AllowUnpredictable())) { 26275 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26276 const DRegister& first = nreglist.GetFirstDRegister(); 26277 uint32_t len_encoding; 26278 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26279 len_encoding = 0x8; 26280 } 26281 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26282 len_encoding = 0x9; 26283 } 26284 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26285 len_encoding = 0x3; 26286 } 26287 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 26288 (encoded_align_1.GetEncodingValue() << 4) | 26289 first.Encode(22, 12) | (len_encoding << 8) | 26290 (rn.GetCode() << 16)); 26291 AdvanceIT(); 26292 return; 26293 } 26294 } 26295 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26296 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26297 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26298 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26299 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26300 operand.IsPostIndex() && encoded_align_1.IsValid() && 26301 (!rn.IsPC() || AllowUnpredictable())) { 26302 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26303 const DRegister& first = nreglist.GetFirstDRegister(); 26304 uint32_t len_encoding; 26305 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26306 len_encoding = 0x8; 26307 } 26308 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26309 len_encoding = 0x9; 26310 } 26311 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26312 len_encoding = 0x3; 26313 } 26314 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 26315 (encoded_align_1.GetEncodingValue() << 4) | 26316 first.Encode(22, 12) | (len_encoding << 8) | 26317 (rn.GetCode() << 16)); 26318 AdvanceIT(); 26319 return; 26320 } 26321 } 26322 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26323 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26324 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26325 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26326 operand.IsOffset() && encoded_align_2.IsValid() && 26327 (!rn.IsPC() || AllowUnpredictable())) { 26328 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26329 const DRegister& first = nreglist.GetFirstDRegister(); 26330 EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) | 26331 (encoded_align_2.GetEncodingValue() << 4) | 26332 first.Encode(22, 12) | (rn.GetCode() << 16)); 26333 AdvanceIT(); 26334 return; 26335 } 26336 } 26337 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26338 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26339 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26340 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26341 operand.IsPostIndex() && encoded_align_2.IsValid() && 26342 (!rn.IsPC() || AllowUnpredictable())) { 26343 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26344 const DRegister& first = nreglist.GetFirstDRegister(); 26345 EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) | 26346 (encoded_align_2.GetEncodingValue() << 4) | 26347 first.Encode(22, 12) | (rn.GetCode() << 16)); 26348 AdvanceIT(); 26349 return; 26350 } 26351 } 26352 } else { 26353 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26354 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26355 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26356 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26357 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26358 operand.IsOffset() && encoded_align_1.IsValid() && 26359 (!rn.IsPC() || AllowUnpredictable())) { 26360 if (cond.Is(al)) { 26361 const DRegister& first = nreglist.GetFirstDRegister(); 26362 uint32_t len_encoding; 26363 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26364 len_encoding = 0x8; 26365 } 26366 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26367 len_encoding = 0x9; 26368 } 26369 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26370 len_encoding = 0x3; 26371 } 26372 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 26373 (encoded_align_1.GetEncodingValue() << 4) | 26374 first.Encode(22, 12) | (len_encoding << 8) | 26375 (rn.GetCode() << 16)); 26376 return; 26377 } 26378 } 26379 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26380 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26381 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26382 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26383 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26384 operand.IsPostIndex() && encoded_align_1.IsValid() && 26385 (!rn.IsPC() || AllowUnpredictable())) { 26386 if (cond.Is(al)) { 26387 const DRegister& first = nreglist.GetFirstDRegister(); 26388 uint32_t len_encoding; 26389 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26390 len_encoding = 0x8; 26391 } 26392 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26393 len_encoding = 0x9; 26394 } 26395 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26396 len_encoding = 0x3; 26397 } 26398 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 26399 (encoded_align_1.GetEncodingValue() << 4) | 26400 first.Encode(22, 12) | (len_encoding << 8) | 26401 (rn.GetCode() << 16)); 26402 return; 26403 } 26404 } 26405 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26406 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26407 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26408 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26409 operand.IsOffset() && encoded_align_2.IsValid() && 26410 (!rn.IsPC() || AllowUnpredictable())) { 26411 if (cond.Is(al)) { 26412 const DRegister& first = nreglist.GetFirstDRegister(); 26413 EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) | 26414 (encoded_align_2.GetEncodingValue() << 4) | 26415 first.Encode(22, 12) | (rn.GetCode() << 16)); 26416 return; 26417 } 26418 } 26419 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26420 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26421 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26422 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26423 operand.IsPostIndex() && encoded_align_2.IsValid() && 26424 (!rn.IsPC() || AllowUnpredictable())) { 26425 if (cond.Is(al)) { 26426 const DRegister& first = nreglist.GetFirstDRegister(); 26427 EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) | 26428 (encoded_align_2.GetEncodingValue() << 4) | 26429 first.Encode(22, 12) | (rn.GetCode() << 16)); 26430 return; 26431 } 26432 } 26433 } 26434 } 26435 if (operand.IsPlainRegister()) { 26436 Register rn = operand.GetBaseRegister(); 26437 Alignment align = operand.GetAlignment(); 26438 Register rm = operand.GetOffsetRegister(); 26439 Dt_size_7 encoded_dt(dt); 26440 Align_align_2 encoded_align_1(align, nreglist); 26441 Align_index_align_2 encoded_align_2(align, nreglist, dt); 26442 if (IsUsingT32()) { 26443 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26444 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26445 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26446 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26447 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26448 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26449 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26450 const DRegister& first = nreglist.GetFirstDRegister(); 26451 uint32_t len_encoding; 26452 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26453 len_encoding = 0x8; 26454 } 26455 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26456 len_encoding = 0x9; 26457 } 26458 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26459 len_encoding = 0x3; 26460 } 26461 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 26462 (encoded_align_1.GetEncodingValue() << 4) | 26463 first.Encode(22, 12) | (len_encoding << 8) | 26464 (rn.GetCode() << 16) | rm.GetCode()); 26465 AdvanceIT(); 26466 return; 26467 } 26468 } 26469 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26470 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26471 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26472 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26473 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26474 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26475 const DRegister& first = nreglist.GetFirstDRegister(); 26476 EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) | 26477 (encoded_align_2.GetEncodingValue() << 4) | 26478 first.Encode(22, 12) | (rn.GetCode() << 16) | 26479 rm.GetCode()); 26480 AdvanceIT(); 26481 return; 26482 } 26483 } 26484 } else { 26485 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26486 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26487 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26488 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 26489 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 26490 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26491 if (cond.Is(al)) { 26492 const DRegister& first = nreglist.GetFirstDRegister(); 26493 uint32_t len_encoding; 26494 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 26495 len_encoding = 0x8; 26496 } 26497 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 26498 len_encoding = 0x9; 26499 } 26500 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 26501 len_encoding = 0x3; 26502 } 26503 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 26504 (encoded_align_1.GetEncodingValue() << 4) | 26505 first.Encode(22, 12) | (len_encoding << 8) | 26506 (rn.GetCode() << 16) | rm.GetCode()); 26507 return; 26508 } 26509 } 26510 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26511 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26512 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 26513 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 26514 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26515 if (cond.Is(al)) { 26516 const DRegister& first = nreglist.GetFirstDRegister(); 26517 EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) | 26518 (encoded_align_2.GetEncodingValue() << 4) | 26519 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 26520 return; 26521 } 26522 } 26523 } 26524 } 26525 Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand); 26526 } 26527 26528 void Assembler::vst3(Condition cond, 26529 DataType dt, 26530 const NeonRegisterList& nreglist, 26531 const AlignedMemOperand& operand) { 26532 VIXL_ASSERT(AllowAssembler()); 26533 CheckIT(cond); 26534 if (operand.IsImmediateZero()) { 26535 Register rn = operand.GetBaseRegister(); 26536 Alignment align = operand.GetAlignment(); 26537 Dt_size_7 encoded_dt(dt); 26538 Align_align_3 encoded_align_1(align); 26539 if (IsUsingT32()) { 26540 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26541 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26542 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26543 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26544 operand.IsOffset() && encoded_align_1.IsValid() && 26545 (!rn.IsPC() || AllowUnpredictable())) { 26546 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26547 const DRegister& first = nreglist.GetFirstDRegister(); 26548 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26549 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 26550 (encoded_align_1.GetEncodingValue() << 4) | 26551 first.Encode(22, 12) | (len_encoding << 8) | 26552 (rn.GetCode() << 16)); 26553 AdvanceIT(); 26554 return; 26555 } 26556 } 26557 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26558 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26559 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26560 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26561 operand.IsPostIndex() && encoded_align_1.IsValid() && 26562 (!rn.IsPC() || AllowUnpredictable())) { 26563 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26564 const DRegister& first = nreglist.GetFirstDRegister(); 26565 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26566 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 26567 (encoded_align_1.GetEncodingValue() << 4) | 26568 first.Encode(22, 12) | (len_encoding << 8) | 26569 (rn.GetCode() << 16)); 26570 AdvanceIT(); 26571 return; 26572 } 26573 } 26574 } else { 26575 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26576 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26577 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26578 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26579 operand.IsOffset() && encoded_align_1.IsValid() && 26580 (!rn.IsPC() || AllowUnpredictable())) { 26581 if (cond.Is(al)) { 26582 const DRegister& first = nreglist.GetFirstDRegister(); 26583 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26584 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 26585 (encoded_align_1.GetEncodingValue() << 4) | 26586 first.Encode(22, 12) | (len_encoding << 8) | 26587 (rn.GetCode() << 16)); 26588 return; 26589 } 26590 } 26591 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26592 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26593 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26594 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26595 operand.IsPostIndex() && encoded_align_1.IsValid() && 26596 (!rn.IsPC() || AllowUnpredictable())) { 26597 if (cond.Is(al)) { 26598 const DRegister& first = nreglist.GetFirstDRegister(); 26599 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26600 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 26601 (encoded_align_1.GetEncodingValue() << 4) | 26602 first.Encode(22, 12) | (len_encoding << 8) | 26603 (rn.GetCode() << 16)); 26604 return; 26605 } 26606 } 26607 } 26608 } 26609 if (operand.IsPlainRegister()) { 26610 Register rn = operand.GetBaseRegister(); 26611 Alignment align = operand.GetAlignment(); 26612 Register rm = operand.GetOffsetRegister(); 26613 Dt_size_7 encoded_dt(dt); 26614 Align_align_3 encoded_align_1(align); 26615 if (IsUsingT32()) { 26616 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26617 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26618 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26619 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26620 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26621 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26622 const DRegister& first = nreglist.GetFirstDRegister(); 26623 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26624 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 26625 (encoded_align_1.GetEncodingValue() << 4) | 26626 first.Encode(22, 12) | (len_encoding << 8) | 26627 (rn.GetCode() << 16) | rm.GetCode()); 26628 AdvanceIT(); 26629 return; 26630 } 26631 } 26632 } else { 26633 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26634 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26635 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26636 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26637 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26638 if (cond.Is(al)) { 26639 const DRegister& first = nreglist.GetFirstDRegister(); 26640 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 26641 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 26642 (encoded_align_1.GetEncodingValue() << 4) | 26643 first.Encode(22, 12) | (len_encoding << 8) | 26644 (rn.GetCode() << 16) | rm.GetCode()); 26645 return; 26646 } 26647 } 26648 } 26649 } 26650 Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand); 26651 } 26652 26653 void Assembler::vst3(Condition cond, 26654 DataType dt, 26655 const NeonRegisterList& nreglist, 26656 const MemOperand& operand) { 26657 VIXL_ASSERT(AllowAssembler()); 26658 CheckIT(cond); 26659 if (operand.IsImmediateZero()) { 26660 Register rn = operand.GetBaseRegister(); 26661 Dt_size_7 encoded_dt(dt); 26662 Index_1 encoded_align_1(nreglist, dt); 26663 if (IsUsingT32()) { 26664 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 26665 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26666 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26667 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26668 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 26669 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26670 const DRegister& first = nreglist.GetFirstDRegister(); 26671 EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) | 26672 (encoded_align_1.GetEncodingValue() << 4) | 26673 first.Encode(22, 12) | (rn.GetCode() << 16)); 26674 AdvanceIT(); 26675 return; 26676 } 26677 } 26678 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 26679 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26680 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26681 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26682 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 26683 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26684 const DRegister& first = nreglist.GetFirstDRegister(); 26685 EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) | 26686 (encoded_align_1.GetEncodingValue() << 4) | 26687 first.Encode(22, 12) | (rn.GetCode() << 16)); 26688 AdvanceIT(); 26689 return; 26690 } 26691 } 26692 } else { 26693 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 26694 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26695 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26696 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26697 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 26698 if (cond.Is(al)) { 26699 const DRegister& first = nreglist.GetFirstDRegister(); 26700 EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) | 26701 (encoded_align_1.GetEncodingValue() << 4) | 26702 first.Encode(22, 12) | (rn.GetCode() << 16)); 26703 return; 26704 } 26705 } 26706 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 26707 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26708 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26709 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26710 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) { 26711 if (cond.Is(al)) { 26712 const DRegister& first = nreglist.GetFirstDRegister(); 26713 EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) | 26714 (encoded_align_1.GetEncodingValue() << 4) | 26715 first.Encode(22, 12) | (rn.GetCode() << 16)); 26716 return; 26717 } 26718 } 26719 } 26720 } 26721 if (operand.IsPlainRegister()) { 26722 Register rn = operand.GetBaseRegister(); 26723 Sign sign = operand.GetSign(); 26724 Register rm = operand.GetOffsetRegister(); 26725 Dt_size_7 encoded_dt(dt); 26726 Index_1 encoded_align_1(nreglist, dt); 26727 if (IsUsingT32()) { 26728 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 26729 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26730 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26731 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26732 sign.IsPlus() && operand.IsPostIndex() && 26733 (!rn.IsPC() || AllowUnpredictable())) { 26734 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26735 const DRegister& first = nreglist.GetFirstDRegister(); 26736 EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) | 26737 (encoded_align_1.GetEncodingValue() << 4) | 26738 first.Encode(22, 12) | (rn.GetCode() << 16) | 26739 rm.GetCode()); 26740 AdvanceIT(); 26741 return; 26742 } 26743 } 26744 } else { 26745 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 26746 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26747 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 26748 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 26749 sign.IsPlus() && operand.IsPostIndex() && 26750 (!rn.IsPC() || AllowUnpredictable())) { 26751 if (cond.Is(al)) { 26752 const DRegister& first = nreglist.GetFirstDRegister(); 26753 EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) | 26754 (encoded_align_1.GetEncodingValue() << 4) | 26755 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 26756 return; 26757 } 26758 } 26759 } 26760 } 26761 Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand); 26762 } 26763 26764 void Assembler::vst4(Condition cond, 26765 DataType dt, 26766 const NeonRegisterList& nreglist, 26767 const AlignedMemOperand& operand) { 26768 VIXL_ASSERT(AllowAssembler()); 26769 CheckIT(cond); 26770 if (operand.IsImmediateZero()) { 26771 Register rn = operand.GetBaseRegister(); 26772 Alignment align = operand.GetAlignment(); 26773 Dt_size_7 encoded_dt(dt); 26774 Align_align_4 encoded_align_1(align); 26775 Align_index_align_3 encoded_align_2(align, nreglist, dt); 26776 if (IsUsingT32()) { 26777 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26778 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26779 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26780 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26781 operand.IsOffset() && encoded_align_1.IsValid() && 26782 (!rn.IsPC() || AllowUnpredictable())) { 26783 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26784 const DRegister& first = nreglist.GetFirstDRegister(); 26785 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26786 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 26787 (encoded_align_1.GetEncodingValue() << 4) | 26788 first.Encode(22, 12) | (len_encoding << 8) | 26789 (rn.GetCode() << 16)); 26790 AdvanceIT(); 26791 return; 26792 } 26793 } 26794 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26795 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26796 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26797 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26798 operand.IsPostIndex() && encoded_align_1.IsValid() && 26799 (!rn.IsPC() || AllowUnpredictable())) { 26800 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26801 const DRegister& first = nreglist.GetFirstDRegister(); 26802 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26803 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 26804 (encoded_align_1.GetEncodingValue() << 4) | 26805 first.Encode(22, 12) | (len_encoding << 8) | 26806 (rn.GetCode() << 16)); 26807 AdvanceIT(); 26808 return; 26809 } 26810 } 26811 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 26812 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26813 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26814 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26815 operand.IsOffset() && encoded_align_2.IsValid() && 26816 (!rn.IsPC() || AllowUnpredictable())) { 26817 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26818 const DRegister& first = nreglist.GetFirstDRegister(); 26819 EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) | 26820 (encoded_align_2.GetEncodingValue() << 4) | 26821 first.Encode(22, 12) | (rn.GetCode() << 16)); 26822 AdvanceIT(); 26823 return; 26824 } 26825 } 26826 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 26827 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26828 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26829 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26830 operand.IsPostIndex() && encoded_align_2.IsValid() && 26831 (!rn.IsPC() || AllowUnpredictable())) { 26832 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26833 const DRegister& first = nreglist.GetFirstDRegister(); 26834 EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) | 26835 (encoded_align_2.GetEncodingValue() << 4) | 26836 first.Encode(22, 12) | (rn.GetCode() << 16)); 26837 AdvanceIT(); 26838 return; 26839 } 26840 } 26841 } else { 26842 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26843 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26844 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26845 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26846 operand.IsOffset() && encoded_align_1.IsValid() && 26847 (!rn.IsPC() || AllowUnpredictable())) { 26848 if (cond.Is(al)) { 26849 const DRegister& first = nreglist.GetFirstDRegister(); 26850 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26851 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 26852 (encoded_align_1.GetEncodingValue() << 4) | 26853 first.Encode(22, 12) | (len_encoding << 8) | 26854 (rn.GetCode() << 16)); 26855 return; 26856 } 26857 } 26858 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26859 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26860 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26861 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26862 operand.IsPostIndex() && encoded_align_1.IsValid() && 26863 (!rn.IsPC() || AllowUnpredictable())) { 26864 if (cond.Is(al)) { 26865 const DRegister& first = nreglist.GetFirstDRegister(); 26866 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26867 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 26868 (encoded_align_1.GetEncodingValue() << 4) | 26869 first.Encode(22, 12) | (len_encoding << 8) | 26870 (rn.GetCode() << 16)); 26871 return; 26872 } 26873 } 26874 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 26875 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26876 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26877 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26878 operand.IsOffset() && encoded_align_2.IsValid() && 26879 (!rn.IsPC() || AllowUnpredictable())) { 26880 if (cond.Is(al)) { 26881 const DRegister& first = nreglist.GetFirstDRegister(); 26882 EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) | 26883 (encoded_align_2.GetEncodingValue() << 4) | 26884 first.Encode(22, 12) | (rn.GetCode() << 16)); 26885 return; 26886 } 26887 } 26888 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 26889 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26890 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26891 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26892 operand.IsPostIndex() && encoded_align_2.IsValid() && 26893 (!rn.IsPC() || AllowUnpredictable())) { 26894 if (cond.Is(al)) { 26895 const DRegister& first = nreglist.GetFirstDRegister(); 26896 EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) | 26897 (encoded_align_2.GetEncodingValue() << 4) | 26898 first.Encode(22, 12) | (rn.GetCode() << 16)); 26899 return; 26900 } 26901 } 26902 } 26903 } 26904 if (operand.IsPlainRegister()) { 26905 Register rn = operand.GetBaseRegister(); 26906 Alignment align = operand.GetAlignment(); 26907 Register rm = operand.GetOffsetRegister(); 26908 Dt_size_7 encoded_dt(dt); 26909 Align_align_4 encoded_align_1(align); 26910 Align_index_align_3 encoded_align_2(align, nreglist, dt); 26911 if (IsUsingT32()) { 26912 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26913 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26914 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26915 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26916 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26917 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26918 const DRegister& first = nreglist.GetFirstDRegister(); 26919 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26920 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 26921 (encoded_align_1.GetEncodingValue() << 4) | 26922 first.Encode(22, 12) | (len_encoding << 8) | 26923 (rn.GetCode() << 16) | rm.GetCode()); 26924 AdvanceIT(); 26925 return; 26926 } 26927 } 26928 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 26929 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26930 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26931 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26932 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26933 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26934 const DRegister& first = nreglist.GetFirstDRegister(); 26935 EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) | 26936 (encoded_align_2.GetEncodingValue() << 4) | 26937 first.Encode(22, 12) | (rn.GetCode() << 16) | 26938 rm.GetCode()); 26939 AdvanceIT(); 26940 return; 26941 } 26942 } 26943 } else { 26944 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26945 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 26946 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26947 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26948 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26949 if (cond.Is(al)) { 26950 const DRegister& first = nreglist.GetFirstDRegister(); 26951 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 26952 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 26953 (encoded_align_1.GetEncodingValue() << 4) | 26954 first.Encode(22, 12) | (len_encoding << 8) | 26955 (rn.GetCode() << 16) | rm.GetCode()); 26956 return; 26957 } 26958 } 26959 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 26960 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 26961 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 26962 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 26963 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) { 26964 if (cond.Is(al)) { 26965 const DRegister& first = nreglist.GetFirstDRegister(); 26966 EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) | 26967 (encoded_align_2.GetEncodingValue() << 4) | 26968 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 26969 return; 26970 } 26971 } 26972 } 26973 } 26974 Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand); 26975 } 26976 26977 void Assembler::vstm(Condition cond, 26978 DataType dt, 26979 Register rn, 26980 WriteBack write_back, 26981 DRegisterList dreglist) { 26982 VIXL_ASSERT(AllowAssembler()); 26983 CheckIT(cond); 26984 USE(dt); 26985 if (IsUsingT32()) { 26986 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 26987 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) || 26988 AllowUnpredictable())) { 26989 const DRegister& dreg = dreglist.GetFirstDRegister(); 26990 unsigned len = dreglist.GetLength() * 2; 26991 EmitT32_32(0xec800b00U | (rn.GetCode() << 16) | 26992 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 26993 (len & 0xff)); 26994 AdvanceIT(); 26995 return; 26996 } 26997 } else { 26998 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 26999 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 27000 (!rn.IsPC() || !write_back.DoesWriteBack())) || 27001 AllowUnpredictable())) { 27002 const DRegister& dreg = dreglist.GetFirstDRegister(); 27003 unsigned len = dreglist.GetLength() * 2; 27004 EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27005 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 27006 (len & 0xff)); 27007 return; 27008 } 27009 } 27010 Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist); 27011 } 27012 27013 void Assembler::vstm(Condition cond, 27014 DataType dt, 27015 Register rn, 27016 WriteBack write_back, 27017 SRegisterList sreglist) { 27018 VIXL_ASSERT(AllowAssembler()); 27019 CheckIT(cond); 27020 USE(dt); 27021 if (IsUsingT32()) { 27022 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 27023 if ((!rn.IsPC() || AllowUnpredictable())) { 27024 const SRegister& sreg = sreglist.GetFirstSRegister(); 27025 unsigned len = sreglist.GetLength(); 27026 EmitT32_32(0xec800a00U | (rn.GetCode() << 16) | 27027 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 27028 (len & 0xff)); 27029 AdvanceIT(); 27030 return; 27031 } 27032 } else { 27033 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 27034 if (cond.IsNotNever() && 27035 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) { 27036 const SRegister& sreg = sreglist.GetFirstSRegister(); 27037 unsigned len = sreglist.GetLength(); 27038 EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27039 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 27040 (len & 0xff)); 27041 return; 27042 } 27043 } 27044 Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist); 27045 } 27046 27047 void Assembler::vstmdb(Condition cond, 27048 DataType dt, 27049 Register rn, 27050 WriteBack write_back, 27051 DRegisterList dreglist) { 27052 VIXL_ASSERT(AllowAssembler()); 27053 CheckIT(cond); 27054 USE(dt); 27055 if (IsUsingT32()) { 27056 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1 27057 if (write_back.DoesWriteBack() && 27058 (((dreglist.GetLength() <= 16) && !rn.IsPC()) || 27059 AllowUnpredictable())) { 27060 const DRegister& dreg = dreglist.GetFirstDRegister(); 27061 unsigned len = dreglist.GetLength() * 2; 27062 EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 27063 (len & 0xff)); 27064 AdvanceIT(); 27065 return; 27066 } 27067 } else { 27068 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1 27069 if (write_back.DoesWriteBack() && cond.IsNotNever() && 27070 (((dreglist.GetLength() <= 16) && !rn.IsPC()) || 27071 AllowUnpredictable())) { 27072 const DRegister& dreg = dreglist.GetFirstDRegister(); 27073 unsigned len = dreglist.GetLength() * 2; 27074 EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27075 dreg.Encode(22, 12) | (len & 0xff)); 27076 return; 27077 } 27078 } 27079 Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist); 27080 } 27081 27082 void Assembler::vstmdb(Condition cond, 27083 DataType dt, 27084 Register rn, 27085 WriteBack write_back, 27086 SRegisterList sreglist) { 27087 VIXL_ASSERT(AllowAssembler()); 27088 CheckIT(cond); 27089 USE(dt); 27090 if (IsUsingT32()) { 27091 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2 27092 if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) { 27093 const SRegister& sreg = sreglist.GetFirstSRegister(); 27094 unsigned len = sreglist.GetLength(); 27095 EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) | 27096 (len & 0xff)); 27097 AdvanceIT(); 27098 return; 27099 } 27100 } else { 27101 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2 27102 if (write_back.DoesWriteBack() && cond.IsNotNever() && 27103 (!rn.IsPC() || AllowUnpredictable())) { 27104 const SRegister& sreg = sreglist.GetFirstSRegister(); 27105 unsigned len = sreglist.GetLength(); 27106 EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27107 sreg.Encode(22, 12) | (len & 0xff)); 27108 return; 27109 } 27110 } 27111 Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist); 27112 } 27113 27114 void Assembler::vstmia(Condition cond, 27115 DataType dt, 27116 Register rn, 27117 WriteBack write_back, 27118 DRegisterList dreglist) { 27119 VIXL_ASSERT(AllowAssembler()); 27120 CheckIT(cond); 27121 USE(dt); 27122 if (IsUsingT32()) { 27123 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 27124 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) || 27125 AllowUnpredictable())) { 27126 const DRegister& dreg = dreglist.GetFirstDRegister(); 27127 unsigned len = dreglist.GetLength() * 2; 27128 EmitT32_32(0xec800b00U | (rn.GetCode() << 16) | 27129 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 27130 (len & 0xff)); 27131 AdvanceIT(); 27132 return; 27133 } 27134 } else { 27135 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 27136 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 27137 (!rn.IsPC() || !write_back.DoesWriteBack())) || 27138 AllowUnpredictable())) { 27139 const DRegister& dreg = dreglist.GetFirstDRegister(); 27140 unsigned len = dreglist.GetLength() * 2; 27141 EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27142 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 27143 (len & 0xff)); 27144 return; 27145 } 27146 } 27147 Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist); 27148 } 27149 27150 void Assembler::vstmia(Condition cond, 27151 DataType dt, 27152 Register rn, 27153 WriteBack write_back, 27154 SRegisterList sreglist) { 27155 VIXL_ASSERT(AllowAssembler()); 27156 CheckIT(cond); 27157 USE(dt); 27158 if (IsUsingT32()) { 27159 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 27160 if ((!rn.IsPC() || AllowUnpredictable())) { 27161 const SRegister& sreg = sreglist.GetFirstSRegister(); 27162 unsigned len = sreglist.GetLength(); 27163 EmitT32_32(0xec800a00U | (rn.GetCode() << 16) | 27164 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 27165 (len & 0xff)); 27166 AdvanceIT(); 27167 return; 27168 } 27169 } else { 27170 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 27171 if (cond.IsNotNever() && 27172 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) { 27173 const SRegister& sreg = sreglist.GetFirstSRegister(); 27174 unsigned len = sreglist.GetLength(); 27175 EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 27176 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 27177 (len & 0xff)); 27178 return; 27179 } 27180 } 27181 Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist); 27182 } 27183 27184 void Assembler::vstr(Condition cond, 27185 DataType dt, 27186 DRegister rd, 27187 const MemOperand& operand) { 27188 VIXL_ASSERT(AllowAssembler()); 27189 CheckIT(cond); 27190 if (operand.IsImmediate()) { 27191 Register rn = operand.GetBaseRegister(); 27192 int32_t offset = operand.GetOffsetImmediate(); 27193 if (IsUsingT32()) { 27194 // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1 27195 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 27196 ((offset % 4) == 0) && operand.IsOffset() && 27197 (!rn.IsPC() || AllowUnpredictable())) { 27198 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 27199 uint32_t offset_ = abs(offset) >> 2; 27200 EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 27201 offset_ | (sign << 23)); 27202 AdvanceIT(); 27203 return; 27204 } 27205 } else { 27206 // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1 27207 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 27208 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) { 27209 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 27210 uint32_t offset_ = abs(offset) >> 2; 27211 EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 27212 (rn.GetCode() << 16) | offset_ | (sign << 23)); 27213 return; 27214 } 27215 } 27216 } 27217 Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand); 27218 } 27219 27220 void Assembler::vstr(Condition cond, 27221 DataType dt, 27222 SRegister rd, 27223 const MemOperand& operand) { 27224 VIXL_ASSERT(AllowAssembler()); 27225 CheckIT(cond); 27226 if (operand.IsImmediate()) { 27227 Register rn = operand.GetBaseRegister(); 27228 int32_t offset = operand.GetOffsetImmediate(); 27229 if (IsUsingT32()) { 27230 // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2 27231 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 27232 ((offset % 4) == 0) && operand.IsOffset() && 27233 (!rn.IsPC() || AllowUnpredictable())) { 27234 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 27235 uint32_t offset_ = abs(offset) >> 2; 27236 EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 27237 offset_ | (sign << 23)); 27238 AdvanceIT(); 27239 return; 27240 } 27241 } else { 27242 // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2 27243 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 27244 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) { 27245 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 27246 uint32_t offset_ = abs(offset) >> 2; 27247 EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 27248 (rn.GetCode() << 16) | offset_ | (sign << 23)); 27249 return; 27250 } 27251 } 27252 } 27253 Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand); 27254 } 27255 27256 void Assembler::vsub( 27257 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 27258 VIXL_ASSERT(AllowAssembler()); 27259 CheckIT(cond); 27260 Dt_size_2 encoded_dt(dt); 27261 if (IsUsingT32()) { 27262 // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 27263 if (dt.Is(F32)) { 27264 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27265 EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27266 rm.Encode(5, 0)); 27267 AdvanceIT(); 27268 return; 27269 } 27270 } 27271 // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 27272 if (dt.Is(F64)) { 27273 EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27274 rm.Encode(5, 0)); 27275 AdvanceIT(); 27276 return; 27277 } 27278 // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 27279 if (encoded_dt.IsValid()) { 27280 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27281 EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) | 27282 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27283 AdvanceIT(); 27284 return; 27285 } 27286 } 27287 } else { 27288 // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 27289 if (dt.Is(F32)) { 27290 if (cond.Is(al)) { 27291 EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27292 rm.Encode(5, 0)); 27293 return; 27294 } 27295 } 27296 // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 27297 if (dt.Is(F64) && cond.IsNotNever()) { 27298 EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 27299 rn.Encode(7, 16) | rm.Encode(5, 0)); 27300 return; 27301 } 27302 // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 27303 if (encoded_dt.IsValid()) { 27304 if (cond.Is(al)) { 27305 EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) | 27306 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27307 return; 27308 } 27309 } 27310 } 27311 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 27312 } 27313 27314 void Assembler::vsub( 27315 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 27316 VIXL_ASSERT(AllowAssembler()); 27317 CheckIT(cond); 27318 Dt_size_2 encoded_dt(dt); 27319 if (IsUsingT32()) { 27320 // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 27321 if (dt.Is(F32)) { 27322 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27323 EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27324 rm.Encode(5, 0)); 27325 AdvanceIT(); 27326 return; 27327 } 27328 } 27329 // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 27330 if (encoded_dt.IsValid()) { 27331 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27332 EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) | 27333 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27334 AdvanceIT(); 27335 return; 27336 } 27337 } 27338 } else { 27339 // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 27340 if (dt.Is(F32)) { 27341 if (cond.Is(al)) { 27342 EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27343 rm.Encode(5, 0)); 27344 return; 27345 } 27346 } 27347 // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 27348 if (encoded_dt.IsValid()) { 27349 if (cond.Is(al)) { 27350 EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) | 27351 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27352 return; 27353 } 27354 } 27355 } 27356 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 27357 } 27358 27359 void Assembler::vsub( 27360 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 27361 VIXL_ASSERT(AllowAssembler()); 27362 CheckIT(cond); 27363 if (IsUsingT32()) { 27364 // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 27365 if (dt.Is(F32)) { 27366 EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 27367 rm.Encode(5, 0)); 27368 AdvanceIT(); 27369 return; 27370 } 27371 } else { 27372 // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 27373 if (dt.Is(F32) && cond.IsNotNever()) { 27374 EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 27375 rn.Encode(7, 16) | rm.Encode(5, 0)); 27376 return; 27377 } 27378 } 27379 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 27380 } 27381 27382 void Assembler::vsubhn( 27383 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 27384 VIXL_ASSERT(AllowAssembler()); 27385 CheckIT(cond); 27386 Dt_size_3 encoded_dt(dt); 27387 if (IsUsingT32()) { 27388 // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 27389 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 27390 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27391 EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) | 27392 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27393 AdvanceIT(); 27394 return; 27395 } 27396 } 27397 } else { 27398 // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 27399 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 27400 if (cond.Is(al)) { 27401 EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) | 27402 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27403 return; 27404 } 27405 } 27406 } 27407 Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm); 27408 } 27409 27410 void Assembler::vsubl( 27411 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 27412 VIXL_ASSERT(AllowAssembler()); 27413 CheckIT(cond); 27414 Dt_U_size_1 encoded_dt(dt); 27415 if (IsUsingT32()) { 27416 // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 27417 if (encoded_dt.IsValid()) { 27418 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27419 EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 27420 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 27421 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27422 AdvanceIT(); 27423 return; 27424 } 27425 } 27426 } else { 27427 // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 27428 if (encoded_dt.IsValid()) { 27429 if (cond.Is(al)) { 27430 EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 27431 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 27432 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27433 return; 27434 } 27435 } 27436 } 27437 Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm); 27438 } 27439 27440 void Assembler::vsubw( 27441 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) { 27442 VIXL_ASSERT(AllowAssembler()); 27443 CheckIT(cond); 27444 Dt_U_size_1 encoded_dt(dt); 27445 if (IsUsingT32()) { 27446 // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1 27447 if (encoded_dt.IsValid()) { 27448 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27449 EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 27450 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 27451 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27452 AdvanceIT(); 27453 return; 27454 } 27455 } 27456 } else { 27457 // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1 27458 if (encoded_dt.IsValid()) { 27459 if (cond.Is(al)) { 27460 EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 27461 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 27462 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27463 return; 27464 } 27465 } 27466 } 27467 Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm); 27468 } 27469 27470 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) { 27471 VIXL_ASSERT(AllowAssembler()); 27472 CheckIT(cond); 27473 USE(dt); 27474 if (IsUsingT32()) { 27475 // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 27476 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27477 EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27478 AdvanceIT(); 27479 return; 27480 } 27481 } else { 27482 // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 27483 if (cond.Is(al)) { 27484 EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27485 return; 27486 } 27487 } 27488 Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm); 27489 } 27490 27491 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) { 27492 VIXL_ASSERT(AllowAssembler()); 27493 CheckIT(cond); 27494 USE(dt); 27495 if (IsUsingT32()) { 27496 // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 27497 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27498 EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27499 AdvanceIT(); 27500 return; 27501 } 27502 } else { 27503 // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 27504 if (cond.Is(al)) { 27505 EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27506 return; 27507 } 27508 } 27509 Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm); 27510 } 27511 27512 void Assembler::vtbl(Condition cond, 27513 DataType dt, 27514 DRegister rd, 27515 const NeonRegisterList& nreglist, 27516 DRegister rm) { 27517 VIXL_ASSERT(AllowAssembler()); 27518 CheckIT(cond); 27519 if (IsUsingT32()) { 27520 // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1 27521 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 27522 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 27523 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27524 const DRegister& first = nreglist.GetFirstDRegister(); 27525 uint32_t len_encoding = nreglist.GetLength() - 1; 27526 EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) | 27527 (len_encoding << 8) | rm.Encode(5, 0)); 27528 AdvanceIT(); 27529 return; 27530 } 27531 } 27532 } else { 27533 // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1 27534 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 27535 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 27536 if (cond.Is(al)) { 27537 const DRegister& first = nreglist.GetFirstDRegister(); 27538 uint32_t len_encoding = nreglist.GetLength() - 1; 27539 EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) | 27540 (len_encoding << 8) | rm.Encode(5, 0)); 27541 return; 27542 } 27543 } 27544 } 27545 Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm); 27546 } 27547 27548 void Assembler::vtbx(Condition cond, 27549 DataType dt, 27550 DRegister rd, 27551 const NeonRegisterList& nreglist, 27552 DRegister rm) { 27553 VIXL_ASSERT(AllowAssembler()); 27554 CheckIT(cond); 27555 if (IsUsingT32()) { 27556 // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1 27557 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 27558 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 27559 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27560 const DRegister& first = nreglist.GetFirstDRegister(); 27561 uint32_t len_encoding = nreglist.GetLength() - 1; 27562 EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) | 27563 (len_encoding << 8) | rm.Encode(5, 0)); 27564 AdvanceIT(); 27565 return; 27566 } 27567 } 27568 } else { 27569 // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1 27570 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 27571 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 27572 if (cond.Is(al)) { 27573 const DRegister& first = nreglist.GetFirstDRegister(); 27574 uint32_t len_encoding = nreglist.GetLength() - 1; 27575 EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) | 27576 (len_encoding << 8) | rm.Encode(5, 0)); 27577 return; 27578 } 27579 } 27580 } 27581 Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm); 27582 } 27583 27584 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) { 27585 VIXL_ASSERT(AllowAssembler()); 27586 CheckIT(cond); 27587 Dt_size_7 encoded_dt(dt); 27588 if (IsUsingT32()) { 27589 // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 27590 if (encoded_dt.IsValid()) { 27591 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27592 EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) | 27593 rd.Encode(22, 12) | rm.Encode(5, 0)); 27594 AdvanceIT(); 27595 return; 27596 } 27597 } 27598 } else { 27599 // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 27600 if (encoded_dt.IsValid()) { 27601 if (cond.Is(al)) { 27602 EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) | 27603 rd.Encode(22, 12) | rm.Encode(5, 0)); 27604 return; 27605 } 27606 } 27607 } 27608 Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm); 27609 } 27610 27611 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) { 27612 VIXL_ASSERT(AllowAssembler()); 27613 CheckIT(cond); 27614 Dt_size_7 encoded_dt(dt); 27615 if (IsUsingT32()) { 27616 // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 27617 if (encoded_dt.IsValid()) { 27618 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27619 EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) | 27620 rd.Encode(22, 12) | rm.Encode(5, 0)); 27621 AdvanceIT(); 27622 return; 27623 } 27624 } 27625 } else { 27626 // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 27627 if (encoded_dt.IsValid()) { 27628 if (cond.Is(al)) { 27629 EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) | 27630 rd.Encode(22, 12) | rm.Encode(5, 0)); 27631 return; 27632 } 27633 } 27634 } 27635 Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm); 27636 } 27637 27638 void Assembler::vtst( 27639 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 27640 VIXL_ASSERT(AllowAssembler()); 27641 CheckIT(cond); 27642 Dt_size_7 encoded_dt(dt); 27643 if (IsUsingT32()) { 27644 // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 27645 if (encoded_dt.IsValid()) { 27646 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27647 EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) | 27648 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27649 AdvanceIT(); 27650 return; 27651 } 27652 } 27653 } else { 27654 // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 27655 if (encoded_dt.IsValid()) { 27656 if (cond.Is(al)) { 27657 EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) | 27658 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27659 return; 27660 } 27661 } 27662 } 27663 Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm); 27664 } 27665 27666 void Assembler::vtst( 27667 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 27668 VIXL_ASSERT(AllowAssembler()); 27669 CheckIT(cond); 27670 Dt_size_7 encoded_dt(dt); 27671 if (IsUsingT32()) { 27672 // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 27673 if (encoded_dt.IsValid()) { 27674 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27675 EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) | 27676 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27677 AdvanceIT(); 27678 return; 27679 } 27680 } 27681 } else { 27682 // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 27683 if (encoded_dt.IsValid()) { 27684 if (cond.Is(al)) { 27685 EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) | 27686 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 27687 return; 27688 } 27689 } 27690 } 27691 Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm); 27692 } 27693 27694 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) { 27695 VIXL_ASSERT(AllowAssembler()); 27696 CheckIT(cond); 27697 Dt_size_15 encoded_dt(dt); 27698 if (IsUsingT32()) { 27699 // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 27700 if (encoded_dt.IsValid()) { 27701 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27702 EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) | 27703 rd.Encode(22, 12) | rm.Encode(5, 0)); 27704 AdvanceIT(); 27705 return; 27706 } 27707 } 27708 // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1 27709 if (dt.Is(Untyped32)) { 27710 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27711 EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27712 AdvanceIT(); 27713 return; 27714 } 27715 } 27716 } else { 27717 // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 27718 if (encoded_dt.IsValid()) { 27719 if (cond.Is(al)) { 27720 EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) | 27721 rd.Encode(22, 12) | rm.Encode(5, 0)); 27722 return; 27723 } 27724 } 27725 // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1 27726 if (dt.Is(Untyped32)) { 27727 if (cond.Is(al)) { 27728 EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27729 return; 27730 } 27731 } 27732 } 27733 Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm); 27734 } 27735 27736 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) { 27737 VIXL_ASSERT(AllowAssembler()); 27738 CheckIT(cond); 27739 Dt_size_7 encoded_dt(dt); 27740 if (IsUsingT32()) { 27741 // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 27742 if (encoded_dt.IsValid()) { 27743 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27744 EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) | 27745 rd.Encode(22, 12) | rm.Encode(5, 0)); 27746 AdvanceIT(); 27747 return; 27748 } 27749 } 27750 } else { 27751 // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 27752 if (encoded_dt.IsValid()) { 27753 if (cond.Is(al)) { 27754 EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) | 27755 rd.Encode(22, 12) | rm.Encode(5, 0)); 27756 return; 27757 } 27758 } 27759 } 27760 Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm); 27761 } 27762 27763 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) { 27764 VIXL_ASSERT(AllowAssembler()); 27765 CheckIT(cond); 27766 Dt_size_15 encoded_dt(dt); 27767 if (IsUsingT32()) { 27768 // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 27769 if (encoded_dt.IsValid()) { 27770 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27771 EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) | 27772 rd.Encode(22, 12) | rm.Encode(5, 0)); 27773 AdvanceIT(); 27774 return; 27775 } 27776 } 27777 // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1 27778 if (dt.Is(Untyped32)) { 27779 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27780 EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27781 AdvanceIT(); 27782 return; 27783 } 27784 } 27785 } else { 27786 // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 27787 if (encoded_dt.IsValid()) { 27788 if (cond.Is(al)) { 27789 EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) | 27790 rd.Encode(22, 12) | rm.Encode(5, 0)); 27791 return; 27792 } 27793 } 27794 // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1 27795 if (dt.Is(Untyped32)) { 27796 if (cond.Is(al)) { 27797 EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 27798 return; 27799 } 27800 } 27801 } 27802 Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm); 27803 } 27804 27805 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) { 27806 VIXL_ASSERT(AllowAssembler()); 27807 CheckIT(cond); 27808 Dt_size_7 encoded_dt(dt); 27809 if (IsUsingT32()) { 27810 // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 27811 if (encoded_dt.IsValid()) { 27812 if (cond.Is(al) || AllowStronglyDiscouraged()) { 27813 EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) | 27814 rd.Encode(22, 12) | rm.Encode(5, 0)); 27815 AdvanceIT(); 27816 return; 27817 } 27818 } 27819 } else { 27820 // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 27821 if (encoded_dt.IsValid()) { 27822 if (cond.Is(al)) { 27823 EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) | 27824 rd.Encode(22, 12) | rm.Encode(5, 0)); 27825 return; 27826 } 27827 } 27828 } 27829 Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm); 27830 } 27831 27832 void Assembler::yield(Condition cond, EncodingSize size) { 27833 VIXL_ASSERT(AllowAssembler()); 27834 CheckIT(cond); 27835 if (IsUsingT32()) { 27836 // YIELD{<c>}{<q>} ; T1 27837 if (!size.IsWide()) { 27838 EmitT32_16(0xbf10); 27839 AdvanceIT(); 27840 return; 27841 } 27842 // YIELD{<c>}.W ; T2 27843 if (!size.IsNarrow()) { 27844 EmitT32_32(0xf3af8001U); 27845 AdvanceIT(); 27846 return; 27847 } 27848 } else { 27849 // YIELD{<c>}{<q>} ; A1 27850 if (cond.IsNotNever()) { 27851 EmitA32(0x0320f001U | (cond.GetCondition() << 28)); 27852 return; 27853 } 27854 } 27855 Delegate(kYield, &Assembler::yield, cond, size); 27856 } 27857 // End of generated code. 27858 27859 } // namespace aarch32 27860 } // namespace vixl 27861