1 // Copyright 2015, 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/constants-aarch32.h" 39 #include "aarch32/instructions-aarch32.h" 40 #include "aarch32/operands-aarch32.h" 41 #include "aarch32/assembler-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 first_condition_ = 72 Condition((first_condition_.GetCondition() & 0xe) | (it_mask_ >> 3)); 73 // For A32, AdavanceIT() is not called by the assembler. We must call it 74 // in order to check that IT instructions are used consistently with 75 // the following conditional instructions. 76 if (IsUsingA32()) AdvanceIT(); 77 } 78 } 79 #endif 80 81 82 void Assembler::BindHelper(Label* label) { 83 VIXL_ASSERT(!label->IsBound()); 84 label->Bind(GetCursorOffset(), GetInstructionSetInUse()); 85 86 for (Label::ForwardRefList::iterator ref = label->GetFirstForwardRef(); 87 ref != label->GetEndForwardRef(); 88 ref++) { 89 EncodeLabelFor(*ref, label); 90 } 91 if (label->IsInVeneerPool()) { 92 label->GetVeneerPoolManager()->RemoveLabel(label); 93 } 94 } 95 96 97 uint32_t Assembler::Link(uint32_t instr, 98 Label* label, 99 const Label::LabelEmitOperator& op) { 100 label->SetReferenced(); 101 if (label->IsBound()) { 102 return op.Encode(instr, 103 GetCursorOffset() + GetArchitectureStatePCOffset(), 104 label); 105 } 106 label->AddForwardRef(GetCursorOffset(), GetInstructionSetInUse(), op); 107 return instr; 108 } 109 110 111 void Assembler::EncodeLabelFor(const Label::ForwardReference& forward, 112 Label* label) { 113 const uint32_t location = forward.GetLocation(); 114 const uint32_t from = location + forward.GetStatePCOffset(); 115 const Label::LabelEmitOperator& encoder = forward.GetEmitOperator(); 116 if (forward.IsUsingT32()) { 117 uint16_t* instr_ptr = buffer_.GetOffsetAddress<uint16_t*>(location); 118 if (Is16BitEncoding(instr_ptr[0])) { 119 // The Encode methods always deals with uint32_t types so we need 120 // to explicitely cast it. 121 uint32_t instr = static_cast<uint32_t>(instr_ptr[0]); 122 instr = encoder.Encode(instr, from, label); 123 // The Encode method should not ever set the top 16 bits. 124 VIXL_ASSERT((instr & ~0xffff) == 0); 125 instr_ptr[0] = static_cast<uint16_t>(instr); 126 } else { 127 uint32_t instr = 128 instr_ptr[1] | (static_cast<uint32_t>(instr_ptr[0]) << 16); 129 instr = encoder.Encode(instr, from, label); 130 instr_ptr[0] = static_cast<uint16_t>(instr >> 16); 131 instr_ptr[1] = static_cast<uint16_t>(instr); 132 } 133 } else { 134 uint32_t* instr_ptr = buffer_.GetOffsetAddress<uint32_t*>(location); 135 instr_ptr[0] = encoder.Encode(instr_ptr[0], from, label); 136 } 137 } 138 139 140 // Start of generated code. 141 class Dt_L_imm6_1 : public EncodingValue { 142 uint32_t type_; 143 144 public: 145 explicit Dt_L_imm6_1(DataType dt); 146 uint32_t GetTypeEncodingValue() const { return type_; } 147 }; 148 149 Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) { 150 switch (dt.GetValue()) { 151 case S8: 152 type_ = 0x0; 153 SetEncodingValue(0x1); 154 break; 155 case U8: 156 type_ = 0x1; 157 SetEncodingValue(0x1); 158 break; 159 case S16: 160 type_ = 0x0; 161 SetEncodingValue(0x2); 162 break; 163 case U16: 164 type_ = 0x1; 165 SetEncodingValue(0x2); 166 break; 167 case S32: 168 type_ = 0x0; 169 SetEncodingValue(0x4); 170 break; 171 case U32: 172 type_ = 0x1; 173 SetEncodingValue(0x4); 174 break; 175 case S64: 176 type_ = 0x0; 177 SetEncodingValue(0x8); 178 break; 179 case U64: 180 type_ = 0x1; 181 SetEncodingValue(0x8); 182 break; 183 default: 184 VIXL_UNREACHABLE(); 185 type_ = 0x0; 186 break; 187 } 188 } 189 190 class Dt_L_imm6_2 : public EncodingValue { 191 uint32_t type_; 192 193 public: 194 explicit Dt_L_imm6_2(DataType dt); 195 uint32_t GetTypeEncodingValue() const { return type_; } 196 }; 197 198 Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) { 199 switch (dt.GetValue()) { 200 case S8: 201 type_ = 0x1; 202 SetEncodingValue(0x1); 203 break; 204 case S16: 205 type_ = 0x1; 206 SetEncodingValue(0x2); 207 break; 208 case S32: 209 type_ = 0x1; 210 SetEncodingValue(0x4); 211 break; 212 case S64: 213 type_ = 0x1; 214 SetEncodingValue(0x8); 215 break; 216 default: 217 VIXL_UNREACHABLE(); 218 type_ = 0x0; 219 break; 220 } 221 } 222 223 class Dt_L_imm6_3 : public EncodingValue { 224 public: 225 explicit Dt_L_imm6_3(DataType dt); 226 }; 227 228 Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) { 229 switch (dt.GetValue()) { 230 case I8: 231 SetEncodingValue(0x1); 232 break; 233 case I16: 234 SetEncodingValue(0x2); 235 break; 236 case I32: 237 SetEncodingValue(0x4); 238 break; 239 case I64: 240 SetEncodingValue(0x8); 241 break; 242 default: 243 break; 244 } 245 } 246 247 class Dt_L_imm6_4 : public EncodingValue { 248 public: 249 explicit Dt_L_imm6_4(DataType dt); 250 }; 251 252 Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) { 253 switch (dt.GetValue()) { 254 case Untyped8: 255 SetEncodingValue(0x1); 256 break; 257 case Untyped16: 258 SetEncodingValue(0x2); 259 break; 260 case Untyped32: 261 SetEncodingValue(0x4); 262 break; 263 case Untyped64: 264 SetEncodingValue(0x8); 265 break; 266 default: 267 break; 268 } 269 } 270 271 class Dt_imm6_1 : public EncodingValue { 272 uint32_t type_; 273 274 public: 275 explicit Dt_imm6_1(DataType dt); 276 uint32_t GetTypeEncodingValue() const { return type_; } 277 }; 278 279 Dt_imm6_1::Dt_imm6_1(DataType dt) { 280 switch (dt.GetValue()) { 281 case S16: 282 type_ = 0x0; 283 SetEncodingValue(0x1); 284 break; 285 case U16: 286 type_ = 0x1; 287 SetEncodingValue(0x1); 288 break; 289 case S32: 290 type_ = 0x0; 291 SetEncodingValue(0x2); 292 break; 293 case U32: 294 type_ = 0x1; 295 SetEncodingValue(0x2); 296 break; 297 case S64: 298 type_ = 0x0; 299 SetEncodingValue(0x4); 300 break; 301 case U64: 302 type_ = 0x1; 303 SetEncodingValue(0x4); 304 break; 305 default: 306 VIXL_UNREACHABLE(); 307 type_ = 0x0; 308 break; 309 } 310 } 311 312 class Dt_imm6_2 : public EncodingValue { 313 uint32_t type_; 314 315 public: 316 explicit Dt_imm6_2(DataType dt); 317 uint32_t GetTypeEncodingValue() const { return type_; } 318 }; 319 320 Dt_imm6_2::Dt_imm6_2(DataType dt) { 321 switch (dt.GetValue()) { 322 case S16: 323 type_ = 0x1; 324 SetEncodingValue(0x1); 325 break; 326 case S32: 327 type_ = 0x1; 328 SetEncodingValue(0x2); 329 break; 330 case S64: 331 type_ = 0x1; 332 SetEncodingValue(0x4); 333 break; 334 default: 335 VIXL_UNREACHABLE(); 336 type_ = 0x0; 337 break; 338 } 339 } 340 341 class Dt_imm6_3 : public EncodingValue { 342 public: 343 explicit Dt_imm6_3(DataType dt); 344 }; 345 346 Dt_imm6_3::Dt_imm6_3(DataType dt) { 347 switch (dt.GetValue()) { 348 case I16: 349 SetEncodingValue(0x1); 350 break; 351 case I32: 352 SetEncodingValue(0x2); 353 break; 354 case I64: 355 SetEncodingValue(0x4); 356 break; 357 default: 358 break; 359 } 360 } 361 362 class Dt_imm6_4 : public EncodingValue { 363 uint32_t type_; 364 365 public: 366 explicit Dt_imm6_4(DataType dt); 367 uint32_t GetTypeEncodingValue() const { return type_; } 368 }; 369 370 Dt_imm6_4::Dt_imm6_4(DataType dt) { 371 switch (dt.GetValue()) { 372 case S8: 373 type_ = 0x0; 374 SetEncodingValue(0x1); 375 break; 376 case U8: 377 type_ = 0x1; 378 SetEncodingValue(0x1); 379 break; 380 case S16: 381 type_ = 0x0; 382 SetEncodingValue(0x2); 383 break; 384 case U16: 385 type_ = 0x1; 386 SetEncodingValue(0x2); 387 break; 388 case S32: 389 type_ = 0x0; 390 SetEncodingValue(0x4); 391 break; 392 case U32: 393 type_ = 0x1; 394 SetEncodingValue(0x4); 395 break; 396 default: 397 VIXL_UNREACHABLE(); 398 type_ = 0x0; 399 break; 400 } 401 } 402 403 class Dt_op_U_size_1 : public EncodingValue { 404 public: 405 explicit Dt_op_U_size_1(DataType dt); 406 }; 407 408 Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) { 409 switch (dt.GetValue()) { 410 case S8: 411 SetEncodingValue(0x0); 412 break; 413 case S16: 414 SetEncodingValue(0x1); 415 break; 416 case S32: 417 SetEncodingValue(0x2); 418 break; 419 case U8: 420 SetEncodingValue(0x4); 421 break; 422 case U16: 423 SetEncodingValue(0x5); 424 break; 425 case U32: 426 SetEncodingValue(0x6); 427 break; 428 case P8: 429 SetEncodingValue(0x8); 430 break; 431 case P64: 432 SetEncodingValue(0xa); 433 break; 434 default: 435 break; 436 } 437 } 438 439 class Dt_op_size_1 : public EncodingValue { 440 public: 441 explicit Dt_op_size_1(DataType dt); 442 }; 443 444 Dt_op_size_1::Dt_op_size_1(DataType dt) { 445 switch (dt.GetValue()) { 446 case I8: 447 SetEncodingValue(0x0); 448 break; 449 case I16: 450 SetEncodingValue(0x1); 451 break; 452 case I32: 453 SetEncodingValue(0x2); 454 break; 455 case P8: 456 SetEncodingValue(0x4); 457 break; 458 default: 459 break; 460 } 461 } 462 463 class Dt_op_size_2 : public EncodingValue { 464 public: 465 explicit Dt_op_size_2(DataType dt); 466 }; 467 468 Dt_op_size_2::Dt_op_size_2(DataType dt) { 469 switch (dt.GetValue()) { 470 case S8: 471 SetEncodingValue(0x0); 472 break; 473 case S16: 474 SetEncodingValue(0x1); 475 break; 476 case S32: 477 SetEncodingValue(0x2); 478 break; 479 case U8: 480 SetEncodingValue(0x4); 481 break; 482 case U16: 483 SetEncodingValue(0x5); 484 break; 485 case U32: 486 SetEncodingValue(0x6); 487 break; 488 default: 489 break; 490 } 491 } 492 493 class Dt_op_size_3 : public EncodingValue { 494 public: 495 explicit Dt_op_size_3(DataType dt); 496 }; 497 498 Dt_op_size_3::Dt_op_size_3(DataType dt) { 499 switch (dt.GetValue()) { 500 case S16: 501 SetEncodingValue(0x0); 502 break; 503 case S32: 504 SetEncodingValue(0x1); 505 break; 506 case S64: 507 SetEncodingValue(0x2); 508 break; 509 case U16: 510 SetEncodingValue(0x4); 511 break; 512 case U32: 513 SetEncodingValue(0x5); 514 break; 515 case U64: 516 SetEncodingValue(0x6); 517 break; 518 default: 519 break; 520 } 521 } 522 523 class Dt_U_imm3H_1 : public EncodingValue { 524 public: 525 explicit Dt_U_imm3H_1(DataType dt); 526 }; 527 528 Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) { 529 switch (dt.GetValue()) { 530 case S8: 531 SetEncodingValue(0x1); 532 break; 533 case S16: 534 SetEncodingValue(0x2); 535 break; 536 case S32: 537 SetEncodingValue(0x4); 538 break; 539 case U8: 540 SetEncodingValue(0x9); 541 break; 542 case U16: 543 SetEncodingValue(0xa); 544 break; 545 case U32: 546 SetEncodingValue(0xc); 547 break; 548 default: 549 break; 550 } 551 } 552 553 class Dt_U_opc1_opc2_1 : public EncodingValue { 554 public: 555 explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane); 556 }; 557 558 Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) { 559 switch (dt.GetValue()) { 560 case S8: 561 if ((lane.GetLane() & 7) != lane.GetLane()) { 562 return; 563 } 564 SetEncodingValue(0x8 | lane.GetLane()); 565 break; 566 case S16: 567 if ((lane.GetLane() & 3) != lane.GetLane()) { 568 return; 569 } 570 SetEncodingValue(0x1 | (lane.GetLane() << 1)); 571 break; 572 case U8: 573 if ((lane.GetLane() & 7) != lane.GetLane()) { 574 return; 575 } 576 SetEncodingValue(0x18 | lane.GetLane()); 577 break; 578 case U16: 579 if ((lane.GetLane() & 3) != lane.GetLane()) { 580 return; 581 } 582 SetEncodingValue(0x11 | (lane.GetLane() << 1)); 583 break; 584 case Untyped32: 585 if ((lane.GetLane() & 1) != lane.GetLane()) { 586 return; 587 } 588 SetEncodingValue(0x0 | (lane.GetLane() << 2)); 589 break; 590 case kDataTypeValueNone: 591 if ((lane.GetLane() & 1) != lane.GetLane()) { 592 return; 593 } 594 SetEncodingValue(0x0 | (lane.GetLane() << 2)); 595 break; 596 default: 597 break; 598 } 599 } 600 601 class Dt_opc1_opc2_1 : public EncodingValue { 602 public: 603 explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane); 604 }; 605 606 Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) { 607 switch (dt.GetValue()) { 608 case Untyped8: 609 if ((lane.GetLane() & 7) != lane.GetLane()) { 610 return; 611 } 612 SetEncodingValue(0x8 | lane.GetLane()); 613 break; 614 case Untyped16: 615 if ((lane.GetLane() & 3) != lane.GetLane()) { 616 return; 617 } 618 SetEncodingValue(0x1 | (lane.GetLane() << 1)); 619 break; 620 case Untyped32: 621 if ((lane.GetLane() & 1) != lane.GetLane()) { 622 return; 623 } 624 SetEncodingValue(0x0 | (lane.GetLane() << 2)); 625 break; 626 case kDataTypeValueNone: 627 if ((lane.GetLane() & 1) != lane.GetLane()) { 628 return; 629 } 630 SetEncodingValue(0x0 | (lane.GetLane() << 2)); 631 break; 632 default: 633 break; 634 } 635 } 636 637 class Dt_imm4_1 : public EncodingValue { 638 public: 639 explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane); 640 }; 641 642 Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) { 643 switch (dt.GetValue()) { 644 case Untyped8: 645 if ((lane.GetLane() & 7) != lane.GetLane()) { 646 return; 647 } 648 SetEncodingValue(0x1 | (lane.GetLane() << 1)); 649 break; 650 case Untyped16: 651 if ((lane.GetLane() & 3) != lane.GetLane()) { 652 return; 653 } 654 SetEncodingValue(0x2 | (lane.GetLane() << 2)); 655 break; 656 case Untyped32: 657 if ((lane.GetLane() & 1) != lane.GetLane()) { 658 return; 659 } 660 SetEncodingValue(0x4 | (lane.GetLane() << 3)); 661 break; 662 default: 663 break; 664 } 665 } 666 667 class Dt_B_E_1 : public EncodingValue { 668 public: 669 explicit Dt_B_E_1(DataType dt); 670 }; 671 672 Dt_B_E_1::Dt_B_E_1(DataType dt) { 673 switch (dt.GetValue()) { 674 case Untyped8: 675 SetEncodingValue(0x2); 676 break; 677 case Untyped16: 678 SetEncodingValue(0x1); 679 break; 680 case Untyped32: 681 SetEncodingValue(0x0); 682 break; 683 default: 684 break; 685 } 686 } 687 688 class Dt_op_1 : public EncodingValue { 689 public: 690 Dt_op_1(DataType dt1, DataType dt2); 691 }; 692 693 Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) { 694 if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) { 695 SetEncodingValue(0x0); 696 return; 697 } 698 if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) { 699 SetEncodingValue(0x1); 700 return; 701 } 702 if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) { 703 SetEncodingValue(0x2); 704 return; 705 } 706 if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) { 707 SetEncodingValue(0x3); 708 return; 709 } 710 } 711 712 class Dt_op_2 : public EncodingValue { 713 public: 714 explicit Dt_op_2(DataType dt); 715 }; 716 717 Dt_op_2::Dt_op_2(DataType dt) { 718 switch (dt.GetValue()) { 719 case U32: 720 SetEncodingValue(0x0); 721 break; 722 case S32: 723 SetEncodingValue(0x1); 724 break; 725 default: 726 break; 727 } 728 } 729 730 class Dt_op_3 : public EncodingValue { 731 public: 732 explicit Dt_op_3(DataType dt); 733 }; 734 735 Dt_op_3::Dt_op_3(DataType dt) { 736 switch (dt.GetValue()) { 737 case S32: 738 SetEncodingValue(0x0); 739 break; 740 case U32: 741 SetEncodingValue(0x1); 742 break; 743 default: 744 break; 745 } 746 } 747 748 class Dt_U_sx_1 : public EncodingValue { 749 public: 750 explicit Dt_U_sx_1(DataType dt); 751 }; 752 753 Dt_U_sx_1::Dt_U_sx_1(DataType dt) { 754 switch (dt.GetValue()) { 755 case S16: 756 SetEncodingValue(0x0); 757 break; 758 case S32: 759 SetEncodingValue(0x1); 760 break; 761 case U16: 762 SetEncodingValue(0x2); 763 break; 764 case U32: 765 SetEncodingValue(0x3); 766 break; 767 default: 768 break; 769 } 770 } 771 772 class Dt_op_U_1 : public EncodingValue { 773 public: 774 Dt_op_U_1(DataType dt1, DataType dt2); 775 }; 776 777 Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) { 778 if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) { 779 SetEncodingValue(0x0); 780 return; 781 } 782 if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) { 783 SetEncodingValue(0x1); 784 return; 785 } 786 if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) { 787 SetEncodingValue(0x2); 788 return; 789 } 790 if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) { 791 SetEncodingValue(0x3); 792 return; 793 } 794 } 795 796 class Dt_sz_1 : public EncodingValue { 797 public: 798 explicit Dt_sz_1(DataType dt); 799 }; 800 801 Dt_sz_1::Dt_sz_1(DataType dt) { 802 switch (dt.GetValue()) { 803 case F32: 804 SetEncodingValue(0x0); 805 break; 806 default: 807 break; 808 } 809 } 810 811 class Dt_F_size_1 : public EncodingValue { 812 public: 813 explicit Dt_F_size_1(DataType dt); 814 }; 815 816 Dt_F_size_1::Dt_F_size_1(DataType dt) { 817 switch (dt.GetValue()) { 818 case S8: 819 SetEncodingValue(0x0); 820 break; 821 case S16: 822 SetEncodingValue(0x1); 823 break; 824 case S32: 825 SetEncodingValue(0x2); 826 break; 827 case F32: 828 SetEncodingValue(0x6); 829 break; 830 default: 831 break; 832 } 833 } 834 835 class Dt_F_size_2 : public EncodingValue { 836 public: 837 explicit Dt_F_size_2(DataType dt); 838 }; 839 840 Dt_F_size_2::Dt_F_size_2(DataType dt) { 841 switch (dt.GetValue()) { 842 case I8: 843 SetEncodingValue(0x0); 844 break; 845 case I16: 846 SetEncodingValue(0x1); 847 break; 848 case I32: 849 SetEncodingValue(0x2); 850 break; 851 case F32: 852 SetEncodingValue(0x6); 853 break; 854 default: 855 break; 856 } 857 } 858 859 class Dt_F_size_3 : public EncodingValue { 860 public: 861 explicit Dt_F_size_3(DataType dt); 862 }; 863 864 Dt_F_size_3::Dt_F_size_3(DataType dt) { 865 switch (dt.GetValue()) { 866 case I16: 867 SetEncodingValue(0x1); 868 break; 869 case I32: 870 SetEncodingValue(0x2); 871 break; 872 case F32: 873 SetEncodingValue(0x6); 874 break; 875 default: 876 break; 877 } 878 } 879 880 class Dt_F_size_4 : public EncodingValue { 881 public: 882 explicit Dt_F_size_4(DataType dt); 883 }; 884 885 Dt_F_size_4::Dt_F_size_4(DataType dt) { 886 switch (dt.GetValue()) { 887 case U32: 888 SetEncodingValue(0x2); 889 break; 890 case F32: 891 SetEncodingValue(0x6); 892 break; 893 default: 894 break; 895 } 896 } 897 898 class Dt_U_size_1 : public EncodingValue { 899 public: 900 explicit Dt_U_size_1(DataType dt); 901 }; 902 903 Dt_U_size_1::Dt_U_size_1(DataType dt) { 904 switch (dt.GetValue()) { 905 case S8: 906 SetEncodingValue(0x0); 907 break; 908 case S16: 909 SetEncodingValue(0x1); 910 break; 911 case S32: 912 SetEncodingValue(0x2); 913 break; 914 case U8: 915 SetEncodingValue(0x4); 916 break; 917 case U16: 918 SetEncodingValue(0x5); 919 break; 920 case U32: 921 SetEncodingValue(0x6); 922 break; 923 default: 924 break; 925 } 926 } 927 928 class Dt_U_size_2 : public EncodingValue { 929 public: 930 explicit Dt_U_size_2(DataType dt); 931 }; 932 933 Dt_U_size_2::Dt_U_size_2(DataType dt) { 934 switch (dt.GetValue()) { 935 case S16: 936 SetEncodingValue(0x1); 937 break; 938 case S32: 939 SetEncodingValue(0x2); 940 break; 941 case U16: 942 SetEncodingValue(0x5); 943 break; 944 case U32: 945 SetEncodingValue(0x6); 946 break; 947 default: 948 break; 949 } 950 } 951 952 class Dt_U_size_3 : public EncodingValue { 953 public: 954 explicit Dt_U_size_3(DataType dt); 955 }; 956 957 Dt_U_size_3::Dt_U_size_3(DataType dt) { 958 switch (dt.GetValue()) { 959 case S8: 960 SetEncodingValue(0x0); 961 break; 962 case S16: 963 SetEncodingValue(0x1); 964 break; 965 case S32: 966 SetEncodingValue(0x2); 967 break; 968 case S64: 969 SetEncodingValue(0x3); 970 break; 971 case U8: 972 SetEncodingValue(0x4); 973 break; 974 case U16: 975 SetEncodingValue(0x5); 976 break; 977 case U32: 978 SetEncodingValue(0x6); 979 break; 980 case U64: 981 SetEncodingValue(0x7); 982 break; 983 default: 984 break; 985 } 986 } 987 988 class Dt_size_1 : public EncodingValue { 989 public: 990 explicit Dt_size_1(DataType dt); 991 }; 992 993 Dt_size_1::Dt_size_1(DataType dt) { 994 switch (dt.GetValue()) { 995 case Untyped8: 996 SetEncodingValue(0x0); 997 break; 998 default: 999 break; 1000 } 1001 } 1002 1003 class Dt_size_2 : public EncodingValue { 1004 public: 1005 explicit Dt_size_2(DataType dt); 1006 }; 1007 1008 Dt_size_2::Dt_size_2(DataType dt) { 1009 switch (dt.GetValue()) { 1010 case I8: 1011 SetEncodingValue(0x0); 1012 break; 1013 case I16: 1014 SetEncodingValue(0x1); 1015 break; 1016 case I32: 1017 SetEncodingValue(0x2); 1018 break; 1019 case I64: 1020 SetEncodingValue(0x3); 1021 break; 1022 default: 1023 break; 1024 } 1025 } 1026 1027 class Dt_size_3 : public EncodingValue { 1028 public: 1029 explicit Dt_size_3(DataType dt); 1030 }; 1031 1032 Dt_size_3::Dt_size_3(DataType dt) { 1033 switch (dt.GetValue()) { 1034 case I16: 1035 SetEncodingValue(0x0); 1036 break; 1037 case I32: 1038 SetEncodingValue(0x1); 1039 break; 1040 case I64: 1041 SetEncodingValue(0x2); 1042 break; 1043 default: 1044 break; 1045 } 1046 } 1047 1048 class Dt_size_4 : public EncodingValue { 1049 public: 1050 explicit Dt_size_4(DataType dt); 1051 }; 1052 1053 Dt_size_4::Dt_size_4(DataType dt) { 1054 switch (dt.GetValue()) { 1055 case I8: 1056 SetEncodingValue(0x0); 1057 break; 1058 case I16: 1059 SetEncodingValue(0x1); 1060 break; 1061 case I32: 1062 SetEncodingValue(0x2); 1063 break; 1064 default: 1065 break; 1066 } 1067 } 1068 1069 class Dt_size_5 : public EncodingValue { 1070 public: 1071 explicit Dt_size_5(DataType dt); 1072 }; 1073 1074 Dt_size_5::Dt_size_5(DataType dt) { 1075 switch (dt.GetValue()) { 1076 case S8: 1077 SetEncodingValue(0x0); 1078 break; 1079 case S16: 1080 SetEncodingValue(0x1); 1081 break; 1082 case S32: 1083 SetEncodingValue(0x2); 1084 break; 1085 default: 1086 break; 1087 } 1088 } 1089 1090 class Dt_size_6 : public EncodingValue { 1091 public: 1092 explicit Dt_size_6(DataType dt); 1093 }; 1094 1095 Dt_size_6::Dt_size_6(DataType dt) { 1096 switch (dt.GetValue()) { 1097 case Untyped8: 1098 SetEncodingValue(0x0); 1099 break; 1100 case Untyped16: 1101 SetEncodingValue(0x1); 1102 break; 1103 case Untyped32: 1104 SetEncodingValue(0x2); 1105 break; 1106 case Untyped64: 1107 SetEncodingValue(0x3); 1108 break; 1109 default: 1110 break; 1111 } 1112 } 1113 1114 class Dt_size_7 : public EncodingValue { 1115 public: 1116 explicit Dt_size_7(DataType dt); 1117 }; 1118 1119 Dt_size_7::Dt_size_7(DataType dt) { 1120 switch (dt.GetValue()) { 1121 case Untyped8: 1122 SetEncodingValue(0x0); 1123 break; 1124 case Untyped16: 1125 SetEncodingValue(0x1); 1126 break; 1127 case Untyped32: 1128 SetEncodingValue(0x2); 1129 break; 1130 default: 1131 break; 1132 } 1133 } 1134 1135 class Dt_size_8 : public EncodingValue { 1136 public: 1137 Dt_size_8(DataType dt, Alignment align); 1138 }; 1139 1140 Dt_size_8::Dt_size_8(DataType dt, Alignment align) { 1141 switch (dt.GetValue()) { 1142 case Untyped8: 1143 SetEncodingValue(0x0); 1144 break; 1145 case Untyped16: 1146 SetEncodingValue(0x1); 1147 break; 1148 case Untyped32: 1149 if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) { 1150 SetEncodingValue(0x2); 1151 } else if (align.Is(k128BitAlign)) { 1152 SetEncodingValue(0x3); 1153 } 1154 break; 1155 default: 1156 break; 1157 } 1158 } 1159 1160 class Dt_size_9 : public EncodingValue { 1161 uint32_t type_; 1162 1163 public: 1164 explicit Dt_size_9(DataType dt); 1165 uint32_t GetTypeEncodingValue() const { return type_; } 1166 }; 1167 1168 Dt_size_9::Dt_size_9(DataType dt) { 1169 switch (dt.GetValue()) { 1170 case I16: 1171 type_ = 0x0; 1172 SetEncodingValue(0x1); 1173 break; 1174 case I32: 1175 type_ = 0x0; 1176 SetEncodingValue(0x2); 1177 break; 1178 case F32: 1179 type_ = 0x1; 1180 SetEncodingValue(0x2); 1181 break; 1182 default: 1183 VIXL_UNREACHABLE(); 1184 type_ = 0x0; 1185 break; 1186 } 1187 } 1188 1189 class Dt_size_10 : public EncodingValue { 1190 public: 1191 explicit Dt_size_10(DataType dt); 1192 }; 1193 1194 Dt_size_10::Dt_size_10(DataType dt) { 1195 switch (dt.GetValue()) { 1196 case S8: 1197 case U8: 1198 case I8: 1199 SetEncodingValue(0x0); 1200 break; 1201 case S16: 1202 case U16: 1203 case I16: 1204 SetEncodingValue(0x1); 1205 break; 1206 case S32: 1207 case U32: 1208 case I32: 1209 SetEncodingValue(0x2); 1210 break; 1211 default: 1212 break; 1213 } 1214 } 1215 1216 class Dt_size_11 : public EncodingValue { 1217 uint32_t type_; 1218 1219 public: 1220 explicit Dt_size_11(DataType dt); 1221 uint32_t GetTypeEncodingValue() const { return type_; } 1222 }; 1223 1224 Dt_size_11::Dt_size_11(DataType dt) { 1225 switch (dt.GetValue()) { 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_12 : public EncodingValue { 1250 uint32_t type_; 1251 1252 public: 1253 explicit Dt_size_12(DataType dt); 1254 uint32_t GetTypeEncodingValue() const { return type_; } 1255 }; 1256 1257 Dt_size_12::Dt_size_12(DataType dt) { 1258 switch (dt.GetValue()) { 1259 case S8: 1260 type_ = 0x0; 1261 SetEncodingValue(0x0); 1262 break; 1263 case U8: 1264 type_ = 0x1; 1265 SetEncodingValue(0x0); 1266 break; 1267 case S16: 1268 type_ = 0x0; 1269 SetEncodingValue(0x1); 1270 break; 1271 case U16: 1272 type_ = 0x1; 1273 SetEncodingValue(0x1); 1274 break; 1275 case S32: 1276 type_ = 0x0; 1277 SetEncodingValue(0x2); 1278 break; 1279 case U32: 1280 type_ = 0x1; 1281 SetEncodingValue(0x2); 1282 break; 1283 default: 1284 VIXL_UNREACHABLE(); 1285 type_ = 0x0; 1286 break; 1287 } 1288 } 1289 1290 class Dt_size_13 : public EncodingValue { 1291 public: 1292 explicit Dt_size_13(DataType dt); 1293 }; 1294 1295 Dt_size_13::Dt_size_13(DataType dt) { 1296 switch (dt.GetValue()) { 1297 case S16: 1298 SetEncodingValue(0x1); 1299 break; 1300 case S32: 1301 SetEncodingValue(0x2); 1302 break; 1303 default: 1304 break; 1305 } 1306 } 1307 1308 class Dt_size_14 : public EncodingValue { 1309 public: 1310 explicit Dt_size_14(DataType dt); 1311 }; 1312 1313 Dt_size_14::Dt_size_14(DataType dt) { 1314 switch (dt.GetValue()) { 1315 case S16: 1316 SetEncodingValue(0x0); 1317 break; 1318 case S32: 1319 SetEncodingValue(0x1); 1320 break; 1321 case S64: 1322 SetEncodingValue(0x2); 1323 break; 1324 default: 1325 break; 1326 } 1327 } 1328 1329 class Dt_size_15 : public EncodingValue { 1330 public: 1331 explicit Dt_size_15(DataType dt); 1332 }; 1333 1334 Dt_size_15::Dt_size_15(DataType dt) { 1335 switch (dt.GetValue()) { 1336 case Untyped8: 1337 SetEncodingValue(0x0); 1338 break; 1339 case Untyped16: 1340 SetEncodingValue(0x1); 1341 break; 1342 default: 1343 break; 1344 } 1345 } 1346 1347 class Dt_size_16 : public EncodingValue { 1348 public: 1349 explicit Dt_size_16(DataType dt); 1350 }; 1351 1352 Dt_size_16::Dt_size_16(DataType dt) { 1353 switch (dt.GetValue()) { 1354 case I8: 1355 SetEncodingValue(0x0); 1356 break; 1357 case I16: 1358 SetEncodingValue(0x1); 1359 break; 1360 case I32: 1361 SetEncodingValue(0x2); 1362 break; 1363 default: 1364 break; 1365 } 1366 } 1367 1368 class Index_1 : public EncodingValue { 1369 public: 1370 Index_1(const NeonRegisterList& nreglist, DataType dt); 1371 }; 1372 1373 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) { 1374 switch (dt.GetValue()) { 1375 case Untyped8: { 1376 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1377 return; 1378 } 1379 uint32_t value = nreglist.GetTransferLane() << 1; 1380 if (!nreglist.IsSingleSpaced()) return; 1381 SetEncodingValue(value); 1382 break; 1383 } 1384 case Untyped16: { 1385 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1386 return; 1387 } 1388 uint32_t value = nreglist.GetTransferLane() << 2; 1389 if (nreglist.IsDoubleSpaced()) value |= 2; 1390 SetEncodingValue(value); 1391 break; 1392 } 1393 case Untyped32: { 1394 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1395 return; 1396 } 1397 uint32_t value = nreglist.GetTransferLane() << 3; 1398 if (nreglist.IsDoubleSpaced()) value |= 4; 1399 SetEncodingValue(value); 1400 break; 1401 } 1402 default: 1403 break; 1404 } 1405 } 1406 1407 class Align_index_align_1 : public EncodingValue { 1408 public: 1409 Align_index_align_1(Alignment align, 1410 const NeonRegisterList& nreglist, 1411 DataType dt); 1412 }; 1413 1414 Align_index_align_1::Align_index_align_1(Alignment align, 1415 const NeonRegisterList& nreglist, 1416 DataType dt) { 1417 switch (dt.GetValue()) { 1418 case Untyped8: { 1419 uint32_t value; 1420 if (align.GetType() == kNoAlignment) { 1421 value = 0; 1422 } else { 1423 return; 1424 } 1425 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1426 return; 1427 } 1428 value |= nreglist.GetTransferLane() << 1; 1429 SetEncodingValue(value); 1430 break; 1431 } 1432 case Untyped16: { 1433 uint32_t value; 1434 if (align.GetType() == k16BitAlign) { 1435 value = 1; 1436 } else if (align.GetType() == kNoAlignment) { 1437 value = 0; 1438 } else { 1439 return; 1440 } 1441 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1442 return; 1443 } 1444 value |= nreglist.GetTransferLane() << 2; 1445 SetEncodingValue(value); 1446 break; 1447 } 1448 case Untyped32: { 1449 uint32_t value; 1450 if (align.GetType() == k32BitAlign) { 1451 value = 3; 1452 } else if (align.GetType() == kNoAlignment) { 1453 value = 0; 1454 } else { 1455 return; 1456 } 1457 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1458 return; 1459 } 1460 value |= nreglist.GetTransferLane() << 3; 1461 SetEncodingValue(value); 1462 break; 1463 } 1464 default: 1465 break; 1466 } 1467 } 1468 1469 class Align_index_align_2 : public EncodingValue { 1470 public: 1471 Align_index_align_2(Alignment align, 1472 const NeonRegisterList& nreglist, 1473 DataType dt); 1474 }; 1475 1476 Align_index_align_2::Align_index_align_2(Alignment align, 1477 const NeonRegisterList& nreglist, 1478 DataType dt) { 1479 switch (dt.GetValue()) { 1480 case Untyped8: { 1481 uint32_t value; 1482 if (align.GetType() == k16BitAlign) { 1483 value = 1; 1484 } else if (align.GetType() == kNoAlignment) { 1485 value = 0; 1486 } else { 1487 return; 1488 } 1489 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1490 return; 1491 } 1492 value |= nreglist.GetTransferLane() << 1; 1493 if (!nreglist.IsSingleSpaced()) return; 1494 SetEncodingValue(value); 1495 break; 1496 } 1497 case Untyped16: { 1498 uint32_t value; 1499 if (align.GetType() == k32BitAlign) { 1500 value = 1; 1501 } else if (align.GetType() == kNoAlignment) { 1502 value = 0; 1503 } else { 1504 return; 1505 } 1506 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1507 return; 1508 } 1509 value |= nreglist.GetTransferLane() << 2; 1510 if (nreglist.IsDoubleSpaced()) value |= 2; 1511 SetEncodingValue(value); 1512 break; 1513 } 1514 case Untyped32: { 1515 uint32_t value; 1516 if (align.GetType() == k64BitAlign) { 1517 value = 1; 1518 } else if (align.GetType() == kNoAlignment) { 1519 value = 0; 1520 } else { 1521 return; 1522 } 1523 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1524 return; 1525 } 1526 value |= nreglist.GetTransferLane() << 3; 1527 if (nreglist.IsDoubleSpaced()) value |= 4; 1528 SetEncodingValue(value); 1529 break; 1530 } 1531 default: 1532 break; 1533 } 1534 } 1535 1536 class Align_index_align_3 : public EncodingValue { 1537 public: 1538 Align_index_align_3(Alignment align, 1539 const NeonRegisterList& nreglist, 1540 DataType dt); 1541 }; 1542 1543 Align_index_align_3::Align_index_align_3(Alignment align, 1544 const NeonRegisterList& nreglist, 1545 DataType dt) { 1546 switch (dt.GetValue()) { 1547 case Untyped8: { 1548 uint32_t value; 1549 if (align.GetType() == k32BitAlign) { 1550 value = 1; 1551 } else if (align.GetType() == kNoAlignment) { 1552 value = 0; 1553 } else { 1554 return; 1555 } 1556 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { 1557 return; 1558 } 1559 value |= nreglist.GetTransferLane() << 1; 1560 if (!nreglist.IsSingleSpaced()) return; 1561 SetEncodingValue(value); 1562 break; 1563 } 1564 case Untyped16: { 1565 uint32_t value; 1566 if (align.GetType() == k64BitAlign) { 1567 value = 1; 1568 } else if (align.GetType() == kNoAlignment) { 1569 value = 0; 1570 } else { 1571 return; 1572 } 1573 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { 1574 return; 1575 } 1576 value |= nreglist.GetTransferLane() << 2; 1577 if (nreglist.IsDoubleSpaced()) value |= 2; 1578 SetEncodingValue(value); 1579 break; 1580 } 1581 case Untyped32: { 1582 uint32_t value; 1583 if (align.GetType() == k64BitAlign) { 1584 value = 1; 1585 } else if (align.GetType() == k128BitAlign) { 1586 value = 2; 1587 } else if (align.GetType() == kNoAlignment) { 1588 value = 0; 1589 } else { 1590 return; 1591 } 1592 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { 1593 return; 1594 } 1595 value |= nreglist.GetTransferLane() << 3; 1596 if (nreglist.IsDoubleSpaced()) value |= 4; 1597 SetEncodingValue(value); 1598 break; 1599 } 1600 default: 1601 break; 1602 } 1603 } 1604 1605 class Align_a_1 : public EncodingValue { 1606 public: 1607 Align_a_1(Alignment align, DataType dt); 1608 }; 1609 1610 Align_a_1::Align_a_1(Alignment align, DataType dt) { 1611 switch (align.GetType()) { 1612 case k16BitAlign: 1613 if (dt.Is(Untyped16)) SetEncodingValue(0x1); 1614 break; 1615 case k32BitAlign: 1616 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1617 break; 1618 case kNoAlignment: 1619 SetEncodingValue(0x0); 1620 break; 1621 default: 1622 break; 1623 } 1624 } 1625 1626 class Align_a_2 : public EncodingValue { 1627 public: 1628 Align_a_2(Alignment align, DataType dt); 1629 }; 1630 1631 Align_a_2::Align_a_2(Alignment align, DataType dt) { 1632 switch (align.GetType()) { 1633 case k16BitAlign: 1634 if (dt.Is(Untyped8)) SetEncodingValue(0x1); 1635 break; 1636 case k32BitAlign: 1637 if (dt.Is(Untyped16)) SetEncodingValue(0x1); 1638 break; 1639 case k64BitAlign: 1640 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1641 break; 1642 case kNoAlignment: 1643 SetEncodingValue(0x0); 1644 break; 1645 default: 1646 break; 1647 } 1648 } 1649 1650 class Align_a_3 : public EncodingValue { 1651 public: 1652 Align_a_3(Alignment align, DataType dt); 1653 }; 1654 1655 Align_a_3::Align_a_3(Alignment align, DataType dt) { 1656 switch (align.GetType()) { 1657 case k32BitAlign: 1658 if (dt.Is(Untyped8)) SetEncodingValue(0x1); 1659 break; 1660 case k64BitAlign: 1661 if (dt.Is(Untyped16)) 1662 SetEncodingValue(0x1); 1663 else if (dt.Is(Untyped32)) 1664 SetEncodingValue(0x1); 1665 break; 1666 case k128BitAlign: 1667 if (dt.Is(Untyped32)) SetEncodingValue(0x1); 1668 break; 1669 case kNoAlignment: 1670 SetEncodingValue(0x0); 1671 break; 1672 default: 1673 break; 1674 } 1675 } 1676 1677 class Align_align_1 : public EncodingValue { 1678 public: 1679 Align_align_1(Alignment align, const NeonRegisterList& nreglist); 1680 }; 1681 1682 Align_align_1::Align_align_1(Alignment align, 1683 const NeonRegisterList& nreglist) { 1684 switch (align.GetType()) { 1685 case k64BitAlign: 1686 SetEncodingValue(0x1); 1687 break; 1688 case k128BitAlign: 1689 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1690 SetEncodingValue(0x2); 1691 break; 1692 case k256BitAlign: 1693 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1694 SetEncodingValue(0x3); 1695 break; 1696 case kNoAlignment: 1697 SetEncodingValue(0x0); 1698 break; 1699 default: 1700 break; 1701 } 1702 } 1703 1704 class Align_align_2 : public EncodingValue { 1705 public: 1706 Align_align_2(Alignment align, const NeonRegisterList& nreglist); 1707 }; 1708 1709 Align_align_2::Align_align_2(Alignment align, 1710 const NeonRegisterList& nreglist) { 1711 switch (align.GetType()) { 1712 case k64BitAlign: 1713 SetEncodingValue(0x1); 1714 break; 1715 case k128BitAlign: 1716 SetEncodingValue(0x2); 1717 break; 1718 case k256BitAlign: 1719 if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3); 1720 break; 1721 case kNoAlignment: 1722 SetEncodingValue(0x0); 1723 break; 1724 default: 1725 break; 1726 } 1727 } 1728 1729 class Align_align_3 : public EncodingValue { 1730 public: 1731 explicit Align_align_3(Alignment align); 1732 }; 1733 1734 Align_align_3::Align_align_3(Alignment align) { 1735 switch (align.GetType()) { 1736 case k64BitAlign: 1737 SetEncodingValue(0x1); 1738 break; 1739 case kNoAlignment: 1740 SetEncodingValue(0x0); 1741 break; 1742 default: 1743 break; 1744 } 1745 } 1746 1747 class Align_align_4 : public EncodingValue { 1748 public: 1749 explicit Align_align_4(Alignment align); 1750 }; 1751 1752 Align_align_4::Align_align_4(Alignment align) { 1753 switch (align.GetType()) { 1754 case k64BitAlign: 1755 SetEncodingValue(0x1); 1756 break; 1757 case k128BitAlign: 1758 SetEncodingValue(0x2); 1759 break; 1760 case k256BitAlign: 1761 SetEncodingValue(0x3); 1762 break; 1763 case kNoAlignment: 1764 SetEncodingValue(0x0); 1765 break; 1766 default: 1767 break; 1768 } 1769 } 1770 1771 class Align_align_5 : public EncodingValue { 1772 public: 1773 Align_align_5(Alignment align, const NeonRegisterList& nreglist); 1774 }; 1775 1776 Align_align_5::Align_align_5(Alignment align, 1777 const NeonRegisterList& nreglist) { 1778 switch (align.GetType()) { 1779 case k64BitAlign: 1780 SetEncodingValue(0x1); 1781 break; 1782 case k128BitAlign: 1783 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) 1784 SetEncodingValue(0x2); 1785 break; 1786 case k256BitAlign: 1787 if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3); 1788 break; 1789 case kNoAlignment: 1790 SetEncodingValue(0x0); 1791 break; 1792 default: 1793 break; 1794 } 1795 } 1796 1797 1798 void Assembler::adc(Condition cond, 1799 EncodingSize size, 1800 Register rd, 1801 Register rn, 1802 const Operand& operand) { 1803 VIXL_ASSERT(AllowAssembler()); 1804 CheckIT(cond); 1805 if (operand.IsImmediate()) { 1806 uint32_t imm = operand.GetImmediate(); 1807 if (IsUsingT32()) { 1808 ImmediateT32 immediate_t32(imm); 1809 // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 1810 if (!size.IsNarrow() && immediate_t32.IsValid() && 1811 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 1812 EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 1813 (immediate_t32.GetEncodingValue() & 0xff) | 1814 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 1815 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 1816 AdvanceIT(); 1817 return; 1818 } 1819 } else { 1820 ImmediateA32 immediate_a32(imm); 1821 // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 1822 if (immediate_a32.IsValid() && cond.IsNotNever()) { 1823 EmitA32(0x02a00000U | (cond.GetCondition() << 28) | 1824 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 1825 immediate_a32.GetEncodingValue()); 1826 return; 1827 } 1828 } 1829 } 1830 if (operand.IsImmediateShiftedRegister()) { 1831 Register rm = operand.GetBaseRegister(); 1832 if (operand.IsPlainRegister()) { 1833 if (IsUsingT32()) { 1834 // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 1835 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 1836 rm.IsLow()) { 1837 EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); 1838 AdvanceIT(); 1839 return; 1840 } 1841 } 1842 } 1843 Shift shift = operand.GetShift(); 1844 uint32_t amount = operand.GetShiftAmount(); 1845 if (IsUsingT32()) { 1846 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 1847 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 1848 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 1849 uint32_t amount_ = amount % 32; 1850 EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 1851 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 1852 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 1853 AdvanceIT(); 1854 return; 1855 } 1856 } else { 1857 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 1858 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 1859 uint32_t amount_ = amount % 32; 1860 EmitA32(0x00a00000U | (cond.GetCondition() << 28) | 1861 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 1862 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 1863 return; 1864 } 1865 } 1866 } 1867 if (operand.IsRegisterShiftedRegister()) { 1868 Register rm = operand.GetBaseRegister(); 1869 Shift shift = operand.GetShift(); 1870 if (IsUsingA32()) { 1871 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 1872 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && 1873 !operand.GetShiftRegister().IsPC()) || 1874 AllowUnpredictable())) { 1875 EmitA32(0x00a00010U | (cond.GetCondition() << 28) | 1876 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 1877 (shift.GetType() << 5) | 1878 (operand.GetShiftRegister().GetCode() << 8)); 1879 return; 1880 } 1881 } 1882 } 1883 Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); 1884 } 1885 1886 void Assembler::adcs(Condition cond, 1887 EncodingSize size, 1888 Register rd, 1889 Register rn, 1890 const Operand& operand) { 1891 VIXL_ASSERT(AllowAssembler()); 1892 CheckIT(cond); 1893 if (operand.IsImmediate()) { 1894 uint32_t imm = operand.GetImmediate(); 1895 if (IsUsingT32()) { 1896 ImmediateT32 immediate_t32(imm); 1897 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 1898 if (!size.IsNarrow() && immediate_t32.IsValid() && 1899 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 1900 EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 1901 (immediate_t32.GetEncodingValue() & 0xff) | 1902 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 1903 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 1904 AdvanceIT(); 1905 return; 1906 } 1907 } else { 1908 ImmediateA32 immediate_a32(imm); 1909 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 1910 if (immediate_a32.IsValid() && cond.IsNotNever()) { 1911 EmitA32(0x02b00000U | (cond.GetCondition() << 28) | 1912 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 1913 immediate_a32.GetEncodingValue()); 1914 return; 1915 } 1916 } 1917 } 1918 if (operand.IsImmediateShiftedRegister()) { 1919 Register rm = operand.GetBaseRegister(); 1920 if (operand.IsPlainRegister()) { 1921 if (IsUsingT32()) { 1922 // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 1923 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 1924 rm.IsLow()) { 1925 EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); 1926 AdvanceIT(); 1927 return; 1928 } 1929 } 1930 } 1931 Shift shift = operand.GetShift(); 1932 uint32_t amount = operand.GetShiftAmount(); 1933 if (IsUsingT32()) { 1934 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 1935 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 1936 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 1937 uint32_t amount_ = amount % 32; 1938 EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 1939 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 1940 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 1941 AdvanceIT(); 1942 return; 1943 } 1944 } else { 1945 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 1946 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 1947 uint32_t amount_ = amount % 32; 1948 EmitA32(0x00b00000U | (cond.GetCondition() << 28) | 1949 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 1950 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 1951 return; 1952 } 1953 } 1954 } 1955 if (operand.IsRegisterShiftedRegister()) { 1956 Register rm = operand.GetBaseRegister(); 1957 Shift shift = operand.GetShift(); 1958 if (IsUsingA32()) { 1959 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 1960 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && 1961 !operand.GetShiftRegister().IsPC()) || 1962 AllowUnpredictable())) { 1963 EmitA32(0x00b00010U | (cond.GetCondition() << 28) | 1964 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 1965 (shift.GetType() << 5) | 1966 (operand.GetShiftRegister().GetCode() << 8)); 1967 return; 1968 } 1969 } 1970 } 1971 Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); 1972 } 1973 1974 void Assembler::add(Condition cond, 1975 EncodingSize size, 1976 Register rd, 1977 Register rn, 1978 const Operand& operand) { 1979 VIXL_ASSERT(AllowAssembler()); 1980 CheckIT(cond); 1981 if (operand.IsImmediate()) { 1982 uint32_t imm = operand.GetImmediate(); 1983 if (IsUsingT32()) { 1984 ImmediateT32 immediate_t32(imm); 1985 // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1 1986 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && 1987 ((imm % 4) == 0)) { 1988 uint32_t imm_ = imm >> 2; 1989 EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); 1990 AdvanceIT(); 1991 return; 1992 } 1993 // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1 1994 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 1995 (imm <= 7)) { 1996 EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 1997 AdvanceIT(); 1998 return; 1999 } 2000 // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 2001 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2002 (imm <= 255)) { 2003 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2004 AdvanceIT(); 2005 return; 2006 } 2007 // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1 2008 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && 2009 ((imm % 4) == 0)) { 2010 uint32_t imm_ = imm >> 2; 2011 EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); 2012 AdvanceIT(); 2013 return; 2014 } 2015 // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2 2016 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && 2017 ((imm % 4) == 0)) { 2018 uint32_t imm_ = imm >> 2; 2019 EmitT32_16(0xb000 | imm_); 2020 AdvanceIT(); 2021 return; 2022 } 2023 // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3 2024 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && 2025 (!rd.IsPC() || AllowUnpredictable())) { 2026 EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2027 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2028 AdvanceIT(); 2029 return; 2030 } 2031 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 2032 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 2033 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { 2034 EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2035 (immediate_t32.GetEncodingValue() & 0xff) | 2036 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2037 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2038 AdvanceIT(); 2039 return; 2040 } 2041 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 2042 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 2043 (!rd.IsPC() || AllowUnpredictable())) { 2044 EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2045 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2046 AdvanceIT(); 2047 return; 2048 } 2049 // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3 2050 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 2051 (!rd.IsPC() || AllowUnpredictable())) { 2052 EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | 2053 (immediate_t32.GetEncodingValue() & 0xff) | 2054 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2055 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2056 AdvanceIT(); 2057 return; 2058 } 2059 // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4 2060 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && 2061 (!rd.IsPC() || AllowUnpredictable())) { 2062 EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2063 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2064 AdvanceIT(); 2065 return; 2066 } 2067 } else { 2068 ImmediateA32 immediate_a32(imm); 2069 // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1 2070 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { 2071 EmitA32(0x028f0000U | (cond.GetCondition() << 28) | 2072 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2073 return; 2074 } 2075 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2076 if (immediate_a32.IsValid() && cond.IsNotNever() && 2077 ((rn.GetCode() & 0xd) != 0xd)) { 2078 EmitA32(0x02800000U | (cond.GetCondition() << 28) | 2079 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2080 immediate_a32.GetEncodingValue()); 2081 return; 2082 } 2083 // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 2084 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 2085 EmitA32(0x028d0000U | (cond.GetCondition() << 28) | 2086 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2087 return; 2088 } 2089 } 2090 } 2091 if (operand.IsImmediateShiftedRegister()) { 2092 Register rm = operand.GetBaseRegister(); 2093 if (operand.IsPlainRegister()) { 2094 if (IsUsingT32()) { 2095 // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 2096 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2097 rm.IsLow()) { 2098 EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | 2099 (rm.GetCode() << 6)); 2100 AdvanceIT(); 2101 return; 2102 } 2103 // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2 2104 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && 2105 (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && 2106 (!rd.IsPC() || !rm.IsPC())) || 2107 AllowUnpredictable())) { 2108 EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | 2109 ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 2110 AdvanceIT(); 2111 return; 2112 } 2113 // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1 2114 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && 2115 ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 2116 AllowUnpredictable())) { 2117 EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | 2118 ((rd.GetCode() & 0x8) << 4)); 2119 AdvanceIT(); 2120 return; 2121 } 2122 // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2 2123 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { 2124 EmitT32_16(0x4485 | (rm.GetCode() << 3)); 2125 AdvanceIT(); 2126 return; 2127 } 2128 } 2129 } 2130 Shift shift = operand.GetShift(); 2131 uint32_t amount = operand.GetShiftAmount(); 2132 if (IsUsingT32()) { 2133 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 2134 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 2135 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2136 uint32_t amount_ = amount % 32; 2137 EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2138 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2139 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2140 AdvanceIT(); 2141 return; 2142 } 2143 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 2144 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 2145 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2146 uint32_t amount_ = amount % 32; 2147 EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | 2148 (operand.GetTypeEncodingValue() << 4) | 2149 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2150 AdvanceIT(); 2151 return; 2152 } 2153 } else { 2154 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2155 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 2156 uint32_t amount_ = amount % 32; 2157 EmitA32(0x00800000U | (cond.GetCondition() << 28) | 2158 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2159 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2160 return; 2161 } 2162 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 2163 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 2164 uint32_t amount_ = amount % 32; 2165 EmitA32(0x008d0000U | (cond.GetCondition() << 28) | 2166 (rd.GetCode() << 12) | rm.GetCode() | 2167 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2168 return; 2169 } 2170 } 2171 } 2172 if (operand.IsRegisterShiftedRegister()) { 2173 Register rm = operand.GetBaseRegister(); 2174 Shift shift = operand.GetShift(); 2175 if (IsUsingA32()) { 2176 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2177 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && 2178 !operand.GetShiftRegister().IsPC()) || 2179 AllowUnpredictable())) { 2180 EmitA32(0x00800010U | (cond.GetCondition() << 28) | 2181 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2182 (shift.GetType() << 5) | 2183 (operand.GetShiftRegister().GetCode() << 8)); 2184 return; 2185 } 2186 } 2187 } 2188 Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); 2189 } 2190 2191 void Assembler::add(Condition cond, Register rd, const Operand& operand) { 2192 VIXL_ASSERT(AllowAssembler()); 2193 CheckIT(cond); 2194 if (operand.IsImmediate()) { 2195 uint32_t imm = operand.GetImmediate(); 2196 if (IsUsingT32()) { 2197 // ADD<c>{<q>} <Rdn>, #<imm8> ; T2 2198 if (InITBlock() && rd.IsLow() && (imm <= 255)) { 2199 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2200 AdvanceIT(); 2201 return; 2202 } 2203 } 2204 } 2205 if (operand.IsPlainRegister()) { 2206 Register rm = operand.GetBaseRegister(); 2207 if (IsUsingT32()) { 2208 // ADD<c>{<q>} <Rdn>, <Rm> ; T2 2209 if (InITBlock() && !rm.Is(sp) && 2210 (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && 2211 (!rd.IsPC() || !rm.IsPC())) || 2212 AllowUnpredictable())) { 2213 EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | 2214 (rm.GetCode() << 3)); 2215 AdvanceIT(); 2216 return; 2217 } 2218 } 2219 } 2220 Delegate(kAdd, &Assembler::add, cond, rd, operand); 2221 } 2222 2223 void Assembler::adds(Condition cond, 2224 EncodingSize size, 2225 Register rd, 2226 Register rn, 2227 const Operand& operand) { 2228 VIXL_ASSERT(AllowAssembler()); 2229 CheckIT(cond); 2230 if (operand.IsImmediate()) { 2231 uint32_t imm = operand.GetImmediate(); 2232 if (IsUsingT32()) { 2233 ImmediateT32 immediate_t32(imm); 2234 // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1 2235 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2236 (imm <= 7)) { 2237 EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 2238 AdvanceIT(); 2239 return; 2240 } 2241 // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 2242 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2243 (imm <= 255)) { 2244 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2245 AdvanceIT(); 2246 return; 2247 } 2248 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 2249 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 2250 !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { 2251 EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2252 (immediate_t32.GetEncodingValue() & 0xff) | 2253 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2254 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2255 AdvanceIT(); 2256 return; 2257 } 2258 // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3 2259 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 2260 !rd.Is(pc)) { 2261 EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | 2262 (immediate_t32.GetEncodingValue() & 0xff) | 2263 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2264 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2265 AdvanceIT(); 2266 return; 2267 } 2268 } else { 2269 ImmediateA32 immediate_a32(imm); 2270 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2271 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { 2272 EmitA32(0x02900000U | (cond.GetCondition() << 28) | 2273 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2274 immediate_a32.GetEncodingValue()); 2275 return; 2276 } 2277 // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 2278 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 2279 EmitA32(0x029d0000U | (cond.GetCondition() << 28) | 2280 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 2281 return; 2282 } 2283 } 2284 } 2285 if (operand.IsImmediateShiftedRegister()) { 2286 Register rm = operand.GetBaseRegister(); 2287 if (operand.IsPlainRegister()) { 2288 if (IsUsingT32()) { 2289 // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1 2290 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 2291 rm.IsLow()) { 2292 EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | 2293 (rm.GetCode() << 6)); 2294 AdvanceIT(); 2295 return; 2296 } 2297 } 2298 } 2299 Shift shift = operand.GetShift(); 2300 uint32_t amount = operand.GetShiftAmount(); 2301 if (IsUsingT32()) { 2302 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 2303 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 2304 !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 2305 uint32_t amount_ = amount % 32; 2306 EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2307 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2308 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2309 AdvanceIT(); 2310 return; 2311 } 2312 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 2313 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 2314 !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { 2315 uint32_t amount_ = amount % 32; 2316 EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | 2317 (operand.GetTypeEncodingValue() << 4) | 2318 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2319 AdvanceIT(); 2320 return; 2321 } 2322 } else { 2323 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2324 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 2325 uint32_t amount_ = amount % 32; 2326 EmitA32(0x00900000U | (cond.GetCondition() << 28) | 2327 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2328 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2329 return; 2330 } 2331 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 2332 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 2333 uint32_t amount_ = amount % 32; 2334 EmitA32(0x009d0000U | (cond.GetCondition() << 28) | 2335 (rd.GetCode() << 12) | rm.GetCode() | 2336 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2337 return; 2338 } 2339 } 2340 } 2341 if (operand.IsRegisterShiftedRegister()) { 2342 Register rm = operand.GetBaseRegister(); 2343 Shift shift = operand.GetShift(); 2344 if (IsUsingA32()) { 2345 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2346 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && 2347 !operand.GetShiftRegister().IsPC()) || 2348 AllowUnpredictable())) { 2349 EmitA32(0x00900010U | (cond.GetCondition() << 28) | 2350 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2351 (shift.GetType() << 5) | 2352 (operand.GetShiftRegister().GetCode() << 8)); 2353 return; 2354 } 2355 } 2356 } 2357 Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand); 2358 } 2359 2360 void Assembler::adds(Register rd, const Operand& operand) { 2361 VIXL_ASSERT(AllowAssembler()); 2362 CheckIT(al); 2363 if (operand.IsImmediate()) { 2364 uint32_t imm = operand.GetImmediate(); 2365 if (IsUsingT32()) { 2366 // ADDS{<q>} <Rdn>, #<imm8> ; T2 2367 if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) { 2368 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); 2369 AdvanceIT(); 2370 return; 2371 } 2372 } 2373 } 2374 Delegate(kAdds, &Assembler::adds, rd, operand); 2375 } 2376 2377 void Assembler::addw(Condition cond, 2378 Register rd, 2379 Register rn, 2380 const Operand& operand) { 2381 VIXL_ASSERT(AllowAssembler()); 2382 CheckIT(cond); 2383 if (operand.IsImmediate()) { 2384 uint32_t imm = operand.GetImmediate(); 2385 if (IsUsingT32()) { 2386 // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3 2387 if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2388 EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2389 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2390 AdvanceIT(); 2391 return; 2392 } 2393 // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 2394 if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && 2395 (!rd.IsPC() || AllowUnpredictable())) { 2396 EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2397 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2398 AdvanceIT(); 2399 return; 2400 } 2401 // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4 2402 if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2403 EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | 2404 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 2405 AdvanceIT(); 2406 return; 2407 } 2408 } 2409 } 2410 Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand); 2411 } 2412 2413 void Assembler::adr(Condition cond, 2414 EncodingSize size, 2415 Register rd, 2416 Label* label) { 2417 VIXL_ASSERT(AllowAssembler()); 2418 CheckIT(cond); 2419 Label::Offset offset = 2420 label->IsBound() 2421 ? label->GetLocation() - 2422 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 2423 : 0; 2424 if (IsUsingT32()) { 2425 int32_t neg_offset = -offset; 2426 // ADR{<c>}{<q>} <Rd>, <label> ; T1 2427 if (!size.IsWide() && rd.IsLow() && 2428 ((label->IsBound() && (offset >= 0) && (offset <= 1020) && 2429 ((offset & 0x3) == 0)) || 2430 (!label->IsBound() && size.IsNarrow()))) { 2431 static class EmitOp : public Label::LabelEmitOperator { 2432 public: 2433 EmitOp() : Label::LabelEmitOperator(0, 1020) {} 2434 virtual uint32_t Encode(uint32_t instr, 2435 Label::Offset pc, 2436 const Label* label) const VIXL_OVERRIDE { 2437 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 2438 VIXL_ASSERT((offset >= 0) && (offset <= 1020) && 2439 ((offset & 0x3) == 0)); 2440 const int32_t target = offset >> 2; 2441 return instr | (target & 0xff); 2442 } 2443 } immop; 2444 EmitT32_16(Link(0xa000 | (rd.GetCode() << 8), label, immop)); 2445 AdvanceIT(); 2446 return; 2447 } 2448 // ADR{<c>}{<q>} <Rd>, <label> ; T2 2449 if (!size.IsNarrow() && label->IsBound() && (neg_offset > 0) && 2450 (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { 2451 EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) | 2452 ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15)); 2453 AdvanceIT(); 2454 return; 2455 } 2456 // ADR{<c>}{<q>} <Rd>, <label> ; T3 2457 if (!size.IsNarrow() && 2458 (!label->IsBound() || ((offset >= 0) && (offset <= 4095))) && 2459 (!rd.IsPC() || AllowUnpredictable())) { 2460 static class EmitOp : public Label::LabelEmitOperator { 2461 public: 2462 EmitOp() : Label::LabelEmitOperator(0, 4095) {} 2463 virtual uint32_t Encode(uint32_t instr, 2464 Label::Offset pc, 2465 const Label* label) const VIXL_OVERRIDE { 2466 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 2467 int32_t target; 2468 if ((offset >= 0) && (offset <= 4095) && !label->IsMinusZero()) { 2469 target = offset; 2470 } else { 2471 target = -offset; 2472 VIXL_ASSERT((target >= 0) && (target <= 4095)); 2473 // Emit the T2 encoding. 2474 instr |= 0x00a00000; 2475 } 2476 return instr | (target & 0xff) | ((target & 0x700) << 4) | 2477 ((target & 0x800) << 15); 2478 } 2479 } immop; 2480 EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8), label, immop)); 2481 AdvanceIT(); 2482 return; 2483 } 2484 } else { 2485 ImmediateA32 positive_immediate_a32(offset); 2486 ImmediateA32 negative_immediate_a32(-offset); 2487 // ADR{<c>}{<q>} <Rd>, <label> ; A1 2488 if ((!label->IsBound() || positive_immediate_a32.IsValid()) && 2489 cond.IsNotNever()) { 2490 static class EmitOp : public Label::LabelEmitOperator { 2491 public: 2492 EmitOp() : Label::LabelEmitOperator(0, 255) {} 2493 virtual uint32_t Encode(uint32_t instr, 2494 Label::Offset pc, 2495 const Label* label) const VIXL_OVERRIDE { 2496 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 2497 int32_t target; 2498 ImmediateA32 positive_immediate_a32(offset); 2499 if (positive_immediate_a32.IsValid()) { 2500 target = positive_immediate_a32.GetEncodingValue(); 2501 } else { 2502 ImmediateA32 negative_immediate_a32(-offset); 2503 VIXL_ASSERT(negative_immediate_a32.IsValid()); 2504 // Emit the A2 encoding. 2505 target = negative_immediate_a32.GetEncodingValue(); 2506 instr = (instr & ~0x00f00000) | 0x00400000; 2507 } 2508 return instr | (target & 0xfff); 2509 } 2510 } immop; 2511 EmitA32( 2512 Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12), 2513 label, 2514 immop)); 2515 return; 2516 } 2517 // ADR{<c>}{<q>} <Rd>, <label> ; A2 2518 if (label->IsBound() && negative_immediate_a32.IsValid() && 2519 cond.IsNotNever()) { 2520 EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 2521 negative_immediate_a32.GetEncodingValue()); 2522 return; 2523 } 2524 } 2525 Delegate(kAdr, &Assembler::adr, cond, size, rd, label); 2526 } 2527 2528 void Assembler::and_(Condition cond, 2529 EncodingSize size, 2530 Register rd, 2531 Register rn, 2532 const Operand& operand) { 2533 VIXL_ASSERT(AllowAssembler()); 2534 CheckIT(cond); 2535 if (operand.IsImmediate()) { 2536 uint32_t imm = operand.GetImmediate(); 2537 if (IsUsingT32()) { 2538 ImmediateT32 immediate_t32(imm); 2539 // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 2540 if (!size.IsNarrow() && immediate_t32.IsValid()) { 2541 EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2542 (immediate_t32.GetEncodingValue() & 0xff) | 2543 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2544 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2545 AdvanceIT(); 2546 return; 2547 } 2548 } else { 2549 ImmediateA32 immediate_a32(imm); 2550 // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2551 if (immediate_a32.IsValid() && cond.IsNotNever()) { 2552 EmitA32(0x02000000U | (cond.GetCondition() << 28) | 2553 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2554 immediate_a32.GetEncodingValue()); 2555 return; 2556 } 2557 } 2558 } 2559 if (operand.IsImmediateShiftedRegister()) { 2560 Register rm = operand.GetBaseRegister(); 2561 if (operand.IsPlainRegister()) { 2562 if (IsUsingT32()) { 2563 // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 2564 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2565 rm.IsLow()) { 2566 EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3)); 2567 AdvanceIT(); 2568 return; 2569 } 2570 } 2571 } 2572 Shift shift = operand.GetShift(); 2573 uint32_t amount = operand.GetShiftAmount(); 2574 if (IsUsingT32()) { 2575 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 2576 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 2577 uint32_t amount_ = amount % 32; 2578 EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2579 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2580 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2581 AdvanceIT(); 2582 return; 2583 } 2584 } else { 2585 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2586 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 2587 uint32_t amount_ = amount % 32; 2588 EmitA32(0x00000000U | (cond.GetCondition() << 28) | 2589 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2590 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2591 return; 2592 } 2593 } 2594 } 2595 if (operand.IsRegisterShiftedRegister()) { 2596 Register rm = operand.GetBaseRegister(); 2597 Shift shift = operand.GetShift(); 2598 if (IsUsingA32()) { 2599 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2600 if (cond.IsNotNever()) { 2601 EmitA32(0x00000010U | (cond.GetCondition() << 28) | 2602 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2603 (shift.GetType() << 5) | 2604 (operand.GetShiftRegister().GetCode() << 8)); 2605 return; 2606 } 2607 } 2608 } 2609 Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand); 2610 } 2611 2612 void Assembler::ands(Condition cond, 2613 EncodingSize size, 2614 Register rd, 2615 Register rn, 2616 const Operand& operand) { 2617 VIXL_ASSERT(AllowAssembler()); 2618 CheckIT(cond); 2619 if (operand.IsImmediate()) { 2620 uint32_t imm = operand.GetImmediate(); 2621 if (IsUsingT32()) { 2622 ImmediateT32 immediate_t32(imm); 2623 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 2624 if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) { 2625 EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2626 (immediate_t32.GetEncodingValue() & 0xff) | 2627 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 2628 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 2629 AdvanceIT(); 2630 return; 2631 } 2632 } else { 2633 ImmediateA32 immediate_a32(imm); 2634 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 2635 if (immediate_a32.IsValid() && cond.IsNotNever()) { 2636 EmitA32(0x02100000U | (cond.GetCondition() << 28) | 2637 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 2638 immediate_a32.GetEncodingValue()); 2639 return; 2640 } 2641 } 2642 } 2643 if (operand.IsImmediateShiftedRegister()) { 2644 Register rm = operand.GetBaseRegister(); 2645 if (operand.IsPlainRegister()) { 2646 if (IsUsingT32()) { 2647 // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 2648 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 2649 rm.IsLow()) { 2650 EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3)); 2651 AdvanceIT(); 2652 return; 2653 } 2654 } 2655 } 2656 Shift shift = operand.GetShift(); 2657 uint32_t amount = operand.GetShiftAmount(); 2658 if (IsUsingT32()) { 2659 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 2660 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) { 2661 uint32_t amount_ = amount % 32; 2662 EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 2663 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 2664 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2665 AdvanceIT(); 2666 return; 2667 } 2668 } else { 2669 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 2670 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 2671 uint32_t amount_ = amount % 32; 2672 EmitA32(0x00100000U | (cond.GetCondition() << 28) | 2673 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2674 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 2675 return; 2676 } 2677 } 2678 } 2679 if (operand.IsRegisterShiftedRegister()) { 2680 Register rm = operand.GetBaseRegister(); 2681 Shift shift = operand.GetShift(); 2682 if (IsUsingA32()) { 2683 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 2684 if (cond.IsNotNever()) { 2685 EmitA32(0x00100010U | (cond.GetCondition() << 28) | 2686 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 2687 (shift.GetType() << 5) | 2688 (operand.GetShiftRegister().GetCode() << 8)); 2689 return; 2690 } 2691 } 2692 } 2693 Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand); 2694 } 2695 2696 void Assembler::asr(Condition cond, 2697 EncodingSize size, 2698 Register rd, 2699 Register rm, 2700 const Operand& operand) { 2701 VIXL_ASSERT(AllowAssembler()); 2702 CheckIT(cond); 2703 if (operand.IsImmediate()) { 2704 uint32_t imm = operand.GetImmediate(); 2705 if (IsUsingT32()) { 2706 // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 2707 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 2708 (imm >= 1) && (imm <= 32)) { 2709 uint32_t amount_ = imm % 32; 2710 EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) | 2711 (amount_ << 6)); 2712 AdvanceIT(); 2713 return; 2714 } 2715 // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 2716 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) { 2717 uint32_t amount_ = imm % 32; 2718 EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() | 2719 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2720 AdvanceIT(); 2721 return; 2722 } 2723 } else { 2724 // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 2725 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 2726 uint32_t amount_ = imm % 32; 2727 EmitA32(0x01a00040U | (cond.GetCondition() << 28) | 2728 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 2729 return; 2730 } 2731 } 2732 } 2733 if (operand.IsPlainRegister()) { 2734 Register rs = operand.GetBaseRegister(); 2735 if (IsUsingT32()) { 2736 // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 2737 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 2738 rs.IsLow()) { 2739 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 2740 AdvanceIT(); 2741 return; 2742 } 2743 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 2744 if (!size.IsNarrow()) { 2745 EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 2746 rs.GetCode()); 2747 AdvanceIT(); 2748 return; 2749 } 2750 } else { 2751 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 2752 if (cond.IsNotNever()) { 2753 EmitA32(0x01a00050U | (cond.GetCondition() << 28) | 2754 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 2755 return; 2756 } 2757 } 2758 } 2759 Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand); 2760 } 2761 2762 void Assembler::asrs(Condition cond, 2763 EncodingSize size, 2764 Register rd, 2765 Register rm, 2766 const Operand& operand) { 2767 VIXL_ASSERT(AllowAssembler()); 2768 CheckIT(cond); 2769 if (operand.IsImmediate()) { 2770 uint32_t imm = operand.GetImmediate(); 2771 if (IsUsingT32()) { 2772 // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 2773 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 2774 (imm >= 1) && (imm <= 32)) { 2775 uint32_t amount_ = imm % 32; 2776 EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) | 2777 (amount_ << 6)); 2778 AdvanceIT(); 2779 return; 2780 } 2781 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 2782 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) { 2783 uint32_t amount_ = imm % 32; 2784 EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() | 2785 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 2786 AdvanceIT(); 2787 return; 2788 } 2789 } else { 2790 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 2791 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 2792 uint32_t amount_ = imm % 32; 2793 EmitA32(0x01b00040U | (cond.GetCondition() << 28) | 2794 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 2795 return; 2796 } 2797 } 2798 } 2799 if (operand.IsPlainRegister()) { 2800 Register rs = operand.GetBaseRegister(); 2801 if (IsUsingT32()) { 2802 // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 2803 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 2804 rs.IsLow()) { 2805 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3)); 2806 AdvanceIT(); 2807 return; 2808 } 2809 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 2810 if (!size.IsNarrow()) { 2811 EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 2812 rs.GetCode()); 2813 AdvanceIT(); 2814 return; 2815 } 2816 } else { 2817 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 2818 if (cond.IsNotNever()) { 2819 EmitA32(0x01b00050U | (cond.GetCondition() << 28) | 2820 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 2821 return; 2822 } 2823 } 2824 } 2825 Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand); 2826 } 2827 2828 void Assembler::b(Condition cond, EncodingSize size, Label* label) { 2829 VIXL_ASSERT(AllowAssembler()); 2830 Label::Offset offset = 2831 label->IsBound() 2832 ? label->GetLocation() - 2833 (GetCursorOffset() + GetArchitectureStatePCOffset()) 2834 : 0; 2835 if (IsUsingT32()) { 2836 // B<c>{<q>} <label> ; T1 2837 if (OutsideITBlock() && !size.IsWide() && 2838 ((label->IsBound() && (offset >= -256) && (offset <= 254) && 2839 ((offset & 0x1) == 0)) || 2840 (!label->IsBound() && size.IsNarrow())) && 2841 !cond.Is(al) && cond.IsNotNever()) { 2842 static class EmitOp : public Label::LabelEmitOperator { 2843 public: 2844 EmitOp() : Label::LabelEmitOperator(-256, 254) {} 2845 virtual uint32_t Encode(uint32_t instr, 2846 Label::Offset pc, 2847 const Label* label) const VIXL_OVERRIDE { 2848 Label::Offset offset = label->GetLocation() - pc; 2849 VIXL_ASSERT((offset >= -256) && (offset <= 254) && 2850 ((offset & 0x1) == 0)); 2851 const int32_t target = offset >> 1; 2852 return instr | (target & 0xff); 2853 } 2854 } immop; 2855 EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8), label, immop)); 2856 AdvanceIT(); 2857 return; 2858 } 2859 // B{<c>}{<q>} <label> ; T2 2860 if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && 2861 ((label->IsBound() && (offset >= -2048) && (offset <= 2046) && 2862 ((offset & 0x1) == 0)) || 2863 (!label->IsBound() && size.IsNarrow()))) { 2864 CheckIT(cond); 2865 static class EmitOp : public Label::LabelEmitOperator { 2866 public: 2867 EmitOp() : Label::LabelEmitOperator(-2048, 2046) {} 2868 virtual uint32_t Encode(uint32_t instr, 2869 Label::Offset pc, 2870 const Label* label) const VIXL_OVERRIDE { 2871 Label::Offset offset = label->GetLocation() - pc; 2872 VIXL_ASSERT((offset >= -2048) && (offset <= 2046) && 2873 ((offset & 0x1) == 0)); 2874 const int32_t target = offset >> 1; 2875 return instr | (target & 0x7ff); 2876 } 2877 } immop; 2878 EmitT32_16(Link(0xe000, label, immop)); 2879 AdvanceIT(); 2880 return; 2881 } 2882 // B<c>{<q>} <label> ; T3 2883 if (OutsideITBlock() && !size.IsNarrow() && 2884 ((label->IsBound() && (offset >= -1048576) && (offset <= 1048574) && 2885 ((offset & 0x1) == 0)) || 2886 !label->IsBound()) && 2887 !cond.Is(al) && cond.IsNotNever()) { 2888 static class EmitOp : public Label::LabelEmitOperator { 2889 public: 2890 EmitOp() : Label::LabelEmitOperator(-1048576, 1048574) {} 2891 virtual uint32_t Encode(uint32_t instr, 2892 Label::Offset pc, 2893 const Label* label) const VIXL_OVERRIDE { 2894 Label::Offset offset = label->GetLocation() - pc; 2895 VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) && 2896 ((offset & 0x1) == 0)); 2897 const int32_t target = offset >> 1; 2898 return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) | 2899 ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) | 2900 ((target & 0x80000) << 7); 2901 } 2902 } immop; 2903 EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22), label, immop)); 2904 AdvanceIT(); 2905 return; 2906 } 2907 // B{<c>}{<q>} <label> ; T4 2908 if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() && 2909 ((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) && 2910 ((offset & 0x1) == 0)) || 2911 !label->IsBound())) { 2912 CheckIT(cond); 2913 static class EmitOp : public Label::LabelEmitOperator { 2914 public: 2915 EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {} 2916 virtual uint32_t Encode(uint32_t instr, 2917 Label::Offset pc, 2918 const Label* label) const VIXL_OVERRIDE { 2919 Label::Offset offset = label->GetLocation() - pc; 2920 VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) && 2921 ((offset & 0x1) == 0)); 2922 int32_t target = offset >> 1; 2923 uint32_t S = target & (1 << 23); 2924 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21); 2925 return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) | 2926 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) | 2927 ((target & 0x800000) << 3); 2928 } 2929 } immop; 2930 EmitT32_32(Link(0xf0009000U, label, immop)); 2931 AdvanceIT(); 2932 return; 2933 } 2934 } else { 2935 // B{<c>}{<q>} <label> ; A1 2936 if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) && 2937 ((offset & 0x3) == 0)) || 2938 !label->IsBound()) && 2939 cond.IsNotNever()) { 2940 static class EmitOp : public Label::LabelEmitOperator { 2941 public: 2942 EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {} 2943 virtual uint32_t Encode(uint32_t instr, 2944 Label::Offset pc, 2945 const Label* label) const VIXL_OVERRIDE { 2946 Label::Offset offset = label->GetLocation() - pc; 2947 VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) && 2948 ((offset & 0x3) == 0)); 2949 const int32_t target = offset >> 2; 2950 return instr | (target & 0xffffff); 2951 } 2952 } immop; 2953 EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28), label, immop)); 2954 return; 2955 } 2956 } 2957 Delegate(kB, &Assembler::b, cond, size, label); 2958 } 2959 2960 void Assembler::bfc(Condition cond, 2961 Register rd, 2962 uint32_t lsb, 2963 const Operand& operand) { 2964 VIXL_ASSERT(AllowAssembler()); 2965 CheckIT(cond); 2966 if (operand.IsImmediate()) { 2967 uint32_t width = operand.GetImmediate(); 2968 if (IsUsingT32()) { 2969 // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1 2970 if ((lsb <= 31) && 2971 (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) { 2972 uint32_t msb = lsb + width - 1; 2973 EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) | 2974 ((lsb & 0x1c) << 10) | msb); 2975 AdvanceIT(); 2976 return; 2977 } 2978 } else { 2979 // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1 2980 if ((lsb <= 31) && cond.IsNotNever() && 2981 (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) { 2982 uint32_t msb = lsb + width - 1; 2983 EmitA32(0x07c0001fU | (cond.GetCondition() << 28) | 2984 (rd.GetCode() << 12) | (lsb << 7) | (msb << 16)); 2985 return; 2986 } 2987 } 2988 } 2989 Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, operand); 2990 } 2991 2992 void Assembler::bfi(Condition cond, 2993 Register rd, 2994 Register rn, 2995 uint32_t lsb, 2996 const Operand& operand) { 2997 VIXL_ASSERT(AllowAssembler()); 2998 CheckIT(cond); 2999 if (operand.IsImmediate()) { 3000 uint32_t width = operand.GetImmediate(); 3001 if (IsUsingT32()) { 3002 // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 3003 if ((lsb <= 31) && !rn.Is(pc) && 3004 (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) { 3005 uint32_t msb = lsb + width - 1; 3006 EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3007 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb); 3008 AdvanceIT(); 3009 return; 3010 } 3011 } else { 3012 // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 3013 if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) && 3014 (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) { 3015 uint32_t msb = lsb + width - 1; 3016 EmitA32(0x07c00010U | (cond.GetCondition() << 28) | 3017 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) | (msb << 16)); 3018 return; 3019 } 3020 } 3021 } 3022 Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, operand); 3023 } 3024 3025 void Assembler::bic(Condition cond, 3026 EncodingSize size, 3027 Register rd, 3028 Register rn, 3029 const Operand& operand) { 3030 VIXL_ASSERT(AllowAssembler()); 3031 CheckIT(cond); 3032 if (operand.IsImmediate()) { 3033 uint32_t imm = operand.GetImmediate(); 3034 if (IsUsingT32()) { 3035 ImmediateT32 immediate_t32(imm); 3036 // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 3037 if (!size.IsNarrow() && immediate_t32.IsValid()) { 3038 EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3039 (immediate_t32.GetEncodingValue() & 0xff) | 3040 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3041 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3042 AdvanceIT(); 3043 return; 3044 } 3045 } else { 3046 ImmediateA32 immediate_a32(imm); 3047 // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 3048 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3049 EmitA32(0x03c00000U | (cond.GetCondition() << 28) | 3050 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 3051 immediate_a32.GetEncodingValue()); 3052 return; 3053 } 3054 } 3055 } 3056 if (operand.IsImmediateShiftedRegister()) { 3057 Register rm = operand.GetBaseRegister(); 3058 if (operand.IsPlainRegister()) { 3059 if (IsUsingT32()) { 3060 // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 3061 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 3062 rm.IsLow()) { 3063 EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3)); 3064 AdvanceIT(); 3065 return; 3066 } 3067 } 3068 } 3069 Shift shift = operand.GetShift(); 3070 uint32_t amount = operand.GetShiftAmount(); 3071 if (IsUsingT32()) { 3072 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 3073 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 3074 uint32_t amount_ = amount % 32; 3075 EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3076 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 3077 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3078 AdvanceIT(); 3079 return; 3080 } 3081 } else { 3082 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 3083 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3084 uint32_t amount_ = amount % 32; 3085 EmitA32(0x01c00000U | (cond.GetCondition() << 28) | 3086 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3087 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3088 return; 3089 } 3090 } 3091 } 3092 if (operand.IsRegisterShiftedRegister()) { 3093 Register rm = operand.GetBaseRegister(); 3094 Shift shift = operand.GetShift(); 3095 if (IsUsingA32()) { 3096 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 3097 if (cond.IsNotNever()) { 3098 EmitA32(0x01c00010U | (cond.GetCondition() << 28) | 3099 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3100 (shift.GetType() << 5) | 3101 (operand.GetShiftRegister().GetCode() << 8)); 3102 return; 3103 } 3104 } 3105 } 3106 Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand); 3107 } 3108 3109 void Assembler::bics(Condition cond, 3110 EncodingSize size, 3111 Register rd, 3112 Register rn, 3113 const Operand& operand) { 3114 VIXL_ASSERT(AllowAssembler()); 3115 CheckIT(cond); 3116 if (operand.IsImmediate()) { 3117 uint32_t imm = operand.GetImmediate(); 3118 if (IsUsingT32()) { 3119 ImmediateT32 immediate_t32(imm); 3120 // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 3121 if (!size.IsNarrow() && immediate_t32.IsValid()) { 3122 EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3123 (immediate_t32.GetEncodingValue() & 0xff) | 3124 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3125 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3126 AdvanceIT(); 3127 return; 3128 } 3129 } else { 3130 ImmediateA32 immediate_a32(imm); 3131 // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 3132 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3133 EmitA32(0x03d00000U | (cond.GetCondition() << 28) | 3134 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 3135 immediate_a32.GetEncodingValue()); 3136 return; 3137 } 3138 } 3139 } 3140 if (operand.IsImmediateShiftedRegister()) { 3141 Register rm = operand.GetBaseRegister(); 3142 if (operand.IsPlainRegister()) { 3143 if (IsUsingT32()) { 3144 // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 3145 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 3146 rm.IsLow()) { 3147 EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3)); 3148 AdvanceIT(); 3149 return; 3150 } 3151 } 3152 } 3153 Shift shift = operand.GetShift(); 3154 uint32_t amount = operand.GetShiftAmount(); 3155 if (IsUsingT32()) { 3156 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 3157 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 3158 uint32_t amount_ = amount % 32; 3159 EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3160 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 3161 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3162 AdvanceIT(); 3163 return; 3164 } 3165 } else { 3166 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 3167 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3168 uint32_t amount_ = amount % 32; 3169 EmitA32(0x01d00000U | (cond.GetCondition() << 28) | 3170 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3171 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3172 return; 3173 } 3174 } 3175 } 3176 if (operand.IsRegisterShiftedRegister()) { 3177 Register rm = operand.GetBaseRegister(); 3178 Shift shift = operand.GetShift(); 3179 if (IsUsingA32()) { 3180 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 3181 if (cond.IsNotNever()) { 3182 EmitA32(0x01d00010U | (cond.GetCondition() << 28) | 3183 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3184 (shift.GetType() << 5) | 3185 (operand.GetShiftRegister().GetCode() << 8)); 3186 return; 3187 } 3188 } 3189 } 3190 Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand); 3191 } 3192 3193 void Assembler::bkpt(Condition cond, uint32_t imm) { 3194 VIXL_ASSERT(AllowAssembler()); 3195 CheckIT(cond); 3196 if (IsUsingT32()) { 3197 // BKPT{<q>} {#}<imm> ; T1 3198 if ((imm <= 255)) { 3199 EmitT32_16(0xbe00 | imm); 3200 AdvanceIT(); 3201 return; 3202 } 3203 } else { 3204 // BKPT{<q>} {#}<imm> ; A1 3205 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 3206 EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) | 3207 ((imm & 0xfff0) << 4)); 3208 return; 3209 } 3210 } 3211 Delegate(kBkpt, &Assembler::bkpt, cond, imm); 3212 } 3213 3214 void Assembler::bl(Condition cond, Label* label) { 3215 VIXL_ASSERT(AllowAssembler()); 3216 CheckIT(cond); 3217 Label::Offset offset = 3218 label->IsBound() 3219 ? label->GetLocation() - 3220 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3221 : 0; 3222 if (IsUsingT32()) { 3223 // BL{<c>}{<q>} <label> ; T1 3224 if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) && 3225 ((offset & 0x1) == 0)) || 3226 !label->IsBound())) { 3227 static class EmitOp : public Label::LabelEmitOperator { 3228 public: 3229 EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {} 3230 virtual uint32_t Encode(uint32_t instr, 3231 Label::Offset pc, 3232 const Label* label) const VIXL_OVERRIDE { 3233 Label::Offset offset = label->GetLocation() - pc; 3234 VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) && 3235 ((offset & 0x1) == 0)); 3236 int32_t target = offset >> 1; 3237 uint32_t S = target & (1 << 23); 3238 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21); 3239 return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) | 3240 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) | 3241 ((target & 0x800000) << 3); 3242 } 3243 } immop; 3244 EmitT32_32(Link(0xf000d000U, label, immop)); 3245 AdvanceIT(); 3246 return; 3247 } 3248 } else { 3249 // BL{<c>}{<q>} <label> ; A1 3250 if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) && 3251 ((offset & 0x3) == 0)) || 3252 !label->IsBound()) && 3253 cond.IsNotNever()) { 3254 static class EmitOp : public Label::LabelEmitOperator { 3255 public: 3256 EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {} 3257 virtual uint32_t Encode(uint32_t instr, 3258 Label::Offset pc, 3259 const Label* label) const VIXL_OVERRIDE { 3260 Label::Offset offset = label->GetLocation() - pc; 3261 VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) && 3262 ((offset & 0x3) == 0)); 3263 const int32_t target = offset >> 2; 3264 return instr | (target & 0xffffff); 3265 } 3266 } immop; 3267 EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28), label, immop)); 3268 return; 3269 } 3270 } 3271 Delegate(kBl, &Assembler::bl, cond, label); 3272 } 3273 3274 void Assembler::blx(Condition cond, Label* label) { 3275 VIXL_ASSERT(AllowAssembler()); 3276 CheckIT(cond); 3277 Label::Offset offset = 3278 label->IsBound() 3279 ? label->GetLocation() - 3280 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 3281 : 0; 3282 if (IsUsingT32()) { 3283 // BLX{<c>}{<q>} <label> ; T2 3284 if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777212) && 3285 ((offset & 0x3) == 0)) || 3286 !label->IsBound())) { 3287 static class EmitOp : public Label::LabelEmitOperator { 3288 public: 3289 EmitOp() : Label::LabelEmitOperator(-16777216, 16777212) {} 3290 virtual uint32_t Encode(uint32_t instr, 3291 Label::Offset pc, 3292 const Label* label) const VIXL_OVERRIDE { 3293 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 3294 VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) && 3295 ((offset & 0x3) == 0)); 3296 int32_t target = offset >> 2; 3297 uint32_t S = target & (1 << 22); 3298 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20); 3299 return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) | 3300 ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) | 3301 ((target & 0x400000) << 4); 3302 } 3303 } immop; 3304 EmitT32_32(Link(0xf000c000U, label, immop)); 3305 AdvanceIT(); 3306 return; 3307 } 3308 } else { 3309 // BLX{<c>}{<q>} <label> ; A2 3310 if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554430) && 3311 ((offset & 0x1) == 0)) || 3312 !label->IsBound())) { 3313 if (cond.Is(al) || AllowStronglyDiscouraged()) { 3314 static class EmitOp : public Label::LabelEmitOperator { 3315 public: 3316 EmitOp() : Label::LabelEmitOperator(-33554432, 33554430) {} 3317 virtual uint32_t Encode(uint32_t instr, 3318 Label::Offset pc, 3319 const Label* label) const VIXL_OVERRIDE { 3320 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 3321 VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) && 3322 ((offset & 0x1) == 0)); 3323 const int32_t target = offset >> 1; 3324 return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1); 3325 } 3326 } immop; 3327 EmitA32(Link(0xfa000000U, label, immop)); 3328 return; 3329 } 3330 } 3331 } 3332 Delegate(kBlx, &Assembler::blx, cond, label); 3333 } 3334 3335 void Assembler::blx(Condition cond, Register rm) { 3336 VIXL_ASSERT(AllowAssembler()); 3337 CheckIT(cond); 3338 if (IsUsingT32()) { 3339 // BLX{<c>}{<q>} <Rm> ; T1 3340 EmitT32_16(0x4780 | (rm.GetCode() << 3)); 3341 AdvanceIT(); 3342 return; 3343 } else { 3344 // BLX{<c>}{<q>} <Rm> ; A1 3345 if (cond.IsNotNever()) { 3346 EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode()); 3347 return; 3348 } 3349 } 3350 Delegate(kBlx, &Assembler::blx, cond, rm); 3351 } 3352 3353 void Assembler::bx(Condition cond, Register rm) { 3354 VIXL_ASSERT(AllowAssembler()); 3355 CheckIT(cond); 3356 if (IsUsingT32()) { 3357 // BX{<c>}{<q>} <Rm> ; T1 3358 EmitT32_16(0x4700 | (rm.GetCode() << 3)); 3359 AdvanceIT(); 3360 return; 3361 } else { 3362 // BX{<c>}{<q>} <Rm> ; A1 3363 if (cond.IsNotNever()) { 3364 EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode()); 3365 return; 3366 } 3367 } 3368 Delegate(kBx, &Assembler::bx, cond, rm); 3369 } 3370 3371 void Assembler::bxj(Condition cond, Register rm) { 3372 VIXL_ASSERT(AllowAssembler()); 3373 CheckIT(cond); 3374 if (IsUsingT32()) { 3375 // BXJ{<c>}{<q>} <Rm> ; T1 3376 EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16)); 3377 AdvanceIT(); 3378 return; 3379 } else { 3380 // BXJ{<c>}{<q>} <Rm> ; A1 3381 if (cond.IsNotNever()) { 3382 EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode()); 3383 return; 3384 } 3385 } 3386 Delegate(kBxj, &Assembler::bxj, cond, rm); 3387 } 3388 3389 void Assembler::cbnz(Register rn, Label* label) { 3390 VIXL_ASSERT(AllowAssembler()); 3391 CheckIT(al); 3392 Label::Offset offset = 3393 label->IsBound() 3394 ? label->GetLocation() - 3395 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3396 : 0; 3397 if (IsUsingT32()) { 3398 // CBNZ{<q>} <Rn>, <label> ; T1 3399 if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) && 3400 ((offset & 0x1) == 0)) || 3401 !label->IsBound())) { 3402 static class EmitOp : public Label::LabelEmitOperator { 3403 public: 3404 EmitOp() : Label::LabelEmitOperator(0, 126) {} 3405 virtual uint32_t Encode(uint32_t instr, 3406 Label::Offset pc, 3407 const Label* label) const VIXL_OVERRIDE { 3408 Label::Offset offset = label->GetLocation() - pc; 3409 VIXL_ASSERT((offset >= 0) && (offset <= 126) && 3410 ((offset & 0x1) == 0)); 3411 const int32_t target = offset >> 1; 3412 return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4); 3413 } 3414 } immop; 3415 EmitT32_16(Link(0xb900 | rn.GetCode(), label, immop)); 3416 AdvanceIT(); 3417 return; 3418 } 3419 } 3420 Delegate(kCbnz, &Assembler::cbnz, rn, label); 3421 } 3422 3423 void Assembler::cbz(Register rn, Label* label) { 3424 VIXL_ASSERT(AllowAssembler()); 3425 CheckIT(al); 3426 Label::Offset offset = 3427 label->IsBound() 3428 ? label->GetLocation() - 3429 (GetCursorOffset() + GetArchitectureStatePCOffset()) 3430 : 0; 3431 if (IsUsingT32()) { 3432 // CBZ{<q>} <Rn>, <label> ; T1 3433 if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) && 3434 ((offset & 0x1) == 0)) || 3435 !label->IsBound())) { 3436 static class EmitOp : public Label::LabelEmitOperator { 3437 public: 3438 EmitOp() : Label::LabelEmitOperator(0, 126) {} 3439 virtual uint32_t Encode(uint32_t instr, 3440 Label::Offset pc, 3441 const Label* label) const VIXL_OVERRIDE { 3442 Label::Offset offset = label->GetLocation() - pc; 3443 VIXL_ASSERT((offset >= 0) && (offset <= 126) && 3444 ((offset & 0x1) == 0)); 3445 const int32_t target = offset >> 1; 3446 return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4); 3447 } 3448 } immop; 3449 EmitT32_16(Link(0xb100 | rn.GetCode(), label, immop)); 3450 AdvanceIT(); 3451 return; 3452 } 3453 } 3454 Delegate(kCbz, &Assembler::cbz, rn, label); 3455 } 3456 3457 void Assembler::clrex(Condition cond) { 3458 VIXL_ASSERT(AllowAssembler()); 3459 CheckIT(cond); 3460 if (IsUsingT32()) { 3461 // CLREX{<c>}{<q>} ; T1 3462 EmitT32_32(0xf3bf8f2fU); 3463 AdvanceIT(); 3464 return; 3465 } else { 3466 // CLREX{<c>}{<q>} ; A1 3467 if (cond.Is(al)) { 3468 EmitA32(0xf57ff01fU); 3469 return; 3470 } 3471 } 3472 Delegate(kClrex, &Assembler::clrex, cond); 3473 } 3474 3475 void Assembler::clz(Condition cond, Register rd, Register rm) { 3476 VIXL_ASSERT(AllowAssembler()); 3477 CheckIT(cond); 3478 if (IsUsingT32()) { 3479 // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1 3480 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3481 EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() | 3482 (rm.GetCode() << 16)); 3483 AdvanceIT(); 3484 return; 3485 } 3486 } else { 3487 // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1 3488 if (cond.IsNotNever() && 3489 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 3490 EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3491 rm.GetCode()); 3492 return; 3493 } 3494 } 3495 Delegate(kClz, &Assembler::clz, cond, rd, rm); 3496 } 3497 3498 void Assembler::cmn(Condition cond, 3499 EncodingSize size, 3500 Register rn, 3501 const Operand& operand) { 3502 VIXL_ASSERT(AllowAssembler()); 3503 CheckIT(cond); 3504 if (operand.IsImmediate()) { 3505 uint32_t imm = operand.GetImmediate(); 3506 if (IsUsingT32()) { 3507 ImmediateT32 immediate_t32(imm); 3508 // CMN{<c>}{<q>} <Rn>, #<const> ; T1 3509 if (!size.IsNarrow() && immediate_t32.IsValid()) { 3510 EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) | 3511 (immediate_t32.GetEncodingValue() & 0xff) | 3512 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3513 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3514 AdvanceIT(); 3515 return; 3516 } 3517 } else { 3518 ImmediateA32 immediate_a32(imm); 3519 // CMN{<c>}{<q>} <Rn>, #<const> ; A1 3520 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3521 EmitA32(0x03700000U | (cond.GetCondition() << 28) | 3522 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 3523 return; 3524 } 3525 } 3526 } 3527 if (operand.IsImmediateShiftedRegister()) { 3528 Register rm = operand.GetBaseRegister(); 3529 if (operand.IsPlainRegister()) { 3530 if (IsUsingT32()) { 3531 // CMN{<c>}{<q>} <Rn>, <Rm> ; T1 3532 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 3533 EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3)); 3534 AdvanceIT(); 3535 return; 3536 } 3537 } 3538 } 3539 Shift shift = operand.GetShift(); 3540 uint32_t amount = operand.GetShiftAmount(); 3541 if (IsUsingT32()) { 3542 // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2 3543 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 3544 uint32_t amount_ = amount % 32; 3545 EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() | 3546 (operand.GetTypeEncodingValue() << 4) | 3547 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3548 AdvanceIT(); 3549 return; 3550 } 3551 } else { 3552 // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 3553 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3554 uint32_t amount_ = amount % 32; 3555 EmitA32(0x01700000U | (cond.GetCondition() << 28) | 3556 (rn.GetCode() << 16) | rm.GetCode() | 3557 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3558 return; 3559 } 3560 } 3561 } 3562 if (operand.IsRegisterShiftedRegister()) { 3563 Register rm = operand.GetBaseRegister(); 3564 Shift shift = operand.GetShift(); 3565 if (IsUsingA32()) { 3566 // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 3567 if (cond.IsNotNever()) { 3568 EmitA32(0x01700010U | (cond.GetCondition() << 28) | 3569 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 3570 (operand.GetShiftRegister().GetCode() << 8)); 3571 return; 3572 } 3573 } 3574 } 3575 Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand); 3576 } 3577 3578 void Assembler::cmp(Condition cond, 3579 EncodingSize size, 3580 Register rn, 3581 const Operand& operand) { 3582 VIXL_ASSERT(AllowAssembler()); 3583 CheckIT(cond); 3584 if (operand.IsImmediate()) { 3585 uint32_t imm = operand.GetImmediate(); 3586 if (IsUsingT32()) { 3587 ImmediateT32 immediate_t32(imm); 3588 // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1 3589 if (!size.IsWide() && rn.IsLow() && (imm <= 255)) { 3590 EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm); 3591 AdvanceIT(); 3592 return; 3593 } 3594 // CMP{<c>}{<q>} <Rn>, #<const> ; T2 3595 if (!size.IsNarrow() && immediate_t32.IsValid()) { 3596 EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) | 3597 (immediate_t32.GetEncodingValue() & 0xff) | 3598 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3599 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3600 AdvanceIT(); 3601 return; 3602 } 3603 } else { 3604 ImmediateA32 immediate_a32(imm); 3605 // CMP{<c>}{<q>} <Rn>, #<const> ; A1 3606 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3607 EmitA32(0x03500000U | (cond.GetCondition() << 28) | 3608 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 3609 return; 3610 } 3611 } 3612 } 3613 if (operand.IsImmediateShiftedRegister()) { 3614 Register rm = operand.GetBaseRegister(); 3615 if (operand.IsPlainRegister()) { 3616 if (IsUsingT32()) { 3617 // CMP{<c>}{<q>} <Rn>, <Rm> ; T1 3618 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 3619 EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3)); 3620 AdvanceIT(); 3621 return; 3622 } 3623 // CMP{<c>}{<q>} <Rn>, <Rm> ; T2 3624 if (!size.IsWide()) { 3625 EmitT32_16(0x4500 | (rn.GetCode() & 0x7) | 3626 ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 3627 AdvanceIT(); 3628 return; 3629 } 3630 } 3631 } 3632 Shift shift = operand.GetShift(); 3633 uint32_t amount = operand.GetShiftAmount(); 3634 if (IsUsingT32()) { 3635 // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3 3636 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 3637 uint32_t amount_ = amount % 32; 3638 EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() | 3639 (operand.GetTypeEncodingValue() << 4) | 3640 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3641 AdvanceIT(); 3642 return; 3643 } 3644 } else { 3645 // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 3646 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3647 uint32_t amount_ = amount % 32; 3648 EmitA32(0x01500000U | (cond.GetCondition() << 28) | 3649 (rn.GetCode() << 16) | rm.GetCode() | 3650 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3651 return; 3652 } 3653 } 3654 } 3655 if (operand.IsRegisterShiftedRegister()) { 3656 Register rm = operand.GetBaseRegister(); 3657 Shift shift = operand.GetShift(); 3658 if (IsUsingA32()) { 3659 // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 3660 if (cond.IsNotNever()) { 3661 EmitA32(0x01500010U | (cond.GetCondition() << 28) | 3662 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 3663 (operand.GetShiftRegister().GetCode() << 8)); 3664 return; 3665 } 3666 } 3667 } 3668 Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand); 3669 } 3670 3671 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) { 3672 VIXL_ASSERT(AllowAssembler()); 3673 CheckIT(cond); 3674 if (IsUsingT32()) { 3675 // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1 3676 EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3677 rm.GetCode()); 3678 AdvanceIT(); 3679 return; 3680 } else { 3681 // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1 3682 if ((cond.Is(al) || AllowUnpredictable())) { 3683 EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3684 (rn.GetCode() << 16) | rm.GetCode()); 3685 return; 3686 } 3687 } 3688 Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm); 3689 } 3690 3691 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) { 3692 VIXL_ASSERT(AllowAssembler()); 3693 CheckIT(cond); 3694 if (IsUsingT32()) { 3695 // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1 3696 EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3697 rm.GetCode()); 3698 AdvanceIT(); 3699 return; 3700 } else { 3701 // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1 3702 if ((cond.Is(al) || AllowUnpredictable())) { 3703 EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3704 (rn.GetCode() << 16) | rm.GetCode()); 3705 return; 3706 } 3707 } 3708 Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm); 3709 } 3710 3711 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) { 3712 VIXL_ASSERT(AllowAssembler()); 3713 CheckIT(cond); 3714 if (IsUsingT32()) { 3715 // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1 3716 EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3717 rm.GetCode()); 3718 AdvanceIT(); 3719 return; 3720 } else { 3721 // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1 3722 if ((cond.Is(al) || AllowUnpredictable())) { 3723 EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3724 (rn.GetCode() << 16) | rm.GetCode()); 3725 return; 3726 } 3727 } 3728 Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm); 3729 } 3730 3731 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) { 3732 VIXL_ASSERT(AllowAssembler()); 3733 CheckIT(cond); 3734 if (IsUsingT32()) { 3735 // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1 3736 EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3737 rm.GetCode()); 3738 AdvanceIT(); 3739 return; 3740 } else { 3741 // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1 3742 if ((cond.Is(al) || AllowUnpredictable())) { 3743 EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3744 (rn.GetCode() << 16) | rm.GetCode()); 3745 return; 3746 } 3747 } 3748 Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm); 3749 } 3750 3751 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) { 3752 VIXL_ASSERT(AllowAssembler()); 3753 CheckIT(cond); 3754 if (IsUsingT32()) { 3755 // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1 3756 EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3757 rm.GetCode()); 3758 AdvanceIT(); 3759 return; 3760 } else { 3761 // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1 3762 if ((cond.Is(al) || AllowUnpredictable())) { 3763 EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3764 (rn.GetCode() << 16) | rm.GetCode()); 3765 return; 3766 } 3767 } 3768 Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm); 3769 } 3770 3771 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) { 3772 VIXL_ASSERT(AllowAssembler()); 3773 CheckIT(cond); 3774 if (IsUsingT32()) { 3775 // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1 3776 EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3777 rm.GetCode()); 3778 AdvanceIT(); 3779 return; 3780 } else { 3781 // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1 3782 if ((cond.Is(al) || AllowUnpredictable())) { 3783 EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 3784 (rn.GetCode() << 16) | rm.GetCode()); 3785 return; 3786 } 3787 } 3788 Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm); 3789 } 3790 3791 void Assembler::dmb(Condition cond, MemoryBarrier option) { 3792 VIXL_ASSERT(AllowAssembler()); 3793 CheckIT(cond); 3794 if (IsUsingT32()) { 3795 // DMB{<c>}{<q>} {<option>} ; T1 3796 EmitT32_32(0xf3bf8f50U | option.GetType()); 3797 AdvanceIT(); 3798 return; 3799 } else { 3800 // DMB{<c>}{<q>} {<option>} ; A1 3801 if (cond.Is(al)) { 3802 EmitA32(0xf57ff050U | option.GetType()); 3803 return; 3804 } 3805 } 3806 Delegate(kDmb, &Assembler::dmb, cond, option); 3807 } 3808 3809 void Assembler::dsb(Condition cond, MemoryBarrier option) { 3810 VIXL_ASSERT(AllowAssembler()); 3811 CheckIT(cond); 3812 if (IsUsingT32()) { 3813 // DSB{<c>}{<q>} {<option>} ; T1 3814 EmitT32_32(0xf3bf8f40U | option.GetType()); 3815 AdvanceIT(); 3816 return; 3817 } else { 3818 // DSB{<c>}{<q>} {<option>} ; A1 3819 if (cond.Is(al)) { 3820 EmitA32(0xf57ff040U | option.GetType()); 3821 return; 3822 } 3823 } 3824 Delegate(kDsb, &Assembler::dsb, cond, option); 3825 } 3826 3827 void Assembler::eor(Condition cond, 3828 EncodingSize size, 3829 Register rd, 3830 Register rn, 3831 const Operand& operand) { 3832 VIXL_ASSERT(AllowAssembler()); 3833 CheckIT(cond); 3834 if (operand.IsImmediate()) { 3835 uint32_t imm = operand.GetImmediate(); 3836 if (IsUsingT32()) { 3837 ImmediateT32 immediate_t32(imm); 3838 // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 3839 if (!size.IsNarrow() && immediate_t32.IsValid()) { 3840 EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3841 (immediate_t32.GetEncodingValue() & 0xff) | 3842 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3843 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3844 AdvanceIT(); 3845 return; 3846 } 3847 } else { 3848 ImmediateA32 immediate_a32(imm); 3849 // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 3850 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3851 EmitA32(0x02200000U | (cond.GetCondition() << 28) | 3852 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 3853 immediate_a32.GetEncodingValue()); 3854 return; 3855 } 3856 } 3857 } 3858 if (operand.IsImmediateShiftedRegister()) { 3859 Register rm = operand.GetBaseRegister(); 3860 if (operand.IsPlainRegister()) { 3861 if (IsUsingT32()) { 3862 // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 3863 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 3864 rm.IsLow()) { 3865 EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3)); 3866 AdvanceIT(); 3867 return; 3868 } 3869 } 3870 } 3871 Shift shift = operand.GetShift(); 3872 uint32_t amount = operand.GetShiftAmount(); 3873 if (IsUsingT32()) { 3874 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 3875 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 3876 uint32_t amount_ = amount % 32; 3877 EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3878 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 3879 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3880 AdvanceIT(); 3881 return; 3882 } 3883 } else { 3884 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 3885 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3886 uint32_t amount_ = amount % 32; 3887 EmitA32(0x00200000U | (cond.GetCondition() << 28) | 3888 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3889 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3890 return; 3891 } 3892 } 3893 } 3894 if (operand.IsRegisterShiftedRegister()) { 3895 Register rm = operand.GetBaseRegister(); 3896 Shift shift = operand.GetShift(); 3897 if (IsUsingA32()) { 3898 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 3899 if (cond.IsNotNever()) { 3900 EmitA32(0x00200010U | (cond.GetCondition() << 28) | 3901 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3902 (shift.GetType() << 5) | 3903 (operand.GetShiftRegister().GetCode() << 8)); 3904 return; 3905 } 3906 } 3907 } 3908 Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand); 3909 } 3910 3911 void Assembler::eors(Condition cond, 3912 EncodingSize size, 3913 Register rd, 3914 Register rn, 3915 const Operand& operand) { 3916 VIXL_ASSERT(AllowAssembler()); 3917 CheckIT(cond); 3918 if (operand.IsImmediate()) { 3919 uint32_t imm = operand.GetImmediate(); 3920 if (IsUsingT32()) { 3921 ImmediateT32 immediate_t32(imm); 3922 // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 3923 if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) { 3924 EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3925 (immediate_t32.GetEncodingValue() & 0xff) | 3926 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 3927 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 3928 AdvanceIT(); 3929 return; 3930 } 3931 } else { 3932 ImmediateA32 immediate_a32(imm); 3933 // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 3934 if (immediate_a32.IsValid() && cond.IsNotNever()) { 3935 EmitA32(0x02300000U | (cond.GetCondition() << 28) | 3936 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 3937 immediate_a32.GetEncodingValue()); 3938 return; 3939 } 3940 } 3941 } 3942 if (operand.IsImmediateShiftedRegister()) { 3943 Register rm = operand.GetBaseRegister(); 3944 if (operand.IsPlainRegister()) { 3945 if (IsUsingT32()) { 3946 // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 3947 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 3948 rm.IsLow()) { 3949 EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3)); 3950 AdvanceIT(); 3951 return; 3952 } 3953 } 3954 } 3955 Shift shift = operand.GetShift(); 3956 uint32_t amount = operand.GetShiftAmount(); 3957 if (IsUsingT32()) { 3958 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 3959 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) { 3960 uint32_t amount_ = amount % 32; 3961 EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 3962 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 3963 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 3964 AdvanceIT(); 3965 return; 3966 } 3967 } else { 3968 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 3969 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 3970 uint32_t amount_ = amount % 32; 3971 EmitA32(0x00300000U | (cond.GetCondition() << 28) | 3972 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3973 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 3974 return; 3975 } 3976 } 3977 } 3978 if (operand.IsRegisterShiftedRegister()) { 3979 Register rm = operand.GetBaseRegister(); 3980 Shift shift = operand.GetShift(); 3981 if (IsUsingA32()) { 3982 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 3983 if (cond.IsNotNever()) { 3984 EmitA32(0x00300010U | (cond.GetCondition() << 28) | 3985 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 3986 (shift.GetType() << 5) | 3987 (operand.GetShiftRegister().GetCode() << 8)); 3988 return; 3989 } 3990 } 3991 } 3992 Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand); 3993 } 3994 3995 void Assembler::fldmdbx(Condition cond, 3996 Register rn, 3997 WriteBack write_back, 3998 DRegisterList dreglist) { 3999 VIXL_ASSERT(AllowAssembler()); 4000 CheckIT(cond); 4001 if (IsUsingT32()) { 4002 // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1 4003 if (write_back.DoesWriteBack() && 4004 (((dreglist.GetLength() <= 16) && 4005 (dreglist.GetLastDRegister().GetCode() < 16)) || 4006 AllowUnpredictable())) { 4007 const DRegister& dreg = dreglist.GetFirstDRegister(); 4008 unsigned len = dreglist.GetLength() * 2; 4009 EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 4010 (len & 0xff)); 4011 AdvanceIT(); 4012 return; 4013 } 4014 } else { 4015 // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1 4016 if (write_back.DoesWriteBack() && cond.IsNotNever() && 4017 (((dreglist.GetLength() <= 16) && 4018 (dreglist.GetLastDRegister().GetCode() < 16)) || 4019 AllowUnpredictable())) { 4020 const DRegister& dreg = dreglist.GetFirstDRegister(); 4021 unsigned len = dreglist.GetLength() * 2; 4022 EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4023 dreg.Encode(22, 12) | (len & 0xff)); 4024 return; 4025 } 4026 } 4027 Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist); 4028 } 4029 4030 void Assembler::fldmiax(Condition cond, 4031 Register rn, 4032 WriteBack write_back, 4033 DRegisterList dreglist) { 4034 VIXL_ASSERT(AllowAssembler()); 4035 CheckIT(cond); 4036 if (IsUsingT32()) { 4037 // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1 4038 if ((((dreglist.GetLength() <= 16) && 4039 (dreglist.GetLastDRegister().GetCode() < 16)) || 4040 AllowUnpredictable())) { 4041 const DRegister& dreg = dreglist.GetFirstDRegister(); 4042 unsigned len = dreglist.GetLength() * 2; 4043 EmitT32_32(0xec900b01U | (rn.GetCode() << 16) | 4044 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4045 (len & 0xff)); 4046 AdvanceIT(); 4047 return; 4048 } 4049 } else { 4050 // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1 4051 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 4052 (dreglist.GetLastDRegister().GetCode() < 16)) || 4053 AllowUnpredictable())) { 4054 const DRegister& dreg = dreglist.GetFirstDRegister(); 4055 unsigned len = dreglist.GetLength() * 2; 4056 EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4057 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4058 (len & 0xff)); 4059 return; 4060 } 4061 } 4062 Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist); 4063 } 4064 4065 void Assembler::fstmdbx(Condition cond, 4066 Register rn, 4067 WriteBack write_back, 4068 DRegisterList dreglist) { 4069 VIXL_ASSERT(AllowAssembler()); 4070 CheckIT(cond); 4071 if (IsUsingT32()) { 4072 // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1 4073 if (write_back.DoesWriteBack() && 4074 (((dreglist.GetLength() <= 16) && 4075 (dreglist.GetLastDRegister().GetCode() < 16)) || 4076 AllowUnpredictable())) { 4077 const DRegister& dreg = dreglist.GetFirstDRegister(); 4078 unsigned len = dreglist.GetLength() * 2; 4079 EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 4080 (len & 0xff)); 4081 AdvanceIT(); 4082 return; 4083 } 4084 } else { 4085 // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1 4086 if (write_back.DoesWriteBack() && cond.IsNotNever() && 4087 (((dreglist.GetLength() <= 16) && 4088 (dreglist.GetLastDRegister().GetCode() < 16)) || 4089 AllowUnpredictable())) { 4090 const DRegister& dreg = dreglist.GetFirstDRegister(); 4091 unsigned len = dreglist.GetLength() * 2; 4092 EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4093 dreg.Encode(22, 12) | (len & 0xff)); 4094 return; 4095 } 4096 } 4097 Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist); 4098 } 4099 4100 void Assembler::fstmiax(Condition cond, 4101 Register rn, 4102 WriteBack write_back, 4103 DRegisterList dreglist) { 4104 VIXL_ASSERT(AllowAssembler()); 4105 CheckIT(cond); 4106 if (IsUsingT32()) { 4107 // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1 4108 if ((((dreglist.GetLength() <= 16) && 4109 (dreglist.GetLastDRegister().GetCode() < 16)) || 4110 AllowUnpredictable())) { 4111 const DRegister& dreg = dreglist.GetFirstDRegister(); 4112 unsigned len = dreglist.GetLength() * 2; 4113 EmitT32_32(0xec800b01U | (rn.GetCode() << 16) | 4114 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4115 (len & 0xff)); 4116 AdvanceIT(); 4117 return; 4118 } 4119 } else { 4120 // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1 4121 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) && 4122 (dreglist.GetLastDRegister().GetCode() < 16)) || 4123 AllowUnpredictable())) { 4124 const DRegister& dreg = dreglist.GetFirstDRegister(); 4125 unsigned len = dreglist.GetLength() * 2; 4126 EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4127 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 4128 (len & 0xff)); 4129 return; 4130 } 4131 } 4132 Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist); 4133 } 4134 4135 void Assembler::hlt(Condition cond, uint32_t imm) { 4136 VIXL_ASSERT(AllowAssembler()); 4137 CheckIT(cond); 4138 if (IsUsingT32()) { 4139 // HLT{<q>} {#}<imm> ; T1 4140 if ((imm <= 63)) { 4141 EmitT32_16(0xba80 | imm); 4142 AdvanceIT(); 4143 return; 4144 } 4145 } else { 4146 // HLT{<q>} {#}<imm> ; A1 4147 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 4148 EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) | 4149 ((imm & 0xfff0) << 4)); 4150 return; 4151 } 4152 } 4153 Delegate(kHlt, &Assembler::hlt, cond, imm); 4154 } 4155 4156 void Assembler::hvc(Condition cond, uint32_t imm) { 4157 VIXL_ASSERT(AllowAssembler()); 4158 CheckIT(cond); 4159 if (IsUsingT32()) { 4160 // HVC{<q>} {#}<imm16> ; T1 4161 if ((imm <= 65535)) { 4162 EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4)); 4163 AdvanceIT(); 4164 return; 4165 } 4166 } else { 4167 // HVC{<q>} {#}<imm16> ; A1 4168 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) { 4169 EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) | 4170 ((imm & 0xfff0) << 4)); 4171 return; 4172 } 4173 } 4174 Delegate(kHvc, &Assembler::hvc, cond, imm); 4175 } 4176 4177 void Assembler::isb(Condition cond, MemoryBarrier option) { 4178 VIXL_ASSERT(AllowAssembler()); 4179 CheckIT(cond); 4180 if (IsUsingT32()) { 4181 // ISB{<c>}{<q>} {<option>} ; T1 4182 EmitT32_32(0xf3bf8f60U | option.GetType()); 4183 AdvanceIT(); 4184 return; 4185 } else { 4186 // ISB{<c>}{<q>} {<option>} ; A1 4187 if (cond.Is(al)) { 4188 EmitA32(0xf57ff060U | option.GetType()); 4189 return; 4190 } 4191 } 4192 Delegate(kIsb, &Assembler::isb, cond, option); 4193 } 4194 4195 void Assembler::it(Condition cond, uint16_t mask) { 4196 VIXL_ASSERT(AllowAssembler()); 4197 CheckNotIT(); 4198 if (mask != 0) { 4199 if ((cond.GetCondition() & 0x1) != 0) { 4200 if ((mask & 0x1) != 0) { 4201 mask ^= 0xE; 4202 } else if ((mask & 0x2) != 0) { 4203 mask ^= 0xC; 4204 } else if ((mask & 0x4) != 0) { 4205 mask ^= 0x8; 4206 } 4207 } 4208 if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask); 4209 SetIT(cond, mask); 4210 return; 4211 } 4212 DelegateIt(cond, mask); 4213 } 4214 4215 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) { 4216 VIXL_ASSERT(AllowAssembler()); 4217 CheckIT(cond); 4218 if (operand.IsImmediateZero()) { 4219 Register rn = operand.GetBaseRegister(); 4220 if (IsUsingT32()) { 4221 // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1 4222 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 4223 EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4224 AdvanceIT(); 4225 return; 4226 } 4227 } else { 4228 // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1 4229 if (operand.IsOffset() && cond.IsNotNever() && 4230 (!rn.IsPC() || AllowUnpredictable())) { 4231 EmitA32(0x01900c9fU | (cond.GetCondition() << 28) | 4232 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4233 return; 4234 } 4235 } 4236 } 4237 Delegate(kLda, &Assembler::lda, cond, rt, operand); 4238 } 4239 4240 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) { 4241 VIXL_ASSERT(AllowAssembler()); 4242 CheckIT(cond); 4243 if (operand.IsImmediateZero()) { 4244 Register rn = operand.GetBaseRegister(); 4245 if (IsUsingT32()) { 4246 // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1 4247 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 4248 EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4249 AdvanceIT(); 4250 return; 4251 } 4252 } else { 4253 // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1 4254 if (operand.IsOffset() && cond.IsNotNever() && 4255 (!rn.IsPC() || AllowUnpredictable())) { 4256 EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) | 4257 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4258 return; 4259 } 4260 } 4261 } 4262 Delegate(kLdab, &Assembler::ldab, cond, rt, operand); 4263 } 4264 4265 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) { 4266 VIXL_ASSERT(AllowAssembler()); 4267 CheckIT(cond); 4268 if (operand.IsImmediateZero()) { 4269 Register rn = operand.GetBaseRegister(); 4270 if (IsUsingT32()) { 4271 // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1 4272 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 4273 EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4274 AdvanceIT(); 4275 return; 4276 } 4277 } else { 4278 // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1 4279 if (operand.IsOffset() && cond.IsNotNever() && 4280 (!rn.IsPC() || AllowUnpredictable())) { 4281 EmitA32(0x01900e9fU | (cond.GetCondition() << 28) | 4282 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4283 return; 4284 } 4285 } 4286 } 4287 Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand); 4288 } 4289 4290 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) { 4291 VIXL_ASSERT(AllowAssembler()); 4292 CheckIT(cond); 4293 if (operand.IsImmediateZero()) { 4294 Register rn = operand.GetBaseRegister(); 4295 if (IsUsingT32()) { 4296 // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1 4297 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 4298 EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4299 AdvanceIT(); 4300 return; 4301 } 4302 } else { 4303 // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1 4304 if (operand.IsOffset() && cond.IsNotNever() && 4305 (!rn.IsPC() || AllowUnpredictable())) { 4306 EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) | 4307 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4308 return; 4309 } 4310 } 4311 } 4312 Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand); 4313 } 4314 4315 void Assembler::ldaexd(Condition cond, 4316 Register rt, 4317 Register rt2, 4318 const MemOperand& operand) { 4319 VIXL_ASSERT(AllowAssembler()); 4320 CheckIT(cond); 4321 if (operand.IsImmediateZero()) { 4322 Register rn = operand.GetBaseRegister(); 4323 if (IsUsingT32()) { 4324 // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1 4325 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 4326 EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 4327 (rn.GetCode() << 16)); 4328 AdvanceIT(); 4329 return; 4330 } 4331 } else { 4332 // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1 4333 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 4334 operand.IsOffset() && cond.IsNotNever() && 4335 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) || 4336 AllowUnpredictable())) { 4337 EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) | 4338 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4339 return; 4340 } 4341 } 4342 } 4343 Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand); 4344 } 4345 4346 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) { 4347 VIXL_ASSERT(AllowAssembler()); 4348 CheckIT(cond); 4349 if (operand.IsImmediateZero()) { 4350 Register rn = operand.GetBaseRegister(); 4351 if (IsUsingT32()) { 4352 // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1 4353 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 4354 EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4355 AdvanceIT(); 4356 return; 4357 } 4358 } else { 4359 // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1 4360 if (operand.IsOffset() && cond.IsNotNever() && 4361 (!rn.IsPC() || AllowUnpredictable())) { 4362 EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) | 4363 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4364 return; 4365 } 4366 } 4367 } 4368 Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand); 4369 } 4370 4371 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) { 4372 VIXL_ASSERT(AllowAssembler()); 4373 CheckIT(cond); 4374 if (operand.IsImmediateZero()) { 4375 Register rn = operand.GetBaseRegister(); 4376 if (IsUsingT32()) { 4377 // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1 4378 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 4379 EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4380 AdvanceIT(); 4381 return; 4382 } 4383 } else { 4384 // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1 4385 if (operand.IsOffset() && cond.IsNotNever() && 4386 (!rn.IsPC() || AllowUnpredictable())) { 4387 EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) | 4388 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 4389 return; 4390 } 4391 } 4392 } 4393 Delegate(kLdah, &Assembler::ldah, cond, rt, operand); 4394 } 4395 4396 void Assembler::ldm(Condition cond, 4397 EncodingSize size, 4398 Register rn, 4399 WriteBack write_back, 4400 RegisterList registers) { 4401 VIXL_ASSERT(AllowAssembler()); 4402 CheckIT(cond); 4403 if (IsUsingT32()) { 4404 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1 4405 if (!size.IsWide() && rn.IsLow() && 4406 (((registers.GetList() & (1 << rn.GetCode())) == 0) == 4407 write_back.DoesWriteBack()) && 4408 ((registers.GetList() & ~0xff) == 0)) { 4409 EmitT32_16(0xc800 | (rn.GetCode() << 8) | 4410 GetRegisterListEncoding(registers, 0, 8)); 4411 AdvanceIT(); 4412 return; 4413 } 4414 // LDM{<c>}{<q>} SP!, <registers> ; T1 4415 if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() && 4416 ((registers.GetList() & ~0x80ff) == 0)) { 4417 EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) | 4418 GetRegisterListEncoding(registers, 0, 8)); 4419 AdvanceIT(); 4420 return; 4421 } 4422 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2 4423 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) { 4424 EmitT32_32(0xe8900000U | (rn.GetCode() << 16) | 4425 (write_back.GetWriteBackUint32() << 21) | 4426 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4427 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4428 GetRegisterListEncoding(registers, 0, 13)); 4429 AdvanceIT(); 4430 return; 4431 } 4432 } else { 4433 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1 4434 if (cond.IsNotNever()) { 4435 EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4436 (write_back.GetWriteBackUint32() << 21) | 4437 GetRegisterListEncoding(registers, 0, 16)); 4438 return; 4439 } 4440 } 4441 Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers); 4442 } 4443 4444 void Assembler::ldmda(Condition cond, 4445 Register rn, 4446 WriteBack write_back, 4447 RegisterList registers) { 4448 VIXL_ASSERT(AllowAssembler()); 4449 CheckIT(cond); 4450 if (IsUsingA32()) { 4451 // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4452 if (cond.IsNotNever()) { 4453 EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4454 (write_back.GetWriteBackUint32() << 21) | 4455 GetRegisterListEncoding(registers, 0, 16)); 4456 return; 4457 } 4458 } 4459 Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers); 4460 } 4461 4462 void Assembler::ldmdb(Condition cond, 4463 Register rn, 4464 WriteBack write_back, 4465 RegisterList registers) { 4466 VIXL_ASSERT(AllowAssembler()); 4467 CheckIT(cond); 4468 if (IsUsingT32()) { 4469 // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1 4470 if (((registers.GetList() & ~0xdfff) == 0)) { 4471 EmitT32_32(0xe9100000U | (rn.GetCode() << 16) | 4472 (write_back.GetWriteBackUint32() << 21) | 4473 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4474 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4475 GetRegisterListEncoding(registers, 0, 13)); 4476 AdvanceIT(); 4477 return; 4478 } 4479 } else { 4480 // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1 4481 if (cond.IsNotNever()) { 4482 EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4483 (write_back.GetWriteBackUint32() << 21) | 4484 GetRegisterListEncoding(registers, 0, 16)); 4485 return; 4486 } 4487 } 4488 Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers); 4489 } 4490 4491 void Assembler::ldmea(Condition cond, 4492 Register rn, 4493 WriteBack write_back, 4494 RegisterList registers) { 4495 VIXL_ASSERT(AllowAssembler()); 4496 CheckIT(cond); 4497 if (IsUsingT32()) { 4498 // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1 4499 if (((registers.GetList() & ~0xdfff) == 0)) { 4500 EmitT32_32(0xe9100000U | (rn.GetCode() << 16) | 4501 (write_back.GetWriteBackUint32() << 21) | 4502 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4503 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4504 GetRegisterListEncoding(registers, 0, 13)); 4505 AdvanceIT(); 4506 return; 4507 } 4508 } else { 4509 // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4510 if (cond.IsNotNever()) { 4511 EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4512 (write_back.GetWriteBackUint32() << 21) | 4513 GetRegisterListEncoding(registers, 0, 16)); 4514 return; 4515 } 4516 } 4517 Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers); 4518 } 4519 4520 void Assembler::ldmed(Condition cond, 4521 Register rn, 4522 WriteBack write_back, 4523 RegisterList registers) { 4524 VIXL_ASSERT(AllowAssembler()); 4525 CheckIT(cond); 4526 if (IsUsingA32()) { 4527 // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1 4528 if (cond.IsNotNever()) { 4529 EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4530 (write_back.GetWriteBackUint32() << 21) | 4531 GetRegisterListEncoding(registers, 0, 16)); 4532 return; 4533 } 4534 } 4535 Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers); 4536 } 4537 4538 void Assembler::ldmfa(Condition cond, 4539 Register rn, 4540 WriteBack write_back, 4541 RegisterList registers) { 4542 VIXL_ASSERT(AllowAssembler()); 4543 CheckIT(cond); 4544 if (IsUsingA32()) { 4545 // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1 4546 if (cond.IsNotNever()) { 4547 EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4548 (write_back.GetWriteBackUint32() << 21) | 4549 GetRegisterListEncoding(registers, 0, 16)); 4550 return; 4551 } 4552 } 4553 Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers); 4554 } 4555 4556 void Assembler::ldmfd(Condition cond, 4557 EncodingSize size, 4558 Register rn, 4559 WriteBack write_back, 4560 RegisterList registers) { 4561 VIXL_ASSERT(AllowAssembler()); 4562 CheckIT(cond); 4563 if (IsUsingT32()) { 4564 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1 4565 if (!size.IsWide() && rn.IsLow() && 4566 (((registers.GetList() & (1 << rn.GetCode())) == 0) == 4567 write_back.DoesWriteBack()) && 4568 ((registers.GetList() & ~0xff) == 0)) { 4569 EmitT32_16(0xc800 | (rn.GetCode() << 8) | 4570 GetRegisterListEncoding(registers, 0, 8)); 4571 AdvanceIT(); 4572 return; 4573 } 4574 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2 4575 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) { 4576 EmitT32_32(0xe8900000U | (rn.GetCode() << 16) | 4577 (write_back.GetWriteBackUint32() << 21) | 4578 (GetRegisterListEncoding(registers, 15, 1) << 15) | 4579 (GetRegisterListEncoding(registers, 14, 1) << 14) | 4580 GetRegisterListEncoding(registers, 0, 13)); 4581 AdvanceIT(); 4582 return; 4583 } 4584 } else { 4585 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1 4586 if (cond.IsNotNever()) { 4587 EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4588 (write_back.GetWriteBackUint32() << 21) | 4589 GetRegisterListEncoding(registers, 0, 16)); 4590 return; 4591 } 4592 } 4593 Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers); 4594 } 4595 4596 void Assembler::ldmib(Condition cond, 4597 Register rn, 4598 WriteBack write_back, 4599 RegisterList registers) { 4600 VIXL_ASSERT(AllowAssembler()); 4601 CheckIT(cond); 4602 if (IsUsingA32()) { 4603 // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1 4604 if (cond.IsNotNever()) { 4605 EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 4606 (write_back.GetWriteBackUint32() << 21) | 4607 GetRegisterListEncoding(registers, 0, 16)); 4608 return; 4609 } 4610 } 4611 Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers); 4612 } 4613 4614 void Assembler::ldr(Condition cond, 4615 EncodingSize size, 4616 Register rt, 4617 const MemOperand& operand) { 4618 VIXL_ASSERT(AllowAssembler()); 4619 CheckIT(cond); 4620 if (operand.IsImmediate()) { 4621 Register rn = operand.GetBaseRegister(); 4622 int32_t offset = operand.GetOffsetImmediate(); 4623 if (IsUsingT32()) { 4624 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 4625 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 4626 (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) { 4627 int32_t offset_ = offset >> 2; 4628 EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) | 4629 ((offset_ & 0x1f) << 6)); 4630 AdvanceIT(); 4631 return; 4632 } 4633 // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2 4634 if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) && 4635 ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) { 4636 int32_t offset_ = offset >> 2; 4637 EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff)); 4638 AdvanceIT(); 4639 return; 4640 } 4641 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3 4642 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 4643 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 4644 EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4645 (offset & 0xfff)); 4646 AdvanceIT(); 4647 return; 4648 } 4649 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4 4650 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 4651 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 4652 EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4653 (-offset & 0xff)); 4654 AdvanceIT(); 4655 return; 4656 } 4657 // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4 4658 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 4659 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 4660 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4661 uint32_t offset_ = abs(offset); 4662 EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4663 offset_ | (sign << 9)); 4664 AdvanceIT(); 4665 return; 4666 } 4667 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4 4668 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 4669 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 4670 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4671 uint32_t offset_ = abs(offset); 4672 EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4673 offset_ | (sign << 9)); 4674 AdvanceIT(); 4675 return; 4676 } 4677 // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2 4678 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 4679 rn.Is(pc) && operand.IsOffset()) { 4680 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4681 uint32_t offset_ = abs(offset); 4682 EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 4683 AdvanceIT(); 4684 return; 4685 } 4686 } else { 4687 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 4688 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 4689 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 4690 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4691 uint32_t offset_ = abs(offset); 4692 EmitA32(0x05100000U | (cond.GetCondition() << 28) | 4693 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 4694 (sign << 23)); 4695 return; 4696 } 4697 // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 4698 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 4699 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 4700 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4701 uint32_t offset_ = abs(offset); 4702 EmitA32(0x04100000U | (cond.GetCondition() << 28) | 4703 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 4704 (sign << 23)); 4705 return; 4706 } 4707 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 4708 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 4709 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 4710 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4711 uint32_t offset_ = abs(offset); 4712 EmitA32(0x05300000U | (cond.GetCondition() << 28) | 4713 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 4714 (sign << 23)); 4715 return; 4716 } 4717 // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 4718 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 4719 operand.IsOffset() && cond.IsNotNever()) { 4720 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4721 uint32_t offset_ = abs(offset); 4722 EmitA32(0x051f0000U | (cond.GetCondition() << 28) | 4723 (rt.GetCode() << 12) | offset_ | (sign << 23)); 4724 return; 4725 } 4726 } 4727 } 4728 if (operand.IsPlainRegister()) { 4729 Register rn = operand.GetBaseRegister(); 4730 Sign sign = operand.GetSign(); 4731 Register rm = operand.GetOffsetRegister(); 4732 if (IsUsingT32()) { 4733 // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 4734 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 4735 sign.IsPlus() && operand.IsOffset()) { 4736 EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) | 4737 (rm.GetCode() << 6)); 4738 AdvanceIT(); 4739 return; 4740 } 4741 } 4742 } 4743 if (operand.IsShiftedRegister()) { 4744 Register rn = operand.GetBaseRegister(); 4745 Sign sign = operand.GetSign(); 4746 Register rm = operand.GetOffsetRegister(); 4747 Shift shift = operand.GetShift(); 4748 uint32_t amount = operand.GetShiftAmount(); 4749 if (IsUsingT32()) { 4750 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 4751 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 4752 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 4753 EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4754 rm.GetCode() | (amount << 4)); 4755 AdvanceIT(); 4756 return; 4757 } 4758 } else { 4759 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 4760 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) { 4761 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 4762 uint32_t shift_ = TypeEncodingValue(shift); 4763 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 4764 EmitA32(0x07100000U | (cond.GetCondition() << 28) | 4765 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4766 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 4767 return; 4768 } 4769 // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 4770 if (operand.IsShiftValid() && operand.IsPostIndex() && 4771 cond.IsNotNever()) { 4772 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 4773 uint32_t shift_ = TypeEncodingValue(shift); 4774 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 4775 EmitA32(0x06100000U | (cond.GetCondition() << 28) | 4776 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4777 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 4778 return; 4779 } 4780 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 4781 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) { 4782 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 4783 uint32_t shift_ = TypeEncodingValue(shift); 4784 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 4785 EmitA32(0x07300000U | (cond.GetCondition() << 28) | 4786 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 4787 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 4788 return; 4789 } 4790 } 4791 } 4792 Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand); 4793 } 4794 4795 void Assembler::ldr(Condition cond, 4796 EncodingSize size, 4797 Register rt, 4798 Label* label) { 4799 VIXL_ASSERT(AllowAssembler()); 4800 CheckIT(cond); 4801 Label::Offset offset = 4802 label->IsBound() 4803 ? label->GetLocation() - 4804 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 4805 : 0; 4806 if (IsUsingT32()) { 4807 // LDR{<c>}{<q>} <Rt>, <label> ; T1 4808 if (!size.IsWide() && rt.IsLow() && 4809 ((label->IsBound() && (offset >= 0) && (offset <= 1020) && 4810 ((offset & 0x3) == 0)) || 4811 (!label->IsBound() && size.IsNarrow()))) { 4812 static class EmitOp : public Label::LabelEmitOperator { 4813 public: 4814 EmitOp() : Label::LabelEmitOperator(0, 1020) {} 4815 virtual uint32_t Encode(uint32_t instr, 4816 Label::Offset pc, 4817 const Label* label) const VIXL_OVERRIDE { 4818 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 4819 VIXL_ASSERT((offset >= 0) && (offset <= 1020) && 4820 ((offset & 0x3) == 0)); 4821 const int32_t target = offset >> 2; 4822 return instr | (target & 0xff); 4823 } 4824 } immop; 4825 EmitT32_16(Link(0x4800 | (rt.GetCode() << 8), label, immop)); 4826 AdvanceIT(); 4827 return; 4828 } 4829 // LDR{<c>}{<q>} <Rt>, <label> ; T2 4830 if (!size.IsNarrow() && 4831 ((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 4832 !label->IsBound())) { 4833 static class EmitOp : public Label::LabelEmitOperator { 4834 public: 4835 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 4836 virtual uint32_t Encode(uint32_t instr, 4837 Label::Offset pc, 4838 const Label* label) const VIXL_OVERRIDE { 4839 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 4840 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 4841 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 4842 int32_t target = abs(offset) | (U << 12); 4843 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 4844 } 4845 } immop; 4846 EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12), label, immop)); 4847 AdvanceIT(); 4848 return; 4849 } 4850 } else { 4851 // LDR{<c>}{<q>} <Rt>, <label> ; A1 4852 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 4853 !label->IsBound()) && 4854 cond.IsNotNever()) { 4855 static class EmitOp : public Label::LabelEmitOperator { 4856 public: 4857 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 4858 virtual uint32_t Encode(uint32_t instr, 4859 Label::Offset pc, 4860 const Label* label) const VIXL_OVERRIDE { 4861 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 4862 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 4863 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 4864 int32_t target = abs(offset) | (U << 12); 4865 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 4866 } 4867 } immop; 4868 EmitA32( 4869 Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 4870 label, 4871 immop)); 4872 return; 4873 } 4874 } 4875 Delegate(kLdr, &Assembler::ldr, cond, size, rt, label); 4876 } 4877 4878 void Assembler::ldrb(Condition cond, 4879 EncodingSize size, 4880 Register rt, 4881 const MemOperand& operand) { 4882 VIXL_ASSERT(AllowAssembler()); 4883 CheckIT(cond); 4884 if (operand.IsImmediate()) { 4885 Register rn = operand.GetBaseRegister(); 4886 int32_t offset = operand.GetOffsetImmediate(); 4887 if (IsUsingT32()) { 4888 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 4889 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 4890 (offset <= 31) && operand.IsOffset()) { 4891 EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) | 4892 ((offset & 0x1f) << 6)); 4893 AdvanceIT(); 4894 return; 4895 } 4896 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 4897 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 4898 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 4899 EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4900 (offset & 0xfff)); 4901 AdvanceIT(); 4902 return; 4903 } 4904 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 4905 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 4906 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 4907 EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4908 (-offset & 0xff)); 4909 AdvanceIT(); 4910 return; 4911 } 4912 // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 4913 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 4914 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 4915 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4916 uint32_t offset_ = abs(offset); 4917 EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4918 offset_ | (sign << 9)); 4919 AdvanceIT(); 4920 return; 4921 } 4922 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 4923 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 4924 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 4925 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4926 uint32_t offset_ = abs(offset); 4927 EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 4928 offset_ | (sign << 9)); 4929 AdvanceIT(); 4930 return; 4931 } 4932 // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 4933 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 4934 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 4935 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4936 uint32_t offset_ = abs(offset); 4937 EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 4938 AdvanceIT(); 4939 return; 4940 } 4941 } else { 4942 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 4943 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 4944 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 4945 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4946 uint32_t offset_ = abs(offset); 4947 EmitA32(0x05500000U | (cond.GetCondition() << 28) | 4948 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 4949 (sign << 23)); 4950 return; 4951 } 4952 // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 4953 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 4954 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 4955 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4956 uint32_t offset_ = abs(offset); 4957 EmitA32(0x04500000U | (cond.GetCondition() << 28) | 4958 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 4959 (sign << 23)); 4960 return; 4961 } 4962 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 4963 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 4964 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 4965 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4966 uint32_t offset_ = abs(offset); 4967 EmitA32(0x05700000U | (cond.GetCondition() << 28) | 4968 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 4969 (sign << 23)); 4970 return; 4971 } 4972 // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 4973 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 4974 operand.IsOffset() && cond.IsNotNever()) { 4975 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 4976 uint32_t offset_ = abs(offset); 4977 EmitA32(0x055f0000U | (cond.GetCondition() << 28) | 4978 (rt.GetCode() << 12) | offset_ | (sign << 23)); 4979 return; 4980 } 4981 } 4982 } 4983 if (operand.IsPlainRegister()) { 4984 Register rn = operand.GetBaseRegister(); 4985 Sign sign = operand.GetSign(); 4986 Register rm = operand.GetOffsetRegister(); 4987 if (IsUsingT32()) { 4988 // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 4989 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 4990 sign.IsPlus() && operand.IsOffset()) { 4991 EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) | 4992 (rm.GetCode() << 6)); 4993 AdvanceIT(); 4994 return; 4995 } 4996 } 4997 } 4998 if (operand.IsShiftedRegister()) { 4999 Register rn = operand.GetBaseRegister(); 5000 Sign sign = operand.GetSign(); 5001 Register rm = operand.GetOffsetRegister(); 5002 Shift shift = operand.GetShift(); 5003 uint32_t amount = operand.GetShiftAmount(); 5004 if (IsUsingT32()) { 5005 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 5006 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 5007 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5008 EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5009 rm.GetCode() | (amount << 4)); 5010 AdvanceIT(); 5011 return; 5012 } 5013 } else { 5014 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 5015 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) { 5016 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5017 uint32_t shift_ = TypeEncodingValue(shift); 5018 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5019 EmitA32(0x07500000U | (cond.GetCondition() << 28) | 5020 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5021 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5022 return; 5023 } 5024 // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 5025 if (operand.IsShiftValid() && operand.IsPostIndex() && 5026 cond.IsNotNever()) { 5027 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5028 uint32_t shift_ = TypeEncodingValue(shift); 5029 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5030 EmitA32(0x06500000U | (cond.GetCondition() << 28) | 5031 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5032 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5033 return; 5034 } 5035 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 5036 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) { 5037 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5038 uint32_t shift_ = TypeEncodingValue(shift); 5039 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 5040 EmitA32(0x07700000U | (cond.GetCondition() << 28) | 5041 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5042 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 5043 return; 5044 } 5045 } 5046 } 5047 Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand); 5048 } 5049 5050 void Assembler::ldrb(Condition cond, Register rt, Label* label) { 5051 VIXL_ASSERT(AllowAssembler()); 5052 CheckIT(cond); 5053 Label::Offset offset = 5054 label->IsBound() 5055 ? label->GetLocation() - 5056 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5057 : 0; 5058 if (IsUsingT32()) { 5059 // LDRB{<c>}{<q>} <Rt>, <label> ; T1 5060 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5061 !label->IsBound()) && 5062 !rt.Is(pc)) { 5063 static class EmitOp : public Label::LabelEmitOperator { 5064 public: 5065 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 5066 virtual uint32_t Encode(uint32_t instr, 5067 Label::Offset pc, 5068 const Label* label) const VIXL_OVERRIDE { 5069 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 5070 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 5071 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 5072 int32_t target = abs(offset) | (U << 12); 5073 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5074 } 5075 } immop; 5076 EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12), label, immop)); 5077 AdvanceIT(); 5078 return; 5079 } 5080 } else { 5081 // LDRB{<c>}{<q>} <Rt>, <label> ; A1 5082 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5083 !label->IsBound()) && 5084 cond.IsNotNever()) { 5085 static class EmitOp : public Label::LabelEmitOperator { 5086 public: 5087 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 5088 virtual uint32_t Encode(uint32_t instr, 5089 Label::Offset pc, 5090 const Label* label) const VIXL_OVERRIDE { 5091 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 5092 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 5093 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 5094 int32_t target = abs(offset) | (U << 12); 5095 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5096 } 5097 } immop; 5098 EmitA32( 5099 Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5100 label, 5101 immop)); 5102 return; 5103 } 5104 } 5105 Delegate(kLdrb, &Assembler::ldrb, cond, rt, label); 5106 } 5107 5108 void Assembler::ldrd(Condition cond, 5109 Register rt, 5110 Register rt2, 5111 const MemOperand& operand) { 5112 VIXL_ASSERT(AllowAssembler()); 5113 CheckIT(cond); 5114 if (operand.IsImmediate()) { 5115 Register rn = operand.GetBaseRegister(); 5116 int32_t offset = operand.GetOffsetImmediate(); 5117 if (IsUsingT32()) { 5118 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1 5119 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5120 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 5121 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5122 uint32_t offset_ = abs(offset) >> 2; 5123 EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5124 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5125 AdvanceIT(); 5126 return; 5127 } 5128 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1 5129 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5130 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5131 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5132 uint32_t offset_ = abs(offset) >> 2; 5133 EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5134 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5135 AdvanceIT(); 5136 return; 5137 } 5138 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1 5139 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 5140 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5141 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5142 uint32_t offset_ = abs(offset) >> 2; 5143 EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5144 (rn.GetCode() << 16) | offset_ | (sign << 23)); 5145 AdvanceIT(); 5146 return; 5147 } 5148 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1 5149 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 5150 operand.IsOffset()) { 5151 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5152 uint32_t offset_ = abs(offset); 5153 EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5154 offset_ | (sign << 23)); 5155 AdvanceIT(); 5156 return; 5157 } 5158 } else { 5159 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1 5160 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5161 (offset >= -255) && (offset <= 255) && operand.IsOffset() && 5162 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5163 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 5164 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5165 uint32_t offset_ = abs(offset); 5166 EmitA32(0x014000d0U | (cond.GetCondition() << 28) | 5167 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5168 ((offset_ & 0xf0) << 4) | (sign << 23)); 5169 return; 5170 } 5171 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1 5172 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5173 (offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 5174 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5175 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 5176 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5177 uint32_t offset_ = abs(offset); 5178 EmitA32(0x004000d0U | (cond.GetCondition() << 28) | 5179 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5180 ((offset_ & 0xf0) << 4) | (sign << 23)); 5181 return; 5182 } 5183 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1 5184 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5185 (offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 5186 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) && 5187 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 5188 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5189 uint32_t offset_ = abs(offset); 5190 EmitA32(0x016000d0U | (cond.GetCondition() << 28) | 5191 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5192 ((offset_ & 0xf0) << 4) | (sign << 23)); 5193 return; 5194 } 5195 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1 5196 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5197 (offset >= -255) && (offset <= 255) && rn.Is(pc) && 5198 operand.IsOffset() && cond.IsNotNever() && 5199 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 5200 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5201 uint32_t offset_ = abs(offset); 5202 EmitA32(0x014f00d0U | (cond.GetCondition() << 28) | 5203 (rt.GetCode() << 12) | (offset_ & 0xf) | 5204 ((offset_ & 0xf0) << 4) | (sign << 23)); 5205 return; 5206 } 5207 } 5208 } 5209 if (operand.IsPlainRegister()) { 5210 Register rn = operand.GetBaseRegister(); 5211 Sign sign = operand.GetSign(); 5212 Register rm = operand.GetOffsetRegister(); 5213 if (IsUsingA32()) { 5214 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1 5215 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5216 operand.IsOffset() && cond.IsNotNever() && 5217 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 5218 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5219 EmitA32(0x010000d0U | (cond.GetCondition() << 28) | 5220 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5221 (sign_ << 23)); 5222 return; 5223 } 5224 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1 5225 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5226 operand.IsPostIndex() && cond.IsNotNever() && 5227 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 5228 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5229 EmitA32(0x000000d0U | (cond.GetCondition() << 28) | 5230 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5231 (sign_ << 23)); 5232 return; 5233 } 5234 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1 5235 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5236 operand.IsPreIndex() && cond.IsNotNever() && 5237 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 5238 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5239 EmitA32(0x012000d0U | (cond.GetCondition() << 28) | 5240 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5241 (sign_ << 23)); 5242 return; 5243 } 5244 } 5245 } 5246 Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand); 5247 } 5248 5249 void Assembler::ldrd(Condition cond, Register rt, Register rt2, Label* label) { 5250 VIXL_ASSERT(AllowAssembler()); 5251 CheckIT(cond); 5252 Label::Offset offset = 5253 label->IsBound() 5254 ? label->GetLocation() - 5255 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5256 : 0; 5257 if (IsUsingT32()) { 5258 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1 5259 if (((label->IsBound() && (offset >= -1020) && (offset <= 1020) && 5260 ((offset & 0x3) == 0)) || 5261 !label->IsBound())) { 5262 static class EmitOp : public Label::LabelEmitOperator { 5263 public: 5264 EmitOp() : Label::LabelEmitOperator(-1020, 1020) {} 5265 virtual uint32_t Encode(uint32_t instr, 5266 Label::Offset pc, 5267 const Label* label) const VIXL_OVERRIDE { 5268 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 5269 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 5270 ((offset & 0x3) == 0)); 5271 int32_t target = offset >> 2; 5272 uint32_t U = (target >= 0) && !label->IsMinusZero(); 5273 target = abs(target) | (U << 8); 5274 return instr | (target & 0xff) | ((target & 0x100) << 15); 5275 } 5276 } immop; 5277 EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8), 5278 label, 5279 immop)); 5280 AdvanceIT(); 5281 return; 5282 } 5283 } else { 5284 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1 5285 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5286 ((label->IsBound() && (offset >= -255) && (offset <= 255)) || 5287 !label->IsBound()) && 5288 cond.IsNotNever() && 5289 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 5290 static class EmitOp : public Label::LabelEmitOperator { 5291 public: 5292 EmitOp() : Label::LabelEmitOperator(-255, 255) {} 5293 virtual uint32_t Encode(uint32_t instr, 5294 Label::Offset pc, 5295 const Label* label) const VIXL_OVERRIDE { 5296 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 5297 VIXL_ASSERT((offset >= -255) && (offset <= 255)); 5298 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 5299 int32_t target = abs(offset) | (U << 8); 5300 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 5301 ((target & 0x100) << 15); 5302 } 5303 } immop; 5304 EmitA32( 5305 Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5306 label, 5307 immop)); 5308 return; 5309 } 5310 } 5311 Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, label); 5312 } 5313 5314 void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) { 5315 VIXL_ASSERT(AllowAssembler()); 5316 CheckIT(cond); 5317 if (operand.IsImmediate()) { 5318 Register rn = operand.GetBaseRegister(); 5319 int32_t offset = operand.GetOffsetImmediate(); 5320 if (IsUsingT32()) { 5321 // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1 5322 if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) && 5323 operand.IsOffset()) { 5324 int32_t offset_ = offset >> 2; 5325 EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5326 (offset_ & 0xff)); 5327 AdvanceIT(); 5328 return; 5329 } 5330 } else { 5331 // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1 5332 if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) { 5333 EmitA32(0x01900f9fU | (cond.GetCondition() << 28) | 5334 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5335 return; 5336 } 5337 } 5338 } 5339 Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand); 5340 } 5341 5342 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) { 5343 VIXL_ASSERT(AllowAssembler()); 5344 CheckIT(cond); 5345 if (operand.IsImmediateZero()) { 5346 Register rn = operand.GetBaseRegister(); 5347 if (IsUsingT32()) { 5348 // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1 5349 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 5350 EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5351 AdvanceIT(); 5352 return; 5353 } 5354 } else { 5355 // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1 5356 if (operand.IsOffset() && cond.IsNotNever() && 5357 (!rn.IsPC() || AllowUnpredictable())) { 5358 EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) | 5359 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5360 return; 5361 } 5362 } 5363 } 5364 Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand); 5365 } 5366 5367 void Assembler::ldrexd(Condition cond, 5368 Register rt, 5369 Register rt2, 5370 const MemOperand& operand) { 5371 VIXL_ASSERT(AllowAssembler()); 5372 CheckIT(cond); 5373 if (operand.IsImmediateZero()) { 5374 Register rn = operand.GetBaseRegister(); 5375 if (IsUsingT32()) { 5376 // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1 5377 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 5378 EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 5379 (rn.GetCode() << 16)); 5380 AdvanceIT(); 5381 return; 5382 } 5383 } else { 5384 // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1 5385 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 5386 operand.IsOffset() && cond.IsNotNever() && 5387 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) || 5388 AllowUnpredictable())) { 5389 EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) | 5390 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5391 return; 5392 } 5393 } 5394 } 5395 Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand); 5396 } 5397 5398 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) { 5399 VIXL_ASSERT(AllowAssembler()); 5400 CheckIT(cond); 5401 if (operand.IsImmediateZero()) { 5402 Register rn = operand.GetBaseRegister(); 5403 if (IsUsingT32()) { 5404 // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1 5405 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 5406 EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5407 AdvanceIT(); 5408 return; 5409 } 5410 } else { 5411 // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1 5412 if (operand.IsOffset() && cond.IsNotNever() && 5413 (!rn.IsPC() || AllowUnpredictable())) { 5414 EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) | 5415 (rt.GetCode() << 12) | (rn.GetCode() << 16)); 5416 return; 5417 } 5418 } 5419 } 5420 Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand); 5421 } 5422 5423 void Assembler::ldrh(Condition cond, 5424 EncodingSize size, 5425 Register rt, 5426 const MemOperand& operand) { 5427 VIXL_ASSERT(AllowAssembler()); 5428 CheckIT(cond); 5429 if (operand.IsImmediate()) { 5430 Register rn = operand.GetBaseRegister(); 5431 int32_t offset = operand.GetOffsetImmediate(); 5432 if (IsUsingT32()) { 5433 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 5434 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 5435 (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) { 5436 int32_t offset_ = offset >> 1; 5437 EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) | 5438 ((offset_ & 0x1f) << 6)); 5439 AdvanceIT(); 5440 return; 5441 } 5442 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 5443 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5444 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5445 EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5446 (offset & 0xfff)); 5447 AdvanceIT(); 5448 return; 5449 } 5450 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 5451 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5452 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5453 EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5454 (-offset & 0xff)); 5455 AdvanceIT(); 5456 return; 5457 } 5458 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 5459 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5460 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5461 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5462 uint32_t offset_ = abs(offset); 5463 EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5464 offset_ | (sign << 9)); 5465 AdvanceIT(); 5466 return; 5467 } 5468 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 5469 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5470 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5471 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5472 uint32_t offset_ = abs(offset); 5473 EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5474 offset_ | (sign << 9)); 5475 AdvanceIT(); 5476 return; 5477 } 5478 // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 5479 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 5480 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 5481 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5482 uint32_t offset_ = abs(offset); 5483 EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 5484 AdvanceIT(); 5485 return; 5486 } 5487 } else { 5488 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 5489 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 5490 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5491 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5492 uint32_t offset_ = abs(offset); 5493 EmitA32(0x015000b0U | (cond.GetCondition() << 28) | 5494 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5495 ((offset_ & 0xf0) << 4) | (sign << 23)); 5496 return; 5497 } 5498 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 5499 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 5500 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5501 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5502 uint32_t offset_ = abs(offset); 5503 EmitA32(0x005000b0U | (cond.GetCondition() << 28) | 5504 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5505 ((offset_ & 0xf0) << 4) | (sign << 23)); 5506 return; 5507 } 5508 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 5509 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 5510 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5511 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5512 uint32_t offset_ = abs(offset); 5513 EmitA32(0x017000b0U | (cond.GetCondition() << 28) | 5514 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5515 ((offset_ & 0xf0) << 4) | (sign << 23)); 5516 return; 5517 } 5518 // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 5519 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 5520 operand.IsOffset() && cond.IsNotNever()) { 5521 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5522 uint32_t offset_ = abs(offset); 5523 EmitA32(0x015f00b0U | (cond.GetCondition() << 28) | 5524 (rt.GetCode() << 12) | (offset_ & 0xf) | 5525 ((offset_ & 0xf0) << 4) | (sign << 23)); 5526 return; 5527 } 5528 } 5529 } 5530 if (operand.IsPlainRegister()) { 5531 Register rn = operand.GetBaseRegister(); 5532 Sign sign = operand.GetSign(); 5533 Register rm = operand.GetOffsetRegister(); 5534 if (IsUsingT32()) { 5535 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 5536 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 5537 sign.IsPlus() && operand.IsOffset()) { 5538 EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) | 5539 (rm.GetCode() << 6)); 5540 AdvanceIT(); 5541 return; 5542 } 5543 } else { 5544 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 5545 if (operand.IsOffset() && cond.IsNotNever()) { 5546 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5547 EmitA32(0x011000b0U | (cond.GetCondition() << 28) | 5548 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5549 (sign_ << 23)); 5550 return; 5551 } 5552 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 5553 if (operand.IsPostIndex() && cond.IsNotNever()) { 5554 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5555 EmitA32(0x001000b0U | (cond.GetCondition() << 28) | 5556 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5557 (sign_ << 23)); 5558 return; 5559 } 5560 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 5561 if (operand.IsPreIndex() && cond.IsNotNever()) { 5562 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5563 EmitA32(0x013000b0U | (cond.GetCondition() << 28) | 5564 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5565 (sign_ << 23)); 5566 return; 5567 } 5568 } 5569 } 5570 if (operand.IsShiftedRegister()) { 5571 Register rn = operand.GetBaseRegister(); 5572 Sign sign = operand.GetSign(); 5573 Register rm = operand.GetOffsetRegister(); 5574 Shift shift = operand.GetShift(); 5575 uint32_t amount = operand.GetShiftAmount(); 5576 if (IsUsingT32()) { 5577 // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 5578 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 5579 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5580 EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5581 rm.GetCode() | (amount << 4)); 5582 AdvanceIT(); 5583 return; 5584 } 5585 } 5586 } 5587 Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand); 5588 } 5589 5590 void Assembler::ldrh(Condition cond, Register rt, Label* label) { 5591 VIXL_ASSERT(AllowAssembler()); 5592 CheckIT(cond); 5593 Label::Offset offset = 5594 label->IsBound() 5595 ? label->GetLocation() - 5596 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5597 : 0; 5598 if (IsUsingT32()) { 5599 // LDRH{<c>}{<q>} <Rt>, <label> ; T1 5600 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5601 !label->IsBound()) && 5602 !rt.Is(pc)) { 5603 static class EmitOp : public Label::LabelEmitOperator { 5604 public: 5605 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 5606 virtual uint32_t Encode(uint32_t instr, 5607 Label::Offset pc, 5608 const Label* label) const VIXL_OVERRIDE { 5609 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 5610 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 5611 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 5612 int32_t target = abs(offset) | (U << 12); 5613 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5614 } 5615 } immop; 5616 EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12), label, immop)); 5617 AdvanceIT(); 5618 return; 5619 } 5620 } else { 5621 // LDRH{<c>}{<q>} <Rt>, <label> ; A1 5622 if (((label->IsBound() && (offset >= -255) && (offset <= 255)) || 5623 !label->IsBound()) && 5624 cond.IsNotNever()) { 5625 static class EmitOp : public Label::LabelEmitOperator { 5626 public: 5627 EmitOp() : Label::LabelEmitOperator(-255, 255) {} 5628 virtual uint32_t Encode(uint32_t instr, 5629 Label::Offset pc, 5630 const Label* label) const VIXL_OVERRIDE { 5631 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 5632 VIXL_ASSERT((offset >= -255) && (offset <= 255)); 5633 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 5634 int32_t target = abs(offset) | (U << 8); 5635 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 5636 ((target & 0x100) << 15); 5637 } 5638 } immop; 5639 EmitA32( 5640 Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5641 label, 5642 immop)); 5643 return; 5644 } 5645 } 5646 Delegate(kLdrh, &Assembler::ldrh, cond, rt, label); 5647 } 5648 5649 void Assembler::ldrsb(Condition cond, 5650 EncodingSize size, 5651 Register rt, 5652 const MemOperand& operand) { 5653 VIXL_ASSERT(AllowAssembler()); 5654 CheckIT(cond); 5655 if (operand.IsImmediate()) { 5656 Register rn = operand.GetBaseRegister(); 5657 int32_t offset = operand.GetOffsetImmediate(); 5658 if (IsUsingT32()) { 5659 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 5660 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5661 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5662 EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5663 (offset & 0xfff)); 5664 AdvanceIT(); 5665 return; 5666 } 5667 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2 5668 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5669 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5670 EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5671 (-offset & 0xff)); 5672 AdvanceIT(); 5673 return; 5674 } 5675 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2 5676 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5677 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5678 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5679 uint32_t offset_ = abs(offset); 5680 EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5681 offset_ | (sign << 9)); 5682 AdvanceIT(); 5683 return; 5684 } 5685 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2 5686 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5687 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5688 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5689 uint32_t offset_ = abs(offset); 5690 EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5691 offset_ | (sign << 9)); 5692 AdvanceIT(); 5693 return; 5694 } 5695 // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 5696 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 5697 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 5698 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5699 uint32_t offset_ = abs(offset); 5700 EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 5701 AdvanceIT(); 5702 return; 5703 } 5704 } else { 5705 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1 5706 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 5707 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5708 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5709 uint32_t offset_ = abs(offset); 5710 EmitA32(0x015000d0U | (cond.GetCondition() << 28) | 5711 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5712 ((offset_ & 0xf0) << 4) | (sign << 23)); 5713 return; 5714 } 5715 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1 5716 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 5717 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5718 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5719 uint32_t offset_ = abs(offset); 5720 EmitA32(0x005000d0U | (cond.GetCondition() << 28) | 5721 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5722 ((offset_ & 0xf0) << 4) | (sign << 23)); 5723 return; 5724 } 5725 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1 5726 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 5727 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5728 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5729 uint32_t offset_ = abs(offset); 5730 EmitA32(0x017000d0U | (cond.GetCondition() << 28) | 5731 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5732 ((offset_ & 0xf0) << 4) | (sign << 23)); 5733 return; 5734 } 5735 // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 5736 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 5737 operand.IsOffset() && cond.IsNotNever()) { 5738 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5739 uint32_t offset_ = abs(offset); 5740 EmitA32(0x015f00d0U | (cond.GetCondition() << 28) | 5741 (rt.GetCode() << 12) | (offset_ & 0xf) | 5742 ((offset_ & 0xf0) << 4) | (sign << 23)); 5743 return; 5744 } 5745 } 5746 } 5747 if (operand.IsPlainRegister()) { 5748 Register rn = operand.GetBaseRegister(); 5749 Sign sign = operand.GetSign(); 5750 Register rm = operand.GetOffsetRegister(); 5751 if (IsUsingT32()) { 5752 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 5753 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 5754 sign.IsPlus() && operand.IsOffset()) { 5755 EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) | 5756 (rm.GetCode() << 6)); 5757 AdvanceIT(); 5758 return; 5759 } 5760 } else { 5761 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 5762 if (operand.IsOffset() && cond.IsNotNever()) { 5763 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5764 EmitA32(0x011000d0U | (cond.GetCondition() << 28) | 5765 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5766 (sign_ << 23)); 5767 return; 5768 } 5769 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 5770 if (operand.IsPostIndex() && cond.IsNotNever()) { 5771 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5772 EmitA32(0x001000d0U | (cond.GetCondition() << 28) | 5773 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5774 (sign_ << 23)); 5775 return; 5776 } 5777 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 5778 if (operand.IsPreIndex() && cond.IsNotNever()) { 5779 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5780 EmitA32(0x013000d0U | (cond.GetCondition() << 28) | 5781 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5782 (sign_ << 23)); 5783 return; 5784 } 5785 } 5786 } 5787 if (operand.IsShiftedRegister()) { 5788 Register rn = operand.GetBaseRegister(); 5789 Sign sign = operand.GetSign(); 5790 Register rm = operand.GetOffsetRegister(); 5791 Shift shift = operand.GetShift(); 5792 uint32_t amount = operand.GetShiftAmount(); 5793 if (IsUsingT32()) { 5794 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 5795 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 5796 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5797 EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5798 rm.GetCode() | (amount << 4)); 5799 AdvanceIT(); 5800 return; 5801 } 5802 } 5803 } 5804 Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand); 5805 } 5806 5807 void Assembler::ldrsb(Condition cond, Register rt, Label* label) { 5808 VIXL_ASSERT(AllowAssembler()); 5809 CheckIT(cond); 5810 Label::Offset offset = 5811 label->IsBound() 5812 ? label->GetLocation() - 5813 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 5814 : 0; 5815 if (IsUsingT32()) { 5816 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1 5817 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 5818 !label->IsBound()) && 5819 !rt.Is(pc)) { 5820 static class EmitOp : public Label::LabelEmitOperator { 5821 public: 5822 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 5823 virtual uint32_t Encode(uint32_t instr, 5824 Label::Offset pc, 5825 const Label* label) const VIXL_OVERRIDE { 5826 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 5827 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 5828 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 5829 int32_t target = abs(offset) | (U << 12); 5830 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 5831 } 5832 } immop; 5833 EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12), label, immop)); 5834 AdvanceIT(); 5835 return; 5836 } 5837 } else { 5838 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1 5839 if (((label->IsBound() && (offset >= -255) && (offset <= 255)) || 5840 !label->IsBound()) && 5841 cond.IsNotNever()) { 5842 static class EmitOp : public Label::LabelEmitOperator { 5843 public: 5844 EmitOp() : Label::LabelEmitOperator(-255, 255) {} 5845 virtual uint32_t Encode(uint32_t instr, 5846 Label::Offset pc, 5847 const Label* label) const VIXL_OVERRIDE { 5848 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 5849 VIXL_ASSERT((offset >= -255) && (offset <= 255)); 5850 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 5851 int32_t target = abs(offset) | (U << 8); 5852 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 5853 ((target & 0x100) << 15); 5854 } 5855 } immop; 5856 EmitA32( 5857 Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 5858 label, 5859 immop)); 5860 return; 5861 } 5862 } 5863 Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, label); 5864 } 5865 5866 void Assembler::ldrsh(Condition cond, 5867 EncodingSize size, 5868 Register rt, 5869 const MemOperand& operand) { 5870 VIXL_ASSERT(AllowAssembler()); 5871 CheckIT(cond); 5872 if (operand.IsImmediate()) { 5873 Register rn = operand.GetBaseRegister(); 5874 int32_t offset = operand.GetOffsetImmediate(); 5875 if (IsUsingT32()) { 5876 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 5877 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 5878 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5879 EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5880 (offset & 0xfff)); 5881 AdvanceIT(); 5882 return; 5883 } 5884 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2 5885 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 5886 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 5887 EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5888 (-offset & 0xff)); 5889 AdvanceIT(); 5890 return; 5891 } 5892 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2 5893 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5894 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5895 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5896 uint32_t offset_ = abs(offset); 5897 EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5898 offset_ | (sign << 9)); 5899 AdvanceIT(); 5900 return; 5901 } 5902 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2 5903 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 5904 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 5905 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5906 uint32_t offset_ = abs(offset); 5907 EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 5908 offset_ | (sign << 9)); 5909 AdvanceIT(); 5910 return; 5911 } 5912 // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1 5913 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) && 5914 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) { 5915 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5916 uint32_t offset_ = abs(offset); 5917 EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23)); 5918 AdvanceIT(); 5919 return; 5920 } 5921 } else { 5922 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1 5923 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 5924 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5925 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5926 uint32_t offset_ = abs(offset); 5927 EmitA32(0x015000f0U | (cond.GetCondition() << 28) | 5928 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5929 ((offset_ & 0xf0) << 4) | (sign << 23)); 5930 return; 5931 } 5932 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1 5933 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 5934 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5935 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5936 uint32_t offset_ = abs(offset); 5937 EmitA32(0x005000f0U | (cond.GetCondition() << 28) | 5938 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5939 ((offset_ & 0xf0) << 4) | (sign << 23)); 5940 return; 5941 } 5942 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1 5943 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 5944 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) { 5945 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5946 uint32_t offset_ = abs(offset); 5947 EmitA32(0x017000f0U | (cond.GetCondition() << 28) | 5948 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 5949 ((offset_ & 0xf0) << 4) | (sign << 23)); 5950 return; 5951 } 5952 // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1 5953 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) && 5954 operand.IsOffset() && cond.IsNotNever()) { 5955 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 5956 uint32_t offset_ = abs(offset); 5957 EmitA32(0x015f00f0U | (cond.GetCondition() << 28) | 5958 (rt.GetCode() << 12) | (offset_ & 0xf) | 5959 ((offset_ & 0xf0) << 4) | (sign << 23)); 5960 return; 5961 } 5962 } 5963 } 5964 if (operand.IsPlainRegister()) { 5965 Register rn = operand.GetBaseRegister(); 5966 Sign sign = operand.GetSign(); 5967 Register rm = operand.GetOffsetRegister(); 5968 if (IsUsingT32()) { 5969 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 5970 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 5971 sign.IsPlus() && operand.IsOffset()) { 5972 EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) | 5973 (rm.GetCode() << 6)); 5974 AdvanceIT(); 5975 return; 5976 } 5977 } else { 5978 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 5979 if (operand.IsOffset() && cond.IsNotNever()) { 5980 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5981 EmitA32(0x011000f0U | (cond.GetCondition() << 28) | 5982 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5983 (sign_ << 23)); 5984 return; 5985 } 5986 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 5987 if (operand.IsPostIndex() && cond.IsNotNever()) { 5988 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5989 EmitA32(0x001000f0U | (cond.GetCondition() << 28) | 5990 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5991 (sign_ << 23)); 5992 return; 5993 } 5994 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 5995 if (operand.IsPreIndex() && cond.IsNotNever()) { 5996 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 5997 EmitA32(0x013000f0U | (cond.GetCondition() << 28) | 5998 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 5999 (sign_ << 23)); 6000 return; 6001 } 6002 } 6003 } 6004 if (operand.IsShiftedRegister()) { 6005 Register rn = operand.GetBaseRegister(); 6006 Sign sign = operand.GetSign(); 6007 Register rm = operand.GetOffsetRegister(); 6008 Shift shift = operand.GetShift(); 6009 uint32_t amount = operand.GetShiftAmount(); 6010 if (IsUsingT32()) { 6011 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 6012 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 6013 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) { 6014 EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 6015 rm.GetCode() | (amount << 4)); 6016 AdvanceIT(); 6017 return; 6018 } 6019 } 6020 } 6021 Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand); 6022 } 6023 6024 void Assembler::ldrsh(Condition cond, Register rt, Label* label) { 6025 VIXL_ASSERT(AllowAssembler()); 6026 CheckIT(cond); 6027 Label::Offset offset = 6028 label->IsBound() 6029 ? label->GetLocation() - 6030 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 6031 : 0; 6032 if (IsUsingT32()) { 6033 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1 6034 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 6035 !label->IsBound()) && 6036 !rt.Is(pc)) { 6037 static class EmitOp : public Label::LabelEmitOperator { 6038 public: 6039 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 6040 virtual uint32_t Encode(uint32_t instr, 6041 Label::Offset pc, 6042 const Label* label) const VIXL_OVERRIDE { 6043 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 6044 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 6045 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 6046 int32_t target = abs(offset) | (U << 12); 6047 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 6048 } 6049 } immop; 6050 EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12), label, immop)); 6051 AdvanceIT(); 6052 return; 6053 } 6054 } else { 6055 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1 6056 if (((label->IsBound() && (offset >= -255) && (offset <= 255)) || 6057 !label->IsBound()) && 6058 cond.IsNotNever()) { 6059 static class EmitOp : public Label::LabelEmitOperator { 6060 public: 6061 EmitOp() : Label::LabelEmitOperator(-255, 255) {} 6062 virtual uint32_t Encode(uint32_t instr, 6063 Label::Offset pc, 6064 const Label* label) const VIXL_OVERRIDE { 6065 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 6066 VIXL_ASSERT((offset >= -255) && (offset <= 255)); 6067 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 6068 int32_t target = abs(offset) | (U << 8); 6069 return instr | (target & 0xf) | ((target & 0xf0) << 4) | 6070 ((target & 0x100) << 15); 6071 } 6072 } immop; 6073 EmitA32( 6074 Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12), 6075 label, 6076 immop)); 6077 return; 6078 } 6079 } 6080 Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, label); 6081 } 6082 6083 void Assembler::lsl(Condition cond, 6084 EncodingSize size, 6085 Register rd, 6086 Register rm, 6087 const Operand& operand) { 6088 VIXL_ASSERT(AllowAssembler()); 6089 CheckIT(cond); 6090 if (operand.IsImmediate()) { 6091 uint32_t imm = operand.GetImmediate(); 6092 if (IsUsingT32()) { 6093 // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6094 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6095 (imm >= 1) && (imm <= 31)) { 6096 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6)); 6097 AdvanceIT(); 6098 return; 6099 } 6100 // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6101 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) { 6102 EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6103 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 6104 AdvanceIT(); 6105 return; 6106 } 6107 } else { 6108 // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6109 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 6110 EmitA32(0x01a00000U | (cond.GetCondition() << 28) | 6111 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 6112 return; 6113 } 6114 } 6115 } 6116 if (operand.IsPlainRegister()) { 6117 Register rs = operand.GetBaseRegister(); 6118 if (IsUsingT32()) { 6119 // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6120 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6121 rs.IsLow()) { 6122 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 6123 AdvanceIT(); 6124 return; 6125 } 6126 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6127 if (!size.IsNarrow()) { 6128 EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6129 rs.GetCode()); 6130 AdvanceIT(); 6131 return; 6132 } 6133 } else { 6134 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6135 if (cond.IsNotNever()) { 6136 EmitA32(0x01a00010U | (cond.GetCondition() << 28) | 6137 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6138 return; 6139 } 6140 } 6141 } 6142 Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand); 6143 } 6144 6145 void Assembler::lsls(Condition cond, 6146 EncodingSize size, 6147 Register rd, 6148 Register rm, 6149 const Operand& operand) { 6150 VIXL_ASSERT(AllowAssembler()); 6151 CheckIT(cond); 6152 if (operand.IsImmediate()) { 6153 uint32_t imm = operand.GetImmediate(); 6154 if (IsUsingT32()) { 6155 // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6156 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6157 (imm >= 1) && (imm <= 31)) { 6158 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6)); 6159 AdvanceIT(); 6160 return; 6161 } 6162 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6163 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) { 6164 EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6165 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 6166 AdvanceIT(); 6167 return; 6168 } 6169 } else { 6170 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6171 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 6172 EmitA32(0x01b00000U | (cond.GetCondition() << 28) | 6173 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 6174 return; 6175 } 6176 } 6177 } 6178 if (operand.IsPlainRegister()) { 6179 Register rs = operand.GetBaseRegister(); 6180 if (IsUsingT32()) { 6181 // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6182 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6183 rs.IsLow()) { 6184 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3)); 6185 AdvanceIT(); 6186 return; 6187 } 6188 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6189 if (!size.IsNarrow()) { 6190 EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6191 rs.GetCode()); 6192 AdvanceIT(); 6193 return; 6194 } 6195 } else { 6196 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6197 if (cond.IsNotNever()) { 6198 EmitA32(0x01b00010U | (cond.GetCondition() << 28) | 6199 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6200 return; 6201 } 6202 } 6203 } 6204 Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand); 6205 } 6206 6207 void Assembler::lsr(Condition cond, 6208 EncodingSize size, 6209 Register rd, 6210 Register rm, 6211 const Operand& operand) { 6212 VIXL_ASSERT(AllowAssembler()); 6213 CheckIT(cond); 6214 if (operand.IsImmediate()) { 6215 uint32_t imm = operand.GetImmediate(); 6216 if (IsUsingT32()) { 6217 // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6218 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6219 (imm >= 1) && (imm <= 32)) { 6220 uint32_t amount_ = imm % 32; 6221 EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) | 6222 (amount_ << 6)); 6223 AdvanceIT(); 6224 return; 6225 } 6226 // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6227 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) { 6228 uint32_t amount_ = imm % 32; 6229 EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() | 6230 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6231 AdvanceIT(); 6232 return; 6233 } 6234 } else { 6235 // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6236 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 6237 uint32_t amount_ = imm % 32; 6238 EmitA32(0x01a00020U | (cond.GetCondition() << 28) | 6239 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 6240 return; 6241 } 6242 } 6243 } 6244 if (operand.IsPlainRegister()) { 6245 Register rs = operand.GetBaseRegister(); 6246 if (IsUsingT32()) { 6247 // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6248 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6249 rs.IsLow()) { 6250 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 6251 AdvanceIT(); 6252 return; 6253 } 6254 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6255 if (!size.IsNarrow()) { 6256 EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6257 rs.GetCode()); 6258 AdvanceIT(); 6259 return; 6260 } 6261 } else { 6262 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6263 if (cond.IsNotNever()) { 6264 EmitA32(0x01a00030U | (cond.GetCondition() << 28) | 6265 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6266 return; 6267 } 6268 } 6269 } 6270 Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand); 6271 } 6272 6273 void Assembler::lsrs(Condition cond, 6274 EncodingSize size, 6275 Register rd, 6276 Register rm, 6277 const Operand& operand) { 6278 VIXL_ASSERT(AllowAssembler()); 6279 CheckIT(cond); 6280 if (operand.IsImmediate()) { 6281 uint32_t imm = operand.GetImmediate(); 6282 if (IsUsingT32()) { 6283 // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2 6284 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() && 6285 (imm >= 1) && (imm <= 32)) { 6286 uint32_t amount_ = imm % 32; 6287 EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) | 6288 (amount_ << 6)); 6289 AdvanceIT(); 6290 return; 6291 } 6292 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 6293 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) { 6294 uint32_t amount_ = imm % 32; 6295 EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() | 6296 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6297 AdvanceIT(); 6298 return; 6299 } 6300 } else { 6301 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 6302 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) { 6303 uint32_t amount_ = imm % 32; 6304 EmitA32(0x01b00020U | (cond.GetCondition() << 28) | 6305 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7)); 6306 return; 6307 } 6308 } 6309 } 6310 if (operand.IsPlainRegister()) { 6311 Register rs = operand.GetBaseRegister(); 6312 if (IsUsingT32()) { 6313 // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 6314 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6315 rs.IsLow()) { 6316 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3)); 6317 AdvanceIT(); 6318 return; 6319 } 6320 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 6321 if (!size.IsNarrow()) { 6322 EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6323 rs.GetCode()); 6324 AdvanceIT(); 6325 return; 6326 } 6327 } else { 6328 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 6329 if (cond.IsNotNever()) { 6330 EmitA32(0x01b00030U | (cond.GetCondition() << 28) | 6331 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 6332 return; 6333 } 6334 } 6335 } 6336 Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand); 6337 } 6338 6339 void Assembler::mla( 6340 Condition cond, Register rd, Register rn, Register rm, Register ra) { 6341 VIXL_ASSERT(AllowAssembler()); 6342 CheckIT(cond); 6343 if (IsUsingT32()) { 6344 // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 6345 if (!ra.Is(pc)) { 6346 EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 6347 rm.GetCode() | (ra.GetCode() << 12)); 6348 AdvanceIT(); 6349 return; 6350 } 6351 } else { 6352 // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 6353 if (cond.IsNotNever()) { 6354 EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 6355 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 6356 return; 6357 } 6358 } 6359 Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra); 6360 } 6361 6362 void Assembler::mlas( 6363 Condition cond, Register rd, Register rn, Register rm, Register ra) { 6364 VIXL_ASSERT(AllowAssembler()); 6365 CheckIT(cond); 6366 if (IsUsingA32()) { 6367 // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 6368 if (cond.IsNotNever()) { 6369 EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 6370 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 6371 return; 6372 } 6373 } 6374 Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra); 6375 } 6376 6377 void Assembler::mls( 6378 Condition cond, Register rd, Register rn, Register rm, Register ra) { 6379 VIXL_ASSERT(AllowAssembler()); 6380 CheckIT(cond); 6381 if (IsUsingT32()) { 6382 // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 6383 EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 6384 rm.GetCode() | (ra.GetCode() << 12)); 6385 AdvanceIT(); 6386 return; 6387 } else { 6388 // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 6389 if (cond.IsNotNever()) { 6390 EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 6391 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 6392 return; 6393 } 6394 } 6395 Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra); 6396 } 6397 6398 void Assembler::mov(Condition cond, 6399 EncodingSize size, 6400 Register rd, 6401 const Operand& operand) { 6402 VIXL_ASSERT(AllowAssembler()); 6403 CheckIT(cond); 6404 if (operand.IsImmediateShiftedRegister()) { 6405 Register rm = operand.GetBaseRegister(); 6406 if (operand.IsPlainRegister()) { 6407 if (IsUsingT32()) { 6408 // MOV{<c>}{<q>} <Rd>, <Rm> ; T1 6409 if (!size.IsWide() && 6410 ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || 6411 AllowUnpredictable())) { 6412 EmitT32_16(0x4600 | (rd.GetCode() & 0x7) | 6413 ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); 6414 AdvanceIT(); 6415 return; 6416 } 6417 } 6418 } 6419 Shift shift = operand.GetShift(); 6420 uint32_t amount = operand.GetShiftAmount(); 6421 if (IsUsingT32()) { 6422 // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 6423 if (InITBlock() && !size.IsWide() && rd.IsLow() && 6424 shift.IsValidAmount(amount) && rm.IsLow() && 6425 (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) && 6426 ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) { 6427 uint32_t amount_ = amount % 32; 6428 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | 6429 (operand.GetTypeEncodingValue() << 11) | (amount_ << 6)); 6430 AdvanceIT(); 6431 return; 6432 } 6433 // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3 6434 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 6435 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6436 uint32_t amount_ = amount % 32; 6437 EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6438 (operand.GetTypeEncodingValue() << 4) | 6439 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6440 AdvanceIT(); 6441 return; 6442 } 6443 } else { 6444 // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 6445 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 6446 uint32_t amount_ = amount % 32; 6447 EmitA32(0x01a00000U | (cond.GetCondition() << 28) | 6448 (rd.GetCode() << 12) | rm.GetCode() | 6449 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 6450 return; 6451 } 6452 } 6453 } 6454 if (operand.IsRegisterShiftedRegister()) { 6455 Register rm = operand.GetBaseRegister(); 6456 Shift shift = operand.GetShift(); 6457 if (IsUsingT32()) { 6458 // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1 6459 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6460 shift.IsASR() && operand.GetShiftRegister().IsLow()) { 6461 EmitT32_16(0x4100 | rd.GetCode() | 6462 (operand.GetShiftRegister().GetCode() << 3)); 6463 AdvanceIT(); 6464 return; 6465 } 6466 // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1 6467 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6468 shift.IsLSL() && operand.GetShiftRegister().IsLow()) { 6469 EmitT32_16(0x4080 | rd.GetCode() | 6470 (operand.GetShiftRegister().GetCode() << 3)); 6471 AdvanceIT(); 6472 return; 6473 } 6474 // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1 6475 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6476 shift.IsLSR() && operand.GetShiftRegister().IsLow()) { 6477 EmitT32_16(0x40c0 | rd.GetCode() | 6478 (operand.GetShiftRegister().GetCode() << 3)); 6479 AdvanceIT(); 6480 return; 6481 } 6482 // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1 6483 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6484 shift.IsROR() && operand.GetShiftRegister().IsLow()) { 6485 EmitT32_16(0x41c0 | rd.GetCode() | 6486 (operand.GetShiftRegister().GetCode() << 3)); 6487 AdvanceIT(); 6488 return; 6489 } 6490 // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2 6491 if (!size.IsNarrow() && 6492 ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || 6493 AllowUnpredictable())) { 6494 EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6495 (shift.GetType() << 21) | 6496 operand.GetShiftRegister().GetCode()); 6497 AdvanceIT(); 6498 return; 6499 } 6500 } else { 6501 // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 6502 if (cond.IsNotNever() && 6503 ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || 6504 AllowUnpredictable())) { 6505 EmitA32(0x01a00010U | (cond.GetCondition() << 28) | 6506 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 6507 (operand.GetShiftRegister().GetCode() << 8)); 6508 return; 6509 } 6510 } 6511 } 6512 if (operand.IsImmediate()) { 6513 uint32_t imm = operand.GetImmediate(); 6514 if (IsUsingT32()) { 6515 ImmediateT32 immediate_t32(imm); 6516 // MOV<c>{<q>} <Rd>, #<imm8> ; T1 6517 if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) { 6518 EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm); 6519 AdvanceIT(); 6520 return; 6521 } 6522 // MOV{<c>}{<q>} <Rd>, #<const> ; T2 6523 if (!size.IsNarrow() && immediate_t32.IsValid() && 6524 (!rd.IsPC() || AllowUnpredictable())) { 6525 EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) | 6526 (immediate_t32.GetEncodingValue() & 0xff) | 6527 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 6528 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 6529 AdvanceIT(); 6530 return; 6531 } 6532 // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3 6533 if (!size.IsNarrow() && (imm <= 65535) && 6534 (!rd.IsPC() || AllowUnpredictable())) { 6535 EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) | 6536 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 6537 ((imm & 0xf000) << 4)); 6538 AdvanceIT(); 6539 return; 6540 } 6541 } else { 6542 ImmediateA32 immediate_a32(imm); 6543 // MOV{<c>}{<q>} <Rd>, #<const> ; A1 6544 if (immediate_a32.IsValid() && cond.IsNotNever()) { 6545 EmitA32(0x03a00000U | (cond.GetCondition() << 28) | 6546 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 6547 return; 6548 } 6549 // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2 6550 if ((imm <= 65535) && cond.IsNotNever() && 6551 (!rd.IsPC() || AllowUnpredictable())) { 6552 EmitA32(0x03000000U | (cond.GetCondition() << 28) | 6553 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 6554 return; 6555 } 6556 } 6557 } 6558 Delegate(kMov, &Assembler::mov, cond, size, rd, operand); 6559 } 6560 6561 void Assembler::movs(Condition cond, 6562 EncodingSize size, 6563 Register rd, 6564 const Operand& operand) { 6565 VIXL_ASSERT(AllowAssembler()); 6566 CheckIT(cond); 6567 if (operand.IsImmediateShiftedRegister()) { 6568 Register rm = operand.GetBaseRegister(); 6569 Shift shift = operand.GetShift(); 6570 uint32_t amount = operand.GetShiftAmount(); 6571 if (IsUsingT32()) { 6572 // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 6573 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && 6574 shift.IsValidAmount(amount) && rm.IsLow() && 6575 (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) { 6576 uint32_t amount_ = amount % 32; 6577 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | 6578 (operand.GetTypeEncodingValue() << 11) | (amount_ << 6)); 6579 AdvanceIT(); 6580 return; 6581 } 6582 // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3 6583 if (!size.IsNarrow() && shift.IsValidAmount(amount) && 6584 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { 6585 uint32_t amount_ = amount % 32; 6586 EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6587 (operand.GetTypeEncodingValue() << 4) | 6588 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6589 AdvanceIT(); 6590 return; 6591 } 6592 } else { 6593 // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 6594 if (shift.IsValidAmount(amount) && cond.IsNotNever() && 6595 (!rd.IsPC() || AllowUnpredictable())) { 6596 uint32_t amount_ = amount % 32; 6597 EmitA32(0x01b00000U | (cond.GetCondition() << 28) | 6598 (rd.GetCode() << 12) | rm.GetCode() | 6599 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 6600 return; 6601 } 6602 } 6603 } 6604 if (operand.IsRegisterShiftedRegister()) { 6605 Register rm = operand.GetBaseRegister(); 6606 Shift shift = operand.GetShift(); 6607 if (IsUsingT32()) { 6608 // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1 6609 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6610 shift.IsASR() && operand.GetShiftRegister().IsLow()) { 6611 EmitT32_16(0x4100 | rd.GetCode() | 6612 (operand.GetShiftRegister().GetCode() << 3)); 6613 AdvanceIT(); 6614 return; 6615 } 6616 // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1 6617 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6618 shift.IsLSL() && operand.GetShiftRegister().IsLow()) { 6619 EmitT32_16(0x4080 | rd.GetCode() | 6620 (operand.GetShiftRegister().GetCode() << 3)); 6621 AdvanceIT(); 6622 return; 6623 } 6624 // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1 6625 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6626 shift.IsLSR() && operand.GetShiftRegister().IsLow()) { 6627 EmitT32_16(0x40c0 | rd.GetCode() | 6628 (operand.GetShiftRegister().GetCode() << 3)); 6629 AdvanceIT(); 6630 return; 6631 } 6632 // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1 6633 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 6634 shift.IsROR() && operand.GetShiftRegister().IsLow()) { 6635 EmitT32_16(0x41c0 | rd.GetCode() | 6636 (operand.GetShiftRegister().GetCode() << 3)); 6637 AdvanceIT(); 6638 return; 6639 } 6640 // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2 6641 if (!size.IsNarrow() && 6642 ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || 6643 AllowUnpredictable())) { 6644 EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 6645 (shift.GetType() << 21) | 6646 operand.GetShiftRegister().GetCode()); 6647 AdvanceIT(); 6648 return; 6649 } 6650 } else { 6651 // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 6652 if (cond.IsNotNever() && 6653 ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || 6654 AllowUnpredictable())) { 6655 EmitA32(0x01b00010U | (cond.GetCondition() << 28) | 6656 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 6657 (operand.GetShiftRegister().GetCode() << 8)); 6658 return; 6659 } 6660 } 6661 } 6662 if (operand.IsImmediate()) { 6663 uint32_t imm = operand.GetImmediate(); 6664 if (IsUsingT32()) { 6665 ImmediateT32 immediate_t32(imm); 6666 // MOVS{<q>} <Rd>, #<imm8> ; T1 6667 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) { 6668 EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm); 6669 AdvanceIT(); 6670 return; 6671 } 6672 // MOVS{<c>}{<q>} <Rd>, #<const> ; T2 6673 if (!size.IsNarrow() && immediate_t32.IsValid() && 6674 (!rd.IsPC() || AllowUnpredictable())) { 6675 EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) | 6676 (immediate_t32.GetEncodingValue() & 0xff) | 6677 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 6678 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 6679 AdvanceIT(); 6680 return; 6681 } 6682 } else { 6683 ImmediateA32 immediate_a32(imm); 6684 // MOVS{<c>}{<q>} <Rd>, #<const> ; A1 6685 if (immediate_a32.IsValid() && cond.IsNotNever()) { 6686 EmitA32(0x03b00000U | (cond.GetCondition() << 28) | 6687 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 6688 return; 6689 } 6690 } 6691 } 6692 Delegate(kMovs, &Assembler::movs, cond, size, rd, operand); 6693 } 6694 6695 void Assembler::movt(Condition cond, Register rd, const Operand& operand) { 6696 VIXL_ASSERT(AllowAssembler()); 6697 CheckIT(cond); 6698 if (operand.IsImmediate()) { 6699 uint32_t imm = operand.GetImmediate(); 6700 if (IsUsingT32()) { 6701 // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1 6702 if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) { 6703 EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) | 6704 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 6705 ((imm & 0xf000) << 4)); 6706 AdvanceIT(); 6707 return; 6708 } 6709 } else { 6710 // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1 6711 if ((imm <= 65535) && cond.IsNotNever() && 6712 (!rd.IsPC() || AllowUnpredictable())) { 6713 EmitA32(0x03400000U | (cond.GetCondition() << 28) | 6714 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 6715 return; 6716 } 6717 } 6718 } 6719 Delegate(kMovt, &Assembler::movt, cond, rd, operand); 6720 } 6721 6722 void Assembler::movw(Condition cond, Register rd, const Operand& operand) { 6723 VIXL_ASSERT(AllowAssembler()); 6724 CheckIT(cond); 6725 if (operand.IsImmediate()) { 6726 uint32_t imm = operand.GetImmediate(); 6727 if (IsUsingT32()) { 6728 // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3 6729 if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) { 6730 EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) | 6731 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) | 6732 ((imm & 0xf000) << 4)); 6733 AdvanceIT(); 6734 return; 6735 } 6736 } else { 6737 // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2 6738 if ((imm <= 65535) && cond.IsNotNever() && 6739 (!rd.IsPC() || AllowUnpredictable())) { 6740 EmitA32(0x03000000U | (cond.GetCondition() << 28) | 6741 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4)); 6742 return; 6743 } 6744 } 6745 } 6746 Delegate(kMovw, &Assembler::movw, cond, rd, operand); 6747 } 6748 6749 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) { 6750 VIXL_ASSERT(AllowAssembler()); 6751 CheckIT(cond); 6752 if (IsUsingT32()) { 6753 // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1 6754 EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20)); 6755 AdvanceIT(); 6756 return; 6757 } else { 6758 // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1 6759 if (cond.IsNotNever()) { 6760 EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 6761 (spec_reg.GetReg() << 22)); 6762 return; 6763 } 6764 } 6765 Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg); 6766 } 6767 6768 void Assembler::msr(Condition cond, 6769 MaskedSpecialRegister spec_reg, 6770 const Operand& operand) { 6771 VIXL_ASSERT(AllowAssembler()); 6772 CheckIT(cond); 6773 if (operand.IsImmediate()) { 6774 uint32_t imm = operand.GetImmediate(); 6775 if (IsUsingA32()) { 6776 ImmediateA32 immediate_a32(imm); 6777 // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1 6778 if (immediate_a32.IsValid() && cond.IsNotNever()) { 6779 EmitA32(0x0320f000U | (cond.GetCondition() << 28) | 6780 ((spec_reg.GetReg() & 0xf) << 16) | 6781 ((spec_reg.GetReg() & 0x10) << 18) | 6782 immediate_a32.GetEncodingValue()); 6783 return; 6784 } 6785 } 6786 } 6787 if (operand.IsPlainRegister()) { 6788 Register rn = operand.GetBaseRegister(); 6789 if (IsUsingT32()) { 6790 // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1 6791 EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) | 6792 ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16)); 6793 AdvanceIT(); 6794 return; 6795 } else { 6796 // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1 6797 if (cond.IsNotNever()) { 6798 EmitA32(0x0120f000U | (cond.GetCondition() << 28) | 6799 ((spec_reg.GetReg() & 0xf) << 16) | 6800 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode()); 6801 return; 6802 } 6803 } 6804 } 6805 Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand); 6806 } 6807 6808 void Assembler::mul( 6809 Condition cond, EncodingSize size, Register rd, Register rn, Register rm) { 6810 VIXL_ASSERT(AllowAssembler()); 6811 CheckIT(cond); 6812 if (IsUsingT32()) { 6813 // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1 6814 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() && 6815 rm.IsLow()) { 6816 EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3)); 6817 AdvanceIT(); 6818 return; 6819 } 6820 // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2 6821 if (!size.IsNarrow()) { 6822 EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 6823 rm.GetCode()); 6824 AdvanceIT(); 6825 return; 6826 } 6827 } else { 6828 // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1 6829 if (cond.IsNotNever()) { 6830 EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 6831 rn.GetCode() | (rm.GetCode() << 8)); 6832 return; 6833 } 6834 } 6835 Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm); 6836 } 6837 6838 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) { 6839 VIXL_ASSERT(AllowAssembler()); 6840 CheckIT(cond); 6841 if (IsUsingT32()) { 6842 // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1 6843 if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) { 6844 EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3)); 6845 AdvanceIT(); 6846 return; 6847 } 6848 } else { 6849 // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1 6850 if (cond.IsNotNever()) { 6851 EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 6852 rn.GetCode() | (rm.GetCode() << 8)); 6853 return; 6854 } 6855 } 6856 Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm); 6857 } 6858 6859 void Assembler::mvn(Condition cond, 6860 EncodingSize size, 6861 Register rd, 6862 const Operand& operand) { 6863 VIXL_ASSERT(AllowAssembler()); 6864 CheckIT(cond); 6865 if (operand.IsImmediate()) { 6866 uint32_t imm = operand.GetImmediate(); 6867 if (IsUsingT32()) { 6868 ImmediateT32 immediate_t32(imm); 6869 // MVN{<c>}{<q>} <Rd>, #<const> ; T1 6870 if (!size.IsNarrow() && immediate_t32.IsValid()) { 6871 EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) | 6872 (immediate_t32.GetEncodingValue() & 0xff) | 6873 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 6874 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 6875 AdvanceIT(); 6876 return; 6877 } 6878 } else { 6879 ImmediateA32 immediate_a32(imm); 6880 // MVN{<c>}{<q>} <Rd>, #<const> ; A1 6881 if (immediate_a32.IsValid() && cond.IsNotNever()) { 6882 EmitA32(0x03e00000U | (cond.GetCondition() << 28) | 6883 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 6884 return; 6885 } 6886 } 6887 } 6888 if (operand.IsImmediateShiftedRegister()) { 6889 Register rm = operand.GetBaseRegister(); 6890 if (operand.IsPlainRegister()) { 6891 if (IsUsingT32()) { 6892 // MVN<c>{<q>} <Rd>, <Rm> ; T1 6893 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) { 6894 EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3)); 6895 AdvanceIT(); 6896 return; 6897 } 6898 } 6899 } 6900 Shift shift = operand.GetShift(); 6901 uint32_t amount = operand.GetShiftAmount(); 6902 if (IsUsingT32()) { 6903 // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 6904 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 6905 uint32_t amount_ = amount % 32; 6906 EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6907 (operand.GetTypeEncodingValue() << 4) | 6908 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6909 AdvanceIT(); 6910 return; 6911 } 6912 } else { 6913 // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 6914 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 6915 uint32_t amount_ = amount % 32; 6916 EmitA32(0x01e00000U | (cond.GetCondition() << 28) | 6917 (rd.GetCode() << 12) | rm.GetCode() | 6918 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 6919 return; 6920 } 6921 } 6922 } 6923 if (operand.IsRegisterShiftedRegister()) { 6924 Register rm = operand.GetBaseRegister(); 6925 Shift shift = operand.GetShift(); 6926 if (IsUsingA32()) { 6927 // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 6928 if (cond.IsNotNever()) { 6929 EmitA32(0x01e00010U | (cond.GetCondition() << 28) | 6930 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 6931 (operand.GetShiftRegister().GetCode() << 8)); 6932 return; 6933 } 6934 } 6935 } 6936 Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand); 6937 } 6938 6939 void Assembler::mvns(Condition cond, 6940 EncodingSize size, 6941 Register rd, 6942 const Operand& operand) { 6943 VIXL_ASSERT(AllowAssembler()); 6944 CheckIT(cond); 6945 if (operand.IsImmediate()) { 6946 uint32_t imm = operand.GetImmediate(); 6947 if (IsUsingT32()) { 6948 ImmediateT32 immediate_t32(imm); 6949 // MVNS{<c>}{<q>} <Rd>, #<const> ; T1 6950 if (!size.IsNarrow() && immediate_t32.IsValid()) { 6951 EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) | 6952 (immediate_t32.GetEncodingValue() & 0xff) | 6953 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 6954 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 6955 AdvanceIT(); 6956 return; 6957 } 6958 } else { 6959 ImmediateA32 immediate_a32(imm); 6960 // MVNS{<c>}{<q>} <Rd>, #<const> ; A1 6961 if (immediate_a32.IsValid() && cond.IsNotNever()) { 6962 EmitA32(0x03f00000U | (cond.GetCondition() << 28) | 6963 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 6964 return; 6965 } 6966 } 6967 } 6968 if (operand.IsImmediateShiftedRegister()) { 6969 Register rm = operand.GetBaseRegister(); 6970 if (operand.IsPlainRegister()) { 6971 if (IsUsingT32()) { 6972 // MVNS{<q>} <Rd>, <Rm> ; T1 6973 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) { 6974 EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3)); 6975 AdvanceIT(); 6976 return; 6977 } 6978 } 6979 } 6980 Shift shift = operand.GetShift(); 6981 uint32_t amount = operand.GetShiftAmount(); 6982 if (IsUsingT32()) { 6983 // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 6984 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 6985 uint32_t amount_ = amount % 32; 6986 EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() | 6987 (operand.GetTypeEncodingValue() << 4) | 6988 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 6989 AdvanceIT(); 6990 return; 6991 } 6992 } else { 6993 // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1 6994 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 6995 uint32_t amount_ = amount % 32; 6996 EmitA32(0x01f00000U | (cond.GetCondition() << 28) | 6997 (rd.GetCode() << 12) | rm.GetCode() | 6998 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 6999 return; 7000 } 7001 } 7002 } 7003 if (operand.IsRegisterShiftedRegister()) { 7004 Register rm = operand.GetBaseRegister(); 7005 Shift shift = operand.GetShift(); 7006 if (IsUsingA32()) { 7007 // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1 7008 if (cond.IsNotNever()) { 7009 EmitA32(0x01f00010U | (cond.GetCondition() << 28) | 7010 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) | 7011 (operand.GetShiftRegister().GetCode() << 8)); 7012 return; 7013 } 7014 } 7015 } 7016 Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand); 7017 } 7018 7019 void Assembler::nop(Condition cond, EncodingSize size) { 7020 VIXL_ASSERT(AllowAssembler()); 7021 CheckIT(cond); 7022 if (IsUsingT32()) { 7023 // NOP{<c>}{<q>} ; T1 7024 if (!size.IsWide()) { 7025 EmitT32_16(0xbf00); 7026 AdvanceIT(); 7027 return; 7028 } 7029 // NOP{<c>}.W ; T2 7030 if (!size.IsNarrow()) { 7031 EmitT32_32(0xf3af8000U); 7032 AdvanceIT(); 7033 return; 7034 } 7035 } else { 7036 // NOP{<c>}{<q>} ; A1 7037 if (cond.IsNotNever()) { 7038 EmitA32(0x0320f000U | (cond.GetCondition() << 28)); 7039 return; 7040 } 7041 } 7042 Delegate(kNop, &Assembler::nop, cond, size); 7043 } 7044 7045 void Assembler::orn(Condition cond, 7046 Register rd, 7047 Register rn, 7048 const Operand& operand) { 7049 VIXL_ASSERT(AllowAssembler()); 7050 CheckIT(cond); 7051 if (operand.IsImmediate()) { 7052 uint32_t imm = operand.GetImmediate(); 7053 if (IsUsingT32()) { 7054 ImmediateT32 immediate_t32(imm); 7055 // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7056 if (immediate_t32.IsValid() && !rn.Is(pc)) { 7057 EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7058 (immediate_t32.GetEncodingValue() & 0xff) | 7059 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7060 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7061 AdvanceIT(); 7062 return; 7063 } 7064 } 7065 } 7066 if (operand.IsImmediateShiftedRegister()) { 7067 Register rm = operand.GetBaseRegister(); 7068 Shift shift = operand.GetShift(); 7069 uint32_t amount = operand.GetShiftAmount(); 7070 if (IsUsingT32()) { 7071 // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 7072 if (shift.IsValidAmount(amount) && !rn.Is(pc)) { 7073 uint32_t amount_ = amount % 32; 7074 EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7075 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7076 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7077 AdvanceIT(); 7078 return; 7079 } 7080 } 7081 } 7082 Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand); 7083 } 7084 7085 void Assembler::orns(Condition cond, 7086 Register rd, 7087 Register rn, 7088 const Operand& operand) { 7089 VIXL_ASSERT(AllowAssembler()); 7090 CheckIT(cond); 7091 if (operand.IsImmediate()) { 7092 uint32_t imm = operand.GetImmediate(); 7093 if (IsUsingT32()) { 7094 ImmediateT32 immediate_t32(imm); 7095 // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7096 if (immediate_t32.IsValid() && !rn.Is(pc)) { 7097 EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7098 (immediate_t32.GetEncodingValue() & 0xff) | 7099 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7100 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7101 AdvanceIT(); 7102 return; 7103 } 7104 } 7105 } 7106 if (operand.IsImmediateShiftedRegister()) { 7107 Register rm = operand.GetBaseRegister(); 7108 Shift shift = operand.GetShift(); 7109 uint32_t amount = operand.GetShiftAmount(); 7110 if (IsUsingT32()) { 7111 // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 7112 if (shift.IsValidAmount(amount) && !rn.Is(pc)) { 7113 uint32_t amount_ = amount % 32; 7114 EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7115 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7116 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7117 AdvanceIT(); 7118 return; 7119 } 7120 } 7121 } 7122 Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand); 7123 } 7124 7125 void Assembler::orr(Condition cond, 7126 EncodingSize size, 7127 Register rd, 7128 Register rn, 7129 const Operand& operand) { 7130 VIXL_ASSERT(AllowAssembler()); 7131 CheckIT(cond); 7132 if (operand.IsImmediate()) { 7133 uint32_t imm = operand.GetImmediate(); 7134 if (IsUsingT32()) { 7135 ImmediateT32 immediate_t32(imm); 7136 // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7137 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) { 7138 EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7139 (immediate_t32.GetEncodingValue() & 0xff) | 7140 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7141 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7142 AdvanceIT(); 7143 return; 7144 } 7145 } else { 7146 ImmediateA32 immediate_a32(imm); 7147 // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 7148 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7149 EmitA32(0x03800000U | (cond.GetCondition() << 28) | 7150 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 7151 immediate_a32.GetEncodingValue()); 7152 return; 7153 } 7154 } 7155 } 7156 if (operand.IsImmediateShiftedRegister()) { 7157 Register rm = operand.GetBaseRegister(); 7158 if (operand.IsPlainRegister()) { 7159 if (IsUsingT32()) { 7160 // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 7161 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 7162 rm.IsLow()) { 7163 EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3)); 7164 AdvanceIT(); 7165 return; 7166 } 7167 } 7168 } 7169 Shift shift = operand.GetShift(); 7170 uint32_t amount = operand.GetShiftAmount(); 7171 if (IsUsingT32()) { 7172 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 7173 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) { 7174 uint32_t amount_ = amount % 32; 7175 EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7176 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7177 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7178 AdvanceIT(); 7179 return; 7180 } 7181 } else { 7182 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 7183 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7184 uint32_t amount_ = amount % 32; 7185 EmitA32(0x01800000U | (cond.GetCondition() << 28) | 7186 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7187 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7188 return; 7189 } 7190 } 7191 } 7192 if (operand.IsRegisterShiftedRegister()) { 7193 Register rm = operand.GetBaseRegister(); 7194 Shift shift = operand.GetShift(); 7195 if (IsUsingA32()) { 7196 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 7197 if (cond.IsNotNever()) { 7198 EmitA32(0x01800010U | (cond.GetCondition() << 28) | 7199 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7200 (shift.GetType() << 5) | 7201 (operand.GetShiftRegister().GetCode() << 8)); 7202 return; 7203 } 7204 } 7205 } 7206 Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand); 7207 } 7208 7209 void Assembler::orrs(Condition cond, 7210 EncodingSize size, 7211 Register rd, 7212 Register rn, 7213 const Operand& operand) { 7214 VIXL_ASSERT(AllowAssembler()); 7215 CheckIT(cond); 7216 if (operand.IsImmediate()) { 7217 uint32_t imm = operand.GetImmediate(); 7218 if (IsUsingT32()) { 7219 ImmediateT32 immediate_t32(imm); 7220 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 7221 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) { 7222 EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7223 (immediate_t32.GetEncodingValue() & 0xff) | 7224 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 7225 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 7226 AdvanceIT(); 7227 return; 7228 } 7229 } else { 7230 ImmediateA32 immediate_a32(imm); 7231 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 7232 if (immediate_a32.IsValid() && cond.IsNotNever()) { 7233 EmitA32(0x03900000U | (cond.GetCondition() << 28) | 7234 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 7235 immediate_a32.GetEncodingValue()); 7236 return; 7237 } 7238 } 7239 } 7240 if (operand.IsImmediateShiftedRegister()) { 7241 Register rm = operand.GetBaseRegister(); 7242 if (operand.IsPlainRegister()) { 7243 if (IsUsingT32()) { 7244 // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 7245 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 7246 rm.IsLow()) { 7247 EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3)); 7248 AdvanceIT(); 7249 return; 7250 } 7251 } 7252 } 7253 Shift shift = operand.GetShift(); 7254 uint32_t amount = operand.GetShiftAmount(); 7255 if (IsUsingT32()) { 7256 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 7257 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) { 7258 uint32_t amount_ = amount % 32; 7259 EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7260 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 7261 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 7262 AdvanceIT(); 7263 return; 7264 } 7265 } else { 7266 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 7267 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 7268 uint32_t amount_ = amount % 32; 7269 EmitA32(0x01900000U | (cond.GetCondition() << 28) | 7270 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7271 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 7272 return; 7273 } 7274 } 7275 } 7276 if (operand.IsRegisterShiftedRegister()) { 7277 Register rm = operand.GetBaseRegister(); 7278 Shift shift = operand.GetShift(); 7279 if (IsUsingA32()) { 7280 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 7281 if (cond.IsNotNever()) { 7282 EmitA32(0x01900010U | (cond.GetCondition() << 28) | 7283 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7284 (shift.GetType() << 5) | 7285 (operand.GetShiftRegister().GetCode() << 8)); 7286 return; 7287 } 7288 } 7289 } 7290 Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand); 7291 } 7292 7293 void Assembler::pkhbt(Condition cond, 7294 Register rd, 7295 Register rn, 7296 const Operand& operand) { 7297 VIXL_ASSERT(AllowAssembler()); 7298 CheckIT(cond); 7299 if (operand.IsImmediateShiftedRegister()) { 7300 Register rm = operand.GetBaseRegister(); 7301 Shift shift = operand.GetShift(); 7302 uint32_t amount = operand.GetShiftAmount(); 7303 if (IsUsingT32()) { 7304 // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1 7305 if (shift.IsLSL() && shift.IsValidAmount(amount)) { 7306 EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7307 rm.GetCode() | ((amount & 0x3) << 6) | 7308 ((amount & 0x1c) << 10)); 7309 AdvanceIT(); 7310 return; 7311 } 7312 } else { 7313 // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1 7314 if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever()) { 7315 EmitA32(0x06800010U | (cond.GetCondition() << 28) | 7316 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7317 (amount << 7)); 7318 return; 7319 } 7320 } 7321 } 7322 Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand); 7323 } 7324 7325 void Assembler::pkhtb(Condition cond, 7326 Register rd, 7327 Register rn, 7328 const Operand& operand) { 7329 VIXL_ASSERT(AllowAssembler()); 7330 CheckIT(cond); 7331 if (operand.IsImmediateShiftedRegister()) { 7332 Register rm = operand.GetBaseRegister(); 7333 Shift shift = operand.GetShift(); 7334 uint32_t amount = operand.GetShiftAmount(); 7335 if (IsUsingT32()) { 7336 // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1 7337 if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount)) { 7338 uint32_t amount_ = amount % 32; 7339 EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7340 rm.GetCode() | ((amount_ & 0x3) << 6) | 7341 ((amount_ & 0x1c) << 10)); 7342 AdvanceIT(); 7343 return; 7344 } 7345 } else { 7346 // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1 7347 if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) && 7348 cond.IsNotNever()) { 7349 uint32_t amount_ = amount % 32; 7350 EmitA32(0x06800050U | (cond.GetCondition() << 28) | 7351 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 7352 (amount_ << 7)); 7353 return; 7354 } 7355 } 7356 } 7357 Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand); 7358 } 7359 7360 void Assembler::pld(Condition cond, Label* label) { 7361 VIXL_ASSERT(AllowAssembler()); 7362 CheckIT(cond); 7363 Label::Offset offset = 7364 label->IsBound() 7365 ? label->GetLocation() - 7366 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 7367 : 0; 7368 if (IsUsingT32()) { 7369 // PLD{<c>}{<q>} <label> ; T1 7370 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 7371 !label->IsBound())) { 7372 static class EmitOp : public Label::LabelEmitOperator { 7373 public: 7374 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 7375 virtual uint32_t Encode(uint32_t instr, 7376 Label::Offset pc, 7377 const Label* label) const VIXL_OVERRIDE { 7378 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 7379 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 7380 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 7381 int32_t target = abs(offset) | (U << 12); 7382 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 7383 } 7384 } immop; 7385 EmitT32_32(Link(0xf81ff000U, label, immop)); 7386 AdvanceIT(); 7387 return; 7388 } 7389 } else { 7390 // PLD{<c>}{<q>} <label> ; A1 7391 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 7392 !label->IsBound())) { 7393 if (cond.Is(al)) { 7394 static class EmitOp : public Label::LabelEmitOperator { 7395 public: 7396 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 7397 virtual uint32_t Encode(uint32_t instr, 7398 Label::Offset pc, 7399 const Label* label) const VIXL_OVERRIDE { 7400 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 7401 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 7402 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 7403 int32_t target = abs(offset) | (U << 12); 7404 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 7405 } 7406 } immop; 7407 EmitA32(Link(0xf55ff000U, label, immop)); 7408 return; 7409 } 7410 } 7411 } 7412 Delegate(kPld, &Assembler::pld, cond, label); 7413 } 7414 7415 void Assembler::pld(Condition cond, const MemOperand& operand) { 7416 VIXL_ASSERT(AllowAssembler()); 7417 CheckIT(cond); 7418 if (operand.IsImmediate()) { 7419 Register rn = operand.GetBaseRegister(); 7420 int32_t offset = operand.GetOffsetImmediate(); 7421 if (IsUsingT32()) { 7422 // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1 7423 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 7424 operand.IsOffset()) { 7425 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 7426 uint32_t offset_ = abs(offset); 7427 EmitT32_32(0xf81ff000U | offset_ | (sign << 23)); 7428 AdvanceIT(); 7429 return; 7430 } 7431 } else { 7432 // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1 7433 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 7434 operand.IsOffset()) { 7435 if (cond.Is(al)) { 7436 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 7437 uint32_t offset_ = abs(offset); 7438 EmitA32(0xf55ff000U | offset_ | (sign << 23)); 7439 return; 7440 } 7441 } 7442 } 7443 } 7444 if (operand.IsImmediate()) { 7445 Register rn = operand.GetBaseRegister(); 7446 int32_t offset = operand.GetOffsetImmediate(); 7447 if (IsUsingT32()) { 7448 // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 7449 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 7450 ((rn.GetCode() & 0xf) != 0xf)) { 7451 EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 7452 AdvanceIT(); 7453 return; 7454 } 7455 // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 7456 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 7457 ((rn.GetCode() & 0xf) != 0xf)) { 7458 EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 7459 AdvanceIT(); 7460 return; 7461 } 7462 } else { 7463 // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1 7464 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 7465 ((rn.GetCode() & 0xf) != 0xf)) { 7466 if (cond.Is(al)) { 7467 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 7468 uint32_t offset_ = abs(offset); 7469 EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 7470 return; 7471 } 7472 } 7473 } 7474 } 7475 if (operand.IsShiftedRegister()) { 7476 Register rn = operand.GetBaseRegister(); 7477 Sign sign = operand.GetSign(); 7478 Register rm = operand.GetOffsetRegister(); 7479 Shift shift = operand.GetShift(); 7480 uint32_t amount = operand.GetShiftAmount(); 7481 if (IsUsingT32()) { 7482 // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 7483 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 7484 ((rn.GetCode() & 0xf) != 0xf)) { 7485 EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() | 7486 (amount << 4)); 7487 AdvanceIT(); 7488 return; 7489 } 7490 } else { 7491 // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 7492 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) { 7493 if (cond.Is(al)) { 7494 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 7495 uint32_t amount_ = amount % 32; 7496 EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() | 7497 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 7498 return; 7499 } 7500 } 7501 // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 7502 if (shift.IsRRX() && operand.IsOffset()) { 7503 if (cond.Is(al)) { 7504 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 7505 EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() | 7506 (sign_ << 23)); 7507 return; 7508 } 7509 } 7510 } 7511 } 7512 Delegate(kPld, &Assembler::pld, cond, operand); 7513 } 7514 7515 void Assembler::pldw(Condition cond, const MemOperand& operand) { 7516 VIXL_ASSERT(AllowAssembler()); 7517 CheckIT(cond); 7518 if (operand.IsImmediate()) { 7519 Register rn = operand.GetBaseRegister(); 7520 int32_t offset = operand.GetOffsetImmediate(); 7521 if (IsUsingT32()) { 7522 // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 7523 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 7524 ((rn.GetCode() & 0xf) != 0xf)) { 7525 EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 7526 AdvanceIT(); 7527 return; 7528 } 7529 // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 7530 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 7531 ((rn.GetCode() & 0xf) != 0xf)) { 7532 EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 7533 AdvanceIT(); 7534 return; 7535 } 7536 } else { 7537 // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1 7538 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 7539 ((rn.GetCode() & 0xf) != 0xf)) { 7540 if (cond.Is(al)) { 7541 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 7542 uint32_t offset_ = abs(offset); 7543 EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 7544 return; 7545 } 7546 } 7547 } 7548 } 7549 if (operand.IsShiftedRegister()) { 7550 Register rn = operand.GetBaseRegister(); 7551 Sign sign = operand.GetSign(); 7552 Register rm = operand.GetOffsetRegister(); 7553 Shift shift = operand.GetShift(); 7554 uint32_t amount = operand.GetShiftAmount(); 7555 if (IsUsingT32()) { 7556 // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 7557 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 7558 ((rn.GetCode() & 0xf) != 0xf)) { 7559 EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() | 7560 (amount << 4)); 7561 AdvanceIT(); 7562 return; 7563 } 7564 } else { 7565 // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 7566 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) { 7567 if (cond.Is(al)) { 7568 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 7569 uint32_t amount_ = amount % 32; 7570 EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() | 7571 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 7572 return; 7573 } 7574 } 7575 // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 7576 if (shift.IsRRX() && operand.IsOffset()) { 7577 if (cond.Is(al)) { 7578 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 7579 EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() | 7580 (sign_ << 23)); 7581 return; 7582 } 7583 } 7584 } 7585 } 7586 Delegate(kPldw, &Assembler::pldw, cond, operand); 7587 } 7588 7589 void Assembler::pli(Condition cond, const MemOperand& operand) { 7590 VIXL_ASSERT(AllowAssembler()); 7591 CheckIT(cond); 7592 if (operand.IsImmediate()) { 7593 Register rn = operand.GetBaseRegister(); 7594 int32_t offset = operand.GetOffsetImmediate(); 7595 if (IsUsingT32()) { 7596 // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1 7597 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() && 7598 ((rn.GetCode() & 0xf) != 0xf)) { 7599 EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff)); 7600 AdvanceIT(); 7601 return; 7602 } 7603 // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 7604 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() && 7605 ((rn.GetCode() & 0xf) != 0xf)) { 7606 EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff)); 7607 AdvanceIT(); 7608 return; 7609 } 7610 } else { 7611 // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1 7612 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 7613 ((rn.GetCode() & 0xf) != 0xf)) { 7614 if (cond.Is(al)) { 7615 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 7616 uint32_t offset_ = abs(offset); 7617 EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23)); 7618 return; 7619 } 7620 } 7621 } 7622 } 7623 if (operand.IsImmediate()) { 7624 Register rn = operand.GetBaseRegister(); 7625 int32_t offset = operand.GetOffsetImmediate(); 7626 if (IsUsingT32()) { 7627 // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3 7628 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 7629 operand.IsOffset()) { 7630 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 7631 uint32_t offset_ = abs(offset); 7632 EmitT32_32(0xf91ff000U | offset_ | (sign << 23)); 7633 AdvanceIT(); 7634 return; 7635 } 7636 } else { 7637 // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1 7638 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) && 7639 operand.IsOffset()) { 7640 if (cond.Is(al)) { 7641 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 7642 uint32_t offset_ = abs(offset); 7643 EmitA32(0xf45ff000U | offset_ | (sign << 23)); 7644 return; 7645 } 7646 } 7647 } 7648 } 7649 if (operand.IsShiftedRegister()) { 7650 Register rn = operand.GetBaseRegister(); 7651 Sign sign = operand.GetSign(); 7652 Register rm = operand.GetOffsetRegister(); 7653 Shift shift = operand.GetShift(); 7654 uint32_t amount = operand.GetShiftAmount(); 7655 if (IsUsingT32()) { 7656 // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 7657 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() && 7658 ((rn.GetCode() & 0xf) != 0xf)) { 7659 EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() | 7660 (amount << 4)); 7661 AdvanceIT(); 7662 return; 7663 } 7664 } else { 7665 // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1 7666 if (shift.IsRRX() && operand.IsOffset()) { 7667 if (cond.Is(al)) { 7668 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 7669 EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() | 7670 (sign_ << 23)); 7671 return; 7672 } 7673 } 7674 // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1 7675 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) { 7676 if (cond.Is(al)) { 7677 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 7678 uint32_t amount_ = amount % 32; 7679 EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() | 7680 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7)); 7681 return; 7682 } 7683 } 7684 } 7685 } 7686 Delegate(kPli, &Assembler::pli, cond, operand); 7687 } 7688 7689 void Assembler::pli(Condition cond, Label* label) { 7690 VIXL_ASSERT(AllowAssembler()); 7691 CheckIT(cond); 7692 Label::Offset offset = 7693 label->IsBound() 7694 ? label->GetLocation() - 7695 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 7696 : 0; 7697 if (IsUsingT32()) { 7698 // PLI{<c>}{<q>} <label> ; T3 7699 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 7700 !label->IsBound())) { 7701 static class EmitOp : public Label::LabelEmitOperator { 7702 public: 7703 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 7704 virtual uint32_t Encode(uint32_t instr, 7705 Label::Offset pc, 7706 const Label* label) const VIXL_OVERRIDE { 7707 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 7708 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 7709 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 7710 int32_t target = abs(offset) | (U << 12); 7711 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 7712 } 7713 } immop; 7714 EmitT32_32(Link(0xf91ff000U, label, immop)); 7715 AdvanceIT(); 7716 return; 7717 } 7718 } else { 7719 // PLI{<c>}{<q>} <label> ; A1 7720 if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) || 7721 !label->IsBound())) { 7722 if (cond.Is(al)) { 7723 static class EmitOp : public Label::LabelEmitOperator { 7724 public: 7725 EmitOp() : Label::LabelEmitOperator(-4095, 4095) {} 7726 virtual uint32_t Encode(uint32_t instr, 7727 Label::Offset pc, 7728 const Label* label) const VIXL_OVERRIDE { 7729 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 7730 VIXL_ASSERT((offset >= -4095) && (offset <= 4095)); 7731 uint32_t U = (offset >= 0) && !label->IsMinusZero(); 7732 int32_t target = abs(offset) | (U << 12); 7733 return instr | (target & 0xfff) | ((target & 0x1000) << 11); 7734 } 7735 } immop; 7736 EmitA32(Link(0xf45ff000U, label, immop)); 7737 return; 7738 } 7739 } 7740 } 7741 Delegate(kPli, &Assembler::pli, cond, label); 7742 } 7743 7744 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) { 7745 VIXL_ASSERT(AllowAssembler()); 7746 CheckIT(cond); 7747 if (IsUsingT32()) { 7748 // POP{<c>}{<q>} <registers> ; T1 7749 if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) { 7750 EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) | 7751 GetRegisterListEncoding(registers, 0, 8)); 7752 AdvanceIT(); 7753 return; 7754 } 7755 // POP{<c>}{<q>} <registers> ; T2 7756 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) { 7757 EmitT32_32(0xe8bd0000U | 7758 (GetRegisterListEncoding(registers, 15, 1) << 15) | 7759 (GetRegisterListEncoding(registers, 14, 1) << 14) | 7760 GetRegisterListEncoding(registers, 0, 13)); 7761 AdvanceIT(); 7762 return; 7763 } 7764 } else { 7765 // POP{<c>}{<q>} <registers> ; A1 7766 if (cond.IsNotNever()) { 7767 EmitA32(0x08bd0000U | (cond.GetCondition() << 28) | 7768 GetRegisterListEncoding(registers, 0, 16)); 7769 return; 7770 } 7771 } 7772 Delegate(kPop, &Assembler::pop, cond, size, registers); 7773 } 7774 7775 void Assembler::pop(Condition cond, EncodingSize size, Register rt) { 7776 VIXL_ASSERT(AllowAssembler()); 7777 CheckIT(cond); 7778 if (IsUsingT32()) { 7779 // POP{<c>}{<q>} <single_register_list> ; T4 7780 if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) { 7781 EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12)); 7782 AdvanceIT(); 7783 return; 7784 } 7785 } else { 7786 // POP{<c>}{<q>} <single_register_list> ; A1 7787 if (cond.IsNotNever()) { 7788 EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12)); 7789 return; 7790 } 7791 } 7792 Delegate(kPop, &Assembler::pop, cond, size, rt); 7793 } 7794 7795 void Assembler::push(Condition cond, 7796 EncodingSize size, 7797 RegisterList registers) { 7798 VIXL_ASSERT(AllowAssembler()); 7799 CheckIT(cond); 7800 if (IsUsingT32()) { 7801 // PUSH{<c>}{<q>} <registers> ; T1 7802 if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) { 7803 EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) | 7804 GetRegisterListEncoding(registers, 0, 8)); 7805 AdvanceIT(); 7806 return; 7807 } 7808 // PUSH{<c>}{<q>} <registers> ; T1 7809 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) { 7810 EmitT32_32(0xe92d0000U | 7811 (GetRegisterListEncoding(registers, 14, 1) << 14) | 7812 GetRegisterListEncoding(registers, 0, 13)); 7813 AdvanceIT(); 7814 return; 7815 } 7816 } else { 7817 // PUSH{<c>}{<q>} <registers> ; A1 7818 if (cond.IsNotNever()) { 7819 EmitA32(0x092d0000U | (cond.GetCondition() << 28) | 7820 GetRegisterListEncoding(registers, 0, 16)); 7821 return; 7822 } 7823 } 7824 Delegate(kPush, &Assembler::push, cond, size, registers); 7825 } 7826 7827 void Assembler::push(Condition cond, EncodingSize size, Register rt) { 7828 VIXL_ASSERT(AllowAssembler()); 7829 CheckIT(cond); 7830 if (IsUsingT32()) { 7831 // PUSH{<c>}{<q>} <single_register_list> ; T4 7832 if (!size.IsNarrow()) { 7833 EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12)); 7834 AdvanceIT(); 7835 return; 7836 } 7837 } else { 7838 // PUSH{<c>}{<q>} <single_register_list> ; A1 7839 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) { 7840 EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12)); 7841 return; 7842 } 7843 } 7844 Delegate(kPush, &Assembler::push, cond, size, rt); 7845 } 7846 7847 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) { 7848 VIXL_ASSERT(AllowAssembler()); 7849 CheckIT(cond); 7850 if (IsUsingT32()) { 7851 // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 7852 EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() | 7853 (rn.GetCode() << 16)); 7854 AdvanceIT(); 7855 return; 7856 } else { 7857 // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 7858 if (cond.IsNotNever()) { 7859 EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7860 rm.GetCode() | (rn.GetCode() << 16)); 7861 return; 7862 } 7863 } 7864 Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn); 7865 } 7866 7867 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) { 7868 VIXL_ASSERT(AllowAssembler()); 7869 CheckIT(cond); 7870 if (IsUsingT32()) { 7871 // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 7872 EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7873 rm.GetCode()); 7874 AdvanceIT(); 7875 return; 7876 } else { 7877 // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 7878 if (cond.IsNotNever()) { 7879 EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7880 (rn.GetCode() << 16) | rm.GetCode()); 7881 return; 7882 } 7883 } 7884 Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm); 7885 } 7886 7887 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) { 7888 VIXL_ASSERT(AllowAssembler()); 7889 CheckIT(cond); 7890 if (IsUsingT32()) { 7891 // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 7892 EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7893 rm.GetCode()); 7894 AdvanceIT(); 7895 return; 7896 } else { 7897 // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 7898 if (cond.IsNotNever()) { 7899 EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7900 (rn.GetCode() << 16) | rm.GetCode()); 7901 return; 7902 } 7903 } 7904 Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm); 7905 } 7906 7907 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) { 7908 VIXL_ASSERT(AllowAssembler()); 7909 CheckIT(cond); 7910 if (IsUsingT32()) { 7911 // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 7912 EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7913 rm.GetCode()); 7914 AdvanceIT(); 7915 return; 7916 } else { 7917 // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 7918 if (cond.IsNotNever()) { 7919 EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7920 (rn.GetCode() << 16) | rm.GetCode()); 7921 return; 7922 } 7923 } 7924 Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm); 7925 } 7926 7927 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) { 7928 VIXL_ASSERT(AllowAssembler()); 7929 CheckIT(cond); 7930 if (IsUsingT32()) { 7931 // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 7932 EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() | 7933 (rn.GetCode() << 16)); 7934 AdvanceIT(); 7935 return; 7936 } else { 7937 // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 7938 if (cond.IsNotNever()) { 7939 EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7940 rm.GetCode() | (rn.GetCode() << 16)); 7941 return; 7942 } 7943 } 7944 Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn); 7945 } 7946 7947 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) { 7948 VIXL_ASSERT(AllowAssembler()); 7949 CheckIT(cond); 7950 if (IsUsingT32()) { 7951 // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 7952 EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() | 7953 (rn.GetCode() << 16)); 7954 AdvanceIT(); 7955 return; 7956 } else { 7957 // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 7958 if (cond.IsNotNever()) { 7959 EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7960 rm.GetCode() | (rn.GetCode() << 16)); 7961 return; 7962 } 7963 } 7964 Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn); 7965 } 7966 7967 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) { 7968 VIXL_ASSERT(AllowAssembler()); 7969 CheckIT(cond); 7970 if (IsUsingT32()) { 7971 // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 7972 EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 7973 rm.GetCode()); 7974 AdvanceIT(); 7975 return; 7976 } else { 7977 // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 7978 if (cond.IsNotNever()) { 7979 EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 7980 (rn.GetCode() << 16) | rm.GetCode()); 7981 return; 7982 } 7983 } 7984 Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm); 7985 } 7986 7987 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) { 7988 VIXL_ASSERT(AllowAssembler()); 7989 CheckIT(cond); 7990 if (IsUsingT32()) { 7991 // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1 7992 EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() | 7993 (rn.GetCode() << 16)); 7994 AdvanceIT(); 7995 return; 7996 } else { 7997 // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1 7998 if (cond.IsNotNever()) { 7999 EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8000 rm.GetCode() | (rn.GetCode() << 16)); 8001 return; 8002 } 8003 } 8004 Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn); 8005 } 8006 8007 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) { 8008 VIXL_ASSERT(AllowAssembler()); 8009 CheckIT(cond); 8010 if (IsUsingT32()) { 8011 // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8012 EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8013 rm.GetCode()); 8014 AdvanceIT(); 8015 return; 8016 } else { 8017 // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8018 if (cond.IsNotNever()) { 8019 EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8020 (rn.GetCode() << 16) | rm.GetCode()); 8021 return; 8022 } 8023 } 8024 Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm); 8025 } 8026 8027 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) { 8028 VIXL_ASSERT(AllowAssembler()); 8029 CheckIT(cond); 8030 if (IsUsingT32()) { 8031 // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8032 EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8033 rm.GetCode()); 8034 AdvanceIT(); 8035 return; 8036 } else { 8037 // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8038 if (cond.IsNotNever()) { 8039 EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8040 (rn.GetCode() << 16) | rm.GetCode()); 8041 return; 8042 } 8043 } 8044 Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm); 8045 } 8046 8047 void Assembler::rbit(Condition cond, Register rd, Register rm) { 8048 VIXL_ASSERT(AllowAssembler()); 8049 CheckIT(cond); 8050 if (IsUsingT32()) { 8051 // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1 8052 EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() | 8053 (rm.GetCode() << 16)); 8054 AdvanceIT(); 8055 return; 8056 } else { 8057 // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1 8058 if (cond.IsNotNever()) { 8059 EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8060 rm.GetCode()); 8061 return; 8062 } 8063 } 8064 Delegate(kRbit, &Assembler::rbit, cond, rd, rm); 8065 } 8066 8067 void Assembler::rev(Condition cond, 8068 EncodingSize size, 8069 Register rd, 8070 Register rm) { 8071 VIXL_ASSERT(AllowAssembler()); 8072 CheckIT(cond); 8073 if (IsUsingT32()) { 8074 // REV{<c>}{<q>} <Rd>, <Rm> ; T1 8075 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8076 EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3)); 8077 AdvanceIT(); 8078 return; 8079 } 8080 // REV{<c>}{<q>} <Rd>, <Rm> ; T2 8081 if (!size.IsNarrow()) { 8082 EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() | 8083 (rm.GetCode() << 16)); 8084 AdvanceIT(); 8085 return; 8086 } 8087 } else { 8088 // REV{<c>}{<q>} <Rd>, <Rm> ; A1 8089 if (cond.IsNotNever()) { 8090 EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8091 rm.GetCode()); 8092 return; 8093 } 8094 } 8095 Delegate(kRev, &Assembler::rev, cond, size, rd, rm); 8096 } 8097 8098 void Assembler::rev16(Condition cond, 8099 EncodingSize size, 8100 Register rd, 8101 Register rm) { 8102 VIXL_ASSERT(AllowAssembler()); 8103 CheckIT(cond); 8104 if (IsUsingT32()) { 8105 // REV16{<c>}{<q>} <Rd>, <Rm> ; T1 8106 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8107 EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3)); 8108 AdvanceIT(); 8109 return; 8110 } 8111 // REV16{<c>}{<q>} <Rd>, <Rm> ; T2 8112 if (!size.IsNarrow()) { 8113 EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() | 8114 (rm.GetCode() << 16)); 8115 AdvanceIT(); 8116 return; 8117 } 8118 } else { 8119 // REV16{<c>}{<q>} <Rd>, <Rm> ; A1 8120 if (cond.IsNotNever()) { 8121 EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8122 rm.GetCode()); 8123 return; 8124 } 8125 } 8126 Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm); 8127 } 8128 8129 void Assembler::revsh(Condition cond, 8130 EncodingSize size, 8131 Register rd, 8132 Register rm) { 8133 VIXL_ASSERT(AllowAssembler()); 8134 CheckIT(cond); 8135 if (IsUsingT32()) { 8136 // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1 8137 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 8138 EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3)); 8139 AdvanceIT(); 8140 return; 8141 } 8142 // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2 8143 if (!size.IsNarrow()) { 8144 EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() | 8145 (rm.GetCode() << 16)); 8146 AdvanceIT(); 8147 return; 8148 } 8149 } else { 8150 // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1 8151 if (cond.IsNotNever()) { 8152 EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8153 rm.GetCode()); 8154 return; 8155 } 8156 } 8157 Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm); 8158 } 8159 8160 void Assembler::ror(Condition cond, 8161 EncodingSize size, 8162 Register rd, 8163 Register rm, 8164 const Operand& operand) { 8165 VIXL_ASSERT(AllowAssembler()); 8166 CheckIT(cond); 8167 if (operand.IsImmediate()) { 8168 uint32_t imm = operand.GetImmediate(); 8169 if (IsUsingT32()) { 8170 // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 8171 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) { 8172 EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() | 8173 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 8174 AdvanceIT(); 8175 return; 8176 } 8177 } else { 8178 // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 8179 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 8180 EmitA32(0x01a00060U | (cond.GetCondition() << 28) | 8181 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 8182 return; 8183 } 8184 } 8185 } 8186 if (operand.IsPlainRegister()) { 8187 Register rs = operand.GetBaseRegister(); 8188 if (IsUsingT32()) { 8189 // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 8190 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 8191 rs.IsLow()) { 8192 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 8193 AdvanceIT(); 8194 return; 8195 } 8196 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 8197 if (!size.IsNarrow()) { 8198 EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 8199 rs.GetCode()); 8200 AdvanceIT(); 8201 return; 8202 } 8203 } else { 8204 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 8205 if (cond.IsNotNever()) { 8206 EmitA32(0x01a00070U | (cond.GetCondition() << 28) | 8207 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 8208 return; 8209 } 8210 } 8211 } 8212 Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand); 8213 } 8214 8215 void Assembler::rors(Condition cond, 8216 EncodingSize size, 8217 Register rd, 8218 Register rm, 8219 const Operand& operand) { 8220 VIXL_ASSERT(AllowAssembler()); 8221 CheckIT(cond); 8222 if (operand.IsImmediate()) { 8223 uint32_t imm = operand.GetImmediate(); 8224 if (IsUsingT32()) { 8225 // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3 8226 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) { 8227 EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() | 8228 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10)); 8229 AdvanceIT(); 8230 return; 8231 } 8232 } else { 8233 // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1 8234 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) { 8235 EmitA32(0x01b00060U | (cond.GetCondition() << 28) | 8236 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7)); 8237 return; 8238 } 8239 } 8240 } 8241 if (operand.IsPlainRegister()) { 8242 Register rs = operand.GetBaseRegister(); 8243 if (IsUsingT32()) { 8244 // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 8245 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() && 8246 rs.IsLow()) { 8247 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3)); 8248 AdvanceIT(); 8249 return; 8250 } 8251 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 8252 if (!size.IsNarrow()) { 8253 EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) | 8254 rs.GetCode()); 8255 AdvanceIT(); 8256 return; 8257 } 8258 } else { 8259 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1 8260 if (cond.IsNotNever()) { 8261 EmitA32(0x01b00070U | (cond.GetCondition() << 28) | 8262 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8)); 8263 return; 8264 } 8265 } 8266 } 8267 Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand); 8268 } 8269 8270 void Assembler::rrx(Condition cond, Register rd, Register rm) { 8271 VIXL_ASSERT(AllowAssembler()); 8272 CheckIT(cond); 8273 if (IsUsingT32()) { 8274 // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3 8275 EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode()); 8276 AdvanceIT(); 8277 return; 8278 } else { 8279 // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1 8280 if (cond.IsNotNever()) { 8281 EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8282 rm.GetCode()); 8283 return; 8284 } 8285 } 8286 Delegate(kRrx, &Assembler::rrx, cond, rd, rm); 8287 } 8288 8289 void Assembler::rrxs(Condition cond, Register rd, Register rm) { 8290 VIXL_ASSERT(AllowAssembler()); 8291 CheckIT(cond); 8292 if (IsUsingT32()) { 8293 // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3 8294 EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode()); 8295 AdvanceIT(); 8296 return; 8297 } else { 8298 // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1 8299 if (cond.IsNotNever()) { 8300 EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8301 rm.GetCode()); 8302 return; 8303 } 8304 } 8305 Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm); 8306 } 8307 8308 void Assembler::rsb(Condition cond, 8309 EncodingSize size, 8310 Register rd, 8311 Register rn, 8312 const Operand& operand) { 8313 VIXL_ASSERT(AllowAssembler()); 8314 CheckIT(cond); 8315 if (operand.IsImmediate()) { 8316 uint32_t imm = operand.GetImmediate(); 8317 if (IsUsingT32()) { 8318 ImmediateT32 immediate_t32(imm); 8319 // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1 8320 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 8321 (imm == 0)) { 8322 EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3)); 8323 AdvanceIT(); 8324 return; 8325 } 8326 // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2 8327 if (!size.IsNarrow() && immediate_t32.IsValid()) { 8328 EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8329 (immediate_t32.GetEncodingValue() & 0xff) | 8330 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 8331 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 8332 AdvanceIT(); 8333 return; 8334 } 8335 } else { 8336 ImmediateA32 immediate_a32(imm); 8337 // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 8338 if (immediate_a32.IsValid() && cond.IsNotNever()) { 8339 EmitA32(0x02600000U | (cond.GetCondition() << 28) | 8340 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 8341 immediate_a32.GetEncodingValue()); 8342 return; 8343 } 8344 } 8345 } 8346 if (operand.IsImmediateShiftedRegister()) { 8347 Register rm = operand.GetBaseRegister(); 8348 Shift shift = operand.GetShift(); 8349 uint32_t amount = operand.GetShiftAmount(); 8350 if (IsUsingT32()) { 8351 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 8352 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 8353 uint32_t amount_ = amount % 32; 8354 EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8355 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 8356 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 8357 AdvanceIT(); 8358 return; 8359 } 8360 } else { 8361 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 8362 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 8363 uint32_t amount_ = amount % 32; 8364 EmitA32(0x00600000U | (cond.GetCondition() << 28) | 8365 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8366 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 8367 return; 8368 } 8369 } 8370 } 8371 if (operand.IsRegisterShiftedRegister()) { 8372 Register rm = operand.GetBaseRegister(); 8373 Shift shift = operand.GetShift(); 8374 if (IsUsingA32()) { 8375 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 8376 if (cond.IsNotNever()) { 8377 EmitA32(0x00600010U | (cond.GetCondition() << 28) | 8378 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8379 (shift.GetType() << 5) | 8380 (operand.GetShiftRegister().GetCode() << 8)); 8381 return; 8382 } 8383 } 8384 } 8385 Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand); 8386 } 8387 8388 void Assembler::rsbs(Condition cond, 8389 EncodingSize size, 8390 Register rd, 8391 Register rn, 8392 const Operand& operand) { 8393 VIXL_ASSERT(AllowAssembler()); 8394 CheckIT(cond); 8395 if (operand.IsImmediate()) { 8396 uint32_t imm = operand.GetImmediate(); 8397 if (IsUsingT32()) { 8398 ImmediateT32 immediate_t32(imm); 8399 // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1 8400 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 8401 (imm == 0)) { 8402 EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3)); 8403 AdvanceIT(); 8404 return; 8405 } 8406 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2 8407 if (!size.IsNarrow() && immediate_t32.IsValid()) { 8408 EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8409 (immediate_t32.GetEncodingValue() & 0xff) | 8410 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 8411 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 8412 AdvanceIT(); 8413 return; 8414 } 8415 } else { 8416 ImmediateA32 immediate_a32(imm); 8417 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 8418 if (immediate_a32.IsValid() && cond.IsNotNever()) { 8419 EmitA32(0x02700000U | (cond.GetCondition() << 28) | 8420 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 8421 immediate_a32.GetEncodingValue()); 8422 return; 8423 } 8424 } 8425 } 8426 if (operand.IsImmediateShiftedRegister()) { 8427 Register rm = operand.GetBaseRegister(); 8428 Shift shift = operand.GetShift(); 8429 uint32_t amount = operand.GetShiftAmount(); 8430 if (IsUsingT32()) { 8431 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 8432 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 8433 uint32_t amount_ = amount % 32; 8434 EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8435 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 8436 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 8437 AdvanceIT(); 8438 return; 8439 } 8440 } else { 8441 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 8442 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 8443 uint32_t amount_ = amount % 32; 8444 EmitA32(0x00700000U | (cond.GetCondition() << 28) | 8445 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8446 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 8447 return; 8448 } 8449 } 8450 } 8451 if (operand.IsRegisterShiftedRegister()) { 8452 Register rm = operand.GetBaseRegister(); 8453 Shift shift = operand.GetShift(); 8454 if (IsUsingA32()) { 8455 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 8456 if (cond.IsNotNever()) { 8457 EmitA32(0x00700010U | (cond.GetCondition() << 28) | 8458 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8459 (shift.GetType() << 5) | 8460 (operand.GetShiftRegister().GetCode() << 8)); 8461 return; 8462 } 8463 } 8464 } 8465 Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand); 8466 } 8467 8468 void Assembler::rsc(Condition cond, 8469 Register rd, 8470 Register rn, 8471 const Operand& operand) { 8472 VIXL_ASSERT(AllowAssembler()); 8473 CheckIT(cond); 8474 if (operand.IsImmediate()) { 8475 uint32_t imm = operand.GetImmediate(); 8476 if (IsUsingA32()) { 8477 ImmediateA32 immediate_a32(imm); 8478 // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 8479 if (immediate_a32.IsValid() && cond.IsNotNever()) { 8480 EmitA32(0x02e00000U | (cond.GetCondition() << 28) | 8481 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 8482 immediate_a32.GetEncodingValue()); 8483 return; 8484 } 8485 } 8486 } 8487 if (operand.IsImmediateShiftedRegister()) { 8488 Register rm = operand.GetBaseRegister(); 8489 Shift shift = operand.GetShift(); 8490 uint32_t amount = operand.GetShiftAmount(); 8491 if (IsUsingA32()) { 8492 // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 8493 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 8494 uint32_t amount_ = amount % 32; 8495 EmitA32(0x00e00000U | (cond.GetCondition() << 28) | 8496 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8497 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 8498 return; 8499 } 8500 } 8501 } 8502 if (operand.IsRegisterShiftedRegister()) { 8503 Register rm = operand.GetBaseRegister(); 8504 Shift shift = operand.GetShift(); 8505 if (IsUsingA32()) { 8506 // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 8507 if (cond.IsNotNever()) { 8508 EmitA32(0x00e00010U | (cond.GetCondition() << 28) | 8509 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8510 (shift.GetType() << 5) | 8511 (operand.GetShiftRegister().GetCode() << 8)); 8512 return; 8513 } 8514 } 8515 } 8516 Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand); 8517 } 8518 8519 void Assembler::rscs(Condition cond, 8520 Register rd, 8521 Register rn, 8522 const Operand& operand) { 8523 VIXL_ASSERT(AllowAssembler()); 8524 CheckIT(cond); 8525 if (operand.IsImmediate()) { 8526 uint32_t imm = operand.GetImmediate(); 8527 if (IsUsingA32()) { 8528 ImmediateA32 immediate_a32(imm); 8529 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 8530 if (immediate_a32.IsValid() && cond.IsNotNever()) { 8531 EmitA32(0x02f00000U | (cond.GetCondition() << 28) | 8532 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 8533 immediate_a32.GetEncodingValue()); 8534 return; 8535 } 8536 } 8537 } 8538 if (operand.IsImmediateShiftedRegister()) { 8539 Register rm = operand.GetBaseRegister(); 8540 Shift shift = operand.GetShift(); 8541 uint32_t amount = operand.GetShiftAmount(); 8542 if (IsUsingA32()) { 8543 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 8544 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 8545 uint32_t amount_ = amount % 32; 8546 EmitA32(0x00f00000U | (cond.GetCondition() << 28) | 8547 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8548 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 8549 return; 8550 } 8551 } 8552 } 8553 if (operand.IsRegisterShiftedRegister()) { 8554 Register rm = operand.GetBaseRegister(); 8555 Shift shift = operand.GetShift(); 8556 if (IsUsingA32()) { 8557 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 8558 if (cond.IsNotNever()) { 8559 EmitA32(0x00f00010U | (cond.GetCondition() << 28) | 8560 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8561 (shift.GetType() << 5) | 8562 (operand.GetShiftRegister().GetCode() << 8)); 8563 return; 8564 } 8565 } 8566 } 8567 Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand); 8568 } 8569 8570 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) { 8571 VIXL_ASSERT(AllowAssembler()); 8572 CheckIT(cond); 8573 if (IsUsingT32()) { 8574 // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8575 EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8576 rm.GetCode()); 8577 AdvanceIT(); 8578 return; 8579 } else { 8580 // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8581 if (cond.IsNotNever()) { 8582 EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8583 (rn.GetCode() << 16) | rm.GetCode()); 8584 return; 8585 } 8586 } 8587 Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm); 8588 } 8589 8590 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) { 8591 VIXL_ASSERT(AllowAssembler()); 8592 CheckIT(cond); 8593 if (IsUsingT32()) { 8594 // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8595 EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8596 rm.GetCode()); 8597 AdvanceIT(); 8598 return; 8599 } else { 8600 // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8601 if (cond.IsNotNever()) { 8602 EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8603 (rn.GetCode() << 16) | rm.GetCode()); 8604 return; 8605 } 8606 } 8607 Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm); 8608 } 8609 8610 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) { 8611 VIXL_ASSERT(AllowAssembler()); 8612 CheckIT(cond); 8613 if (IsUsingT32()) { 8614 // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8615 EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8616 rm.GetCode()); 8617 AdvanceIT(); 8618 return; 8619 } else { 8620 // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8621 if (cond.IsNotNever()) { 8622 EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8623 (rn.GetCode() << 16) | rm.GetCode()); 8624 return; 8625 } 8626 } 8627 Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm); 8628 } 8629 8630 void Assembler::sbc(Condition cond, 8631 EncodingSize size, 8632 Register rd, 8633 Register rn, 8634 const Operand& operand) { 8635 VIXL_ASSERT(AllowAssembler()); 8636 CheckIT(cond); 8637 if (operand.IsImmediate()) { 8638 uint32_t imm = operand.GetImmediate(); 8639 if (IsUsingT32()) { 8640 ImmediateT32 immediate_t32(imm); 8641 // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 8642 if (!size.IsNarrow() && immediate_t32.IsValid()) { 8643 EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8644 (immediate_t32.GetEncodingValue() & 0xff) | 8645 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 8646 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 8647 AdvanceIT(); 8648 return; 8649 } 8650 } else { 8651 ImmediateA32 immediate_a32(imm); 8652 // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 8653 if (immediate_a32.IsValid() && cond.IsNotNever()) { 8654 EmitA32(0x02c00000U | (cond.GetCondition() << 28) | 8655 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 8656 immediate_a32.GetEncodingValue()); 8657 return; 8658 } 8659 } 8660 } 8661 if (operand.IsImmediateShiftedRegister()) { 8662 Register rm = operand.GetBaseRegister(); 8663 if (operand.IsPlainRegister()) { 8664 if (IsUsingT32()) { 8665 // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 8666 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 8667 rm.IsLow()) { 8668 EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3)); 8669 AdvanceIT(); 8670 return; 8671 } 8672 } 8673 } 8674 Shift shift = operand.GetShift(); 8675 uint32_t amount = operand.GetShiftAmount(); 8676 if (IsUsingT32()) { 8677 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 8678 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 8679 uint32_t amount_ = amount % 32; 8680 EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8681 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 8682 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 8683 AdvanceIT(); 8684 return; 8685 } 8686 } else { 8687 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 8688 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 8689 uint32_t amount_ = amount % 32; 8690 EmitA32(0x00c00000U | (cond.GetCondition() << 28) | 8691 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8692 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 8693 return; 8694 } 8695 } 8696 } 8697 if (operand.IsRegisterShiftedRegister()) { 8698 Register rm = operand.GetBaseRegister(); 8699 Shift shift = operand.GetShift(); 8700 if (IsUsingA32()) { 8701 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 8702 if (cond.IsNotNever()) { 8703 EmitA32(0x00c00010U | (cond.GetCondition() << 28) | 8704 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8705 (shift.GetType() << 5) | 8706 (operand.GetShiftRegister().GetCode() << 8)); 8707 return; 8708 } 8709 } 8710 } 8711 Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand); 8712 } 8713 8714 void Assembler::sbcs(Condition cond, 8715 EncodingSize size, 8716 Register rd, 8717 Register rn, 8718 const Operand& operand) { 8719 VIXL_ASSERT(AllowAssembler()); 8720 CheckIT(cond); 8721 if (operand.IsImmediate()) { 8722 uint32_t imm = operand.GetImmediate(); 8723 if (IsUsingT32()) { 8724 ImmediateT32 immediate_t32(imm); 8725 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1 8726 if (!size.IsNarrow() && immediate_t32.IsValid()) { 8727 EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8728 (immediate_t32.GetEncodingValue() & 0xff) | 8729 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 8730 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 8731 AdvanceIT(); 8732 return; 8733 } 8734 } else { 8735 ImmediateA32 immediate_a32(imm); 8736 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 8737 if (immediate_a32.IsValid() && cond.IsNotNever()) { 8738 EmitA32(0x02d00000U | (cond.GetCondition() << 28) | 8739 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 8740 immediate_a32.GetEncodingValue()); 8741 return; 8742 } 8743 } 8744 } 8745 if (operand.IsImmediateShiftedRegister()) { 8746 Register rm = operand.GetBaseRegister(); 8747 if (operand.IsPlainRegister()) { 8748 if (IsUsingT32()) { 8749 // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 8750 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 8751 rm.IsLow()) { 8752 EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3)); 8753 AdvanceIT(); 8754 return; 8755 } 8756 } 8757 } 8758 Shift shift = operand.GetShift(); 8759 uint32_t amount = operand.GetShiftAmount(); 8760 if (IsUsingT32()) { 8761 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 8762 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 8763 uint32_t amount_ = amount % 32; 8764 EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8765 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 8766 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 8767 AdvanceIT(); 8768 return; 8769 } 8770 } else { 8771 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 8772 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 8773 uint32_t amount_ = amount % 32; 8774 EmitA32(0x00d00000U | (cond.GetCondition() << 28) | 8775 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8776 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 8777 return; 8778 } 8779 } 8780 } 8781 if (operand.IsRegisterShiftedRegister()) { 8782 Register rm = operand.GetBaseRegister(); 8783 Shift shift = operand.GetShift(); 8784 if (IsUsingA32()) { 8785 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 8786 if (cond.IsNotNever()) { 8787 EmitA32(0x00d00010U | (cond.GetCondition() << 28) | 8788 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 8789 (shift.GetType() << 5) | 8790 (operand.GetShiftRegister().GetCode() << 8)); 8791 return; 8792 } 8793 } 8794 } 8795 Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand); 8796 } 8797 8798 void Assembler::sbfx(Condition cond, 8799 Register rd, 8800 Register rn, 8801 uint32_t lsb, 8802 const Operand& operand) { 8803 VIXL_ASSERT(AllowAssembler()); 8804 CheckIT(cond); 8805 if (operand.IsImmediate()) { 8806 uint32_t width = operand.GetImmediate(); 8807 if (IsUsingT32()) { 8808 // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 8809 if ((lsb <= 31) && 8810 (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) { 8811 uint32_t widthm1 = width - 1; 8812 EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8813 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1); 8814 AdvanceIT(); 8815 return; 8816 } 8817 } else { 8818 // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 8819 if ((lsb <= 31) && cond.IsNotNever() && 8820 (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) { 8821 uint32_t widthm1 = width - 1; 8822 EmitA32(0x07a00050U | (cond.GetCondition() << 28) | 8823 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) | 8824 (widthm1 << 16)); 8825 return; 8826 } 8827 } 8828 } 8829 Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, operand); 8830 } 8831 8832 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) { 8833 VIXL_ASSERT(AllowAssembler()); 8834 CheckIT(cond); 8835 if (IsUsingT32()) { 8836 // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8837 EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8838 rm.GetCode()); 8839 AdvanceIT(); 8840 return; 8841 } else { 8842 // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8843 if (cond.IsNotNever()) { 8844 EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 8845 rn.GetCode() | (rm.GetCode() << 8)); 8846 return; 8847 } 8848 } 8849 Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm); 8850 } 8851 8852 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) { 8853 VIXL_ASSERT(AllowAssembler()); 8854 CheckIT(cond); 8855 if (IsUsingT32()) { 8856 // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8857 EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8858 rm.GetCode()); 8859 AdvanceIT(); 8860 return; 8861 } else { 8862 // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8863 if (cond.IsNotNever()) { 8864 EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8865 (rn.GetCode() << 16) | rm.GetCode()); 8866 return; 8867 } 8868 } 8869 Delegate(kSel, &Assembler::sel, cond, rd, rn, rm); 8870 } 8871 8872 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) { 8873 VIXL_ASSERT(AllowAssembler()); 8874 CheckIT(cond); 8875 if (IsUsingT32()) { 8876 // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8877 EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8878 rm.GetCode()); 8879 AdvanceIT(); 8880 return; 8881 } else { 8882 // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8883 if (cond.IsNotNever()) { 8884 EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8885 (rn.GetCode() << 16) | rm.GetCode()); 8886 return; 8887 } 8888 } 8889 Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm); 8890 } 8891 8892 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) { 8893 VIXL_ASSERT(AllowAssembler()); 8894 CheckIT(cond); 8895 if (IsUsingT32()) { 8896 // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8897 EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8898 rm.GetCode()); 8899 AdvanceIT(); 8900 return; 8901 } else { 8902 // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8903 if (cond.IsNotNever()) { 8904 EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8905 (rn.GetCode() << 16) | rm.GetCode()); 8906 return; 8907 } 8908 } 8909 Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm); 8910 } 8911 8912 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) { 8913 VIXL_ASSERT(AllowAssembler()); 8914 CheckIT(cond); 8915 if (IsUsingT32()) { 8916 // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8917 EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8918 rm.GetCode()); 8919 AdvanceIT(); 8920 return; 8921 } else { 8922 // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8923 if (cond.IsNotNever()) { 8924 EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8925 (rn.GetCode() << 16) | rm.GetCode()); 8926 return; 8927 } 8928 } 8929 Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm); 8930 } 8931 8932 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) { 8933 VIXL_ASSERT(AllowAssembler()); 8934 CheckIT(cond); 8935 if (IsUsingT32()) { 8936 // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8937 EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8938 rm.GetCode()); 8939 AdvanceIT(); 8940 return; 8941 } else { 8942 // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8943 if (cond.IsNotNever()) { 8944 EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8945 (rn.GetCode() << 16) | rm.GetCode()); 8946 return; 8947 } 8948 } 8949 Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm); 8950 } 8951 8952 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) { 8953 VIXL_ASSERT(AllowAssembler()); 8954 CheckIT(cond); 8955 if (IsUsingT32()) { 8956 // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8957 EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8958 rm.GetCode()); 8959 AdvanceIT(); 8960 return; 8961 } else { 8962 // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8963 if (cond.IsNotNever()) { 8964 EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8965 (rn.GetCode() << 16) | rm.GetCode()); 8966 return; 8967 } 8968 } 8969 Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm); 8970 } 8971 8972 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) { 8973 VIXL_ASSERT(AllowAssembler()); 8974 CheckIT(cond); 8975 if (IsUsingT32()) { 8976 // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 8977 EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 8978 rm.GetCode()); 8979 AdvanceIT(); 8980 return; 8981 } else { 8982 // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 8983 if (cond.IsNotNever()) { 8984 EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 8985 (rn.GetCode() << 16) | rm.GetCode()); 8986 return; 8987 } 8988 } 8989 Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm); 8990 } 8991 8992 void Assembler::smlabb( 8993 Condition cond, Register rd, Register rn, Register rm, Register ra) { 8994 VIXL_ASSERT(AllowAssembler()); 8995 CheckIT(cond); 8996 if (IsUsingT32()) { 8997 // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 8998 if (!ra.Is(pc)) { 8999 EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9000 rm.GetCode() | (ra.GetCode() << 12)); 9001 AdvanceIT(); 9002 return; 9003 } 9004 } else { 9005 // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9006 if (cond.IsNotNever()) { 9007 EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9008 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9009 return; 9010 } 9011 } 9012 Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra); 9013 } 9014 9015 void Assembler::smlabt( 9016 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9017 VIXL_ASSERT(AllowAssembler()); 9018 CheckIT(cond); 9019 if (IsUsingT32()) { 9020 // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9021 if (!ra.Is(pc)) { 9022 EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9023 rm.GetCode() | (ra.GetCode() << 12)); 9024 AdvanceIT(); 9025 return; 9026 } 9027 } else { 9028 // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9029 if (cond.IsNotNever()) { 9030 EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9031 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9032 return; 9033 } 9034 } 9035 Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra); 9036 } 9037 9038 void Assembler::smlad( 9039 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9040 VIXL_ASSERT(AllowAssembler()); 9041 CheckIT(cond); 9042 if (IsUsingT32()) { 9043 // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9044 if (!ra.Is(pc)) { 9045 EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9046 rm.GetCode() | (ra.GetCode() << 12)); 9047 AdvanceIT(); 9048 return; 9049 } 9050 } else { 9051 // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9052 if (cond.IsNotNever() && !ra.Is(pc)) { 9053 EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9054 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9055 return; 9056 } 9057 } 9058 Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra); 9059 } 9060 9061 void Assembler::smladx( 9062 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9063 VIXL_ASSERT(AllowAssembler()); 9064 CheckIT(cond); 9065 if (IsUsingT32()) { 9066 // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9067 if (!ra.Is(pc)) { 9068 EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9069 rm.GetCode() | (ra.GetCode() << 12)); 9070 AdvanceIT(); 9071 return; 9072 } 9073 } else { 9074 // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9075 if (cond.IsNotNever() && !ra.Is(pc)) { 9076 EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9077 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9078 return; 9079 } 9080 } 9081 Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra); 9082 } 9083 9084 void Assembler::smlal( 9085 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9086 VIXL_ASSERT(AllowAssembler()); 9087 CheckIT(cond); 9088 if (IsUsingT32()) { 9089 // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9090 EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9091 (rn.GetCode() << 16) | rm.GetCode()); 9092 AdvanceIT(); 9093 return; 9094 } else { 9095 // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9096 if (cond.IsNotNever()) { 9097 EmitA32(0x00e00090U | (cond.GetCondition() << 28) | 9098 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9099 (rm.GetCode() << 8)); 9100 return; 9101 } 9102 } 9103 Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm); 9104 } 9105 9106 void Assembler::smlalbb( 9107 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9108 VIXL_ASSERT(AllowAssembler()); 9109 CheckIT(cond); 9110 if (IsUsingT32()) { 9111 // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9112 EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9113 (rn.GetCode() << 16) | rm.GetCode()); 9114 AdvanceIT(); 9115 return; 9116 } else { 9117 // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9118 if (cond.IsNotNever()) { 9119 EmitA32(0x01400080U | (cond.GetCondition() << 28) | 9120 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9121 (rm.GetCode() << 8)); 9122 return; 9123 } 9124 } 9125 Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm); 9126 } 9127 9128 void Assembler::smlalbt( 9129 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9130 VIXL_ASSERT(AllowAssembler()); 9131 CheckIT(cond); 9132 if (IsUsingT32()) { 9133 // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9134 EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9135 (rn.GetCode() << 16) | rm.GetCode()); 9136 AdvanceIT(); 9137 return; 9138 } else { 9139 // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9140 if (cond.IsNotNever()) { 9141 EmitA32(0x014000c0U | (cond.GetCondition() << 28) | 9142 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9143 (rm.GetCode() << 8)); 9144 return; 9145 } 9146 } 9147 Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm); 9148 } 9149 9150 void Assembler::smlald( 9151 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9152 VIXL_ASSERT(AllowAssembler()); 9153 CheckIT(cond); 9154 if (IsUsingT32()) { 9155 // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9156 EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9157 (rn.GetCode() << 16) | rm.GetCode()); 9158 AdvanceIT(); 9159 return; 9160 } else { 9161 // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9162 if (cond.IsNotNever()) { 9163 EmitA32(0x07400010U | (cond.GetCondition() << 28) | 9164 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9165 (rm.GetCode() << 8)); 9166 return; 9167 } 9168 } 9169 Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm); 9170 } 9171 9172 void Assembler::smlaldx( 9173 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9174 VIXL_ASSERT(AllowAssembler()); 9175 CheckIT(cond); 9176 if (IsUsingT32()) { 9177 // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9178 EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9179 (rn.GetCode() << 16) | rm.GetCode()); 9180 AdvanceIT(); 9181 return; 9182 } else { 9183 // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9184 if (cond.IsNotNever()) { 9185 EmitA32(0x07400030U | (cond.GetCondition() << 28) | 9186 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9187 (rm.GetCode() << 8)); 9188 return; 9189 } 9190 } 9191 Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm); 9192 } 9193 9194 void Assembler::smlals( 9195 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9196 VIXL_ASSERT(AllowAssembler()); 9197 CheckIT(cond); 9198 if (IsUsingA32()) { 9199 // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9200 if (cond.IsNotNever()) { 9201 EmitA32(0x00f00090U | (cond.GetCondition() << 28) | 9202 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9203 (rm.GetCode() << 8)); 9204 return; 9205 } 9206 } 9207 Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm); 9208 } 9209 9210 void Assembler::smlaltb( 9211 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9212 VIXL_ASSERT(AllowAssembler()); 9213 CheckIT(cond); 9214 if (IsUsingT32()) { 9215 // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9216 EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9217 (rn.GetCode() << 16) | rm.GetCode()); 9218 AdvanceIT(); 9219 return; 9220 } else { 9221 // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9222 if (cond.IsNotNever()) { 9223 EmitA32(0x014000a0U | (cond.GetCondition() << 28) | 9224 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9225 (rm.GetCode() << 8)); 9226 return; 9227 } 9228 } 9229 Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm); 9230 } 9231 9232 void Assembler::smlaltt( 9233 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9234 VIXL_ASSERT(AllowAssembler()); 9235 CheckIT(cond); 9236 if (IsUsingT32()) { 9237 // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9238 EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9239 (rn.GetCode() << 16) | rm.GetCode()); 9240 AdvanceIT(); 9241 return; 9242 } else { 9243 // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9244 if (cond.IsNotNever()) { 9245 EmitA32(0x014000e0U | (cond.GetCondition() << 28) | 9246 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9247 (rm.GetCode() << 8)); 9248 return; 9249 } 9250 } 9251 Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm); 9252 } 9253 9254 void Assembler::smlatb( 9255 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9256 VIXL_ASSERT(AllowAssembler()); 9257 CheckIT(cond); 9258 if (IsUsingT32()) { 9259 // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9260 if (!ra.Is(pc)) { 9261 EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9262 rm.GetCode() | (ra.GetCode() << 12)); 9263 AdvanceIT(); 9264 return; 9265 } 9266 } else { 9267 // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9268 if (cond.IsNotNever()) { 9269 EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9270 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9271 return; 9272 } 9273 } 9274 Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra); 9275 } 9276 9277 void Assembler::smlatt( 9278 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9279 VIXL_ASSERT(AllowAssembler()); 9280 CheckIT(cond); 9281 if (IsUsingT32()) { 9282 // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9283 if (!ra.Is(pc)) { 9284 EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9285 rm.GetCode() | (ra.GetCode() << 12)); 9286 AdvanceIT(); 9287 return; 9288 } 9289 } else { 9290 // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9291 if (cond.IsNotNever()) { 9292 EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9293 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9294 return; 9295 } 9296 } 9297 Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra); 9298 } 9299 9300 void Assembler::smlawb( 9301 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9302 VIXL_ASSERT(AllowAssembler()); 9303 CheckIT(cond); 9304 if (IsUsingT32()) { 9305 // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9306 if (!ra.Is(pc)) { 9307 EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9308 rm.GetCode() | (ra.GetCode() << 12)); 9309 AdvanceIT(); 9310 return; 9311 } 9312 } else { 9313 // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9314 if (cond.IsNotNever()) { 9315 EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9316 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9317 return; 9318 } 9319 } 9320 Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra); 9321 } 9322 9323 void Assembler::smlawt( 9324 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9325 VIXL_ASSERT(AllowAssembler()); 9326 CheckIT(cond); 9327 if (IsUsingT32()) { 9328 // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9329 if (!ra.Is(pc)) { 9330 EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9331 rm.GetCode() | (ra.GetCode() << 12)); 9332 AdvanceIT(); 9333 return; 9334 } 9335 } else { 9336 // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9337 if (cond.IsNotNever()) { 9338 EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9339 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9340 return; 9341 } 9342 } 9343 Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra); 9344 } 9345 9346 void Assembler::smlsd( 9347 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9348 VIXL_ASSERT(AllowAssembler()); 9349 CheckIT(cond); 9350 if (IsUsingT32()) { 9351 // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9352 if (!ra.Is(pc)) { 9353 EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9354 rm.GetCode() | (ra.GetCode() << 12)); 9355 AdvanceIT(); 9356 return; 9357 } 9358 } else { 9359 // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9360 if (cond.IsNotNever() && !ra.Is(pc)) { 9361 EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9362 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9363 return; 9364 } 9365 } 9366 Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra); 9367 } 9368 9369 void Assembler::smlsdx( 9370 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9371 VIXL_ASSERT(AllowAssembler()); 9372 CheckIT(cond); 9373 if (IsUsingT32()) { 9374 // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9375 if (!ra.Is(pc)) { 9376 EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9377 rm.GetCode() | (ra.GetCode() << 12)); 9378 AdvanceIT(); 9379 return; 9380 } 9381 } else { 9382 // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9383 if (cond.IsNotNever() && !ra.Is(pc)) { 9384 EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9385 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9386 return; 9387 } 9388 } 9389 Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra); 9390 } 9391 9392 void Assembler::smlsld( 9393 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9394 VIXL_ASSERT(AllowAssembler()); 9395 CheckIT(cond); 9396 if (IsUsingT32()) { 9397 // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9398 EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9399 (rn.GetCode() << 16) | rm.GetCode()); 9400 AdvanceIT(); 9401 return; 9402 } else { 9403 // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9404 if (cond.IsNotNever()) { 9405 EmitA32(0x07400050U | (cond.GetCondition() << 28) | 9406 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9407 (rm.GetCode() << 8)); 9408 return; 9409 } 9410 } 9411 Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm); 9412 } 9413 9414 void Assembler::smlsldx( 9415 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9416 VIXL_ASSERT(AllowAssembler()); 9417 CheckIT(cond); 9418 if (IsUsingT32()) { 9419 // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9420 EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9421 (rn.GetCode() << 16) | rm.GetCode()); 9422 AdvanceIT(); 9423 return; 9424 } else { 9425 // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9426 if (cond.IsNotNever()) { 9427 EmitA32(0x07400070U | (cond.GetCondition() << 28) | 9428 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9429 (rm.GetCode() << 8)); 9430 return; 9431 } 9432 } 9433 Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm); 9434 } 9435 9436 void Assembler::smmla( 9437 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9438 VIXL_ASSERT(AllowAssembler()); 9439 CheckIT(cond); 9440 if (IsUsingT32()) { 9441 // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9442 if (!ra.Is(pc)) { 9443 EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9444 rm.GetCode() | (ra.GetCode() << 12)); 9445 AdvanceIT(); 9446 return; 9447 } 9448 } else { 9449 // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9450 if (cond.IsNotNever() && !ra.Is(pc)) { 9451 EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9452 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9453 return; 9454 } 9455 } 9456 Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra); 9457 } 9458 9459 void Assembler::smmlar( 9460 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9461 VIXL_ASSERT(AllowAssembler()); 9462 CheckIT(cond); 9463 if (IsUsingT32()) { 9464 // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9465 if (!ra.Is(pc)) { 9466 EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9467 rm.GetCode() | (ra.GetCode() << 12)); 9468 AdvanceIT(); 9469 return; 9470 } 9471 } else { 9472 // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9473 if (cond.IsNotNever() && !ra.Is(pc)) { 9474 EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9475 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9476 return; 9477 } 9478 } 9479 Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra); 9480 } 9481 9482 void Assembler::smmls( 9483 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9484 VIXL_ASSERT(AllowAssembler()); 9485 CheckIT(cond); 9486 if (IsUsingT32()) { 9487 // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9488 EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9489 rm.GetCode() | (ra.GetCode() << 12)); 9490 AdvanceIT(); 9491 return; 9492 } else { 9493 // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9494 if (cond.IsNotNever()) { 9495 EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9496 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9497 return; 9498 } 9499 } 9500 Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra); 9501 } 9502 9503 void Assembler::smmlsr( 9504 Condition cond, Register rd, Register rn, Register rm, Register ra) { 9505 VIXL_ASSERT(AllowAssembler()); 9506 CheckIT(cond); 9507 if (IsUsingT32()) { 9508 // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 9509 EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9510 rm.GetCode() | (ra.GetCode() << 12)); 9511 AdvanceIT(); 9512 return; 9513 } else { 9514 // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 9515 if (cond.IsNotNever()) { 9516 EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9517 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 9518 return; 9519 } 9520 } 9521 Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra); 9522 } 9523 9524 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) { 9525 VIXL_ASSERT(AllowAssembler()); 9526 CheckIT(cond); 9527 if (IsUsingT32()) { 9528 // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9529 EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9530 rm.GetCode()); 9531 AdvanceIT(); 9532 return; 9533 } else { 9534 // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9535 if (cond.IsNotNever()) { 9536 EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9537 rn.GetCode() | (rm.GetCode() << 8)); 9538 return; 9539 } 9540 } 9541 Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm); 9542 } 9543 9544 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) { 9545 VIXL_ASSERT(AllowAssembler()); 9546 CheckIT(cond); 9547 if (IsUsingT32()) { 9548 // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9549 EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9550 rm.GetCode()); 9551 AdvanceIT(); 9552 return; 9553 } else { 9554 // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9555 if (cond.IsNotNever()) { 9556 EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9557 rn.GetCode() | (rm.GetCode() << 8)); 9558 return; 9559 } 9560 } 9561 Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm); 9562 } 9563 9564 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) { 9565 VIXL_ASSERT(AllowAssembler()); 9566 CheckIT(cond); 9567 if (IsUsingT32()) { 9568 // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9569 EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9570 rm.GetCode()); 9571 AdvanceIT(); 9572 return; 9573 } else { 9574 // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9575 if (cond.IsNotNever()) { 9576 EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9577 rn.GetCode() | (rm.GetCode() << 8)); 9578 return; 9579 } 9580 } 9581 Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm); 9582 } 9583 9584 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) { 9585 VIXL_ASSERT(AllowAssembler()); 9586 CheckIT(cond); 9587 if (IsUsingT32()) { 9588 // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9589 EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9590 rm.GetCode()); 9591 AdvanceIT(); 9592 return; 9593 } else { 9594 // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9595 if (cond.IsNotNever()) { 9596 EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9597 rn.GetCode() | (rm.GetCode() << 8)); 9598 return; 9599 } 9600 } 9601 Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm); 9602 } 9603 9604 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) { 9605 VIXL_ASSERT(AllowAssembler()); 9606 CheckIT(cond); 9607 if (IsUsingT32()) { 9608 // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9609 EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9610 rm.GetCode()); 9611 AdvanceIT(); 9612 return; 9613 } else { 9614 // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9615 if (cond.IsNotNever()) { 9616 EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9617 rn.GetCode() | (rm.GetCode() << 8)); 9618 return; 9619 } 9620 } 9621 Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm); 9622 } 9623 9624 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) { 9625 VIXL_ASSERT(AllowAssembler()); 9626 CheckIT(cond); 9627 if (IsUsingT32()) { 9628 // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9629 EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9630 rm.GetCode()); 9631 AdvanceIT(); 9632 return; 9633 } else { 9634 // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9635 if (cond.IsNotNever()) { 9636 EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9637 rn.GetCode() | (rm.GetCode() << 8)); 9638 return; 9639 } 9640 } 9641 Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm); 9642 } 9643 9644 void Assembler::smull( 9645 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9646 VIXL_ASSERT(AllowAssembler()); 9647 CheckIT(cond); 9648 if (IsUsingT32()) { 9649 // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 9650 EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 9651 (rn.GetCode() << 16) | rm.GetCode()); 9652 AdvanceIT(); 9653 return; 9654 } else { 9655 // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9656 if (cond.IsNotNever()) { 9657 EmitA32(0x00c00090U | (cond.GetCondition() << 28) | 9658 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9659 (rm.GetCode() << 8)); 9660 return; 9661 } 9662 } 9663 Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm); 9664 } 9665 9666 void Assembler::smulls( 9667 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 9668 VIXL_ASSERT(AllowAssembler()); 9669 CheckIT(cond); 9670 if (IsUsingA32()) { 9671 // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 9672 if (cond.IsNotNever()) { 9673 EmitA32(0x00d00090U | (cond.GetCondition() << 28) | 9674 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 9675 (rm.GetCode() << 8)); 9676 return; 9677 } 9678 } 9679 Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm); 9680 } 9681 9682 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) { 9683 VIXL_ASSERT(AllowAssembler()); 9684 CheckIT(cond); 9685 if (IsUsingT32()) { 9686 // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9687 EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9688 rm.GetCode()); 9689 AdvanceIT(); 9690 return; 9691 } else { 9692 // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9693 if (cond.IsNotNever()) { 9694 EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9695 rn.GetCode() | (rm.GetCode() << 8)); 9696 return; 9697 } 9698 } 9699 Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm); 9700 } 9701 9702 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) { 9703 VIXL_ASSERT(AllowAssembler()); 9704 CheckIT(cond); 9705 if (IsUsingT32()) { 9706 // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9707 EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9708 rm.GetCode()); 9709 AdvanceIT(); 9710 return; 9711 } else { 9712 // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9713 if (cond.IsNotNever()) { 9714 EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9715 rn.GetCode() | (rm.GetCode() << 8)); 9716 return; 9717 } 9718 } 9719 Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm); 9720 } 9721 9722 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) { 9723 VIXL_ASSERT(AllowAssembler()); 9724 CheckIT(cond); 9725 if (IsUsingT32()) { 9726 // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9727 EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9728 rm.GetCode()); 9729 AdvanceIT(); 9730 return; 9731 } else { 9732 // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9733 if (cond.IsNotNever()) { 9734 EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9735 rn.GetCode() | (rm.GetCode() << 8)); 9736 return; 9737 } 9738 } 9739 Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm); 9740 } 9741 9742 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) { 9743 VIXL_ASSERT(AllowAssembler()); 9744 CheckIT(cond); 9745 if (IsUsingT32()) { 9746 // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9747 EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9748 rm.GetCode()); 9749 AdvanceIT(); 9750 return; 9751 } else { 9752 // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9753 if (cond.IsNotNever()) { 9754 EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9755 rn.GetCode() | (rm.GetCode() << 8)); 9756 return; 9757 } 9758 } 9759 Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm); 9760 } 9761 9762 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) { 9763 VIXL_ASSERT(AllowAssembler()); 9764 CheckIT(cond); 9765 if (IsUsingT32()) { 9766 // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9767 EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9768 rm.GetCode()); 9769 AdvanceIT(); 9770 return; 9771 } else { 9772 // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9773 if (cond.IsNotNever()) { 9774 EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9775 rn.GetCode() | (rm.GetCode() << 8)); 9776 return; 9777 } 9778 } 9779 Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm); 9780 } 9781 9782 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) { 9783 VIXL_ASSERT(AllowAssembler()); 9784 CheckIT(cond); 9785 if (IsUsingT32()) { 9786 // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9787 EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9788 rm.GetCode()); 9789 AdvanceIT(); 9790 return; 9791 } else { 9792 // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9793 if (cond.IsNotNever()) { 9794 EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 9795 rn.GetCode() | (rm.GetCode() << 8)); 9796 return; 9797 } 9798 } 9799 Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm); 9800 } 9801 9802 void Assembler::ssat(Condition cond, 9803 Register rd, 9804 uint32_t imm, 9805 const Operand& operand) { 9806 VIXL_ASSERT(AllowAssembler()); 9807 CheckIT(cond); 9808 if (operand.IsImmediateShiftedRegister()) { 9809 Register rn = operand.GetBaseRegister(); 9810 Shift shift = operand.GetShift(); 9811 uint32_t amount = operand.GetShiftAmount(); 9812 if (IsUsingT32()) { 9813 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1 9814 if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) && 9815 (amount <= 31)) { 9816 uint32_t imm_ = imm - 1; 9817 EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ | 9818 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 9819 ((amount & 0x1c) << 10)); 9820 AdvanceIT(); 9821 return; 9822 } 9823 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1 9824 if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31)) { 9825 uint32_t imm_ = imm - 1; 9826 EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ | 9827 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 9828 ((amount & 0x1c) << 10)); 9829 AdvanceIT(); 9830 return; 9831 } 9832 } else { 9833 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1 9834 if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) && 9835 (amount <= 32) && cond.IsNotNever()) { 9836 uint32_t imm_ = imm - 1; 9837 uint32_t amount_ = amount % 32; 9838 EmitA32(0x06a00050U | (cond.GetCondition() << 28) | 9839 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() | 9840 (amount_ << 7)); 9841 return; 9842 } 9843 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1 9844 if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) && 9845 cond.IsNotNever()) { 9846 uint32_t imm_ = imm - 1; 9847 EmitA32(0x06a00010U | (cond.GetCondition() << 28) | 9848 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() | 9849 (amount << 7)); 9850 return; 9851 } 9852 } 9853 } 9854 Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand); 9855 } 9856 9857 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) { 9858 VIXL_ASSERT(AllowAssembler()); 9859 CheckIT(cond); 9860 if (IsUsingT32()) { 9861 // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1 9862 if ((imm >= 1) && (imm <= 16)) { 9863 uint32_t imm_ = imm - 1; 9864 EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ | 9865 (rn.GetCode() << 16)); 9866 AdvanceIT(); 9867 return; 9868 } 9869 } else { 9870 // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1 9871 if ((imm >= 1) && (imm <= 16) && cond.IsNotNever()) { 9872 uint32_t imm_ = imm - 1; 9873 EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9874 (imm_ << 16) | rn.GetCode()); 9875 return; 9876 } 9877 } 9878 Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn); 9879 } 9880 9881 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) { 9882 VIXL_ASSERT(AllowAssembler()); 9883 CheckIT(cond); 9884 if (IsUsingT32()) { 9885 // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9886 EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9887 rm.GetCode()); 9888 AdvanceIT(); 9889 return; 9890 } else { 9891 // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9892 if (cond.IsNotNever()) { 9893 EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9894 (rn.GetCode() << 16) | rm.GetCode()); 9895 return; 9896 } 9897 } 9898 Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm); 9899 } 9900 9901 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) { 9902 VIXL_ASSERT(AllowAssembler()); 9903 CheckIT(cond); 9904 if (IsUsingT32()) { 9905 // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9906 EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9907 rm.GetCode()); 9908 AdvanceIT(); 9909 return; 9910 } else { 9911 // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9912 if (cond.IsNotNever()) { 9913 EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9914 (rn.GetCode() << 16) | rm.GetCode()); 9915 return; 9916 } 9917 } 9918 Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm); 9919 } 9920 9921 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) { 9922 VIXL_ASSERT(AllowAssembler()); 9923 CheckIT(cond); 9924 if (IsUsingT32()) { 9925 // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 9926 EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 9927 rm.GetCode()); 9928 AdvanceIT(); 9929 return; 9930 } else { 9931 // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 9932 if (cond.IsNotNever()) { 9933 EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 9934 (rn.GetCode() << 16) | rm.GetCode()); 9935 return; 9936 } 9937 } 9938 Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm); 9939 } 9940 9941 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) { 9942 VIXL_ASSERT(AllowAssembler()); 9943 CheckIT(cond); 9944 if (operand.IsImmediateZero()) { 9945 Register rn = operand.GetBaseRegister(); 9946 if (IsUsingT32()) { 9947 // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1 9948 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 9949 EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 9950 AdvanceIT(); 9951 return; 9952 } 9953 } else { 9954 // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1 9955 if (operand.IsOffset() && cond.IsNotNever() && 9956 (!rn.IsPC() || AllowUnpredictable())) { 9957 EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 9958 (rn.GetCode() << 16)); 9959 return; 9960 } 9961 } 9962 } 9963 Delegate(kStl, &Assembler::stl, cond, rt, operand); 9964 } 9965 9966 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) { 9967 VIXL_ASSERT(AllowAssembler()); 9968 CheckIT(cond); 9969 if (operand.IsImmediateZero()) { 9970 Register rn = operand.GetBaseRegister(); 9971 if (IsUsingT32()) { 9972 // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1 9973 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 9974 EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 9975 AdvanceIT(); 9976 return; 9977 } 9978 } else { 9979 // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1 9980 if (operand.IsOffset() && cond.IsNotNever() && 9981 (!rn.IsPC() || AllowUnpredictable())) { 9982 EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 9983 (rn.GetCode() << 16)); 9984 return; 9985 } 9986 } 9987 } 9988 Delegate(kStlb, &Assembler::stlb, cond, rt, operand); 9989 } 9990 9991 void Assembler::stlex(Condition cond, 9992 Register rd, 9993 Register rt, 9994 const MemOperand& operand) { 9995 VIXL_ASSERT(AllowAssembler()); 9996 CheckIT(cond); 9997 if (operand.IsImmediateZero()) { 9998 Register rn = operand.GetBaseRegister(); 9999 if (IsUsingT32()) { 10000 // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 10001 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 10002 EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) | 10003 (rn.GetCode() << 16)); 10004 AdvanceIT(); 10005 return; 10006 } 10007 } else { 10008 // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 10009 if (operand.IsOffset() && cond.IsNotNever() && 10010 (!rn.IsPC() || AllowUnpredictable())) { 10011 EmitA32(0x01800e90U | (cond.GetCondition() << 28) | 10012 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10013 return; 10014 } 10015 } 10016 } 10017 Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand); 10018 } 10019 10020 void Assembler::stlexb(Condition cond, 10021 Register rd, 10022 Register rt, 10023 const MemOperand& operand) { 10024 VIXL_ASSERT(AllowAssembler()); 10025 CheckIT(cond); 10026 if (operand.IsImmediateZero()) { 10027 Register rn = operand.GetBaseRegister(); 10028 if (IsUsingT32()) { 10029 // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 10030 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 10031 EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) | 10032 (rn.GetCode() << 16)); 10033 AdvanceIT(); 10034 return; 10035 } 10036 } else { 10037 // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 10038 if (operand.IsOffset() && cond.IsNotNever() && 10039 (!rn.IsPC() || AllowUnpredictable())) { 10040 EmitA32(0x01c00e90U | (cond.GetCondition() << 28) | 10041 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10042 return; 10043 } 10044 } 10045 } 10046 Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand); 10047 } 10048 10049 void Assembler::stlexd(Condition cond, 10050 Register rd, 10051 Register rt, 10052 Register rt2, 10053 const MemOperand& operand) { 10054 VIXL_ASSERT(AllowAssembler()); 10055 CheckIT(cond); 10056 if (operand.IsImmediateZero()) { 10057 Register rn = operand.GetBaseRegister(); 10058 if (IsUsingT32()) { 10059 // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1 10060 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 10061 EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) | 10062 (rt2.GetCode() << 8) | (rn.GetCode() << 16)); 10063 AdvanceIT(); 10064 return; 10065 } 10066 } else { 10067 // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1 10068 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 10069 operand.IsOffset() && cond.IsNotNever() && 10070 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) || 10071 AllowUnpredictable())) { 10072 EmitA32(0x01a00e90U | (cond.GetCondition() << 28) | 10073 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10074 return; 10075 } 10076 } 10077 } 10078 Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand); 10079 } 10080 10081 void Assembler::stlexh(Condition cond, 10082 Register rd, 10083 Register rt, 10084 const MemOperand& operand) { 10085 VIXL_ASSERT(AllowAssembler()); 10086 CheckIT(cond); 10087 if (operand.IsImmediateZero()) { 10088 Register rn = operand.GetBaseRegister(); 10089 if (IsUsingT32()) { 10090 // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 10091 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 10092 EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) | 10093 (rn.GetCode() << 16)); 10094 AdvanceIT(); 10095 return; 10096 } 10097 } else { 10098 // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 10099 if (operand.IsOffset() && cond.IsNotNever() && 10100 (!rn.IsPC() || AllowUnpredictable())) { 10101 EmitA32(0x01e00e90U | (cond.GetCondition() << 28) | 10102 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10103 return; 10104 } 10105 } 10106 } 10107 Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand); 10108 } 10109 10110 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) { 10111 VIXL_ASSERT(AllowAssembler()); 10112 CheckIT(cond); 10113 if (operand.IsImmediateZero()) { 10114 Register rn = operand.GetBaseRegister(); 10115 if (IsUsingT32()) { 10116 // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1 10117 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 10118 EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16)); 10119 AdvanceIT(); 10120 return; 10121 } 10122 } else { 10123 // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1 10124 if (operand.IsOffset() && cond.IsNotNever() && 10125 (!rn.IsPC() || AllowUnpredictable())) { 10126 EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() | 10127 (rn.GetCode() << 16)); 10128 return; 10129 } 10130 } 10131 } 10132 Delegate(kStlh, &Assembler::stlh, cond, rt, operand); 10133 } 10134 10135 void Assembler::stm(Condition cond, 10136 EncodingSize size, 10137 Register rn, 10138 WriteBack write_back, 10139 RegisterList registers) { 10140 VIXL_ASSERT(AllowAssembler()); 10141 CheckIT(cond); 10142 if (IsUsingT32()) { 10143 // STM{<c>}{<q>} <Rn>!, <registers> ; T1 10144 if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() && 10145 ((registers.GetList() & ~0xff) == 0)) { 10146 EmitT32_16(0xc000 | (rn.GetCode() << 8) | 10147 GetRegisterListEncoding(registers, 0, 8)); 10148 AdvanceIT(); 10149 return; 10150 } 10151 // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2 10152 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) { 10153 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 10154 (write_back.GetWriteBackUint32() << 21) | 10155 (GetRegisterListEncoding(registers, 14, 1) << 14) | 10156 GetRegisterListEncoding(registers, 0, 13)); 10157 AdvanceIT(); 10158 return; 10159 } 10160 } else { 10161 // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1 10162 if (cond.IsNotNever()) { 10163 EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 10164 (write_back.GetWriteBackUint32() << 21) | 10165 GetRegisterListEncoding(registers, 0, 16)); 10166 return; 10167 } 10168 } 10169 Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers); 10170 } 10171 10172 void Assembler::stmda(Condition cond, 10173 Register rn, 10174 WriteBack write_back, 10175 RegisterList registers) { 10176 VIXL_ASSERT(AllowAssembler()); 10177 CheckIT(cond); 10178 if (IsUsingA32()) { 10179 // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1 10180 if (cond.IsNotNever()) { 10181 EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 10182 (write_back.GetWriteBackUint32() << 21) | 10183 GetRegisterListEncoding(registers, 0, 16)); 10184 return; 10185 } 10186 } 10187 Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers); 10188 } 10189 10190 void Assembler::stmdb(Condition cond, 10191 EncodingSize size, 10192 Register rn, 10193 WriteBack write_back, 10194 RegisterList registers) { 10195 VIXL_ASSERT(AllowAssembler()); 10196 CheckIT(cond); 10197 if (IsUsingT32()) { 10198 // STMDB{<c>}{<q>} SP!, <registers> ; T1 10199 if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() && 10200 ((registers.GetList() & ~0x40ff) == 0)) { 10201 EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) | 10202 GetRegisterListEncoding(registers, 0, 8)); 10203 AdvanceIT(); 10204 return; 10205 } 10206 // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1 10207 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) { 10208 EmitT32_32(0xe9000000U | (rn.GetCode() << 16) | 10209 (write_back.GetWriteBackUint32() << 21) | 10210 (GetRegisterListEncoding(registers, 14, 1) << 14) | 10211 GetRegisterListEncoding(registers, 0, 13)); 10212 AdvanceIT(); 10213 return; 10214 } 10215 } else { 10216 // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1 10217 if (cond.IsNotNever()) { 10218 EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 10219 (write_back.GetWriteBackUint32() << 21) | 10220 GetRegisterListEncoding(registers, 0, 16)); 10221 return; 10222 } 10223 } 10224 Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers); 10225 } 10226 10227 void Assembler::stmea(Condition cond, 10228 EncodingSize size, 10229 Register rn, 10230 WriteBack write_back, 10231 RegisterList registers) { 10232 VIXL_ASSERT(AllowAssembler()); 10233 CheckIT(cond); 10234 if (IsUsingT32()) { 10235 // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1 10236 if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() && 10237 ((registers.GetList() & ~0xff) == 0)) { 10238 EmitT32_16(0xc000 | (rn.GetCode() << 8) | 10239 GetRegisterListEncoding(registers, 0, 8)); 10240 AdvanceIT(); 10241 return; 10242 } 10243 // STMEA{<c>}.W <Rn>{!}, <registers> ; T2 10244 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) { 10245 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 10246 (write_back.GetWriteBackUint32() << 21) | 10247 (GetRegisterListEncoding(registers, 14, 1) << 14) | 10248 GetRegisterListEncoding(registers, 0, 13)); 10249 AdvanceIT(); 10250 return; 10251 } 10252 // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2 10253 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) { 10254 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) | 10255 (write_back.GetWriteBackUint32() << 21) | 10256 (GetRegisterListEncoding(registers, 14, 1) << 14) | 10257 GetRegisterListEncoding(registers, 0, 13)); 10258 AdvanceIT(); 10259 return; 10260 } 10261 } else { 10262 // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1 10263 if (cond.IsNotNever()) { 10264 EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 10265 (write_back.GetWriteBackUint32() << 21) | 10266 GetRegisterListEncoding(registers, 0, 16)); 10267 return; 10268 } 10269 } 10270 Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers); 10271 } 10272 10273 void Assembler::stmed(Condition cond, 10274 Register rn, 10275 WriteBack write_back, 10276 RegisterList registers) { 10277 VIXL_ASSERT(AllowAssembler()); 10278 CheckIT(cond); 10279 if (IsUsingA32()) { 10280 // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1 10281 if (cond.IsNotNever()) { 10282 EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 10283 (write_back.GetWriteBackUint32() << 21) | 10284 GetRegisterListEncoding(registers, 0, 16)); 10285 return; 10286 } 10287 } 10288 Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers); 10289 } 10290 10291 void Assembler::stmfa(Condition cond, 10292 Register rn, 10293 WriteBack write_back, 10294 RegisterList registers) { 10295 VIXL_ASSERT(AllowAssembler()); 10296 CheckIT(cond); 10297 if (IsUsingA32()) { 10298 // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1 10299 if (cond.IsNotNever()) { 10300 EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 10301 (write_back.GetWriteBackUint32() << 21) | 10302 GetRegisterListEncoding(registers, 0, 16)); 10303 return; 10304 } 10305 } 10306 Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers); 10307 } 10308 10309 void Assembler::stmfd(Condition cond, 10310 Register rn, 10311 WriteBack write_back, 10312 RegisterList registers) { 10313 VIXL_ASSERT(AllowAssembler()); 10314 CheckIT(cond); 10315 if (IsUsingT32()) { 10316 // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1 10317 if (((registers.GetList() & ~0x5fff) == 0)) { 10318 EmitT32_32(0xe9000000U | (rn.GetCode() << 16) | 10319 (write_back.GetWriteBackUint32() << 21) | 10320 (GetRegisterListEncoding(registers, 14, 1) << 14) | 10321 GetRegisterListEncoding(registers, 0, 13)); 10322 AdvanceIT(); 10323 return; 10324 } 10325 } else { 10326 // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1 10327 if (cond.IsNotNever()) { 10328 EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 10329 (write_back.GetWriteBackUint32() << 21) | 10330 GetRegisterListEncoding(registers, 0, 16)); 10331 return; 10332 } 10333 } 10334 Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers); 10335 } 10336 10337 void Assembler::stmib(Condition cond, 10338 Register rn, 10339 WriteBack write_back, 10340 RegisterList registers) { 10341 VIXL_ASSERT(AllowAssembler()); 10342 CheckIT(cond); 10343 if (IsUsingA32()) { 10344 // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1 10345 if (cond.IsNotNever()) { 10346 EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 10347 (write_back.GetWriteBackUint32() << 21) | 10348 GetRegisterListEncoding(registers, 0, 16)); 10349 return; 10350 } 10351 } 10352 Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers); 10353 } 10354 10355 void Assembler::str(Condition cond, 10356 EncodingSize size, 10357 Register rt, 10358 const MemOperand& operand) { 10359 VIXL_ASSERT(AllowAssembler()); 10360 CheckIT(cond); 10361 if (operand.IsImmediate()) { 10362 Register rn = operand.GetBaseRegister(); 10363 int32_t offset = operand.GetOffsetImmediate(); 10364 if (IsUsingT32()) { 10365 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 10366 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 10367 (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) { 10368 int32_t offset_ = offset >> 2; 10369 EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) | 10370 ((offset_ & 0x1f) << 6)); 10371 AdvanceIT(); 10372 return; 10373 } 10374 // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2 10375 if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) && 10376 ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) { 10377 int32_t offset_ = offset >> 2; 10378 EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff)); 10379 AdvanceIT(); 10380 return; 10381 } 10382 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3 10383 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 10384 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10385 EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10386 (offset & 0xfff)); 10387 AdvanceIT(); 10388 return; 10389 } 10390 // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4 10391 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 10392 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10393 EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10394 (-offset & 0xff)); 10395 AdvanceIT(); 10396 return; 10397 } 10398 // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4 10399 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 10400 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 10401 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10402 uint32_t offset_ = abs(offset); 10403 EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10404 offset_ | (sign << 9)); 10405 AdvanceIT(); 10406 return; 10407 } 10408 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4 10409 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 10410 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 10411 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10412 uint32_t offset_ = abs(offset); 10413 EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10414 offset_ | (sign << 9)); 10415 AdvanceIT(); 10416 return; 10417 } 10418 } else { 10419 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 10420 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 10421 cond.IsNotNever()) { 10422 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10423 uint32_t offset_ = abs(offset); 10424 EmitA32(0x05000000U | (cond.GetCondition() << 28) | 10425 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 10426 (sign << 23)); 10427 return; 10428 } 10429 // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 10430 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 10431 cond.IsNotNever()) { 10432 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10433 uint32_t offset_ = abs(offset); 10434 EmitA32(0x04000000U | (cond.GetCondition() << 28) | 10435 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 10436 (sign << 23)); 10437 return; 10438 } 10439 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 10440 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 10441 cond.IsNotNever()) { 10442 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10443 uint32_t offset_ = abs(offset); 10444 EmitA32(0x05200000U | (cond.GetCondition() << 28) | 10445 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 10446 (sign << 23)); 10447 return; 10448 } 10449 } 10450 } 10451 if (operand.IsPlainRegister()) { 10452 Register rn = operand.GetBaseRegister(); 10453 Sign sign = operand.GetSign(); 10454 Register rm = operand.GetOffsetRegister(); 10455 if (IsUsingT32()) { 10456 // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 10457 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 10458 sign.IsPlus() && operand.IsOffset()) { 10459 EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) | 10460 (rm.GetCode() << 6)); 10461 AdvanceIT(); 10462 return; 10463 } 10464 } 10465 } 10466 if (operand.IsShiftedRegister()) { 10467 Register rn = operand.GetBaseRegister(); 10468 Sign sign = operand.GetSign(); 10469 Register rm = operand.GetOffsetRegister(); 10470 Shift shift = operand.GetShift(); 10471 uint32_t amount = operand.GetShiftAmount(); 10472 if (IsUsingT32()) { 10473 // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 10474 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 10475 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10476 EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10477 rm.GetCode() | (amount << 4)); 10478 AdvanceIT(); 10479 return; 10480 } 10481 } else { 10482 // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 10483 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) { 10484 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10485 uint32_t shift_ = TypeEncodingValue(shift); 10486 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 10487 EmitA32(0x07000000U | (cond.GetCondition() << 28) | 10488 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10489 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 10490 return; 10491 } 10492 // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 10493 if (operand.IsShiftValid() && operand.IsPostIndex() && 10494 cond.IsNotNever()) { 10495 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10496 uint32_t shift_ = TypeEncodingValue(shift); 10497 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 10498 EmitA32(0x06000000U | (cond.GetCondition() << 28) | 10499 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10500 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 10501 return; 10502 } 10503 // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 10504 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) { 10505 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10506 uint32_t shift_ = TypeEncodingValue(shift); 10507 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 10508 EmitA32(0x07200000U | (cond.GetCondition() << 28) | 10509 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10510 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 10511 return; 10512 } 10513 } 10514 } 10515 Delegate(kStr, &Assembler::str, cond, size, rt, operand); 10516 } 10517 10518 void Assembler::strb(Condition cond, 10519 EncodingSize size, 10520 Register rt, 10521 const MemOperand& operand) { 10522 VIXL_ASSERT(AllowAssembler()); 10523 CheckIT(cond); 10524 if (operand.IsImmediate()) { 10525 Register rn = operand.GetBaseRegister(); 10526 int32_t offset = operand.GetOffsetImmediate(); 10527 if (IsUsingT32()) { 10528 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 10529 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 10530 (offset <= 31) && operand.IsOffset()) { 10531 EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) | 10532 ((offset & 0x1f) << 6)); 10533 AdvanceIT(); 10534 return; 10535 } 10536 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 10537 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 10538 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10539 EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10540 (offset & 0xfff)); 10541 AdvanceIT(); 10542 return; 10543 } 10544 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 10545 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 10546 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10547 EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10548 (-offset & 0xff)); 10549 AdvanceIT(); 10550 return; 10551 } 10552 // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 10553 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 10554 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 10555 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10556 uint32_t offset_ = abs(offset); 10557 EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10558 offset_ | (sign << 9)); 10559 AdvanceIT(); 10560 return; 10561 } 10562 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 10563 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 10564 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 10565 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10566 uint32_t offset_ = abs(offset); 10567 EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10568 offset_ | (sign << 9)); 10569 AdvanceIT(); 10570 return; 10571 } 10572 } else { 10573 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 10574 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() && 10575 cond.IsNotNever()) { 10576 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10577 uint32_t offset_ = abs(offset); 10578 EmitA32(0x05400000U | (cond.GetCondition() << 28) | 10579 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 10580 (sign << 23)); 10581 return; 10582 } 10583 // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 10584 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() && 10585 cond.IsNotNever()) { 10586 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10587 uint32_t offset_ = abs(offset); 10588 EmitA32(0x04400000U | (cond.GetCondition() << 28) | 10589 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 10590 (sign << 23)); 10591 return; 10592 } 10593 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 10594 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() && 10595 cond.IsNotNever()) { 10596 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10597 uint32_t offset_ = abs(offset); 10598 EmitA32(0x05600000U | (cond.GetCondition() << 28) | 10599 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ | 10600 (sign << 23)); 10601 return; 10602 } 10603 } 10604 } 10605 if (operand.IsPlainRegister()) { 10606 Register rn = operand.GetBaseRegister(); 10607 Sign sign = operand.GetSign(); 10608 Register rm = operand.GetOffsetRegister(); 10609 if (IsUsingT32()) { 10610 // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 10611 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 10612 sign.IsPlus() && operand.IsOffset()) { 10613 EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) | 10614 (rm.GetCode() << 6)); 10615 AdvanceIT(); 10616 return; 10617 } 10618 } 10619 } 10620 if (operand.IsShiftedRegister()) { 10621 Register rn = operand.GetBaseRegister(); 10622 Sign sign = operand.GetSign(); 10623 Register rm = operand.GetOffsetRegister(); 10624 Shift shift = operand.GetShift(); 10625 uint32_t amount = operand.GetShiftAmount(); 10626 if (IsUsingT32()) { 10627 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 10628 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 10629 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10630 EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10631 rm.GetCode() | (amount << 4)); 10632 AdvanceIT(); 10633 return; 10634 } 10635 } else { 10636 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1 10637 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) { 10638 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10639 uint32_t shift_ = TypeEncodingValue(shift); 10640 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 10641 EmitA32(0x07400000U | (cond.GetCondition() << 28) | 10642 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10643 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 10644 return; 10645 } 10646 // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1 10647 if (operand.IsShiftValid() && operand.IsPostIndex() && 10648 cond.IsNotNever()) { 10649 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10650 uint32_t shift_ = TypeEncodingValue(shift); 10651 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 10652 EmitA32(0x06400000U | (cond.GetCondition() << 28) | 10653 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10654 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 10655 return; 10656 } 10657 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1 10658 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) { 10659 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10660 uint32_t shift_ = TypeEncodingValue(shift); 10661 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_); 10662 EmitA32(0x07600000U | (cond.GetCondition() << 28) | 10663 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10664 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5)); 10665 return; 10666 } 10667 } 10668 } 10669 Delegate(kStrb, &Assembler::strb, cond, size, rt, operand); 10670 } 10671 10672 void Assembler::strd(Condition cond, 10673 Register rt, 10674 Register rt2, 10675 const MemOperand& operand) { 10676 VIXL_ASSERT(AllowAssembler()); 10677 CheckIT(cond); 10678 if (operand.IsImmediate()) { 10679 Register rn = operand.GetBaseRegister(); 10680 int32_t offset = operand.GetOffsetImmediate(); 10681 if (IsUsingT32()) { 10682 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1 10683 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 10684 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10685 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10686 uint32_t offset_ = abs(offset) >> 2; 10687 EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 10688 (rn.GetCode() << 16) | offset_ | (sign << 23)); 10689 AdvanceIT(); 10690 return; 10691 } 10692 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1 10693 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 10694 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 10695 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10696 uint32_t offset_ = abs(offset) >> 2; 10697 EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 10698 (rn.GetCode() << 16) | offset_ | (sign << 23)); 10699 AdvanceIT(); 10700 return; 10701 } 10702 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1 10703 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) && 10704 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 10705 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10706 uint32_t offset_ = abs(offset) >> 2; 10707 EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) | 10708 (rn.GetCode() << 16) | offset_ | (sign << 23)); 10709 AdvanceIT(); 10710 return; 10711 } 10712 } else { 10713 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1 10714 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 10715 (offset >= -255) && (offset <= 255) && operand.IsOffset() && 10716 cond.IsNotNever() && 10717 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 10718 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10719 uint32_t offset_ = abs(offset); 10720 EmitA32(0x014000f0U | (cond.GetCondition() << 28) | 10721 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 10722 ((offset_ & 0xf0) << 4) | (sign << 23)); 10723 return; 10724 } 10725 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1 10726 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 10727 (offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 10728 cond.IsNotNever() && 10729 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 10730 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10731 uint32_t offset_ = abs(offset); 10732 EmitA32(0x004000f0U | (cond.GetCondition() << 28) | 10733 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 10734 ((offset_ & 0xf0) << 4) | (sign << 23)); 10735 return; 10736 } 10737 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1 10738 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 10739 (offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 10740 cond.IsNotNever() && 10741 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 10742 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10743 uint32_t offset_ = abs(offset); 10744 EmitA32(0x016000f0U | (cond.GetCondition() << 28) | 10745 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 10746 ((offset_ & 0xf0) << 4) | (sign << 23)); 10747 return; 10748 } 10749 } 10750 } 10751 if (operand.IsPlainRegister()) { 10752 Register rn = operand.GetBaseRegister(); 10753 Sign sign = operand.GetSign(); 10754 Register rm = operand.GetOffsetRegister(); 10755 if (IsUsingA32()) { 10756 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1 10757 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 10758 operand.IsOffset() && cond.IsNotNever() && 10759 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 10760 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10761 EmitA32(0x010000f0U | (cond.GetCondition() << 28) | 10762 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10763 (sign_ << 23)); 10764 return; 10765 } 10766 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1 10767 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 10768 operand.IsPostIndex() && cond.IsNotNever() && 10769 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 10770 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10771 EmitA32(0x000000f0U | (cond.GetCondition() << 28) | 10772 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10773 (sign_ << 23)); 10774 return; 10775 } 10776 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1 10777 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 10778 operand.IsPreIndex() && cond.IsNotNever() && 10779 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) { 10780 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 10781 EmitA32(0x012000f0U | (cond.GetCondition() << 28) | 10782 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 10783 (sign_ << 23)); 10784 return; 10785 } 10786 } 10787 } 10788 Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand); 10789 } 10790 10791 void Assembler::strex(Condition cond, 10792 Register rd, 10793 Register rt, 10794 const MemOperand& operand) { 10795 VIXL_ASSERT(AllowAssembler()); 10796 CheckIT(cond); 10797 if (operand.IsImmediate()) { 10798 Register rn = operand.GetBaseRegister(); 10799 int32_t offset = operand.GetOffsetImmediate(); 10800 if (IsUsingT32()) { 10801 // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1 10802 if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) && 10803 operand.IsOffset()) { 10804 int32_t offset_ = offset >> 2; 10805 EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) | 10806 (rn.GetCode() << 16) | (offset_ & 0xff)); 10807 AdvanceIT(); 10808 return; 10809 } 10810 } else { 10811 // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1 10812 if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) { 10813 EmitA32(0x01800f90U | (cond.GetCondition() << 28) | 10814 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10815 return; 10816 } 10817 } 10818 } 10819 Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand); 10820 } 10821 10822 void Assembler::strexb(Condition cond, 10823 Register rd, 10824 Register rt, 10825 const MemOperand& operand) { 10826 VIXL_ASSERT(AllowAssembler()); 10827 CheckIT(cond); 10828 if (operand.IsImmediateZero()) { 10829 Register rn = operand.GetBaseRegister(); 10830 if (IsUsingT32()) { 10831 // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 10832 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 10833 EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) | 10834 (rn.GetCode() << 16)); 10835 AdvanceIT(); 10836 return; 10837 } 10838 } else { 10839 // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 10840 if (operand.IsOffset() && cond.IsNotNever() && 10841 (!rn.IsPC() || AllowUnpredictable())) { 10842 EmitA32(0x01c00f90U | (cond.GetCondition() << 28) | 10843 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10844 return; 10845 } 10846 } 10847 } 10848 Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand); 10849 } 10850 10851 void Assembler::strexd(Condition cond, 10852 Register rd, 10853 Register rt, 10854 Register rt2, 10855 const MemOperand& operand) { 10856 VIXL_ASSERT(AllowAssembler()); 10857 CheckIT(cond); 10858 if (operand.IsImmediateZero()) { 10859 Register rn = operand.GetBaseRegister(); 10860 if (IsUsingT32()) { 10861 // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1 10862 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 10863 EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) | 10864 (rt2.GetCode() << 8) | (rn.GetCode() << 16)); 10865 AdvanceIT(); 10866 return; 10867 } 10868 } else { 10869 // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1 10870 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) && 10871 operand.IsOffset() && cond.IsNotNever() && 10872 ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) || 10873 AllowUnpredictable())) { 10874 EmitA32(0x01a00f90U | (cond.GetCondition() << 28) | 10875 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10876 return; 10877 } 10878 } 10879 } 10880 Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand); 10881 } 10882 10883 void Assembler::strexh(Condition cond, 10884 Register rd, 10885 Register rt, 10886 const MemOperand& operand) { 10887 VIXL_ASSERT(AllowAssembler()); 10888 CheckIT(cond); 10889 if (operand.IsImmediateZero()) { 10890 Register rn = operand.GetBaseRegister(); 10891 if (IsUsingT32()) { 10892 // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1 10893 if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 10894 EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) | 10895 (rn.GetCode() << 16)); 10896 AdvanceIT(); 10897 return; 10898 } 10899 } else { 10900 // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1 10901 if (operand.IsOffset() && cond.IsNotNever() && 10902 (!rn.IsPC() || AllowUnpredictable())) { 10903 EmitA32(0x01e00f90U | (cond.GetCondition() << 28) | 10904 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16)); 10905 return; 10906 } 10907 } 10908 } 10909 Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand); 10910 } 10911 10912 void Assembler::strh(Condition cond, 10913 EncodingSize size, 10914 Register rt, 10915 const MemOperand& operand) { 10916 VIXL_ASSERT(AllowAssembler()); 10917 CheckIT(cond); 10918 if (operand.IsImmediate()) { 10919 Register rn = operand.GetBaseRegister(); 10920 int32_t offset = operand.GetOffsetImmediate(); 10921 if (IsUsingT32()) { 10922 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 10923 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) && 10924 (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) { 10925 int32_t offset_ = offset >> 1; 10926 EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) | 10927 ((offset_ & 0x1f) << 6)); 10928 AdvanceIT(); 10929 return; 10930 } 10931 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 10932 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) && 10933 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10934 EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10935 (offset & 0xfff)); 10936 AdvanceIT(); 10937 return; 10938 } 10939 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 10940 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) && 10941 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 10942 EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10943 (-offset & 0xff)); 10944 AdvanceIT(); 10945 return; 10946 } 10947 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 10948 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 10949 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 10950 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10951 uint32_t offset_ = abs(offset); 10952 EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10953 offset_ | (sign << 9)); 10954 AdvanceIT(); 10955 return; 10956 } 10957 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 10958 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) && 10959 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) { 10960 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10961 uint32_t offset_ = abs(offset); 10962 EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 10963 offset_ | (sign << 9)); 10964 AdvanceIT(); 10965 return; 10966 } 10967 } else { 10968 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1 10969 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() && 10970 cond.IsNotNever()) { 10971 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10972 uint32_t offset_ = abs(offset); 10973 EmitA32(0x014000b0U | (cond.GetCondition() << 28) | 10974 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 10975 ((offset_ & 0xf0) << 4) | (sign << 23)); 10976 return; 10977 } 10978 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1 10979 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() && 10980 cond.IsNotNever()) { 10981 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10982 uint32_t offset_ = abs(offset); 10983 EmitA32(0x004000b0U | (cond.GetCondition() << 28) | 10984 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 10985 ((offset_ & 0xf0) << 4) | (sign << 23)); 10986 return; 10987 } 10988 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 10989 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() && 10990 cond.IsNotNever()) { 10991 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 10992 uint32_t offset_ = abs(offset); 10993 EmitA32(0x016000b0U | (cond.GetCondition() << 28) | 10994 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) | 10995 ((offset_ & 0xf0) << 4) | (sign << 23)); 10996 return; 10997 } 10998 } 10999 } 11000 if (operand.IsPlainRegister()) { 11001 Register rn = operand.GetBaseRegister(); 11002 Sign sign = operand.GetSign(); 11003 Register rm = operand.GetOffsetRegister(); 11004 if (IsUsingT32()) { 11005 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1 11006 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() && 11007 sign.IsPlus() && operand.IsOffset()) { 11008 EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) | 11009 (rm.GetCode() << 6)); 11010 AdvanceIT(); 11011 return; 11012 } 11013 } else { 11014 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1 11015 if (operand.IsOffset() && cond.IsNotNever()) { 11016 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11017 EmitA32(0x010000b0U | (cond.GetCondition() << 28) | 11018 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11019 (sign_ << 23)); 11020 return; 11021 } 11022 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1 11023 if (operand.IsPostIndex() && cond.IsNotNever()) { 11024 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11025 EmitA32(0x000000b0U | (cond.GetCondition() << 28) | 11026 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11027 (sign_ << 23)); 11028 return; 11029 } 11030 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1 11031 if (operand.IsPreIndex() && cond.IsNotNever()) { 11032 uint32_t sign_ = sign.IsPlus() ? 1 : 0; 11033 EmitA32(0x012000b0U | (cond.GetCondition() << 28) | 11034 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11035 (sign_ << 23)); 11036 return; 11037 } 11038 } 11039 } 11040 if (operand.IsShiftedRegister()) { 11041 Register rn = operand.GetBaseRegister(); 11042 Sign sign = operand.GetSign(); 11043 Register rm = operand.GetOffsetRegister(); 11044 Shift shift = operand.GetShift(); 11045 uint32_t amount = operand.GetShiftAmount(); 11046 if (IsUsingT32()) { 11047 // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 11048 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) && 11049 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) { 11050 EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) | 11051 rm.GetCode() | (amount << 4)); 11052 AdvanceIT(); 11053 return; 11054 } 11055 } 11056 } 11057 Delegate(kStrh, &Assembler::strh, cond, size, rt, operand); 11058 } 11059 11060 void Assembler::sub(Condition cond, 11061 EncodingSize size, 11062 Register rd, 11063 Register rn, 11064 const Operand& operand) { 11065 VIXL_ASSERT(AllowAssembler()); 11066 CheckIT(cond); 11067 if (operand.IsImmediate()) { 11068 uint32_t imm = operand.GetImmediate(); 11069 if (IsUsingT32()) { 11070 ImmediateT32 immediate_t32(imm); 11071 // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1 11072 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 11073 (imm <= 7)) { 11074 EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 11075 AdvanceIT(); 11076 return; 11077 } 11078 // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 11079 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 11080 (imm <= 255)) { 11081 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 11082 AdvanceIT(); 11083 return; 11084 } 11085 // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1 11086 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && 11087 ((imm % 4) == 0)) { 11088 uint32_t imm_ = imm >> 2; 11089 EmitT32_16(0xb080 | imm_); 11090 AdvanceIT(); 11091 return; 11092 } 11093 // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2 11094 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) { 11095 EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) | 11096 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 11097 AdvanceIT(); 11098 return; 11099 } 11100 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 11101 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) { 11102 EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11103 (immediate_t32.GetEncodingValue() & 0xff) | 11104 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 11105 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 11106 AdvanceIT(); 11107 return; 11108 } 11109 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 11110 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) { 11111 EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11112 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 11113 AdvanceIT(); 11114 return; 11115 } 11116 // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2 11117 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) { 11118 EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) | 11119 (immediate_t32.GetEncodingValue() & 0xff) | 11120 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 11121 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 11122 AdvanceIT(); 11123 return; 11124 } 11125 // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3 11126 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) { 11127 EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) | 11128 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 11129 AdvanceIT(); 11130 return; 11131 } 11132 } else { 11133 ImmediateA32 immediate_a32(imm); 11134 // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2 11135 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { 11136 EmitA32(0x024f0000U | (cond.GetCondition() << 28) | 11137 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 11138 return; 11139 } 11140 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 11141 if (immediate_a32.IsValid() && cond.IsNotNever() && 11142 ((rn.GetCode() & 0xd) != 0xd)) { 11143 EmitA32(0x02400000U | (cond.GetCondition() << 28) | 11144 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 11145 immediate_a32.GetEncodingValue()); 11146 return; 11147 } 11148 // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 11149 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 11150 EmitA32(0x024d0000U | (cond.GetCondition() << 28) | 11151 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 11152 return; 11153 } 11154 } 11155 } 11156 if (operand.IsImmediateShiftedRegister()) { 11157 Register rm = operand.GetBaseRegister(); 11158 if (operand.IsPlainRegister()) { 11159 if (IsUsingT32()) { 11160 // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 11161 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 11162 rm.IsLow()) { 11163 EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) | 11164 (rm.GetCode() << 6)); 11165 AdvanceIT(); 11166 return; 11167 } 11168 // SUB{<c>} {<Rd>}, SP, <Rm> ; T1 11169 if (rn.Is(sp)) { 11170 EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode()); 11171 AdvanceIT(); 11172 return; 11173 } 11174 } 11175 } 11176 Shift shift = operand.GetShift(); 11177 uint32_t amount = operand.GetShiftAmount(); 11178 if (IsUsingT32()) { 11179 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 11180 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) { 11181 uint32_t amount_ = amount % 32; 11182 EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11183 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 11184 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 11185 AdvanceIT(); 11186 return; 11187 } 11188 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 11189 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) { 11190 uint32_t amount_ = amount % 32; 11191 EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() | 11192 (operand.GetTypeEncodingValue() << 4) | 11193 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 11194 AdvanceIT(); 11195 return; 11196 } 11197 } else { 11198 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 11199 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 11200 uint32_t amount_ = amount % 32; 11201 EmitA32(0x00400000U | (cond.GetCondition() << 28) | 11202 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11203 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 11204 return; 11205 } 11206 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 11207 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 11208 uint32_t amount_ = amount % 32; 11209 EmitA32(0x004d0000U | (cond.GetCondition() << 28) | 11210 (rd.GetCode() << 12) | rm.GetCode() | 11211 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 11212 return; 11213 } 11214 } 11215 } 11216 if (operand.IsRegisterShiftedRegister()) { 11217 Register rm = operand.GetBaseRegister(); 11218 Shift shift = operand.GetShift(); 11219 if (IsUsingA32()) { 11220 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 11221 if (cond.IsNotNever()) { 11222 EmitA32(0x00400010U | (cond.GetCondition() << 28) | 11223 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11224 (shift.GetType() << 5) | 11225 (operand.GetShiftRegister().GetCode() << 8)); 11226 return; 11227 } 11228 } 11229 } 11230 Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand); 11231 } 11232 11233 void Assembler::sub(Condition cond, Register rd, const Operand& operand) { 11234 VIXL_ASSERT(AllowAssembler()); 11235 CheckIT(cond); 11236 if (operand.IsImmediate()) { 11237 uint32_t imm = operand.GetImmediate(); 11238 if (IsUsingT32()) { 11239 // SUB<c>{<q>} <Rdn>, #<imm8> ; T2 11240 if (InITBlock() && rd.IsLow() && (imm <= 255)) { 11241 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 11242 AdvanceIT(); 11243 return; 11244 } 11245 } 11246 } 11247 Delegate(kSub, &Assembler::sub, cond, rd, operand); 11248 } 11249 11250 void Assembler::subs(Condition cond, 11251 EncodingSize size, 11252 Register rd, 11253 Register rn, 11254 const Operand& operand) { 11255 VIXL_ASSERT(AllowAssembler()); 11256 CheckIT(cond); 11257 if (operand.IsImmediate()) { 11258 uint32_t imm = operand.GetImmediate(); 11259 if (IsUsingT32()) { 11260 ImmediateT32 immediate_t32(imm); 11261 // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1 11262 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 11263 (imm <= 7)) { 11264 EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); 11265 AdvanceIT(); 11266 return; 11267 } 11268 // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2 11269 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && 11270 (imm <= 255)) { 11271 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 11272 AdvanceIT(); 11273 return; 11274 } 11275 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3 11276 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && 11277 !rd.Is(pc)) { 11278 EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11279 (immediate_t32.GetEncodingValue() & 0xff) | 11280 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 11281 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 11282 AdvanceIT(); 11283 return; 11284 } 11285 // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5 11286 if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255)) { 11287 EmitT32_32(0xf3de8f00U | imm); 11288 AdvanceIT(); 11289 return; 11290 } 11291 // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2 11292 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && 11293 !rd.Is(pc)) { 11294 EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) | 11295 (immediate_t32.GetEncodingValue() & 0xff) | 11296 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 11297 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 11298 AdvanceIT(); 11299 return; 11300 } 11301 } else { 11302 ImmediateA32 immediate_a32(imm); 11303 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1 11304 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { 11305 EmitA32(0x02500000U | (cond.GetCondition() << 28) | 11306 (rd.GetCode() << 12) | (rn.GetCode() << 16) | 11307 immediate_a32.GetEncodingValue()); 11308 return; 11309 } 11310 // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1 11311 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { 11312 EmitA32(0x025d0000U | (cond.GetCondition() << 28) | 11313 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); 11314 return; 11315 } 11316 } 11317 } 11318 if (operand.IsImmediateShiftedRegister()) { 11319 Register rm = operand.GetBaseRegister(); 11320 if (operand.IsPlainRegister()) { 11321 if (IsUsingT32()) { 11322 // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1 11323 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && 11324 rm.IsLow()) { 11325 EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) | 11326 (rm.GetCode() << 6)); 11327 AdvanceIT(); 11328 return; 11329 } 11330 } 11331 } 11332 Shift shift = operand.GetShift(); 11333 uint32_t amount = operand.GetShiftAmount(); 11334 if (IsUsingT32()) { 11335 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 11336 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && 11337 !rd.Is(pc)) { 11338 uint32_t amount_ = amount % 32; 11339 EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11340 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | 11341 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 11342 AdvanceIT(); 11343 return; 11344 } 11345 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 11346 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && 11347 !rd.Is(pc)) { 11348 uint32_t amount_ = amount % 32; 11349 EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() | 11350 (operand.GetTypeEncodingValue() << 4) | 11351 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 11352 AdvanceIT(); 11353 return; 11354 } 11355 } else { 11356 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 11357 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { 11358 uint32_t amount_ = amount % 32; 11359 EmitA32(0x00500000U | (cond.GetCondition() << 28) | 11360 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11361 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 11362 return; 11363 } 11364 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 11365 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { 11366 uint32_t amount_ = amount % 32; 11367 EmitA32(0x005d0000U | (cond.GetCondition() << 28) | 11368 (rd.GetCode() << 12) | rm.GetCode() | 11369 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 11370 return; 11371 } 11372 } 11373 } 11374 if (operand.IsRegisterShiftedRegister()) { 11375 Register rm = operand.GetBaseRegister(); 11376 Shift shift = operand.GetShift(); 11377 if (IsUsingA32()) { 11378 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1 11379 if (cond.IsNotNever()) { 11380 EmitA32(0x00500010U | (cond.GetCondition() << 28) | 11381 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11382 (shift.GetType() << 5) | 11383 (operand.GetShiftRegister().GetCode() << 8)); 11384 return; 11385 } 11386 } 11387 } 11388 Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand); 11389 } 11390 11391 void Assembler::subs(Register rd, const Operand& operand) { 11392 VIXL_ASSERT(AllowAssembler()); 11393 CheckIT(al); 11394 if (operand.IsImmediate()) { 11395 uint32_t imm = operand.GetImmediate(); 11396 if (IsUsingT32()) { 11397 // SUBS{<q>} <Rdn>, #<imm8> ; T2 11398 if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) { 11399 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm); 11400 AdvanceIT(); 11401 return; 11402 } 11403 } 11404 } 11405 Delegate(kSubs, &Assembler::subs, rd, operand); 11406 } 11407 11408 void Assembler::subw(Condition cond, 11409 Register rd, 11410 Register rn, 11411 const Operand& operand) { 11412 VIXL_ASSERT(AllowAssembler()); 11413 CheckIT(cond); 11414 if (operand.IsImmediate()) { 11415 uint32_t imm = operand.GetImmediate(); 11416 if (IsUsingT32()) { 11417 // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4 11418 if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) { 11419 EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11420 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 11421 AdvanceIT(); 11422 return; 11423 } 11424 // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3 11425 if (rn.Is(sp) && (imm <= 4095)) { 11426 EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) | 11427 ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); 11428 AdvanceIT(); 11429 return; 11430 } 11431 } 11432 } 11433 Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand); 11434 } 11435 11436 void Assembler::svc(Condition cond, uint32_t imm) { 11437 VIXL_ASSERT(AllowAssembler()); 11438 CheckIT(cond); 11439 if (IsUsingT32()) { 11440 // SVC{<c>}{<q>} {#}<imm> ; T1 11441 if ((imm <= 255)) { 11442 EmitT32_16(0xdf00 | imm); 11443 AdvanceIT(); 11444 return; 11445 } 11446 } else { 11447 // SVC{<c>}{<q>} {#}<imm> ; A1 11448 if ((imm <= 16777215) && cond.IsNotNever()) { 11449 EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm); 11450 return; 11451 } 11452 } 11453 Delegate(kSvc, &Assembler::svc, cond, imm); 11454 } 11455 11456 void Assembler::sxtab(Condition cond, 11457 Register rd, 11458 Register rn, 11459 const Operand& operand) { 11460 VIXL_ASSERT(AllowAssembler()); 11461 CheckIT(cond); 11462 if (operand.IsImmediateShiftedRegister()) { 11463 Register rm = operand.GetBaseRegister(); 11464 Shift shift = operand.GetShift(); 11465 uint32_t amount = operand.GetShiftAmount(); 11466 if (IsUsingT32()) { 11467 // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 11468 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11469 ((amount % 8) == 0) && !rn.Is(pc)) { 11470 uint32_t amount_ = amount / 8; 11471 EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11472 rm.GetCode() | (amount_ << 4)); 11473 AdvanceIT(); 11474 return; 11475 } 11476 } else { 11477 // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 11478 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11479 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) { 11480 uint32_t amount_ = amount / 8; 11481 EmitA32(0x06a00070U | (cond.GetCondition() << 28) | 11482 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11483 (amount_ << 10)); 11484 return; 11485 } 11486 } 11487 } 11488 Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand); 11489 } 11490 11491 void Assembler::sxtab16(Condition cond, 11492 Register rd, 11493 Register rn, 11494 const Operand& operand) { 11495 VIXL_ASSERT(AllowAssembler()); 11496 CheckIT(cond); 11497 if (operand.IsImmediateShiftedRegister()) { 11498 Register rm = operand.GetBaseRegister(); 11499 Shift shift = operand.GetShift(); 11500 uint32_t amount = operand.GetShiftAmount(); 11501 if (IsUsingT32()) { 11502 // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 11503 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11504 ((amount % 8) == 0) && !rn.Is(pc)) { 11505 uint32_t amount_ = amount / 8; 11506 EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11507 rm.GetCode() | (amount_ << 4)); 11508 AdvanceIT(); 11509 return; 11510 } 11511 } else { 11512 // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 11513 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11514 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) { 11515 uint32_t amount_ = amount / 8; 11516 EmitA32(0x06800070U | (cond.GetCondition() << 28) | 11517 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11518 (amount_ << 10)); 11519 return; 11520 } 11521 } 11522 } 11523 Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand); 11524 } 11525 11526 void Assembler::sxtah(Condition cond, 11527 Register rd, 11528 Register rn, 11529 const Operand& operand) { 11530 VIXL_ASSERT(AllowAssembler()); 11531 CheckIT(cond); 11532 if (operand.IsImmediateShiftedRegister()) { 11533 Register rm = operand.GetBaseRegister(); 11534 Shift shift = operand.GetShift(); 11535 uint32_t amount = operand.GetShiftAmount(); 11536 if (IsUsingT32()) { 11537 // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 11538 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11539 ((amount % 8) == 0) && !rn.Is(pc)) { 11540 uint32_t amount_ = amount / 8; 11541 EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11542 rm.GetCode() | (amount_ << 4)); 11543 AdvanceIT(); 11544 return; 11545 } 11546 } else { 11547 // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 11548 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11549 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) { 11550 uint32_t amount_ = amount / 8; 11551 EmitA32(0x06b00070U | (cond.GetCondition() << 28) | 11552 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 11553 (amount_ << 10)); 11554 return; 11555 } 11556 } 11557 } 11558 Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand); 11559 } 11560 11561 void Assembler::sxtb(Condition cond, 11562 EncodingSize size, 11563 Register rd, 11564 const Operand& operand) { 11565 VIXL_ASSERT(AllowAssembler()); 11566 CheckIT(cond); 11567 if (operand.IsImmediateShiftedRegister()) { 11568 Register rm = operand.GetBaseRegister(); 11569 if (operand.IsPlainRegister()) { 11570 if (IsUsingT32()) { 11571 // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1 11572 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 11573 EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3)); 11574 AdvanceIT(); 11575 return; 11576 } 11577 } 11578 } 11579 Shift shift = operand.GetShift(); 11580 uint32_t amount = operand.GetShiftAmount(); 11581 if (IsUsingT32()) { 11582 // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 11583 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 11584 (amount <= 24) && ((amount % 8) == 0)) { 11585 uint32_t amount_ = amount / 8; 11586 EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() | 11587 (amount_ << 4)); 11588 AdvanceIT(); 11589 return; 11590 } 11591 } else { 11592 // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 11593 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11594 ((amount % 8) == 0) && cond.IsNotNever()) { 11595 uint32_t amount_ = amount / 8; 11596 EmitA32(0x06af0070U | (cond.GetCondition() << 28) | 11597 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 11598 return; 11599 } 11600 } 11601 } 11602 Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand); 11603 } 11604 11605 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) { 11606 VIXL_ASSERT(AllowAssembler()); 11607 CheckIT(cond); 11608 if (operand.IsImmediateShiftedRegister()) { 11609 Register rm = operand.GetBaseRegister(); 11610 Shift shift = operand.GetShift(); 11611 uint32_t amount = operand.GetShiftAmount(); 11612 if (IsUsingT32()) { 11613 // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1 11614 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11615 ((amount % 8) == 0)) { 11616 uint32_t amount_ = amount / 8; 11617 EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() | 11618 (amount_ << 4)); 11619 AdvanceIT(); 11620 return; 11621 } 11622 } else { 11623 // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 11624 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11625 ((amount % 8) == 0) && cond.IsNotNever()) { 11626 uint32_t amount_ = amount / 8; 11627 EmitA32(0x068f0070U | (cond.GetCondition() << 28) | 11628 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 11629 return; 11630 } 11631 } 11632 } 11633 Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand); 11634 } 11635 11636 void Assembler::sxth(Condition cond, 11637 EncodingSize size, 11638 Register rd, 11639 const Operand& operand) { 11640 VIXL_ASSERT(AllowAssembler()); 11641 CheckIT(cond); 11642 if (operand.IsImmediateShiftedRegister()) { 11643 Register rm = operand.GetBaseRegister(); 11644 if (operand.IsPlainRegister()) { 11645 if (IsUsingT32()) { 11646 // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1 11647 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 11648 EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3)); 11649 AdvanceIT(); 11650 return; 11651 } 11652 } 11653 } 11654 Shift shift = operand.GetShift(); 11655 uint32_t amount = operand.GetShiftAmount(); 11656 if (IsUsingT32()) { 11657 // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 11658 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 11659 (amount <= 24) && ((amount % 8) == 0)) { 11660 uint32_t amount_ = amount / 8; 11661 EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() | 11662 (amount_ << 4)); 11663 AdvanceIT(); 11664 return; 11665 } 11666 } else { 11667 // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 11668 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 11669 ((amount % 8) == 0) && cond.IsNotNever()) { 11670 uint32_t amount_ = amount / 8; 11671 EmitA32(0x06bf0070U | (cond.GetCondition() << 28) | 11672 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 11673 return; 11674 } 11675 } 11676 } 11677 Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand); 11678 } 11679 11680 void Assembler::tbb(Condition cond, Register rn, Register rm) { 11681 VIXL_ASSERT(AllowAssembler()); 11682 CheckIT(cond); 11683 if (IsUsingT32()) { 11684 // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1 11685 if (OutsideITBlockAndAlOrLast(cond) && 11686 (!rm.IsPC() || AllowUnpredictable())) { 11687 EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode()); 11688 AdvanceIT(); 11689 return; 11690 } 11691 } 11692 Delegate(kTbb, &Assembler::tbb, cond, rn, rm); 11693 } 11694 11695 void Assembler::tbh(Condition cond, Register rn, Register rm) { 11696 VIXL_ASSERT(AllowAssembler()); 11697 CheckIT(cond); 11698 if (IsUsingT32()) { 11699 // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1 11700 if (OutsideITBlockAndAlOrLast(cond) && 11701 (!rm.IsPC() || AllowUnpredictable())) { 11702 EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode()); 11703 AdvanceIT(); 11704 return; 11705 } 11706 } 11707 Delegate(kTbh, &Assembler::tbh, cond, rn, rm); 11708 } 11709 11710 void Assembler::teq(Condition cond, Register rn, const Operand& operand) { 11711 VIXL_ASSERT(AllowAssembler()); 11712 CheckIT(cond); 11713 if (operand.IsImmediate()) { 11714 uint32_t imm = operand.GetImmediate(); 11715 if (IsUsingT32()) { 11716 ImmediateT32 immediate_t32(imm); 11717 // TEQ{<c>}{<q>} <Rn>, #<const> ; T1 11718 if (immediate_t32.IsValid()) { 11719 EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) | 11720 (immediate_t32.GetEncodingValue() & 0xff) | 11721 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 11722 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 11723 AdvanceIT(); 11724 return; 11725 } 11726 } else { 11727 ImmediateA32 immediate_a32(imm); 11728 // TEQ{<c>}{<q>} <Rn>, #<const> ; A1 11729 if (immediate_a32.IsValid() && cond.IsNotNever()) { 11730 EmitA32(0x03300000U | (cond.GetCondition() << 28) | 11731 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 11732 return; 11733 } 11734 } 11735 } 11736 if (operand.IsImmediateShiftedRegister()) { 11737 Register rm = operand.GetBaseRegister(); 11738 Shift shift = operand.GetShift(); 11739 uint32_t amount = operand.GetShiftAmount(); 11740 if (IsUsingT32()) { 11741 // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1 11742 if (shift.IsValidAmount(amount)) { 11743 uint32_t amount_ = amount % 32; 11744 EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() | 11745 (operand.GetTypeEncodingValue() << 4) | 11746 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 11747 AdvanceIT(); 11748 return; 11749 } 11750 } else { 11751 // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 11752 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 11753 uint32_t amount_ = amount % 32; 11754 EmitA32(0x01300000U | (cond.GetCondition() << 28) | 11755 (rn.GetCode() << 16) | rm.GetCode() | 11756 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 11757 return; 11758 } 11759 } 11760 } 11761 if (operand.IsRegisterShiftedRegister()) { 11762 Register rm = operand.GetBaseRegister(); 11763 Shift shift = operand.GetShift(); 11764 if (IsUsingA32()) { 11765 // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 11766 if (cond.IsNotNever()) { 11767 EmitA32(0x01300010U | (cond.GetCondition() << 28) | 11768 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 11769 (operand.GetShiftRegister().GetCode() << 8)); 11770 return; 11771 } 11772 } 11773 } 11774 Delegate(kTeq, &Assembler::teq, cond, rn, operand); 11775 } 11776 11777 void Assembler::tst(Condition cond, 11778 EncodingSize size, 11779 Register rn, 11780 const Operand& operand) { 11781 VIXL_ASSERT(AllowAssembler()); 11782 CheckIT(cond); 11783 if (operand.IsImmediate()) { 11784 uint32_t imm = operand.GetImmediate(); 11785 if (IsUsingT32()) { 11786 ImmediateT32 immediate_t32(imm); 11787 // TST{<c>}{<q>} <Rn>, #<const> ; T1 11788 if (!size.IsNarrow() && immediate_t32.IsValid()) { 11789 EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) | 11790 (immediate_t32.GetEncodingValue() & 0xff) | 11791 ((immediate_t32.GetEncodingValue() & 0x700) << 4) | 11792 ((immediate_t32.GetEncodingValue() & 0x800) << 15)); 11793 AdvanceIT(); 11794 return; 11795 } 11796 } else { 11797 ImmediateA32 immediate_a32(imm); 11798 // TST{<c>}{<q>} <Rn>, #<const> ; A1 11799 if (immediate_a32.IsValid() && cond.IsNotNever()) { 11800 EmitA32(0x03100000U | (cond.GetCondition() << 28) | 11801 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); 11802 return; 11803 } 11804 } 11805 } 11806 if (operand.IsImmediateShiftedRegister()) { 11807 Register rm = operand.GetBaseRegister(); 11808 if (operand.IsPlainRegister()) { 11809 if (IsUsingT32()) { 11810 // TST{<c>}{<q>} <Rn>, <Rm> ; T1 11811 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) { 11812 EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3)); 11813 AdvanceIT(); 11814 return; 11815 } 11816 } 11817 } 11818 Shift shift = operand.GetShift(); 11819 uint32_t amount = operand.GetShiftAmount(); 11820 if (IsUsingT32()) { 11821 // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2 11822 if (!size.IsNarrow() && shift.IsValidAmount(amount)) { 11823 uint32_t amount_ = amount % 32; 11824 EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() | 11825 (operand.GetTypeEncodingValue() << 4) | 11826 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); 11827 AdvanceIT(); 11828 return; 11829 } 11830 } else { 11831 // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1 11832 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { 11833 uint32_t amount_ = amount % 32; 11834 EmitA32(0x01100000U | (cond.GetCondition() << 28) | 11835 (rn.GetCode() << 16) | rm.GetCode() | 11836 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); 11837 return; 11838 } 11839 } 11840 } 11841 if (operand.IsRegisterShiftedRegister()) { 11842 Register rm = operand.GetBaseRegister(); 11843 Shift shift = operand.GetShift(); 11844 if (IsUsingA32()) { 11845 // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1 11846 if (cond.IsNotNever()) { 11847 EmitA32(0x01100010U | (cond.GetCondition() << 28) | 11848 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | 11849 (operand.GetShiftRegister().GetCode() << 8)); 11850 return; 11851 } 11852 } 11853 } 11854 Delegate(kTst, &Assembler::tst, cond, size, rn, operand); 11855 } 11856 11857 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) { 11858 VIXL_ASSERT(AllowAssembler()); 11859 CheckIT(cond); 11860 if (IsUsingT32()) { 11861 // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 11862 EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11863 rm.GetCode()); 11864 AdvanceIT(); 11865 return; 11866 } else { 11867 // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 11868 if (cond.IsNotNever()) { 11869 EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 11870 (rn.GetCode() << 16) | rm.GetCode()); 11871 return; 11872 } 11873 } 11874 Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm); 11875 } 11876 11877 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) { 11878 VIXL_ASSERT(AllowAssembler()); 11879 CheckIT(cond); 11880 if (IsUsingT32()) { 11881 // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 11882 EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11883 rm.GetCode()); 11884 AdvanceIT(); 11885 return; 11886 } else { 11887 // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 11888 if (cond.IsNotNever()) { 11889 EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 11890 (rn.GetCode() << 16) | rm.GetCode()); 11891 return; 11892 } 11893 } 11894 Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm); 11895 } 11896 11897 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) { 11898 VIXL_ASSERT(AllowAssembler()); 11899 CheckIT(cond); 11900 if (IsUsingT32()) { 11901 // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 11902 EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11903 rm.GetCode()); 11904 AdvanceIT(); 11905 return; 11906 } else { 11907 // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 11908 if (cond.IsNotNever()) { 11909 EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 11910 (rn.GetCode() << 16) | rm.GetCode()); 11911 return; 11912 } 11913 } 11914 Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm); 11915 } 11916 11917 void Assembler::ubfx(Condition cond, 11918 Register rd, 11919 Register rn, 11920 uint32_t lsb, 11921 const Operand& operand) { 11922 VIXL_ASSERT(AllowAssembler()); 11923 CheckIT(cond); 11924 if (operand.IsImmediate()) { 11925 uint32_t width = operand.GetImmediate(); 11926 if (IsUsingT32()) { 11927 // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1 11928 if ((lsb <= 31) && 11929 (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) { 11930 uint32_t widthm1 = width - 1; 11931 EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11932 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1); 11933 AdvanceIT(); 11934 return; 11935 } 11936 } else { 11937 // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1 11938 if ((lsb <= 31) && cond.IsNotNever() && 11939 (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) { 11940 uint32_t widthm1 = width - 1; 11941 EmitA32(0x07e00050U | (cond.GetCondition() << 28) | 11942 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) | 11943 (widthm1 << 16)); 11944 return; 11945 } 11946 } 11947 } 11948 Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, operand); 11949 } 11950 11951 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) { 11952 VIXL_ASSERT(AllowAssembler()); 11953 CheckIT(cond); 11954 if (IsUsingT32()) { 11955 // UDF{<c>}{<q>} {#}<imm> ; T1 11956 if (!size.IsWide() && (imm <= 255)) { 11957 if (cond.Is(al) || AllowStronglyDiscouraged()) { 11958 EmitT32_16(0xde00 | imm); 11959 AdvanceIT(); 11960 return; 11961 } 11962 } 11963 // UDF{<c>}{<q>} {#}<imm> ; T2 11964 if (!size.IsNarrow() && (imm <= 65535)) { 11965 if (cond.Is(al) || AllowStronglyDiscouraged()) { 11966 EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4)); 11967 AdvanceIT(); 11968 return; 11969 } 11970 } 11971 } else { 11972 // UDF{<c>}{<q>} {#}<imm> ; A1 11973 if ((imm <= 65535)) { 11974 if (cond.Is(al) || AllowStronglyDiscouraged()) { 11975 EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4)); 11976 return; 11977 } 11978 } 11979 } 11980 Delegate(kUdf, &Assembler::udf, cond, size, imm); 11981 } 11982 11983 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) { 11984 VIXL_ASSERT(AllowAssembler()); 11985 CheckIT(cond); 11986 if (IsUsingT32()) { 11987 // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 11988 EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 11989 rm.GetCode()); 11990 AdvanceIT(); 11991 return; 11992 } else { 11993 // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 11994 if (cond.IsNotNever()) { 11995 EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 11996 rn.GetCode() | (rm.GetCode() << 8)); 11997 return; 11998 } 11999 } 12000 Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm); 12001 } 12002 12003 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) { 12004 VIXL_ASSERT(AllowAssembler()); 12005 CheckIT(cond); 12006 if (IsUsingT32()) { 12007 // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12008 EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12009 rm.GetCode()); 12010 AdvanceIT(); 12011 return; 12012 } else { 12013 // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12014 if (cond.IsNotNever()) { 12015 EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12016 (rn.GetCode() << 16) | rm.GetCode()); 12017 return; 12018 } 12019 } 12020 Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm); 12021 } 12022 12023 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) { 12024 VIXL_ASSERT(AllowAssembler()); 12025 CheckIT(cond); 12026 if (IsUsingT32()) { 12027 // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12028 EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12029 rm.GetCode()); 12030 AdvanceIT(); 12031 return; 12032 } else { 12033 // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12034 if (cond.IsNotNever()) { 12035 EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12036 (rn.GetCode() << 16) | rm.GetCode()); 12037 return; 12038 } 12039 } 12040 Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm); 12041 } 12042 12043 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) { 12044 VIXL_ASSERT(AllowAssembler()); 12045 CheckIT(cond); 12046 if (IsUsingT32()) { 12047 // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12048 EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12049 rm.GetCode()); 12050 AdvanceIT(); 12051 return; 12052 } else { 12053 // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12054 if (cond.IsNotNever()) { 12055 EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12056 (rn.GetCode() << 16) | rm.GetCode()); 12057 return; 12058 } 12059 } 12060 Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm); 12061 } 12062 12063 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) { 12064 VIXL_ASSERT(AllowAssembler()); 12065 CheckIT(cond); 12066 if (IsUsingT32()) { 12067 // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12068 EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12069 rm.GetCode()); 12070 AdvanceIT(); 12071 return; 12072 } else { 12073 // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12074 if (cond.IsNotNever()) { 12075 EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12076 (rn.GetCode() << 16) | rm.GetCode()); 12077 return; 12078 } 12079 } 12080 Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm); 12081 } 12082 12083 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) { 12084 VIXL_ASSERT(AllowAssembler()); 12085 CheckIT(cond); 12086 if (IsUsingT32()) { 12087 // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12088 EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12089 rm.GetCode()); 12090 AdvanceIT(); 12091 return; 12092 } else { 12093 // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12094 if (cond.IsNotNever()) { 12095 EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12096 (rn.GetCode() << 16) | rm.GetCode()); 12097 return; 12098 } 12099 } 12100 Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm); 12101 } 12102 12103 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) { 12104 VIXL_ASSERT(AllowAssembler()); 12105 CheckIT(cond); 12106 if (IsUsingT32()) { 12107 // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12108 EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12109 rm.GetCode()); 12110 AdvanceIT(); 12111 return; 12112 } else { 12113 // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12114 if (cond.IsNotNever()) { 12115 EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12116 (rn.GetCode() << 16) | rm.GetCode()); 12117 return; 12118 } 12119 } 12120 Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm); 12121 } 12122 12123 void Assembler::umaal( 12124 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 12125 VIXL_ASSERT(AllowAssembler()); 12126 CheckIT(cond); 12127 if (IsUsingT32()) { 12128 // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 12129 EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 12130 (rn.GetCode() << 16) | rm.GetCode()); 12131 AdvanceIT(); 12132 return; 12133 } else { 12134 // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 12135 if (cond.IsNotNever()) { 12136 EmitA32(0x00400090U | (cond.GetCondition() << 28) | 12137 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 12138 (rm.GetCode() << 8)); 12139 return; 12140 } 12141 } 12142 Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm); 12143 } 12144 12145 void Assembler::umlal( 12146 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 12147 VIXL_ASSERT(AllowAssembler()); 12148 CheckIT(cond); 12149 if (IsUsingT32()) { 12150 // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 12151 EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 12152 (rn.GetCode() << 16) | rm.GetCode()); 12153 AdvanceIT(); 12154 return; 12155 } else { 12156 // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 12157 if (cond.IsNotNever()) { 12158 EmitA32(0x00a00090U | (cond.GetCondition() << 28) | 12159 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 12160 (rm.GetCode() << 8)); 12161 return; 12162 } 12163 } 12164 Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm); 12165 } 12166 12167 void Assembler::umlals( 12168 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 12169 VIXL_ASSERT(AllowAssembler()); 12170 CheckIT(cond); 12171 if (IsUsingA32()) { 12172 // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 12173 if (cond.IsNotNever()) { 12174 EmitA32(0x00b00090U | (cond.GetCondition() << 28) | 12175 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 12176 (rm.GetCode() << 8)); 12177 return; 12178 } 12179 } 12180 Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm); 12181 } 12182 12183 void Assembler::umull( 12184 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 12185 VIXL_ASSERT(AllowAssembler()); 12186 CheckIT(cond); 12187 if (IsUsingT32()) { 12188 // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1 12189 EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) | 12190 (rn.GetCode() << 16) | rm.GetCode()); 12191 AdvanceIT(); 12192 return; 12193 } else { 12194 // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 12195 if (cond.IsNotNever()) { 12196 EmitA32(0x00800090U | (cond.GetCondition() << 28) | 12197 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 12198 (rm.GetCode() << 8)); 12199 return; 12200 } 12201 } 12202 Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm); 12203 } 12204 12205 void Assembler::umulls( 12206 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 12207 VIXL_ASSERT(AllowAssembler()); 12208 CheckIT(cond); 12209 if (IsUsingA32()) { 12210 // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1 12211 if (cond.IsNotNever()) { 12212 EmitA32(0x00900090U | (cond.GetCondition() << 28) | 12213 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() | 12214 (rm.GetCode() << 8)); 12215 return; 12216 } 12217 } 12218 Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm); 12219 } 12220 12221 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) { 12222 VIXL_ASSERT(AllowAssembler()); 12223 CheckIT(cond); 12224 if (IsUsingT32()) { 12225 // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12226 EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12227 rm.GetCode()); 12228 AdvanceIT(); 12229 return; 12230 } else { 12231 // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12232 if (cond.IsNotNever()) { 12233 EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12234 (rn.GetCode() << 16) | rm.GetCode()); 12235 return; 12236 } 12237 } 12238 Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm); 12239 } 12240 12241 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) { 12242 VIXL_ASSERT(AllowAssembler()); 12243 CheckIT(cond); 12244 if (IsUsingT32()) { 12245 // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12246 EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12247 rm.GetCode()); 12248 AdvanceIT(); 12249 return; 12250 } else { 12251 // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12252 if (cond.IsNotNever()) { 12253 EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12254 (rn.GetCode() << 16) | rm.GetCode()); 12255 return; 12256 } 12257 } 12258 Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm); 12259 } 12260 12261 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) { 12262 VIXL_ASSERT(AllowAssembler()); 12263 CheckIT(cond); 12264 if (IsUsingT32()) { 12265 // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12266 EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12267 rm.GetCode()); 12268 AdvanceIT(); 12269 return; 12270 } else { 12271 // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12272 if (cond.IsNotNever()) { 12273 EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12274 (rn.GetCode() << 16) | rm.GetCode()); 12275 return; 12276 } 12277 } 12278 Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm); 12279 } 12280 12281 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) { 12282 VIXL_ASSERT(AllowAssembler()); 12283 CheckIT(cond); 12284 if (IsUsingT32()) { 12285 // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12286 EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12287 rm.GetCode()); 12288 AdvanceIT(); 12289 return; 12290 } else { 12291 // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12292 if (cond.IsNotNever()) { 12293 EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12294 (rn.GetCode() << 16) | rm.GetCode()); 12295 return; 12296 } 12297 } 12298 Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm); 12299 } 12300 12301 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) { 12302 VIXL_ASSERT(AllowAssembler()); 12303 CheckIT(cond); 12304 if (IsUsingT32()) { 12305 // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12306 EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12307 rm.GetCode()); 12308 AdvanceIT(); 12309 return; 12310 } else { 12311 // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12312 if (cond.IsNotNever()) { 12313 EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12314 (rn.GetCode() << 16) | rm.GetCode()); 12315 return; 12316 } 12317 } 12318 Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm); 12319 } 12320 12321 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) { 12322 VIXL_ASSERT(AllowAssembler()); 12323 CheckIT(cond); 12324 if (IsUsingT32()) { 12325 // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12326 EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12327 rm.GetCode()); 12328 AdvanceIT(); 12329 return; 12330 } else { 12331 // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12332 if (cond.IsNotNever()) { 12333 EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12334 (rn.GetCode() << 16) | rm.GetCode()); 12335 return; 12336 } 12337 } 12338 Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm); 12339 } 12340 12341 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) { 12342 VIXL_ASSERT(AllowAssembler()); 12343 CheckIT(cond); 12344 if (IsUsingT32()) { 12345 // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12346 EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12347 rm.GetCode()); 12348 AdvanceIT(); 12349 return; 12350 } else { 12351 // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12352 if (cond.IsNotNever()) { 12353 EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 12354 rn.GetCode() | (rm.GetCode() << 8)); 12355 return; 12356 } 12357 } 12358 Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm); 12359 } 12360 12361 void Assembler::usada8( 12362 Condition cond, Register rd, Register rn, Register rm, Register ra) { 12363 VIXL_ASSERT(AllowAssembler()); 12364 CheckIT(cond); 12365 if (IsUsingT32()) { 12366 // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1 12367 if (!ra.Is(pc)) { 12368 EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12369 rm.GetCode() | (ra.GetCode() << 12)); 12370 AdvanceIT(); 12371 return; 12372 } 12373 } else { 12374 // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1 12375 if (cond.IsNotNever() && !ra.Is(pc)) { 12376 EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) | 12377 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12)); 12378 return; 12379 } 12380 } 12381 Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra); 12382 } 12383 12384 void Assembler::usat(Condition cond, 12385 Register rd, 12386 uint32_t imm, 12387 const Operand& operand) { 12388 VIXL_ASSERT(AllowAssembler()); 12389 CheckIT(cond); 12390 if (operand.IsImmediateShiftedRegister()) { 12391 Register rn = operand.GetBaseRegister(); 12392 Shift shift = operand.GetShift(); 12393 uint32_t amount = operand.GetShiftAmount(); 12394 if (IsUsingT32()) { 12395 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1 12396 if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31)) { 12397 EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm | 12398 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 12399 ((amount & 0x1c) << 10)); 12400 AdvanceIT(); 12401 return; 12402 } 12403 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1 12404 if ((imm <= 31) && shift.IsLSL() && (amount <= 31)) { 12405 EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm | 12406 (rn.GetCode() << 16) | ((amount & 0x3) << 6) | 12407 ((amount & 0x1c) << 10)); 12408 AdvanceIT(); 12409 return; 12410 } 12411 } else { 12412 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1 12413 if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) && 12414 cond.IsNotNever()) { 12415 uint32_t amount_ = amount % 32; 12416 EmitA32(0x06e00050U | (cond.GetCondition() << 28) | 12417 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() | 12418 (amount_ << 7)); 12419 return; 12420 } 12421 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1 12422 if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever()) { 12423 EmitA32(0x06e00010U | (cond.GetCondition() << 28) | 12424 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() | 12425 (amount << 7)); 12426 return; 12427 } 12428 } 12429 } 12430 Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand); 12431 } 12432 12433 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) { 12434 VIXL_ASSERT(AllowAssembler()); 12435 CheckIT(cond); 12436 if (IsUsingT32()) { 12437 // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1 12438 if ((imm <= 15)) { 12439 EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm | 12440 (rn.GetCode() << 16)); 12441 AdvanceIT(); 12442 return; 12443 } 12444 } else { 12445 // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1 12446 if ((imm <= 15) && cond.IsNotNever()) { 12447 EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12448 (imm << 16) | rn.GetCode()); 12449 return; 12450 } 12451 } 12452 Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn); 12453 } 12454 12455 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) { 12456 VIXL_ASSERT(AllowAssembler()); 12457 CheckIT(cond); 12458 if (IsUsingT32()) { 12459 // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12460 EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12461 rm.GetCode()); 12462 AdvanceIT(); 12463 return; 12464 } else { 12465 // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12466 if (cond.IsNotNever()) { 12467 EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12468 (rn.GetCode() << 16) | rm.GetCode()); 12469 return; 12470 } 12471 } 12472 Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm); 12473 } 12474 12475 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) { 12476 VIXL_ASSERT(AllowAssembler()); 12477 CheckIT(cond); 12478 if (IsUsingT32()) { 12479 // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12480 EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12481 rm.GetCode()); 12482 AdvanceIT(); 12483 return; 12484 } else { 12485 // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12486 if (cond.IsNotNever()) { 12487 EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12488 (rn.GetCode() << 16) | rm.GetCode()); 12489 return; 12490 } 12491 } 12492 Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm); 12493 } 12494 12495 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) { 12496 VIXL_ASSERT(AllowAssembler()); 12497 CheckIT(cond); 12498 if (IsUsingT32()) { 12499 // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1 12500 EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12501 rm.GetCode()); 12502 AdvanceIT(); 12503 return; 12504 } else { 12505 // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1 12506 if (cond.IsNotNever()) { 12507 EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | 12508 (rn.GetCode() << 16) | rm.GetCode()); 12509 return; 12510 } 12511 } 12512 Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm); 12513 } 12514 12515 void Assembler::uxtab(Condition cond, 12516 Register rd, 12517 Register rn, 12518 const Operand& operand) { 12519 VIXL_ASSERT(AllowAssembler()); 12520 CheckIT(cond); 12521 if (operand.IsImmediateShiftedRegister()) { 12522 Register rm = operand.GetBaseRegister(); 12523 Shift shift = operand.GetShift(); 12524 uint32_t amount = operand.GetShiftAmount(); 12525 if (IsUsingT32()) { 12526 // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12527 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12528 ((amount % 8) == 0) && !rn.Is(pc)) { 12529 uint32_t amount_ = amount / 8; 12530 EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12531 rm.GetCode() | (amount_ << 4)); 12532 AdvanceIT(); 12533 return; 12534 } 12535 } else { 12536 // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12537 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12538 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) { 12539 uint32_t amount_ = amount / 8; 12540 EmitA32(0x06e00070U | (cond.GetCondition() << 28) | 12541 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12542 (amount_ << 10)); 12543 return; 12544 } 12545 } 12546 } 12547 Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand); 12548 } 12549 12550 void Assembler::uxtab16(Condition cond, 12551 Register rd, 12552 Register rn, 12553 const Operand& operand) { 12554 VIXL_ASSERT(AllowAssembler()); 12555 CheckIT(cond); 12556 if (operand.IsImmediateShiftedRegister()) { 12557 Register rm = operand.GetBaseRegister(); 12558 Shift shift = operand.GetShift(); 12559 uint32_t amount = operand.GetShiftAmount(); 12560 if (IsUsingT32()) { 12561 // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12562 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12563 ((amount % 8) == 0) && !rn.Is(pc)) { 12564 uint32_t amount_ = amount / 8; 12565 EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12566 rm.GetCode() | (amount_ << 4)); 12567 AdvanceIT(); 12568 return; 12569 } 12570 } else { 12571 // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12572 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12573 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) { 12574 uint32_t amount_ = amount / 8; 12575 EmitA32(0x06c00070U | (cond.GetCondition() << 28) | 12576 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12577 (amount_ << 10)); 12578 return; 12579 } 12580 } 12581 } 12582 Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand); 12583 } 12584 12585 void Assembler::uxtah(Condition cond, 12586 Register rd, 12587 Register rn, 12588 const Operand& operand) { 12589 VIXL_ASSERT(AllowAssembler()); 12590 CheckIT(cond); 12591 if (operand.IsImmediateShiftedRegister()) { 12592 Register rm = operand.GetBaseRegister(); 12593 Shift shift = operand.GetShift(); 12594 uint32_t amount = operand.GetShiftAmount(); 12595 if (IsUsingT32()) { 12596 // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 12597 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12598 ((amount % 8) == 0) && !rn.Is(pc)) { 12599 uint32_t amount_ = amount / 8; 12600 EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | 12601 rm.GetCode() | (amount_ << 4)); 12602 AdvanceIT(); 12603 return; 12604 } 12605 } else { 12606 // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 12607 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12608 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) { 12609 uint32_t amount_ = amount / 8; 12610 EmitA32(0x06f00070U | (cond.GetCondition() << 28) | 12611 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | 12612 (amount_ << 10)); 12613 return; 12614 } 12615 } 12616 } 12617 Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand); 12618 } 12619 12620 void Assembler::uxtb(Condition cond, 12621 EncodingSize size, 12622 Register rd, 12623 const Operand& operand) { 12624 VIXL_ASSERT(AllowAssembler()); 12625 CheckIT(cond); 12626 if (operand.IsImmediateShiftedRegister()) { 12627 Register rm = operand.GetBaseRegister(); 12628 if (operand.IsPlainRegister()) { 12629 if (IsUsingT32()) { 12630 // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1 12631 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 12632 EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3)); 12633 AdvanceIT(); 12634 return; 12635 } 12636 } 12637 } 12638 Shift shift = operand.GetShift(); 12639 uint32_t amount = operand.GetShiftAmount(); 12640 if (IsUsingT32()) { 12641 // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 12642 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 12643 (amount <= 24) && ((amount % 8) == 0)) { 12644 uint32_t amount_ = amount / 8; 12645 EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12646 (amount_ << 4)); 12647 AdvanceIT(); 12648 return; 12649 } 12650 } else { 12651 // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12652 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12653 ((amount % 8) == 0) && cond.IsNotNever()) { 12654 uint32_t amount_ = amount / 8; 12655 EmitA32(0x06ef0070U | (cond.GetCondition() << 28) | 12656 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12657 return; 12658 } 12659 } 12660 } 12661 Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand); 12662 } 12663 12664 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) { 12665 VIXL_ASSERT(AllowAssembler()); 12666 CheckIT(cond); 12667 if (operand.IsImmediateShiftedRegister()) { 12668 Register rm = operand.GetBaseRegister(); 12669 Shift shift = operand.GetShift(); 12670 uint32_t amount = operand.GetShiftAmount(); 12671 if (IsUsingT32()) { 12672 // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1 12673 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12674 ((amount % 8) == 0)) { 12675 uint32_t amount_ = amount / 8; 12676 EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12677 (amount_ << 4)); 12678 AdvanceIT(); 12679 return; 12680 } 12681 } else { 12682 // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12683 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12684 ((amount % 8) == 0) && cond.IsNotNever()) { 12685 uint32_t amount_ = amount / 8; 12686 EmitA32(0x06cf0070U | (cond.GetCondition() << 28) | 12687 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12688 return; 12689 } 12690 } 12691 } 12692 Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand); 12693 } 12694 12695 void Assembler::uxth(Condition cond, 12696 EncodingSize size, 12697 Register rd, 12698 const Operand& operand) { 12699 VIXL_ASSERT(AllowAssembler()); 12700 CheckIT(cond); 12701 if (operand.IsImmediateShiftedRegister()) { 12702 Register rm = operand.GetBaseRegister(); 12703 if (operand.IsPlainRegister()) { 12704 if (IsUsingT32()) { 12705 // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1 12706 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) { 12707 EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3)); 12708 AdvanceIT(); 12709 return; 12710 } 12711 } 12712 } 12713 Shift shift = operand.GetShift(); 12714 uint32_t amount = operand.GetShiftAmount(); 12715 if (IsUsingT32()) { 12716 // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 12717 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) && 12718 (amount <= 24) && ((amount % 8) == 0)) { 12719 uint32_t amount_ = amount / 8; 12720 EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() | 12721 (amount_ << 4)); 12722 AdvanceIT(); 12723 return; 12724 } 12725 } else { 12726 // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1 12727 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) && 12728 ((amount % 8) == 0) && cond.IsNotNever()) { 12729 uint32_t amount_ = amount / 8; 12730 EmitA32(0x06ff0070U | (cond.GetCondition() << 28) | 12731 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10)); 12732 return; 12733 } 12734 } 12735 } 12736 Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand); 12737 } 12738 12739 void Assembler::vaba( 12740 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 12741 VIXL_ASSERT(AllowAssembler()); 12742 CheckIT(cond); 12743 Dt_U_size_1 encoded_dt(dt); 12744 if (IsUsingT32()) { 12745 // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1 12746 if (encoded_dt.IsValid()) { 12747 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12748 EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12749 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 12750 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12751 AdvanceIT(); 12752 return; 12753 } 12754 } 12755 } else { 12756 // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1 12757 if (encoded_dt.IsValid()) { 12758 if (cond.Is(al)) { 12759 EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12760 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 12761 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12762 return; 12763 } 12764 } 12765 } 12766 Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm); 12767 } 12768 12769 void Assembler::vaba( 12770 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 12771 VIXL_ASSERT(AllowAssembler()); 12772 CheckIT(cond); 12773 Dt_U_size_1 encoded_dt(dt); 12774 if (IsUsingT32()) { 12775 // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1 12776 if (encoded_dt.IsValid()) { 12777 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12778 EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12779 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 12780 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12781 AdvanceIT(); 12782 return; 12783 } 12784 } 12785 } else { 12786 // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1 12787 if (encoded_dt.IsValid()) { 12788 if (cond.Is(al)) { 12789 EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12790 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 12791 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12792 return; 12793 } 12794 } 12795 } 12796 Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm); 12797 } 12798 12799 void Assembler::vabal( 12800 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 12801 VIXL_ASSERT(AllowAssembler()); 12802 CheckIT(cond); 12803 Dt_U_size_1 encoded_dt(dt); 12804 if (IsUsingT32()) { 12805 // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 12806 if (encoded_dt.IsValid()) { 12807 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12808 EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12809 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 12810 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12811 AdvanceIT(); 12812 return; 12813 } 12814 } 12815 } else { 12816 // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 12817 if (encoded_dt.IsValid()) { 12818 if (cond.Is(al)) { 12819 EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12820 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 12821 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12822 return; 12823 } 12824 } 12825 } 12826 Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm); 12827 } 12828 12829 void Assembler::vabd( 12830 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 12831 VIXL_ASSERT(AllowAssembler()); 12832 CheckIT(cond); 12833 Dt_U_size_1 encoded_dt(dt); 12834 if (IsUsingT32()) { 12835 // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 12836 if (dt.Is(F32)) { 12837 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12838 EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 12839 rm.Encode(5, 0)); 12840 AdvanceIT(); 12841 return; 12842 } 12843 } 12844 // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 12845 if (encoded_dt.IsValid()) { 12846 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12847 EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12848 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 12849 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12850 AdvanceIT(); 12851 return; 12852 } 12853 } 12854 } else { 12855 // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 12856 if (dt.Is(F32)) { 12857 if (cond.Is(al)) { 12858 EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 12859 rm.Encode(5, 0)); 12860 return; 12861 } 12862 } 12863 // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 12864 if (encoded_dt.IsValid()) { 12865 if (cond.Is(al)) { 12866 EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12867 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 12868 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12869 return; 12870 } 12871 } 12872 } 12873 Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm); 12874 } 12875 12876 void Assembler::vabd( 12877 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 12878 VIXL_ASSERT(AllowAssembler()); 12879 CheckIT(cond); 12880 Dt_U_size_1 encoded_dt(dt); 12881 if (IsUsingT32()) { 12882 // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 12883 if (dt.Is(F32)) { 12884 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12885 EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 12886 rm.Encode(5, 0)); 12887 AdvanceIT(); 12888 return; 12889 } 12890 } 12891 // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 12892 if (encoded_dt.IsValid()) { 12893 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12894 EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12895 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 12896 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12897 AdvanceIT(); 12898 return; 12899 } 12900 } 12901 } else { 12902 // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 12903 if (dt.Is(F32)) { 12904 if (cond.Is(al)) { 12905 EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 12906 rm.Encode(5, 0)); 12907 return; 12908 } 12909 } 12910 // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 12911 if (encoded_dt.IsValid()) { 12912 if (cond.Is(al)) { 12913 EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12914 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 12915 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12916 return; 12917 } 12918 } 12919 } 12920 Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm); 12921 } 12922 12923 void Assembler::vabdl( 12924 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 12925 VIXL_ASSERT(AllowAssembler()); 12926 CheckIT(cond); 12927 Dt_U_size_1 encoded_dt(dt); 12928 if (IsUsingT32()) { 12929 // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 12930 if (encoded_dt.IsValid()) { 12931 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12932 EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12933 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 12934 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12935 AdvanceIT(); 12936 return; 12937 } 12938 } 12939 } else { 12940 // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 12941 if (encoded_dt.IsValid()) { 12942 if (cond.Is(al)) { 12943 EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 12944 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 12945 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 12946 return; 12947 } 12948 } 12949 } 12950 Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm); 12951 } 12952 12953 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) { 12954 VIXL_ASSERT(AllowAssembler()); 12955 CheckIT(cond); 12956 Dt_F_size_1 encoded_dt(dt); 12957 if (IsUsingT32()) { 12958 // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 12959 if (encoded_dt.IsValid()) { 12960 if (cond.Is(al) || AllowStronglyDiscouraged()) { 12961 EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 12962 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 12963 rd.Encode(22, 12) | rm.Encode(5, 0)); 12964 AdvanceIT(); 12965 return; 12966 } 12967 } 12968 // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 12969 if (dt.Is(F64)) { 12970 EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 12971 AdvanceIT(); 12972 return; 12973 } 12974 } else { 12975 // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 12976 if (encoded_dt.IsValid()) { 12977 if (cond.Is(al)) { 12978 EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 12979 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 12980 rd.Encode(22, 12) | rm.Encode(5, 0)); 12981 return; 12982 } 12983 } 12984 // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 12985 if (dt.Is(F64) && cond.IsNotNever()) { 12986 EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 12987 rm.Encode(5, 0)); 12988 return; 12989 } 12990 } 12991 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 12992 } 12993 12994 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) { 12995 VIXL_ASSERT(AllowAssembler()); 12996 CheckIT(cond); 12997 Dt_F_size_1 encoded_dt(dt); 12998 if (IsUsingT32()) { 12999 // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 13000 if (encoded_dt.IsValid()) { 13001 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13002 EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 13003 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 13004 rd.Encode(22, 12) | rm.Encode(5, 0)); 13005 AdvanceIT(); 13006 return; 13007 } 13008 } 13009 } else { 13010 // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 13011 if (encoded_dt.IsValid()) { 13012 if (cond.Is(al)) { 13013 EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 13014 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 13015 rd.Encode(22, 12) | rm.Encode(5, 0)); 13016 return; 13017 } 13018 } 13019 } 13020 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 13021 } 13022 13023 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) { 13024 VIXL_ASSERT(AllowAssembler()); 13025 CheckIT(cond); 13026 if (IsUsingT32()) { 13027 // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 13028 if (dt.Is(F32)) { 13029 EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 13030 AdvanceIT(); 13031 return; 13032 } 13033 } else { 13034 // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 13035 if (dt.Is(F32) && cond.IsNotNever()) { 13036 EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 13037 rm.Encode(5, 0)); 13038 return; 13039 } 13040 } 13041 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm); 13042 } 13043 13044 void Assembler::vacge( 13045 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13046 VIXL_ASSERT(AllowAssembler()); 13047 CheckIT(cond); 13048 if (IsUsingT32()) { 13049 // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 13050 if (dt.Is(F32)) { 13051 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13052 EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13053 rm.Encode(5, 0)); 13054 AdvanceIT(); 13055 return; 13056 } 13057 } 13058 } else { 13059 // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 13060 if (dt.Is(F32)) { 13061 if (cond.Is(al)) { 13062 EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13063 rm.Encode(5, 0)); 13064 return; 13065 } 13066 } 13067 } 13068 Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm); 13069 } 13070 13071 void Assembler::vacge( 13072 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13073 VIXL_ASSERT(AllowAssembler()); 13074 CheckIT(cond); 13075 if (IsUsingT32()) { 13076 // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 13077 if (dt.Is(F32)) { 13078 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13079 EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13080 rm.Encode(5, 0)); 13081 AdvanceIT(); 13082 return; 13083 } 13084 } 13085 } else { 13086 // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 13087 if (dt.Is(F32)) { 13088 if (cond.Is(al)) { 13089 EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13090 rm.Encode(5, 0)); 13091 return; 13092 } 13093 } 13094 } 13095 Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm); 13096 } 13097 13098 void Assembler::vacgt( 13099 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13100 VIXL_ASSERT(AllowAssembler()); 13101 CheckIT(cond); 13102 if (IsUsingT32()) { 13103 // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 13104 if (dt.Is(F32)) { 13105 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13106 EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13107 rm.Encode(5, 0)); 13108 AdvanceIT(); 13109 return; 13110 } 13111 } 13112 } else { 13113 // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 13114 if (dt.Is(F32)) { 13115 if (cond.Is(al)) { 13116 EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13117 rm.Encode(5, 0)); 13118 return; 13119 } 13120 } 13121 } 13122 Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm); 13123 } 13124 13125 void Assembler::vacgt( 13126 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13127 VIXL_ASSERT(AllowAssembler()); 13128 CheckIT(cond); 13129 if (IsUsingT32()) { 13130 // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 13131 if (dt.Is(F32)) { 13132 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13133 EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13134 rm.Encode(5, 0)); 13135 AdvanceIT(); 13136 return; 13137 } 13138 } 13139 } else { 13140 // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 13141 if (dt.Is(F32)) { 13142 if (cond.Is(al)) { 13143 EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13144 rm.Encode(5, 0)); 13145 return; 13146 } 13147 } 13148 } 13149 Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm); 13150 } 13151 13152 void Assembler::vacle( 13153 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13154 VIXL_ASSERT(AllowAssembler()); 13155 CheckIT(cond); 13156 if (IsUsingT32()) { 13157 // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 13158 if (dt.Is(F32)) { 13159 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13160 EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13161 rm.Encode(5, 0)); 13162 AdvanceIT(); 13163 return; 13164 } 13165 } 13166 } else { 13167 // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 13168 if (dt.Is(F32)) { 13169 if (cond.Is(al)) { 13170 EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13171 rm.Encode(5, 0)); 13172 return; 13173 } 13174 } 13175 } 13176 Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm); 13177 } 13178 13179 void Assembler::vacle( 13180 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13181 VIXL_ASSERT(AllowAssembler()); 13182 CheckIT(cond); 13183 if (IsUsingT32()) { 13184 // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 13185 if (dt.Is(F32)) { 13186 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13187 EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13188 rm.Encode(5, 0)); 13189 AdvanceIT(); 13190 return; 13191 } 13192 } 13193 } else { 13194 // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 13195 if (dt.Is(F32)) { 13196 if (cond.Is(al)) { 13197 EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13198 rm.Encode(5, 0)); 13199 return; 13200 } 13201 } 13202 } 13203 Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm); 13204 } 13205 13206 void Assembler::vaclt( 13207 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13208 VIXL_ASSERT(AllowAssembler()); 13209 CheckIT(cond); 13210 if (IsUsingT32()) { 13211 // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 13212 if (dt.Is(F32)) { 13213 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13214 EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13215 rm.Encode(5, 0)); 13216 AdvanceIT(); 13217 return; 13218 } 13219 } 13220 } else { 13221 // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 13222 if (dt.Is(F32)) { 13223 if (cond.Is(al)) { 13224 EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13225 rm.Encode(5, 0)); 13226 return; 13227 } 13228 } 13229 } 13230 Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm); 13231 } 13232 13233 void Assembler::vaclt( 13234 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13235 VIXL_ASSERT(AllowAssembler()); 13236 CheckIT(cond); 13237 if (IsUsingT32()) { 13238 // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 13239 if (dt.Is(F32)) { 13240 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13241 EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13242 rm.Encode(5, 0)); 13243 AdvanceIT(); 13244 return; 13245 } 13246 } 13247 } else { 13248 // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 13249 if (dt.Is(F32)) { 13250 if (cond.Is(al)) { 13251 EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13252 rm.Encode(5, 0)); 13253 return; 13254 } 13255 } 13256 } 13257 Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm); 13258 } 13259 13260 void Assembler::vadd( 13261 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13262 VIXL_ASSERT(AllowAssembler()); 13263 CheckIT(cond); 13264 Dt_size_2 encoded_dt(dt); 13265 if (IsUsingT32()) { 13266 // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 13267 if (dt.Is(F32)) { 13268 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13269 EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13270 rm.Encode(5, 0)); 13271 AdvanceIT(); 13272 return; 13273 } 13274 } 13275 // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 13276 if (dt.Is(F64)) { 13277 EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13278 rm.Encode(5, 0)); 13279 AdvanceIT(); 13280 return; 13281 } 13282 // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 13283 if (encoded_dt.IsValid()) { 13284 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13285 EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) | 13286 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13287 AdvanceIT(); 13288 return; 13289 } 13290 } 13291 } else { 13292 // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 13293 if (dt.Is(F32)) { 13294 if (cond.Is(al)) { 13295 EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13296 rm.Encode(5, 0)); 13297 return; 13298 } 13299 } 13300 // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 13301 if (dt.Is(F64) && cond.IsNotNever()) { 13302 EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 13303 rn.Encode(7, 16) | rm.Encode(5, 0)); 13304 return; 13305 } 13306 // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 13307 if (encoded_dt.IsValid()) { 13308 if (cond.Is(al)) { 13309 EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) | 13310 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13311 return; 13312 } 13313 } 13314 } 13315 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 13316 } 13317 13318 void Assembler::vadd( 13319 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13320 VIXL_ASSERT(AllowAssembler()); 13321 CheckIT(cond); 13322 Dt_size_2 encoded_dt(dt); 13323 if (IsUsingT32()) { 13324 // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 13325 if (dt.Is(F32)) { 13326 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13327 EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13328 rm.Encode(5, 0)); 13329 AdvanceIT(); 13330 return; 13331 } 13332 } 13333 // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 13334 if (encoded_dt.IsValid()) { 13335 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13336 EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) | 13337 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13338 AdvanceIT(); 13339 return; 13340 } 13341 } 13342 } else { 13343 // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 13344 if (dt.Is(F32)) { 13345 if (cond.Is(al)) { 13346 EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13347 rm.Encode(5, 0)); 13348 return; 13349 } 13350 } 13351 // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 13352 if (encoded_dt.IsValid()) { 13353 if (cond.Is(al)) { 13354 EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) | 13355 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13356 return; 13357 } 13358 } 13359 } 13360 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 13361 } 13362 13363 void Assembler::vadd( 13364 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 13365 VIXL_ASSERT(AllowAssembler()); 13366 CheckIT(cond); 13367 if (IsUsingT32()) { 13368 // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 13369 if (dt.Is(F32)) { 13370 EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13371 rm.Encode(5, 0)); 13372 AdvanceIT(); 13373 return; 13374 } 13375 } else { 13376 // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 13377 if (dt.Is(F32) && cond.IsNotNever()) { 13378 EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 13379 rn.Encode(7, 16) | rm.Encode(5, 0)); 13380 return; 13381 } 13382 } 13383 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm); 13384 } 13385 13386 void Assembler::vaddhn( 13387 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 13388 VIXL_ASSERT(AllowAssembler()); 13389 CheckIT(cond); 13390 Dt_size_3 encoded_dt(dt); 13391 if (IsUsingT32()) { 13392 // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 13393 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 13394 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13395 EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) | 13396 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13397 AdvanceIT(); 13398 return; 13399 } 13400 } 13401 } else { 13402 // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 13403 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 13404 if (cond.Is(al)) { 13405 EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) | 13406 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13407 return; 13408 } 13409 } 13410 } 13411 Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm); 13412 } 13413 13414 void Assembler::vaddl( 13415 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 13416 VIXL_ASSERT(AllowAssembler()); 13417 CheckIT(cond); 13418 Dt_U_size_1 encoded_dt(dt); 13419 if (IsUsingT32()) { 13420 // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 13421 if (encoded_dt.IsValid()) { 13422 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13423 EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13424 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13425 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13426 AdvanceIT(); 13427 return; 13428 } 13429 } 13430 } else { 13431 // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 13432 if (encoded_dt.IsValid()) { 13433 if (cond.Is(al)) { 13434 EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13435 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 13436 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13437 return; 13438 } 13439 } 13440 } 13441 Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm); 13442 } 13443 13444 void Assembler::vaddw( 13445 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) { 13446 VIXL_ASSERT(AllowAssembler()); 13447 CheckIT(cond); 13448 Dt_U_size_1 encoded_dt(dt); 13449 if (IsUsingT32()) { 13450 // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1 13451 if (encoded_dt.IsValid()) { 13452 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13453 EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13454 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 13455 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13456 AdvanceIT(); 13457 return; 13458 } 13459 } 13460 } else { 13461 // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1 13462 if (encoded_dt.IsValid()) { 13463 if (cond.Is(al)) { 13464 EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 13465 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 13466 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13467 return; 13468 } 13469 } 13470 } 13471 Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm); 13472 } 13473 13474 void Assembler::vand(Condition cond, 13475 DataType dt, 13476 DRegister rd, 13477 DRegister rn, 13478 const DOperand& operand) { 13479 VIXL_ASSERT(AllowAssembler()); 13480 CheckIT(cond); 13481 if (operand.IsImmediate()) { 13482 ImmediateVand encoded_dt(dt, operand.GetNeonImmediate()); 13483 if (IsUsingT32()) { 13484 // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 13485 if (encoded_dt.IsValid() && rd.Is(rn)) { 13486 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13487 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 13488 rd.Encode(22, 12) | 13489 (encoded_dt.GetEncodedImmediate() & 0xf) | 13490 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 13491 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 13492 AdvanceIT(); 13493 return; 13494 } 13495 } 13496 } else { 13497 // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 13498 if (encoded_dt.IsValid() && rd.Is(rn)) { 13499 if (cond.Is(al)) { 13500 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 13501 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 13502 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 13503 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 13504 return; 13505 } 13506 } 13507 } 13508 } 13509 if (operand.IsRegister()) { 13510 DRegister rm = operand.GetRegister(); 13511 USE(dt); 13512 if (IsUsingT32()) { 13513 // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 13514 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13515 EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13516 rm.Encode(5, 0)); 13517 AdvanceIT(); 13518 return; 13519 } 13520 } else { 13521 // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 13522 if (cond.Is(al)) { 13523 EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13524 rm.Encode(5, 0)); 13525 return; 13526 } 13527 } 13528 } 13529 Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand); 13530 } 13531 13532 void Assembler::vand(Condition cond, 13533 DataType dt, 13534 QRegister rd, 13535 QRegister rn, 13536 const QOperand& operand) { 13537 VIXL_ASSERT(AllowAssembler()); 13538 CheckIT(cond); 13539 if (operand.IsImmediate()) { 13540 ImmediateVand encoded_dt(dt, operand.GetNeonImmediate()); 13541 if (IsUsingT32()) { 13542 // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 13543 if (encoded_dt.IsValid() && rd.Is(rn)) { 13544 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13545 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 13546 rd.Encode(22, 12) | 13547 (encoded_dt.GetEncodedImmediate() & 0xf) | 13548 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 13549 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 13550 AdvanceIT(); 13551 return; 13552 } 13553 } 13554 } else { 13555 // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 13556 if (encoded_dt.IsValid() && rd.Is(rn)) { 13557 if (cond.Is(al)) { 13558 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 13559 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 13560 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 13561 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 13562 return; 13563 } 13564 } 13565 } 13566 } 13567 if (operand.IsRegister()) { 13568 QRegister rm = operand.GetRegister(); 13569 USE(dt); 13570 if (IsUsingT32()) { 13571 // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 13572 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13573 EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13574 rm.Encode(5, 0)); 13575 AdvanceIT(); 13576 return; 13577 } 13578 } else { 13579 // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 13580 if (cond.Is(al)) { 13581 EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13582 rm.Encode(5, 0)); 13583 return; 13584 } 13585 } 13586 } 13587 Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand); 13588 } 13589 13590 void Assembler::vbic(Condition cond, 13591 DataType dt, 13592 DRegister rd, 13593 DRegister rn, 13594 const DOperand& operand) { 13595 VIXL_ASSERT(AllowAssembler()); 13596 CheckIT(cond); 13597 if (operand.IsImmediate()) { 13598 ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate()); 13599 if (IsUsingT32()) { 13600 // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 13601 if (encoded_dt.IsValid() && rd.Is(rn)) { 13602 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13603 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 13604 rd.Encode(22, 12) | 13605 (encoded_dt.GetEncodedImmediate() & 0xf) | 13606 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 13607 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 13608 AdvanceIT(); 13609 return; 13610 } 13611 } 13612 } else { 13613 // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 13614 if (encoded_dt.IsValid() && rd.Is(rn)) { 13615 if (cond.Is(al)) { 13616 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 13617 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 13618 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 13619 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 13620 return; 13621 } 13622 } 13623 } 13624 } 13625 if (operand.IsRegister()) { 13626 DRegister rm = operand.GetRegister(); 13627 USE(dt); 13628 if (IsUsingT32()) { 13629 // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 13630 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13631 EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13632 rm.Encode(5, 0)); 13633 AdvanceIT(); 13634 return; 13635 } 13636 } else { 13637 // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 13638 if (cond.Is(al)) { 13639 EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13640 rm.Encode(5, 0)); 13641 return; 13642 } 13643 } 13644 } 13645 Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand); 13646 } 13647 13648 void Assembler::vbic(Condition cond, 13649 DataType dt, 13650 QRegister rd, 13651 QRegister rn, 13652 const QOperand& operand) { 13653 VIXL_ASSERT(AllowAssembler()); 13654 CheckIT(cond); 13655 if (operand.IsImmediate()) { 13656 ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate()); 13657 if (IsUsingT32()) { 13658 // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 13659 if (encoded_dt.IsValid() && rd.Is(rn)) { 13660 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13661 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 13662 rd.Encode(22, 12) | 13663 (encoded_dt.GetEncodedImmediate() & 0xf) | 13664 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 13665 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 13666 AdvanceIT(); 13667 return; 13668 } 13669 } 13670 } else { 13671 // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 13672 if (encoded_dt.IsValid() && rd.Is(rn)) { 13673 if (cond.Is(al)) { 13674 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 13675 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 13676 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 13677 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 13678 return; 13679 } 13680 } 13681 } 13682 } 13683 if (operand.IsRegister()) { 13684 QRegister rm = operand.GetRegister(); 13685 USE(dt); 13686 if (IsUsingT32()) { 13687 // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 13688 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13689 EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13690 rm.Encode(5, 0)); 13691 AdvanceIT(); 13692 return; 13693 } 13694 } else { 13695 // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 13696 if (cond.Is(al)) { 13697 EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13698 rm.Encode(5, 0)); 13699 return; 13700 } 13701 } 13702 } 13703 Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand); 13704 } 13705 13706 void Assembler::vbif( 13707 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13708 VIXL_ASSERT(AllowAssembler()); 13709 CheckIT(cond); 13710 USE(dt); 13711 if (IsUsingT32()) { 13712 // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 13713 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13714 EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13715 rm.Encode(5, 0)); 13716 AdvanceIT(); 13717 return; 13718 } 13719 } else { 13720 // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 13721 if (cond.Is(al)) { 13722 EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13723 rm.Encode(5, 0)); 13724 return; 13725 } 13726 } 13727 Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm); 13728 } 13729 13730 void Assembler::vbif( 13731 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13732 VIXL_ASSERT(AllowAssembler()); 13733 CheckIT(cond); 13734 USE(dt); 13735 if (IsUsingT32()) { 13736 // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 13737 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13738 EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13739 rm.Encode(5, 0)); 13740 AdvanceIT(); 13741 return; 13742 } 13743 } else { 13744 // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 13745 if (cond.Is(al)) { 13746 EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13747 rm.Encode(5, 0)); 13748 return; 13749 } 13750 } 13751 Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm); 13752 } 13753 13754 void Assembler::vbit( 13755 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13756 VIXL_ASSERT(AllowAssembler()); 13757 CheckIT(cond); 13758 USE(dt); 13759 if (IsUsingT32()) { 13760 // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 13761 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13762 EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13763 rm.Encode(5, 0)); 13764 AdvanceIT(); 13765 return; 13766 } 13767 } else { 13768 // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 13769 if (cond.Is(al)) { 13770 EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13771 rm.Encode(5, 0)); 13772 return; 13773 } 13774 } 13775 Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm); 13776 } 13777 13778 void Assembler::vbit( 13779 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13780 VIXL_ASSERT(AllowAssembler()); 13781 CheckIT(cond); 13782 USE(dt); 13783 if (IsUsingT32()) { 13784 // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 13785 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13786 EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13787 rm.Encode(5, 0)); 13788 AdvanceIT(); 13789 return; 13790 } 13791 } else { 13792 // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 13793 if (cond.Is(al)) { 13794 EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13795 rm.Encode(5, 0)); 13796 return; 13797 } 13798 } 13799 Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm); 13800 } 13801 13802 void Assembler::vbsl( 13803 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13804 VIXL_ASSERT(AllowAssembler()); 13805 CheckIT(cond); 13806 USE(dt); 13807 if (IsUsingT32()) { 13808 // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 13809 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13810 EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13811 rm.Encode(5, 0)); 13812 AdvanceIT(); 13813 return; 13814 } 13815 } else { 13816 // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 13817 if (cond.Is(al)) { 13818 EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13819 rm.Encode(5, 0)); 13820 return; 13821 } 13822 } 13823 Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm); 13824 } 13825 13826 void Assembler::vbsl( 13827 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13828 VIXL_ASSERT(AllowAssembler()); 13829 CheckIT(cond); 13830 USE(dt); 13831 if (IsUsingT32()) { 13832 // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 13833 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13834 EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13835 rm.Encode(5, 0)); 13836 AdvanceIT(); 13837 return; 13838 } 13839 } else { 13840 // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 13841 if (cond.Is(al)) { 13842 EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 13843 rm.Encode(5, 0)); 13844 return; 13845 } 13846 } 13847 Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm); 13848 } 13849 13850 void Assembler::vceq(Condition cond, 13851 DataType dt, 13852 DRegister rd, 13853 DRegister rm, 13854 const DOperand& operand) { 13855 VIXL_ASSERT(AllowAssembler()); 13856 CheckIT(cond); 13857 if (operand.IsImmediate()) { 13858 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 13859 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 13860 Dt_F_size_2 encoded_dt(dt); 13861 if (IsUsingT32()) { 13862 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 13863 if (encoded_dt.IsValid() && (imm == 0)) { 13864 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13865 EmitT32_32(0xffb10100U | 13866 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 13867 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 13868 rd.Encode(22, 12) | rm.Encode(5, 0)); 13869 AdvanceIT(); 13870 return; 13871 } 13872 } 13873 } else { 13874 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 13875 if (encoded_dt.IsValid() && (imm == 0)) { 13876 if (cond.Is(al)) { 13877 EmitA32(0xf3b10100U | 13878 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 13879 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 13880 rd.Encode(22, 12) | rm.Encode(5, 0)); 13881 return; 13882 } 13883 } 13884 } 13885 } 13886 } 13887 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand); 13888 } 13889 13890 void Assembler::vceq(Condition cond, 13891 DataType dt, 13892 QRegister rd, 13893 QRegister rm, 13894 const QOperand& operand) { 13895 VIXL_ASSERT(AllowAssembler()); 13896 CheckIT(cond); 13897 if (operand.IsImmediate()) { 13898 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 13899 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 13900 Dt_F_size_2 encoded_dt(dt); 13901 if (IsUsingT32()) { 13902 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 13903 if (encoded_dt.IsValid() && (imm == 0)) { 13904 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13905 EmitT32_32(0xffb10140U | 13906 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 13907 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 13908 rd.Encode(22, 12) | rm.Encode(5, 0)); 13909 AdvanceIT(); 13910 return; 13911 } 13912 } 13913 } else { 13914 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 13915 if (encoded_dt.IsValid() && (imm == 0)) { 13916 if (cond.Is(al)) { 13917 EmitA32(0xf3b10140U | 13918 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 13919 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 13920 rd.Encode(22, 12) | rm.Encode(5, 0)); 13921 return; 13922 } 13923 } 13924 } 13925 } 13926 } 13927 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand); 13928 } 13929 13930 void Assembler::vceq( 13931 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 13932 VIXL_ASSERT(AllowAssembler()); 13933 CheckIT(cond); 13934 Dt_size_4 encoded_dt(dt); 13935 Dt_sz_1 encoded_dt_2(dt); 13936 if (IsUsingT32()) { 13937 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 13938 if (encoded_dt.IsValid()) { 13939 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13940 EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) | 13941 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13942 AdvanceIT(); 13943 return; 13944 } 13945 } 13946 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2 13947 if (encoded_dt_2.IsValid()) { 13948 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13949 EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) | 13950 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13951 AdvanceIT(); 13952 return; 13953 } 13954 } 13955 } else { 13956 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 13957 if (encoded_dt.IsValid()) { 13958 if (cond.Is(al)) { 13959 EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) | 13960 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13961 return; 13962 } 13963 } 13964 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2 13965 if (encoded_dt_2.IsValid()) { 13966 if (cond.Is(al)) { 13967 EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) | 13968 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13969 return; 13970 } 13971 } 13972 } 13973 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm); 13974 } 13975 13976 void Assembler::vceq( 13977 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 13978 VIXL_ASSERT(AllowAssembler()); 13979 CheckIT(cond); 13980 Dt_size_4 encoded_dt(dt); 13981 Dt_sz_1 encoded_dt_2(dt); 13982 if (IsUsingT32()) { 13983 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 13984 if (encoded_dt.IsValid()) { 13985 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13986 EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) | 13987 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13988 AdvanceIT(); 13989 return; 13990 } 13991 } 13992 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2 13993 if (encoded_dt_2.IsValid()) { 13994 if (cond.Is(al) || AllowStronglyDiscouraged()) { 13995 EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) | 13996 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 13997 AdvanceIT(); 13998 return; 13999 } 14000 } 14001 } else { 14002 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14003 if (encoded_dt.IsValid()) { 14004 if (cond.Is(al)) { 14005 EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) | 14006 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14007 return; 14008 } 14009 } 14010 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2 14011 if (encoded_dt_2.IsValid()) { 14012 if (cond.Is(al)) { 14013 EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) | 14014 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14015 return; 14016 } 14017 } 14018 } 14019 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm); 14020 } 14021 14022 void Assembler::vcge(Condition cond, 14023 DataType dt, 14024 DRegister rd, 14025 DRegister rm, 14026 const DOperand& operand) { 14027 VIXL_ASSERT(AllowAssembler()); 14028 CheckIT(cond); 14029 if (operand.IsImmediate()) { 14030 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14031 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14032 Dt_F_size_1 encoded_dt(dt); 14033 if (IsUsingT32()) { 14034 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 14035 if (encoded_dt.IsValid() && (imm == 0)) { 14036 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14037 EmitT32_32(0xffb10080U | 14038 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14039 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14040 rd.Encode(22, 12) | rm.Encode(5, 0)); 14041 AdvanceIT(); 14042 return; 14043 } 14044 } 14045 } else { 14046 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 14047 if (encoded_dt.IsValid() && (imm == 0)) { 14048 if (cond.Is(al)) { 14049 EmitA32(0xf3b10080U | 14050 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14051 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14052 rd.Encode(22, 12) | rm.Encode(5, 0)); 14053 return; 14054 } 14055 } 14056 } 14057 } 14058 } 14059 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand); 14060 } 14061 14062 void Assembler::vcge(Condition cond, 14063 DataType dt, 14064 QRegister rd, 14065 QRegister rm, 14066 const QOperand& operand) { 14067 VIXL_ASSERT(AllowAssembler()); 14068 CheckIT(cond); 14069 if (operand.IsImmediate()) { 14070 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14071 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14072 Dt_F_size_1 encoded_dt(dt); 14073 if (IsUsingT32()) { 14074 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 14075 if (encoded_dt.IsValid() && (imm == 0)) { 14076 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14077 EmitT32_32(0xffb100c0U | 14078 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14079 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14080 rd.Encode(22, 12) | rm.Encode(5, 0)); 14081 AdvanceIT(); 14082 return; 14083 } 14084 } 14085 } else { 14086 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 14087 if (encoded_dt.IsValid() && (imm == 0)) { 14088 if (cond.Is(al)) { 14089 EmitA32(0xf3b100c0U | 14090 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14091 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14092 rd.Encode(22, 12) | rm.Encode(5, 0)); 14093 return; 14094 } 14095 } 14096 } 14097 } 14098 } 14099 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand); 14100 } 14101 14102 void Assembler::vcge( 14103 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14104 VIXL_ASSERT(AllowAssembler()); 14105 CheckIT(cond); 14106 Dt_U_size_1 encoded_dt(dt); 14107 if (IsUsingT32()) { 14108 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 14109 if (encoded_dt.IsValid()) { 14110 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14111 EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14112 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14113 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14114 AdvanceIT(); 14115 return; 14116 } 14117 } 14118 // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 14119 if (dt.Is(F32)) { 14120 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14121 EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14122 rm.Encode(5, 0)); 14123 AdvanceIT(); 14124 return; 14125 } 14126 } 14127 } else { 14128 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 14129 if (encoded_dt.IsValid()) { 14130 if (cond.Is(al)) { 14131 EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14132 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14133 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14134 return; 14135 } 14136 } 14137 // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 14138 if (dt.Is(F32)) { 14139 if (cond.Is(al)) { 14140 EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14141 rm.Encode(5, 0)); 14142 return; 14143 } 14144 } 14145 } 14146 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm); 14147 } 14148 14149 void Assembler::vcge( 14150 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14151 VIXL_ASSERT(AllowAssembler()); 14152 CheckIT(cond); 14153 Dt_U_size_1 encoded_dt(dt); 14154 if (IsUsingT32()) { 14155 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 14156 if (encoded_dt.IsValid()) { 14157 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14158 EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14159 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14160 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14161 AdvanceIT(); 14162 return; 14163 } 14164 } 14165 // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 14166 if (dt.Is(F32)) { 14167 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14168 EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14169 rm.Encode(5, 0)); 14170 AdvanceIT(); 14171 return; 14172 } 14173 } 14174 } else { 14175 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14176 if (encoded_dt.IsValid()) { 14177 if (cond.Is(al)) { 14178 EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14179 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14180 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14181 return; 14182 } 14183 } 14184 // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 14185 if (dt.Is(F32)) { 14186 if (cond.Is(al)) { 14187 EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14188 rm.Encode(5, 0)); 14189 return; 14190 } 14191 } 14192 } 14193 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm); 14194 } 14195 14196 void Assembler::vcgt(Condition cond, 14197 DataType dt, 14198 DRegister rd, 14199 DRegister rm, 14200 const DOperand& operand) { 14201 VIXL_ASSERT(AllowAssembler()); 14202 CheckIT(cond); 14203 if (operand.IsImmediate()) { 14204 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14205 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14206 Dt_F_size_1 encoded_dt(dt); 14207 if (IsUsingT32()) { 14208 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 14209 if (encoded_dt.IsValid() && (imm == 0)) { 14210 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14211 EmitT32_32(0xffb10000U | 14212 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14213 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14214 rd.Encode(22, 12) | rm.Encode(5, 0)); 14215 AdvanceIT(); 14216 return; 14217 } 14218 } 14219 } else { 14220 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 14221 if (encoded_dt.IsValid() && (imm == 0)) { 14222 if (cond.Is(al)) { 14223 EmitA32(0xf3b10000U | 14224 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14225 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14226 rd.Encode(22, 12) | rm.Encode(5, 0)); 14227 return; 14228 } 14229 } 14230 } 14231 } 14232 } 14233 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand); 14234 } 14235 14236 void Assembler::vcgt(Condition cond, 14237 DataType dt, 14238 QRegister rd, 14239 QRegister rm, 14240 const QOperand& operand) { 14241 VIXL_ASSERT(AllowAssembler()); 14242 CheckIT(cond); 14243 if (operand.IsImmediate()) { 14244 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14245 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14246 Dt_F_size_1 encoded_dt(dt); 14247 if (IsUsingT32()) { 14248 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 14249 if (encoded_dt.IsValid() && (imm == 0)) { 14250 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14251 EmitT32_32(0xffb10040U | 14252 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14253 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14254 rd.Encode(22, 12) | rm.Encode(5, 0)); 14255 AdvanceIT(); 14256 return; 14257 } 14258 } 14259 } else { 14260 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 14261 if (encoded_dt.IsValid() && (imm == 0)) { 14262 if (cond.Is(al)) { 14263 EmitA32(0xf3b10040U | 14264 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14265 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14266 rd.Encode(22, 12) | rm.Encode(5, 0)); 14267 return; 14268 } 14269 } 14270 } 14271 } 14272 } 14273 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand); 14274 } 14275 14276 void Assembler::vcgt( 14277 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14278 VIXL_ASSERT(AllowAssembler()); 14279 CheckIT(cond); 14280 Dt_U_size_1 encoded_dt(dt); 14281 if (IsUsingT32()) { 14282 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 14283 if (encoded_dt.IsValid()) { 14284 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14285 EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14286 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14287 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14288 AdvanceIT(); 14289 return; 14290 } 14291 } 14292 // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 14293 if (dt.Is(F32)) { 14294 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14295 EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14296 rm.Encode(5, 0)); 14297 AdvanceIT(); 14298 return; 14299 } 14300 } 14301 } else { 14302 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 14303 if (encoded_dt.IsValid()) { 14304 if (cond.Is(al)) { 14305 EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14306 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14307 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14308 return; 14309 } 14310 } 14311 // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 14312 if (dt.Is(F32)) { 14313 if (cond.Is(al)) { 14314 EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14315 rm.Encode(5, 0)); 14316 return; 14317 } 14318 } 14319 } 14320 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm); 14321 } 14322 14323 void Assembler::vcgt( 14324 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14325 VIXL_ASSERT(AllowAssembler()); 14326 CheckIT(cond); 14327 Dt_U_size_1 encoded_dt(dt); 14328 if (IsUsingT32()) { 14329 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 14330 if (encoded_dt.IsValid()) { 14331 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14332 EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14333 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14334 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14335 AdvanceIT(); 14336 return; 14337 } 14338 } 14339 // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 14340 if (dt.Is(F32)) { 14341 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14342 EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14343 rm.Encode(5, 0)); 14344 AdvanceIT(); 14345 return; 14346 } 14347 } 14348 } else { 14349 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14350 if (encoded_dt.IsValid()) { 14351 if (cond.Is(al)) { 14352 EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14353 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14354 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 14355 return; 14356 } 14357 } 14358 // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 14359 if (dt.Is(F32)) { 14360 if (cond.Is(al)) { 14361 EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 14362 rm.Encode(5, 0)); 14363 return; 14364 } 14365 } 14366 } 14367 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm); 14368 } 14369 14370 void Assembler::vcle(Condition cond, 14371 DataType dt, 14372 DRegister rd, 14373 DRegister rm, 14374 const DOperand& operand) { 14375 VIXL_ASSERT(AllowAssembler()); 14376 CheckIT(cond); 14377 if (operand.IsImmediate()) { 14378 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14379 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14380 Dt_F_size_1 encoded_dt(dt); 14381 if (IsUsingT32()) { 14382 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 14383 if (encoded_dt.IsValid() && (imm == 0)) { 14384 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14385 EmitT32_32(0xffb10180U | 14386 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14387 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14388 rd.Encode(22, 12) | rm.Encode(5, 0)); 14389 AdvanceIT(); 14390 return; 14391 } 14392 } 14393 } else { 14394 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 14395 if (encoded_dt.IsValid() && (imm == 0)) { 14396 if (cond.Is(al)) { 14397 EmitA32(0xf3b10180U | 14398 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14399 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14400 rd.Encode(22, 12) | rm.Encode(5, 0)); 14401 return; 14402 } 14403 } 14404 } 14405 } 14406 } 14407 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand); 14408 } 14409 14410 void Assembler::vcle(Condition cond, 14411 DataType dt, 14412 QRegister rd, 14413 QRegister rm, 14414 const QOperand& operand) { 14415 VIXL_ASSERT(AllowAssembler()); 14416 CheckIT(cond); 14417 if (operand.IsImmediate()) { 14418 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14419 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14420 Dt_F_size_1 encoded_dt(dt); 14421 if (IsUsingT32()) { 14422 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 14423 if (encoded_dt.IsValid() && (imm == 0)) { 14424 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14425 EmitT32_32(0xffb101c0U | 14426 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14427 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14428 rd.Encode(22, 12) | rm.Encode(5, 0)); 14429 AdvanceIT(); 14430 return; 14431 } 14432 } 14433 } else { 14434 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 14435 if (encoded_dt.IsValid() && (imm == 0)) { 14436 if (cond.Is(al)) { 14437 EmitA32(0xf3b101c0U | 14438 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14439 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14440 rd.Encode(22, 12) | rm.Encode(5, 0)); 14441 return; 14442 } 14443 } 14444 } 14445 } 14446 } 14447 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand); 14448 } 14449 14450 void Assembler::vcle( 14451 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14452 VIXL_ASSERT(AllowAssembler()); 14453 CheckIT(cond); 14454 Dt_U_size_1 encoded_dt(dt); 14455 if (IsUsingT32()) { 14456 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 14457 if (encoded_dt.IsValid()) { 14458 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14459 EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14460 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14461 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 14462 AdvanceIT(); 14463 return; 14464 } 14465 } 14466 // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 14467 if (dt.Is(F32)) { 14468 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14469 EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 14470 rm.Encode(7, 16)); 14471 AdvanceIT(); 14472 return; 14473 } 14474 } 14475 } else { 14476 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 14477 if (encoded_dt.IsValid()) { 14478 if (cond.Is(al)) { 14479 EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14480 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14481 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 14482 return; 14483 } 14484 } 14485 // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 14486 if (dt.Is(F32)) { 14487 if (cond.Is(al)) { 14488 EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 14489 rm.Encode(7, 16)); 14490 return; 14491 } 14492 } 14493 } 14494 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm); 14495 } 14496 14497 void Assembler::vcle( 14498 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14499 VIXL_ASSERT(AllowAssembler()); 14500 CheckIT(cond); 14501 Dt_U_size_1 encoded_dt(dt); 14502 if (IsUsingT32()) { 14503 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 14504 if (encoded_dt.IsValid()) { 14505 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14506 EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14507 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14508 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 14509 AdvanceIT(); 14510 return; 14511 } 14512 } 14513 // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 14514 if (dt.Is(F32)) { 14515 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14516 EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 14517 rm.Encode(7, 16)); 14518 AdvanceIT(); 14519 return; 14520 } 14521 } 14522 } else { 14523 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14524 if (encoded_dt.IsValid()) { 14525 if (cond.Is(al)) { 14526 EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14527 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14528 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 14529 return; 14530 } 14531 } 14532 // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 14533 if (dt.Is(F32)) { 14534 if (cond.Is(al)) { 14535 EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 14536 rm.Encode(7, 16)); 14537 return; 14538 } 14539 } 14540 } 14541 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm); 14542 } 14543 14544 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) { 14545 VIXL_ASSERT(AllowAssembler()); 14546 CheckIT(cond); 14547 Dt_size_5 encoded_dt(dt); 14548 if (IsUsingT32()) { 14549 // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 14550 if (encoded_dt.IsValid()) { 14551 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14552 EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) | 14553 rd.Encode(22, 12) | rm.Encode(5, 0)); 14554 AdvanceIT(); 14555 return; 14556 } 14557 } 14558 } else { 14559 // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 14560 if (encoded_dt.IsValid()) { 14561 if (cond.Is(al)) { 14562 EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) | 14563 rd.Encode(22, 12) | rm.Encode(5, 0)); 14564 return; 14565 } 14566 } 14567 } 14568 Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm); 14569 } 14570 14571 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) { 14572 VIXL_ASSERT(AllowAssembler()); 14573 CheckIT(cond); 14574 Dt_size_5 encoded_dt(dt); 14575 if (IsUsingT32()) { 14576 // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 14577 if (encoded_dt.IsValid()) { 14578 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14579 EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) | 14580 rd.Encode(22, 12) | rm.Encode(5, 0)); 14581 AdvanceIT(); 14582 return; 14583 } 14584 } 14585 } else { 14586 // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 14587 if (encoded_dt.IsValid()) { 14588 if (cond.Is(al)) { 14589 EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) | 14590 rd.Encode(22, 12) | rm.Encode(5, 0)); 14591 return; 14592 } 14593 } 14594 } 14595 Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm); 14596 } 14597 14598 void Assembler::vclt(Condition cond, 14599 DataType dt, 14600 DRegister rd, 14601 DRegister rm, 14602 const DOperand& operand) { 14603 VIXL_ASSERT(AllowAssembler()); 14604 CheckIT(cond); 14605 if (operand.IsImmediate()) { 14606 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14607 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14608 Dt_F_size_1 encoded_dt(dt); 14609 if (IsUsingT32()) { 14610 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 14611 if (encoded_dt.IsValid() && (imm == 0)) { 14612 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14613 EmitT32_32(0xffb10200U | 14614 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14615 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14616 rd.Encode(22, 12) | rm.Encode(5, 0)); 14617 AdvanceIT(); 14618 return; 14619 } 14620 } 14621 } else { 14622 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1 14623 if (encoded_dt.IsValid() && (imm == 0)) { 14624 if (cond.Is(al)) { 14625 EmitA32(0xf3b10200U | 14626 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14627 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14628 rd.Encode(22, 12) | rm.Encode(5, 0)); 14629 return; 14630 } 14631 } 14632 } 14633 } 14634 } 14635 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand); 14636 } 14637 14638 void Assembler::vclt(Condition cond, 14639 DataType dt, 14640 QRegister rd, 14641 QRegister rm, 14642 const QOperand& operand) { 14643 VIXL_ASSERT(AllowAssembler()); 14644 CheckIT(cond); 14645 if (operand.IsImmediate()) { 14646 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 14647 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 14648 Dt_F_size_1 encoded_dt(dt); 14649 if (IsUsingT32()) { 14650 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 14651 if (encoded_dt.IsValid() && (imm == 0)) { 14652 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14653 EmitT32_32(0xffb10240U | 14654 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14655 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14656 rd.Encode(22, 12) | rm.Encode(5, 0)); 14657 AdvanceIT(); 14658 return; 14659 } 14660 } 14661 } else { 14662 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1 14663 if (encoded_dt.IsValid() && (imm == 0)) { 14664 if (cond.Is(al)) { 14665 EmitA32(0xf3b10240U | 14666 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 14667 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 14668 rd.Encode(22, 12) | rm.Encode(5, 0)); 14669 return; 14670 } 14671 } 14672 } 14673 } 14674 } 14675 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand); 14676 } 14677 14678 void Assembler::vclt( 14679 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 14680 VIXL_ASSERT(AllowAssembler()); 14681 CheckIT(cond); 14682 Dt_U_size_1 encoded_dt(dt); 14683 if (IsUsingT32()) { 14684 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 14685 if (encoded_dt.IsValid()) { 14686 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14687 EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14688 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14689 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 14690 AdvanceIT(); 14691 return; 14692 } 14693 } 14694 // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2 14695 if (dt.Is(F32)) { 14696 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14697 EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 14698 rm.Encode(7, 16)); 14699 AdvanceIT(); 14700 return; 14701 } 14702 } 14703 } else { 14704 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 14705 if (encoded_dt.IsValid()) { 14706 if (cond.Is(al)) { 14707 EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14708 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14709 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 14710 return; 14711 } 14712 } 14713 // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2 14714 if (dt.Is(F32)) { 14715 if (cond.Is(al)) { 14716 EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) | 14717 rm.Encode(7, 16)); 14718 return; 14719 } 14720 } 14721 } 14722 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm); 14723 } 14724 14725 void Assembler::vclt( 14726 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 14727 VIXL_ASSERT(AllowAssembler()); 14728 CheckIT(cond); 14729 Dt_U_size_1 encoded_dt(dt); 14730 if (IsUsingT32()) { 14731 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 14732 if (encoded_dt.IsValid()) { 14733 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14734 EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14735 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 14736 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 14737 AdvanceIT(); 14738 return; 14739 } 14740 } 14741 // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2 14742 if (dt.Is(F32)) { 14743 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14744 EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 14745 rm.Encode(7, 16)); 14746 AdvanceIT(); 14747 return; 14748 } 14749 } 14750 } else { 14751 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 14752 if (encoded_dt.IsValid()) { 14753 if (cond.Is(al)) { 14754 EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 14755 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 14756 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16)); 14757 return; 14758 } 14759 } 14760 // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2 14761 if (dt.Is(F32)) { 14762 if (cond.Is(al)) { 14763 EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) | 14764 rm.Encode(7, 16)); 14765 return; 14766 } 14767 } 14768 } 14769 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm); 14770 } 14771 14772 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) { 14773 VIXL_ASSERT(AllowAssembler()); 14774 CheckIT(cond); 14775 Dt_size_4 encoded_dt(dt); 14776 if (IsUsingT32()) { 14777 // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 14778 if (encoded_dt.IsValid()) { 14779 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14780 EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) | 14781 rd.Encode(22, 12) | rm.Encode(5, 0)); 14782 AdvanceIT(); 14783 return; 14784 } 14785 } 14786 } else { 14787 // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 14788 if (encoded_dt.IsValid()) { 14789 if (cond.Is(al)) { 14790 EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) | 14791 rd.Encode(22, 12) | rm.Encode(5, 0)); 14792 return; 14793 } 14794 } 14795 } 14796 Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm); 14797 } 14798 14799 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) { 14800 VIXL_ASSERT(AllowAssembler()); 14801 CheckIT(cond); 14802 Dt_size_4 encoded_dt(dt); 14803 if (IsUsingT32()) { 14804 // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 14805 if (encoded_dt.IsValid()) { 14806 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14807 EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) | 14808 rd.Encode(22, 12) | rm.Encode(5, 0)); 14809 AdvanceIT(); 14810 return; 14811 } 14812 } 14813 } else { 14814 // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 14815 if (encoded_dt.IsValid()) { 14816 if (cond.Is(al)) { 14817 EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) | 14818 rd.Encode(22, 12) | rm.Encode(5, 0)); 14819 return; 14820 } 14821 } 14822 } 14823 Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm); 14824 } 14825 14826 void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm) { 14827 VIXL_ASSERT(AllowAssembler()); 14828 CheckIT(cond); 14829 if (IsUsingT32()) { 14830 // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 14831 if (dt.Is(F32)) { 14832 EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14833 AdvanceIT(); 14834 return; 14835 } 14836 } else { 14837 // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 14838 if (dt.Is(F32) && cond.IsNotNever()) { 14839 EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14840 rm.Encode(5, 0)); 14841 return; 14842 } 14843 } 14844 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm); 14845 } 14846 14847 void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm) { 14848 VIXL_ASSERT(AllowAssembler()); 14849 CheckIT(cond); 14850 if (IsUsingT32()) { 14851 // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 14852 if (dt.Is(F64)) { 14853 EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14854 AdvanceIT(); 14855 return; 14856 } 14857 } else { 14858 // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 14859 if (dt.Is(F64) && cond.IsNotNever()) { 14860 EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14861 rm.Encode(5, 0)); 14862 return; 14863 } 14864 } 14865 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm); 14866 } 14867 14868 void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, double imm) { 14869 VIXL_ASSERT(AllowAssembler()); 14870 CheckIT(cond); 14871 if (IsUsingT32()) { 14872 // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2 14873 if (dt.Is(F32) && (imm == 0.0)) { 14874 EmitT32_32(0xeeb50a40U | rd.Encode(22, 12)); 14875 AdvanceIT(); 14876 return; 14877 } 14878 } else { 14879 // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2 14880 if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) { 14881 EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 14882 return; 14883 } 14884 } 14885 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm); 14886 } 14887 14888 void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, double imm) { 14889 VIXL_ASSERT(AllowAssembler()); 14890 CheckIT(cond); 14891 if (IsUsingT32()) { 14892 // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2 14893 if (dt.Is(F64) && (imm == 0.0)) { 14894 EmitT32_32(0xeeb50b40U | rd.Encode(22, 12)); 14895 AdvanceIT(); 14896 return; 14897 } 14898 } else { 14899 // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2 14900 if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) { 14901 EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 14902 return; 14903 } 14904 } 14905 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm); 14906 } 14907 14908 void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm) { 14909 VIXL_ASSERT(AllowAssembler()); 14910 CheckIT(cond); 14911 if (IsUsingT32()) { 14912 // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 14913 if (dt.Is(F32)) { 14914 EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14915 AdvanceIT(); 14916 return; 14917 } 14918 } else { 14919 // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 14920 if (dt.Is(F32) && cond.IsNotNever()) { 14921 EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14922 rm.Encode(5, 0)); 14923 return; 14924 } 14925 } 14926 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm); 14927 } 14928 14929 void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm) { 14930 VIXL_ASSERT(AllowAssembler()); 14931 CheckIT(cond); 14932 if (IsUsingT32()) { 14933 // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 14934 if (dt.Is(F64)) { 14935 EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14936 AdvanceIT(); 14937 return; 14938 } 14939 } else { 14940 // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 14941 if (dt.Is(F64) && cond.IsNotNever()) { 14942 EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 14943 rm.Encode(5, 0)); 14944 return; 14945 } 14946 } 14947 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm); 14948 } 14949 14950 void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, double imm) { 14951 VIXL_ASSERT(AllowAssembler()); 14952 CheckIT(cond); 14953 if (IsUsingT32()) { 14954 // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2 14955 if (dt.Is(F32) && (imm == 0.0)) { 14956 EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12)); 14957 AdvanceIT(); 14958 return; 14959 } 14960 } else { 14961 // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2 14962 if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) { 14963 EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 14964 return; 14965 } 14966 } 14967 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm); 14968 } 14969 14970 void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, double imm) { 14971 VIXL_ASSERT(AllowAssembler()); 14972 CheckIT(cond); 14973 if (IsUsingT32()) { 14974 // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2 14975 if (dt.Is(F64) && (imm == 0.0)) { 14976 EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12)); 14977 AdvanceIT(); 14978 return; 14979 } 14980 } else { 14981 // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2 14982 if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) { 14983 EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); 14984 return; 14985 } 14986 } 14987 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm); 14988 } 14989 14990 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) { 14991 VIXL_ASSERT(AllowAssembler()); 14992 CheckIT(cond); 14993 if (IsUsingT32()) { 14994 // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1 14995 if (dt.Is(Untyped8)) { 14996 if (cond.Is(al) || AllowStronglyDiscouraged()) { 14997 EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 14998 AdvanceIT(); 14999 return; 15000 } 15001 } 15002 } else { 15003 // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1 15004 if (dt.Is(Untyped8)) { 15005 if (cond.Is(al)) { 15006 EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15007 return; 15008 } 15009 } 15010 } 15011 Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm); 15012 } 15013 15014 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) { 15015 VIXL_ASSERT(AllowAssembler()); 15016 CheckIT(cond); 15017 if (IsUsingT32()) { 15018 // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1 15019 if (dt.Is(Untyped8)) { 15020 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15021 EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15022 AdvanceIT(); 15023 return; 15024 } 15025 } 15026 } else { 15027 // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1 15028 if (dt.Is(Untyped8)) { 15029 if (cond.Is(al)) { 15030 EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15031 return; 15032 } 15033 } 15034 } 15035 Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm); 15036 } 15037 15038 void Assembler::vcvt( 15039 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 15040 VIXL_ASSERT(AllowAssembler()); 15041 CheckIT(cond); 15042 Dt_op_2 encoded_dt(dt2); 15043 if (IsUsingT32()) { 15044 // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1 15045 if (dt1.Is(F64) && dt2.Is(F32)) { 15046 EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15047 AdvanceIT(); 15048 return; 15049 } 15050 // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1 15051 if (dt1.Is(F64) && encoded_dt.IsValid()) { 15052 EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) | 15053 rd.Encode(22, 12) | rm.Encode(5, 0)); 15054 AdvanceIT(); 15055 return; 15056 } 15057 } else { 15058 // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1 15059 if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) { 15060 EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15061 rm.Encode(5, 0)); 15062 return; 15063 } 15064 // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1 15065 if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) { 15066 EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) | 15067 (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) | 15068 rm.Encode(5, 0)); 15069 return; 15070 } 15071 } 15072 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 15073 } 15074 15075 void Assembler::vcvt( 15076 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 15077 VIXL_ASSERT(AllowAssembler()); 15078 CheckIT(cond); 15079 if (IsUsingT32()) { 15080 // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1 15081 if (dt1.Is(F32) && dt2.Is(F64)) { 15082 EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15083 AdvanceIT(); 15084 return; 15085 } 15086 // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1 15087 if (dt1.Is(U32) && dt2.Is(F64)) { 15088 EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15089 AdvanceIT(); 15090 return; 15091 } 15092 // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1 15093 if (dt1.Is(S32) && dt2.Is(F64)) { 15094 EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15095 AdvanceIT(); 15096 return; 15097 } 15098 } else { 15099 // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1 15100 if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) { 15101 EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15102 rm.Encode(5, 0)); 15103 return; 15104 } 15105 // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1 15106 if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) { 15107 EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15108 rm.Encode(5, 0)); 15109 return; 15110 } 15111 // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1 15112 if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) { 15113 EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15114 rm.Encode(5, 0)); 15115 return; 15116 } 15117 } 15118 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 15119 } 15120 15121 void Assembler::vcvt(Condition cond, 15122 DataType dt1, 15123 DataType dt2, 15124 DRegister rd, 15125 DRegister rm, 15126 int32_t fbits) { 15127 VIXL_ASSERT(AllowAssembler()); 15128 CheckIT(cond); 15129 Dt_op_U_1 encoded_dt(dt1, dt2); 15130 Dt_U_sx_1 encoded_dt_2(dt2); 15131 Dt_U_sx_1 encoded_dt_3(dt1); 15132 if (IsUsingT32()) { 15133 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1 15134 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 15135 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15136 uint32_t fbits_ = 64 - fbits; 15137 EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) | 15138 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 15139 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 15140 AdvanceIT(); 15141 return; 15142 } 15143 } 15144 // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1 15145 if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) && 15146 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 15147 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 15148 unsigned offset = 32; 15149 if (dt2.Is(S16) || dt2.Is(U16)) { 15150 offset = 16; 15151 } 15152 uint32_t fbits_ = offset - fbits; 15153 EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 15154 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 15155 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 15156 ((fbits_ & 0x1e) >> 1)); 15157 AdvanceIT(); 15158 return; 15159 } 15160 // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1 15161 if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) && 15162 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 15163 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 15164 unsigned offset = 32; 15165 if (dt1.Is(S16) || dt1.Is(U16)) { 15166 offset = 16; 15167 } 15168 uint32_t fbits_ = offset - fbits; 15169 EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) | 15170 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) | 15171 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 15172 ((fbits_ & 0x1e) >> 1)); 15173 AdvanceIT(); 15174 return; 15175 } 15176 } else { 15177 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1 15178 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 15179 if (cond.Is(al)) { 15180 uint32_t fbits_ = 64 - fbits; 15181 EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) | 15182 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 15183 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 15184 return; 15185 } 15186 } 15187 // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1 15188 if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) && 15189 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 15190 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 15191 cond.IsNotNever()) { 15192 unsigned offset = 32; 15193 if (dt2.Is(S16) || dt2.Is(U16)) { 15194 offset = 16; 15195 } 15196 uint32_t fbits_ = offset - fbits; 15197 EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) | 15198 ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 15199 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 15200 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 15201 ((fbits_ & 0x1e) >> 1)); 15202 return; 15203 } 15204 // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1 15205 if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) && 15206 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 15207 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 15208 cond.IsNotNever()) { 15209 unsigned offset = 32; 15210 if (dt1.Is(S16) || dt1.Is(U16)) { 15211 offset = 16; 15212 } 15213 uint32_t fbits_ = offset - fbits; 15214 EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) | 15215 ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) | 15216 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) | 15217 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 15218 ((fbits_ & 0x1e) >> 1)); 15219 return; 15220 } 15221 } 15222 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 15223 } 15224 15225 void Assembler::vcvt(Condition cond, 15226 DataType dt1, 15227 DataType dt2, 15228 QRegister rd, 15229 QRegister rm, 15230 int32_t fbits) { 15231 VIXL_ASSERT(AllowAssembler()); 15232 CheckIT(cond); 15233 Dt_op_U_1 encoded_dt(dt1, dt2); 15234 if (IsUsingT32()) { 15235 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1 15236 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 15237 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15238 uint32_t fbits_ = 64 - fbits; 15239 EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) | 15240 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 15241 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 15242 AdvanceIT(); 15243 return; 15244 } 15245 } 15246 } else { 15247 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1 15248 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) { 15249 if (cond.Is(al)) { 15250 uint32_t fbits_ = 64 - fbits; 15251 EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) | 15252 ((encoded_dt.GetEncodingValue() & 0x2) << 7) | 15253 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16)); 15254 return; 15255 } 15256 } 15257 } 15258 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 15259 } 15260 15261 void Assembler::vcvt(Condition cond, 15262 DataType dt1, 15263 DataType dt2, 15264 SRegister rd, 15265 SRegister rm, 15266 int32_t fbits) { 15267 VIXL_ASSERT(AllowAssembler()); 15268 CheckIT(cond); 15269 Dt_U_sx_1 encoded_dt(dt2); 15270 Dt_U_sx_1 encoded_dt_2(dt1); 15271 if (IsUsingT32()) { 15272 // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1 15273 if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) && 15274 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 15275 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 15276 unsigned offset = 32; 15277 if (dt2.Is(S16) || dt2.Is(U16)) { 15278 offset = 16; 15279 } 15280 uint32_t fbits_ = offset - fbits; 15281 EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) | 15282 ((encoded_dt.GetEncodingValue() & 0x2) << 15) | 15283 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 15284 ((fbits_ & 0x1e) >> 1)); 15285 AdvanceIT(); 15286 return; 15287 } 15288 // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1 15289 if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) && 15290 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 15291 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) { 15292 unsigned offset = 32; 15293 if (dt1.Is(S16) || dt1.Is(U16)) { 15294 offset = 16; 15295 } 15296 uint32_t fbits_ = offset - fbits; 15297 EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 15298 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 15299 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 15300 ((fbits_ & 0x1e) >> 1)); 15301 AdvanceIT(); 15302 return; 15303 } 15304 } else { 15305 // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1 15306 if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) && 15307 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) || 15308 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 15309 cond.IsNotNever()) { 15310 unsigned offset = 32; 15311 if (dt2.Is(S16) || dt2.Is(U16)) { 15312 offset = 16; 15313 } 15314 uint32_t fbits_ = offset - fbits; 15315 EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) | 15316 ((encoded_dt.GetEncodingValue() & 0x1) << 7) | 15317 ((encoded_dt.GetEncodingValue() & 0x2) << 15) | 15318 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 15319 ((fbits_ & 0x1e) >> 1)); 15320 return; 15321 } 15322 // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1 15323 if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) && 15324 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) || 15325 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) && 15326 cond.IsNotNever()) { 15327 unsigned offset = 32; 15328 if (dt1.Is(S16) || dt1.Is(U16)) { 15329 offset = 16; 15330 } 15331 uint32_t fbits_ = offset - fbits; 15332 EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) | 15333 ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) | 15334 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) | 15335 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) | 15336 ((fbits_ & 0x1e) >> 1)); 15337 return; 15338 } 15339 } 15340 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits); 15341 } 15342 15343 void Assembler::vcvt( 15344 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 15345 VIXL_ASSERT(AllowAssembler()); 15346 CheckIT(cond); 15347 Dt_op_1 encoded_dt(dt1, dt2); 15348 if (IsUsingT32()) { 15349 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1 15350 if (encoded_dt.IsValid()) { 15351 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15352 EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) | 15353 rd.Encode(22, 12) | rm.Encode(5, 0)); 15354 AdvanceIT(); 15355 return; 15356 } 15357 } 15358 } else { 15359 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1 15360 if (encoded_dt.IsValid()) { 15361 if (cond.Is(al)) { 15362 EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) | 15363 rd.Encode(22, 12) | rm.Encode(5, 0)); 15364 return; 15365 } 15366 } 15367 } 15368 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 15369 } 15370 15371 void Assembler::vcvt( 15372 Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 15373 VIXL_ASSERT(AllowAssembler()); 15374 CheckIT(cond); 15375 Dt_op_1 encoded_dt(dt1, dt2); 15376 if (IsUsingT32()) { 15377 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1 15378 if (encoded_dt.IsValid()) { 15379 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15380 EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) | 15381 rd.Encode(22, 12) | rm.Encode(5, 0)); 15382 AdvanceIT(); 15383 return; 15384 } 15385 } 15386 } else { 15387 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1 15388 if (encoded_dt.IsValid()) { 15389 if (cond.Is(al)) { 15390 EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) | 15391 rd.Encode(22, 12) | rm.Encode(5, 0)); 15392 return; 15393 } 15394 } 15395 } 15396 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 15397 } 15398 15399 void Assembler::vcvt( 15400 Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) { 15401 VIXL_ASSERT(AllowAssembler()); 15402 CheckIT(cond); 15403 if (IsUsingT32()) { 15404 // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1 15405 if (dt1.Is(F16) && dt2.Is(F32)) { 15406 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15407 EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15408 AdvanceIT(); 15409 return; 15410 } 15411 } 15412 } else { 15413 // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1 15414 if (dt1.Is(F16) && dt2.Is(F32)) { 15415 if (cond.Is(al)) { 15416 EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15417 return; 15418 } 15419 } 15420 } 15421 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 15422 } 15423 15424 void Assembler::vcvt( 15425 Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) { 15426 VIXL_ASSERT(AllowAssembler()); 15427 CheckIT(cond); 15428 if (IsUsingT32()) { 15429 // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1 15430 if (dt1.Is(F32) && dt2.Is(F16)) { 15431 if (cond.Is(al) || AllowStronglyDiscouraged()) { 15432 EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15433 AdvanceIT(); 15434 return; 15435 } 15436 } 15437 } else { 15438 // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1 15439 if (dt1.Is(F32) && dt2.Is(F16)) { 15440 if (cond.Is(al)) { 15441 EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15442 return; 15443 } 15444 } 15445 } 15446 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 15447 } 15448 15449 void Assembler::vcvt( 15450 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 15451 VIXL_ASSERT(AllowAssembler()); 15452 CheckIT(cond); 15453 Dt_op_2 encoded_dt(dt2); 15454 if (IsUsingT32()) { 15455 // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1 15456 if (dt1.Is(U32) && dt2.Is(F32)) { 15457 EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15458 AdvanceIT(); 15459 return; 15460 } 15461 // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1 15462 if (dt1.Is(S32) && dt2.Is(F32)) { 15463 EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15464 AdvanceIT(); 15465 return; 15466 } 15467 // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1 15468 if (dt1.Is(F32) && encoded_dt.IsValid()) { 15469 EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) | 15470 rd.Encode(22, 12) | rm.Encode(5, 0)); 15471 AdvanceIT(); 15472 return; 15473 } 15474 } else { 15475 // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1 15476 if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) { 15477 EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15478 rm.Encode(5, 0)); 15479 return; 15480 } 15481 // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1 15482 if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) { 15483 EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15484 rm.Encode(5, 0)); 15485 return; 15486 } 15487 // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1 15488 if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) { 15489 EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) | 15490 (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) | 15491 rm.Encode(5, 0)); 15492 return; 15493 } 15494 } 15495 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm); 15496 } 15497 15498 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 15499 VIXL_ASSERT(AllowAssembler()); 15500 CheckIT(al); 15501 Dt_op_3 encoded_dt(dt1); 15502 if (IsUsingT32()) { 15503 // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 15504 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15505 EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) | 15506 rd.Encode(22, 12) | rm.Encode(5, 0)); 15507 AdvanceIT(); 15508 return; 15509 } 15510 } else { 15511 // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 15512 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15513 EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) | 15514 rd.Encode(22, 12) | rm.Encode(5, 0)); 15515 return; 15516 } 15517 } 15518 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 15519 } 15520 15521 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 15522 VIXL_ASSERT(AllowAssembler()); 15523 CheckIT(al); 15524 Dt_op_3 encoded_dt(dt1); 15525 if (IsUsingT32()) { 15526 // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 15527 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15528 EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) | 15529 rd.Encode(22, 12) | rm.Encode(5, 0)); 15530 AdvanceIT(); 15531 return; 15532 } 15533 } else { 15534 // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 15535 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15536 EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) | 15537 rd.Encode(22, 12) | rm.Encode(5, 0)); 15538 return; 15539 } 15540 } 15541 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 15542 } 15543 15544 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 15545 VIXL_ASSERT(AllowAssembler()); 15546 CheckIT(al); 15547 Dt_op_2 encoded_dt(dt1); 15548 if (IsUsingT32()) { 15549 // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 15550 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15551 EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) | 15552 rd.Encode(22, 12) | rm.Encode(5, 0)); 15553 AdvanceIT(); 15554 return; 15555 } 15556 } else { 15557 // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 15558 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15559 EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) | 15560 rd.Encode(22, 12) | rm.Encode(5, 0)); 15561 return; 15562 } 15563 } 15564 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 15565 } 15566 15567 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 15568 VIXL_ASSERT(AllowAssembler()); 15569 CheckIT(al); 15570 Dt_op_2 encoded_dt(dt1); 15571 if (IsUsingT32()) { 15572 // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 15573 if (encoded_dt.IsValid() && dt2.Is(F64)) { 15574 EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) | 15575 rd.Encode(22, 12) | rm.Encode(5, 0)); 15576 AdvanceIT(); 15577 return; 15578 } 15579 } else { 15580 // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 15581 if (encoded_dt.IsValid() && dt2.Is(F64)) { 15582 EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) | 15583 rd.Encode(22, 12) | rm.Encode(5, 0)); 15584 return; 15585 } 15586 } 15587 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm); 15588 } 15589 15590 void Assembler::vcvtb( 15591 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 15592 VIXL_ASSERT(AllowAssembler()); 15593 CheckIT(cond); 15594 if (IsUsingT32()) { 15595 // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1 15596 if (dt1.Is(F32) && dt2.Is(F16)) { 15597 EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15598 AdvanceIT(); 15599 return; 15600 } 15601 // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1 15602 if (dt1.Is(F16) && dt2.Is(F32)) { 15603 EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15604 AdvanceIT(); 15605 return; 15606 } 15607 } else { 15608 // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1 15609 if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) { 15610 EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15611 rm.Encode(5, 0)); 15612 return; 15613 } 15614 // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1 15615 if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) { 15616 EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15617 rm.Encode(5, 0)); 15618 return; 15619 } 15620 } 15621 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 15622 } 15623 15624 void Assembler::vcvtb( 15625 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 15626 VIXL_ASSERT(AllowAssembler()); 15627 CheckIT(cond); 15628 if (IsUsingT32()) { 15629 // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1 15630 if (dt1.Is(F64) && dt2.Is(F16)) { 15631 EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15632 AdvanceIT(); 15633 return; 15634 } 15635 } else { 15636 // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1 15637 if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) { 15638 EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15639 rm.Encode(5, 0)); 15640 return; 15641 } 15642 } 15643 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 15644 } 15645 15646 void Assembler::vcvtb( 15647 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 15648 VIXL_ASSERT(AllowAssembler()); 15649 CheckIT(cond); 15650 if (IsUsingT32()) { 15651 // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1 15652 if (dt1.Is(F16) && dt2.Is(F64)) { 15653 EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15654 AdvanceIT(); 15655 return; 15656 } 15657 } else { 15658 // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1 15659 if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) { 15660 EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15661 rm.Encode(5, 0)); 15662 return; 15663 } 15664 } 15665 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm); 15666 } 15667 15668 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 15669 VIXL_ASSERT(AllowAssembler()); 15670 CheckIT(al); 15671 Dt_op_3 encoded_dt(dt1); 15672 if (IsUsingT32()) { 15673 // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 15674 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15675 EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) | 15676 rd.Encode(22, 12) | rm.Encode(5, 0)); 15677 AdvanceIT(); 15678 return; 15679 } 15680 } else { 15681 // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 15682 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15683 EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) | 15684 rd.Encode(22, 12) | rm.Encode(5, 0)); 15685 return; 15686 } 15687 } 15688 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 15689 } 15690 15691 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 15692 VIXL_ASSERT(AllowAssembler()); 15693 CheckIT(al); 15694 Dt_op_3 encoded_dt(dt1); 15695 if (IsUsingT32()) { 15696 // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 15697 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15698 EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) | 15699 rd.Encode(22, 12) | rm.Encode(5, 0)); 15700 AdvanceIT(); 15701 return; 15702 } 15703 } else { 15704 // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 15705 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15706 EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) | 15707 rd.Encode(22, 12) | rm.Encode(5, 0)); 15708 return; 15709 } 15710 } 15711 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 15712 } 15713 15714 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 15715 VIXL_ASSERT(AllowAssembler()); 15716 CheckIT(al); 15717 Dt_op_2 encoded_dt(dt1); 15718 if (IsUsingT32()) { 15719 // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 15720 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15721 EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) | 15722 rd.Encode(22, 12) | rm.Encode(5, 0)); 15723 AdvanceIT(); 15724 return; 15725 } 15726 } else { 15727 // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 15728 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15729 EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) | 15730 rd.Encode(22, 12) | rm.Encode(5, 0)); 15731 return; 15732 } 15733 } 15734 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 15735 } 15736 15737 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 15738 VIXL_ASSERT(AllowAssembler()); 15739 CheckIT(al); 15740 Dt_op_2 encoded_dt(dt1); 15741 if (IsUsingT32()) { 15742 // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 15743 if (encoded_dt.IsValid() && dt2.Is(F64)) { 15744 EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) | 15745 rd.Encode(22, 12) | rm.Encode(5, 0)); 15746 AdvanceIT(); 15747 return; 15748 } 15749 } else { 15750 // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 15751 if (encoded_dt.IsValid() && dt2.Is(F64)) { 15752 EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) | 15753 rd.Encode(22, 12) | rm.Encode(5, 0)); 15754 return; 15755 } 15756 } 15757 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm); 15758 } 15759 15760 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 15761 VIXL_ASSERT(AllowAssembler()); 15762 CheckIT(al); 15763 Dt_op_3 encoded_dt(dt1); 15764 if (IsUsingT32()) { 15765 // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 15766 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15767 EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) | 15768 rd.Encode(22, 12) | rm.Encode(5, 0)); 15769 AdvanceIT(); 15770 return; 15771 } 15772 } else { 15773 // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 15774 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15775 EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) | 15776 rd.Encode(22, 12) | rm.Encode(5, 0)); 15777 return; 15778 } 15779 } 15780 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 15781 } 15782 15783 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 15784 VIXL_ASSERT(AllowAssembler()); 15785 CheckIT(al); 15786 Dt_op_3 encoded_dt(dt1); 15787 if (IsUsingT32()) { 15788 // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 15789 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15790 EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) | 15791 rd.Encode(22, 12) | rm.Encode(5, 0)); 15792 AdvanceIT(); 15793 return; 15794 } 15795 } else { 15796 // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 15797 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15798 EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) | 15799 rd.Encode(22, 12) | rm.Encode(5, 0)); 15800 return; 15801 } 15802 } 15803 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 15804 } 15805 15806 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 15807 VIXL_ASSERT(AllowAssembler()); 15808 CheckIT(al); 15809 Dt_op_2 encoded_dt(dt1); 15810 if (IsUsingT32()) { 15811 // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 15812 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15813 EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) | 15814 rd.Encode(22, 12) | rm.Encode(5, 0)); 15815 AdvanceIT(); 15816 return; 15817 } 15818 } else { 15819 // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 15820 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15821 EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) | 15822 rd.Encode(22, 12) | rm.Encode(5, 0)); 15823 return; 15824 } 15825 } 15826 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 15827 } 15828 15829 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 15830 VIXL_ASSERT(AllowAssembler()); 15831 CheckIT(al); 15832 Dt_op_2 encoded_dt(dt1); 15833 if (IsUsingT32()) { 15834 // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 15835 if (encoded_dt.IsValid() && dt2.Is(F64)) { 15836 EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) | 15837 rd.Encode(22, 12) | rm.Encode(5, 0)); 15838 AdvanceIT(); 15839 return; 15840 } 15841 } else { 15842 // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 15843 if (encoded_dt.IsValid() && dt2.Is(F64)) { 15844 EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) | 15845 rd.Encode(22, 12) | rm.Encode(5, 0)); 15846 return; 15847 } 15848 } 15849 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm); 15850 } 15851 15852 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 15853 VIXL_ASSERT(AllowAssembler()); 15854 CheckIT(al); 15855 Dt_op_3 encoded_dt(dt1); 15856 if (IsUsingT32()) { 15857 // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 15858 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15859 EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) | 15860 rd.Encode(22, 12) | rm.Encode(5, 0)); 15861 AdvanceIT(); 15862 return; 15863 } 15864 } else { 15865 // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1 15866 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15867 EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) | 15868 rd.Encode(22, 12) | rm.Encode(5, 0)); 15869 return; 15870 } 15871 } 15872 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 15873 } 15874 15875 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 15876 VIXL_ASSERT(AllowAssembler()); 15877 CheckIT(al); 15878 Dt_op_3 encoded_dt(dt1); 15879 if (IsUsingT32()) { 15880 // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 15881 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15882 EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) | 15883 rd.Encode(22, 12) | rm.Encode(5, 0)); 15884 AdvanceIT(); 15885 return; 15886 } 15887 } else { 15888 // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1 15889 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15890 EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) | 15891 rd.Encode(22, 12) | rm.Encode(5, 0)); 15892 return; 15893 } 15894 } 15895 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 15896 } 15897 15898 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 15899 VIXL_ASSERT(AllowAssembler()); 15900 CheckIT(al); 15901 Dt_op_2 encoded_dt(dt1); 15902 if (IsUsingT32()) { 15903 // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1 15904 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15905 EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) | 15906 rd.Encode(22, 12) | rm.Encode(5, 0)); 15907 AdvanceIT(); 15908 return; 15909 } 15910 } else { 15911 // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1 15912 if (encoded_dt.IsValid() && dt2.Is(F32)) { 15913 EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) | 15914 rd.Encode(22, 12) | rm.Encode(5, 0)); 15915 return; 15916 } 15917 } 15918 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 15919 } 15920 15921 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 15922 VIXL_ASSERT(AllowAssembler()); 15923 CheckIT(al); 15924 Dt_op_2 encoded_dt(dt1); 15925 if (IsUsingT32()) { 15926 // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1 15927 if (encoded_dt.IsValid() && dt2.Is(F64)) { 15928 EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) | 15929 rd.Encode(22, 12) | rm.Encode(5, 0)); 15930 AdvanceIT(); 15931 return; 15932 } 15933 } else { 15934 // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1 15935 if (encoded_dt.IsValid() && dt2.Is(F64)) { 15936 EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) | 15937 rd.Encode(22, 12) | rm.Encode(5, 0)); 15938 return; 15939 } 15940 } 15941 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm); 15942 } 15943 15944 void Assembler::vcvtr( 15945 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 15946 VIXL_ASSERT(AllowAssembler()); 15947 CheckIT(cond); 15948 if (IsUsingT32()) { 15949 // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1 15950 if (dt1.Is(U32) && dt2.Is(F32)) { 15951 EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15952 AdvanceIT(); 15953 return; 15954 } 15955 // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1 15956 if (dt1.Is(S32) && dt2.Is(F32)) { 15957 EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15958 AdvanceIT(); 15959 return; 15960 } 15961 } else { 15962 // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1 15963 if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) { 15964 EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15965 rm.Encode(5, 0)); 15966 return; 15967 } 15968 // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1 15969 if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) { 15970 EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15971 rm.Encode(5, 0)); 15972 return; 15973 } 15974 } 15975 Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm); 15976 } 15977 15978 void Assembler::vcvtr( 15979 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 15980 VIXL_ASSERT(AllowAssembler()); 15981 CheckIT(cond); 15982 if (IsUsingT32()) { 15983 // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1 15984 if (dt1.Is(U32) && dt2.Is(F64)) { 15985 EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15986 AdvanceIT(); 15987 return; 15988 } 15989 // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1 15990 if (dt1.Is(S32) && dt2.Is(F64)) { 15991 EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 15992 AdvanceIT(); 15993 return; 15994 } 15995 } else { 15996 // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1 15997 if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) { 15998 EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 15999 rm.Encode(5, 0)); 16000 return; 16001 } 16002 // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1 16003 if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) { 16004 EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16005 rm.Encode(5, 0)); 16006 return; 16007 } 16008 } 16009 Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm); 16010 } 16011 16012 void Assembler::vcvtt( 16013 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 16014 VIXL_ASSERT(AllowAssembler()); 16015 CheckIT(cond); 16016 if (IsUsingT32()) { 16017 // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1 16018 if (dt1.Is(F32) && dt2.Is(F16)) { 16019 EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16020 AdvanceIT(); 16021 return; 16022 } 16023 // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1 16024 if (dt1.Is(F16) && dt2.Is(F32)) { 16025 EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16026 AdvanceIT(); 16027 return; 16028 } 16029 } else { 16030 // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1 16031 if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) { 16032 EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16033 rm.Encode(5, 0)); 16034 return; 16035 } 16036 // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1 16037 if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) { 16038 EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16039 rm.Encode(5, 0)); 16040 return; 16041 } 16042 } 16043 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 16044 } 16045 16046 void Assembler::vcvtt( 16047 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) { 16048 VIXL_ASSERT(AllowAssembler()); 16049 CheckIT(cond); 16050 if (IsUsingT32()) { 16051 // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1 16052 if (dt1.Is(F64) && dt2.Is(F16)) { 16053 EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16054 AdvanceIT(); 16055 return; 16056 } 16057 } else { 16058 // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1 16059 if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) { 16060 EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16061 rm.Encode(5, 0)); 16062 return; 16063 } 16064 } 16065 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 16066 } 16067 16068 void Assembler::vcvtt( 16069 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) { 16070 VIXL_ASSERT(AllowAssembler()); 16071 CheckIT(cond); 16072 if (IsUsingT32()) { 16073 // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1 16074 if (dt1.Is(F16) && dt2.Is(F64)) { 16075 EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 16076 AdvanceIT(); 16077 return; 16078 } 16079 } else { 16080 // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1 16081 if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) { 16082 EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16083 rm.Encode(5, 0)); 16084 return; 16085 } 16086 } 16087 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm); 16088 } 16089 16090 void Assembler::vdiv( 16091 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 16092 VIXL_ASSERT(AllowAssembler()); 16093 CheckIT(cond); 16094 if (IsUsingT32()) { 16095 // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1 16096 if (dt.Is(F32)) { 16097 EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16098 rm.Encode(5, 0)); 16099 AdvanceIT(); 16100 return; 16101 } 16102 } else { 16103 // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1 16104 if (dt.Is(F32) && cond.IsNotNever()) { 16105 EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16106 rn.Encode(7, 16) | rm.Encode(5, 0)); 16107 return; 16108 } 16109 } 16110 Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm); 16111 } 16112 16113 void Assembler::vdiv( 16114 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 16115 VIXL_ASSERT(AllowAssembler()); 16116 CheckIT(cond); 16117 if (IsUsingT32()) { 16118 // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1 16119 if (dt.Is(F64)) { 16120 EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16121 rm.Encode(5, 0)); 16122 AdvanceIT(); 16123 return; 16124 } 16125 } else { 16126 // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1 16127 if (dt.Is(F64) && cond.IsNotNever()) { 16128 EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16129 rn.Encode(7, 16) | rm.Encode(5, 0)); 16130 return; 16131 } 16132 } 16133 Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm); 16134 } 16135 16136 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) { 16137 VIXL_ASSERT(AllowAssembler()); 16138 CheckIT(cond); 16139 Dt_B_E_1 encoded_dt(dt); 16140 if (IsUsingT32()) { 16141 // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1 16142 if (encoded_dt.IsValid()) { 16143 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16144 EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 16145 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 16146 rd.Encode(7, 16) | (rt.GetCode() << 12)); 16147 AdvanceIT(); 16148 return; 16149 } 16150 } 16151 } else { 16152 // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1 16153 if (encoded_dt.IsValid() && cond.IsNotNever()) { 16154 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16155 EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) | 16156 ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 16157 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 16158 rd.Encode(7, 16) | (rt.GetCode() << 12)); 16159 return; 16160 } 16161 } 16162 } 16163 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt); 16164 } 16165 16166 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) { 16167 VIXL_ASSERT(AllowAssembler()); 16168 CheckIT(cond); 16169 Dt_B_E_1 encoded_dt(dt); 16170 if (IsUsingT32()) { 16171 // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1 16172 if (encoded_dt.IsValid()) { 16173 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16174 EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 16175 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 16176 rd.Encode(7, 16) | (rt.GetCode() << 12)); 16177 AdvanceIT(); 16178 return; 16179 } 16180 } 16181 } else { 16182 // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1 16183 if (encoded_dt.IsValid() && cond.IsNotNever()) { 16184 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16185 EmitA32(0x0e800b10U | (cond.GetCondition() << 28) | 16186 ((encoded_dt.GetEncodingValue() & 0x1) << 5) | 16187 ((encoded_dt.GetEncodingValue() & 0x2) << 21) | 16188 rd.Encode(7, 16) | (rt.GetCode() << 12)); 16189 return; 16190 } 16191 } 16192 } 16193 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt); 16194 } 16195 16196 void Assembler::vdup(Condition cond, 16197 DataType dt, 16198 DRegister rd, 16199 DRegisterLane rm) { 16200 VIXL_ASSERT(AllowAssembler()); 16201 CheckIT(cond); 16202 Dt_imm4_1 encoded_dt(dt, rm); 16203 if (IsUsingT32()) { 16204 // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1 16205 if (encoded_dt.IsValid()) { 16206 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16207 EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) | 16208 rd.Encode(22, 12) | rm.Encode(5, 0)); 16209 AdvanceIT(); 16210 return; 16211 } 16212 } 16213 } else { 16214 // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1 16215 if (encoded_dt.IsValid()) { 16216 if (cond.Is(al)) { 16217 EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) | 16218 rd.Encode(22, 12) | rm.Encode(5, 0)); 16219 return; 16220 } 16221 } 16222 } 16223 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm); 16224 } 16225 16226 void Assembler::vdup(Condition cond, 16227 DataType dt, 16228 QRegister rd, 16229 DRegisterLane rm) { 16230 VIXL_ASSERT(AllowAssembler()); 16231 CheckIT(cond); 16232 Dt_imm4_1 encoded_dt(dt, rm); 16233 if (IsUsingT32()) { 16234 // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1 16235 if (encoded_dt.IsValid()) { 16236 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16237 EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) | 16238 rd.Encode(22, 12) | rm.Encode(5, 0)); 16239 AdvanceIT(); 16240 return; 16241 } 16242 } 16243 } else { 16244 // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1 16245 if (encoded_dt.IsValid()) { 16246 if (cond.Is(al)) { 16247 EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) | 16248 rd.Encode(22, 12) | rm.Encode(5, 0)); 16249 return; 16250 } 16251 } 16252 } 16253 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm); 16254 } 16255 16256 void Assembler::veor( 16257 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 16258 VIXL_ASSERT(AllowAssembler()); 16259 CheckIT(cond); 16260 USE(dt); 16261 if (IsUsingT32()) { 16262 // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 16263 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16264 EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16265 rm.Encode(5, 0)); 16266 AdvanceIT(); 16267 return; 16268 } 16269 } else { 16270 // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 16271 if (cond.Is(al)) { 16272 EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16273 rm.Encode(5, 0)); 16274 return; 16275 } 16276 } 16277 Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm); 16278 } 16279 16280 void Assembler::veor( 16281 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 16282 VIXL_ASSERT(AllowAssembler()); 16283 CheckIT(cond); 16284 USE(dt); 16285 if (IsUsingT32()) { 16286 // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 16287 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16288 EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16289 rm.Encode(5, 0)); 16290 AdvanceIT(); 16291 return; 16292 } 16293 } else { 16294 // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 16295 if (cond.Is(al)) { 16296 EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16297 rm.Encode(5, 0)); 16298 return; 16299 } 16300 } 16301 Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm); 16302 } 16303 16304 void Assembler::vext(Condition cond, 16305 DataType dt, 16306 DRegister rd, 16307 DRegister rn, 16308 DRegister rm, 16309 const DOperand& operand) { 16310 VIXL_ASSERT(AllowAssembler()); 16311 CheckIT(cond); 16312 if (operand.IsImmediate()) { 16313 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 16314 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 16315 if (IsUsingT32()) { 16316 // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1 16317 if (dt.Is(Untyped8) && (imm <= 7)) { 16318 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16319 EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16320 rm.Encode(5, 0) | (imm << 8)); 16321 AdvanceIT(); 16322 return; 16323 } 16324 } 16325 // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1 16326 if ((dt.Is(Untyped16) || dt.Is(Untyped32)) && 16327 (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 16328 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16329 uint32_t imm4 = imm / dt.GetSize(); 16330 EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16331 rm.Encode(5, 0) | (imm4 << 8)); 16332 AdvanceIT(); 16333 return; 16334 } 16335 } 16336 } else { 16337 // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1 16338 if (dt.Is(Untyped8) && (imm <= 7)) { 16339 if (cond.Is(al)) { 16340 EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16341 rm.Encode(5, 0) | (imm << 8)); 16342 return; 16343 } 16344 } 16345 // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1 16346 if ((dt.Is(Untyped16) || dt.Is(Untyped32)) && 16347 (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 16348 if (cond.Is(al)) { 16349 uint32_t imm4 = imm / dt.GetSize(); 16350 EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16351 rm.Encode(5, 0) | (imm4 << 8)); 16352 return; 16353 } 16354 } 16355 } 16356 } 16357 } 16358 Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand); 16359 } 16360 16361 void Assembler::vext(Condition cond, 16362 DataType dt, 16363 QRegister rd, 16364 QRegister rn, 16365 QRegister rm, 16366 const QOperand& operand) { 16367 VIXL_ASSERT(AllowAssembler()); 16368 CheckIT(cond); 16369 if (operand.IsImmediate()) { 16370 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 16371 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 16372 if (IsUsingT32()) { 16373 // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1 16374 if (dt.Is(Untyped8) && (imm <= 15)) { 16375 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16376 EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16377 rm.Encode(5, 0) | (imm << 8)); 16378 AdvanceIT(); 16379 return; 16380 } 16381 } 16382 // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1 16383 if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) && 16384 (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 16385 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16386 uint32_t imm4 = imm / dt.GetSize(); 16387 EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16388 rm.Encode(5, 0) | (imm4 << 8)); 16389 AdvanceIT(); 16390 return; 16391 } 16392 } 16393 } else { 16394 // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1 16395 if (dt.Is(Untyped8) && (imm <= 15)) { 16396 if (cond.Is(al)) { 16397 EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16398 rm.Encode(5, 0) | (imm << 8)); 16399 return; 16400 } 16401 } 16402 // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1 16403 if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) && 16404 (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) { 16405 if (cond.Is(al)) { 16406 uint32_t imm4 = imm / dt.GetSize(); 16407 EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16408 rm.Encode(5, 0) | (imm4 << 8)); 16409 return; 16410 } 16411 } 16412 } 16413 } 16414 } 16415 Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand); 16416 } 16417 16418 void Assembler::vfma( 16419 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 16420 VIXL_ASSERT(AllowAssembler()); 16421 CheckIT(cond); 16422 if (IsUsingT32()) { 16423 // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 16424 if (dt.Is(F32)) { 16425 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16426 EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16427 rm.Encode(5, 0)); 16428 AdvanceIT(); 16429 return; 16430 } 16431 } 16432 // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 16433 if (dt.Is(F64)) { 16434 EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16435 rm.Encode(5, 0)); 16436 AdvanceIT(); 16437 return; 16438 } 16439 } else { 16440 // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 16441 if (dt.Is(F32)) { 16442 if (cond.Is(al)) { 16443 EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16444 rm.Encode(5, 0)); 16445 return; 16446 } 16447 } 16448 // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 16449 if (dt.Is(F64) && cond.IsNotNever()) { 16450 EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16451 rn.Encode(7, 16) | rm.Encode(5, 0)); 16452 return; 16453 } 16454 } 16455 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 16456 } 16457 16458 void Assembler::vfma( 16459 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 16460 VIXL_ASSERT(AllowAssembler()); 16461 CheckIT(cond); 16462 if (IsUsingT32()) { 16463 // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 16464 if (dt.Is(F32)) { 16465 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16466 EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16467 rm.Encode(5, 0)); 16468 AdvanceIT(); 16469 return; 16470 } 16471 } 16472 } else { 16473 // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 16474 if (dt.Is(F32)) { 16475 if (cond.Is(al)) { 16476 EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16477 rm.Encode(5, 0)); 16478 return; 16479 } 16480 } 16481 } 16482 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 16483 } 16484 16485 void Assembler::vfma( 16486 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 16487 VIXL_ASSERT(AllowAssembler()); 16488 CheckIT(cond); 16489 if (IsUsingT32()) { 16490 // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 16491 if (dt.Is(F32)) { 16492 EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16493 rm.Encode(5, 0)); 16494 AdvanceIT(); 16495 return; 16496 } 16497 } else { 16498 // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 16499 if (dt.Is(F32) && cond.IsNotNever()) { 16500 EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16501 rn.Encode(7, 16) | rm.Encode(5, 0)); 16502 return; 16503 } 16504 } 16505 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm); 16506 } 16507 16508 void Assembler::vfms( 16509 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 16510 VIXL_ASSERT(AllowAssembler()); 16511 CheckIT(cond); 16512 if (IsUsingT32()) { 16513 // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 16514 if (dt.Is(F32)) { 16515 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16516 EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16517 rm.Encode(5, 0)); 16518 AdvanceIT(); 16519 return; 16520 } 16521 } 16522 // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 16523 if (dt.Is(F64)) { 16524 EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16525 rm.Encode(5, 0)); 16526 AdvanceIT(); 16527 return; 16528 } 16529 } else { 16530 // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 16531 if (dt.Is(F32)) { 16532 if (cond.Is(al)) { 16533 EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16534 rm.Encode(5, 0)); 16535 return; 16536 } 16537 } 16538 // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 16539 if (dt.Is(F64) && cond.IsNotNever()) { 16540 EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16541 rn.Encode(7, 16) | rm.Encode(5, 0)); 16542 return; 16543 } 16544 } 16545 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 16546 } 16547 16548 void Assembler::vfms( 16549 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 16550 VIXL_ASSERT(AllowAssembler()); 16551 CheckIT(cond); 16552 if (IsUsingT32()) { 16553 // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 16554 if (dt.Is(F32)) { 16555 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16556 EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16557 rm.Encode(5, 0)); 16558 AdvanceIT(); 16559 return; 16560 } 16561 } 16562 } else { 16563 // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 16564 if (dt.Is(F32)) { 16565 if (cond.Is(al)) { 16566 EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16567 rm.Encode(5, 0)); 16568 return; 16569 } 16570 } 16571 } 16572 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 16573 } 16574 16575 void Assembler::vfms( 16576 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 16577 VIXL_ASSERT(AllowAssembler()); 16578 CheckIT(cond); 16579 if (IsUsingT32()) { 16580 // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 16581 if (dt.Is(F32)) { 16582 EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16583 rm.Encode(5, 0)); 16584 AdvanceIT(); 16585 return; 16586 } 16587 } else { 16588 // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 16589 if (dt.Is(F32) && cond.IsNotNever()) { 16590 EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16591 rn.Encode(7, 16) | rm.Encode(5, 0)); 16592 return; 16593 } 16594 } 16595 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm); 16596 } 16597 16598 void Assembler::vfnma( 16599 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 16600 VIXL_ASSERT(AllowAssembler()); 16601 CheckIT(cond); 16602 if (IsUsingT32()) { 16603 // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 16604 if (dt.Is(F32)) { 16605 EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16606 rm.Encode(5, 0)); 16607 AdvanceIT(); 16608 return; 16609 } 16610 } else { 16611 // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 16612 if (dt.Is(F32) && cond.IsNotNever()) { 16613 EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16614 rn.Encode(7, 16) | rm.Encode(5, 0)); 16615 return; 16616 } 16617 } 16618 Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm); 16619 } 16620 16621 void Assembler::vfnma( 16622 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 16623 VIXL_ASSERT(AllowAssembler()); 16624 CheckIT(cond); 16625 if (IsUsingT32()) { 16626 // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 16627 if (dt.Is(F64)) { 16628 EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16629 rm.Encode(5, 0)); 16630 AdvanceIT(); 16631 return; 16632 } 16633 } else { 16634 // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 16635 if (dt.Is(F64) && cond.IsNotNever()) { 16636 EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16637 rn.Encode(7, 16) | rm.Encode(5, 0)); 16638 return; 16639 } 16640 } 16641 Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm); 16642 } 16643 16644 void Assembler::vfnms( 16645 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 16646 VIXL_ASSERT(AllowAssembler()); 16647 CheckIT(cond); 16648 if (IsUsingT32()) { 16649 // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 16650 if (dt.Is(F32)) { 16651 EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16652 rm.Encode(5, 0)); 16653 AdvanceIT(); 16654 return; 16655 } 16656 } else { 16657 // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 16658 if (dt.Is(F32) && cond.IsNotNever()) { 16659 EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16660 rn.Encode(7, 16) | rm.Encode(5, 0)); 16661 return; 16662 } 16663 } 16664 Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm); 16665 } 16666 16667 void Assembler::vfnms( 16668 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 16669 VIXL_ASSERT(AllowAssembler()); 16670 CheckIT(cond); 16671 if (IsUsingT32()) { 16672 // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 16673 if (dt.Is(F64)) { 16674 EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 16675 rm.Encode(5, 0)); 16676 AdvanceIT(); 16677 return; 16678 } 16679 } else { 16680 // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 16681 if (dt.Is(F64) && cond.IsNotNever()) { 16682 EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 16683 rn.Encode(7, 16) | rm.Encode(5, 0)); 16684 return; 16685 } 16686 } 16687 Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm); 16688 } 16689 16690 void Assembler::vhadd( 16691 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 16692 VIXL_ASSERT(AllowAssembler()); 16693 CheckIT(cond); 16694 Dt_U_size_1 encoded_dt(dt); 16695 if (IsUsingT32()) { 16696 // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 16697 if (encoded_dt.IsValid()) { 16698 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16699 EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 16700 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 16701 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 16702 AdvanceIT(); 16703 return; 16704 } 16705 } 16706 } else { 16707 // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 16708 if (encoded_dt.IsValid()) { 16709 if (cond.Is(al)) { 16710 EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 16711 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 16712 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 16713 return; 16714 } 16715 } 16716 } 16717 Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm); 16718 } 16719 16720 void Assembler::vhadd( 16721 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 16722 VIXL_ASSERT(AllowAssembler()); 16723 CheckIT(cond); 16724 Dt_U_size_1 encoded_dt(dt); 16725 if (IsUsingT32()) { 16726 // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 16727 if (encoded_dt.IsValid()) { 16728 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16729 EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 16730 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 16731 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 16732 AdvanceIT(); 16733 return; 16734 } 16735 } 16736 } else { 16737 // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 16738 if (encoded_dt.IsValid()) { 16739 if (cond.Is(al)) { 16740 EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 16741 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 16742 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 16743 return; 16744 } 16745 } 16746 } 16747 Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm); 16748 } 16749 16750 void Assembler::vhsub( 16751 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 16752 VIXL_ASSERT(AllowAssembler()); 16753 CheckIT(cond); 16754 Dt_U_size_1 encoded_dt(dt); 16755 if (IsUsingT32()) { 16756 // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 16757 if (encoded_dt.IsValid()) { 16758 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16759 EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 16760 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 16761 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 16762 AdvanceIT(); 16763 return; 16764 } 16765 } 16766 } else { 16767 // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 16768 if (encoded_dt.IsValid()) { 16769 if (cond.Is(al)) { 16770 EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 16771 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 16772 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 16773 return; 16774 } 16775 } 16776 } 16777 Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm); 16778 } 16779 16780 void Assembler::vhsub( 16781 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 16782 VIXL_ASSERT(AllowAssembler()); 16783 CheckIT(cond); 16784 Dt_U_size_1 encoded_dt(dt); 16785 if (IsUsingT32()) { 16786 // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 16787 if (encoded_dt.IsValid()) { 16788 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16789 EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 16790 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 16791 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 16792 AdvanceIT(); 16793 return; 16794 } 16795 } 16796 } else { 16797 // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 16798 if (encoded_dt.IsValid()) { 16799 if (cond.Is(al)) { 16800 EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 16801 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 16802 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 16803 return; 16804 } 16805 } 16806 } 16807 Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm); 16808 } 16809 16810 void Assembler::vld1(Condition cond, 16811 DataType dt, 16812 const NeonRegisterList& nreglist, 16813 const AlignedMemOperand& operand) { 16814 VIXL_ASSERT(AllowAssembler()); 16815 CheckIT(cond); 16816 if (operand.IsImmediateZero()) { 16817 Register rn = operand.GetBaseRegister(); 16818 Alignment align = operand.GetAlignment(); 16819 Dt_size_6 encoded_dt(dt); 16820 Dt_size_7 encoded_dt_2(dt); 16821 Align_align_1 encoded_align_1(align, nreglist); 16822 Align_a_1 encoded_align_2(align, dt); 16823 Align_index_align_1 encoded_align_3(align, nreglist, dt); 16824 if (IsUsingT32()) { 16825 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 16826 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 16827 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 16828 operand.IsOffset() && encoded_align_1.IsValid() && 16829 (!rn.IsPC() || AllowUnpredictable())) { 16830 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16831 const DRegister& first = nreglist.GetFirstDRegister(); 16832 uint32_t len_encoding; 16833 switch (nreglist.GetLength()) { 16834 default: 16835 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 16836 case 1: 16837 len_encoding = 0x7; 16838 break; 16839 case 2: 16840 len_encoding = 0xa; 16841 break; 16842 case 3: 16843 len_encoding = 0x6; 16844 break; 16845 case 4: 16846 len_encoding = 0x2; 16847 break; 16848 } 16849 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 16850 (encoded_align_1.GetEncodingValue() << 4) | 16851 first.Encode(22, 12) | (len_encoding << 8) | 16852 (rn.GetCode() << 16)); 16853 AdvanceIT(); 16854 return; 16855 } 16856 } 16857 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 16858 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 16859 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 16860 operand.IsPostIndex() && encoded_align_1.IsValid() && 16861 (!rn.IsPC() || AllowUnpredictable())) { 16862 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16863 const DRegister& first = nreglist.GetFirstDRegister(); 16864 uint32_t len_encoding; 16865 switch (nreglist.GetLength()) { 16866 default: 16867 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 16868 case 1: 16869 len_encoding = 0x7; 16870 break; 16871 case 2: 16872 len_encoding = 0xa; 16873 break; 16874 case 3: 16875 len_encoding = 0x6; 16876 break; 16877 case 4: 16878 len_encoding = 0x2; 16879 break; 16880 } 16881 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 16882 (encoded_align_1.GetEncodingValue() << 4) | 16883 first.Encode(22, 12) | (len_encoding << 8) | 16884 (rn.GetCode() << 16)); 16885 AdvanceIT(); 16886 return; 16887 } 16888 } 16889 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 16890 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 16891 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 16892 operand.IsOffset() && encoded_align_2.IsValid() && 16893 (!rn.IsPC() || AllowUnpredictable())) { 16894 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16895 const DRegister& first = nreglist.GetFirstDRegister(); 16896 uint32_t len_encoding = nreglist.GetLength() - 1; 16897 EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) | 16898 (encoded_align_2.GetEncodingValue() << 4) | 16899 first.Encode(22, 12) | (len_encoding << 5) | 16900 (rn.GetCode() << 16)); 16901 AdvanceIT(); 16902 return; 16903 } 16904 } 16905 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 16906 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 16907 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 16908 operand.IsPostIndex() && encoded_align_2.IsValid() && 16909 (!rn.IsPC() || AllowUnpredictable())) { 16910 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16911 const DRegister& first = nreglist.GetFirstDRegister(); 16912 uint32_t len_encoding = nreglist.GetLength() - 1; 16913 EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) | 16914 (encoded_align_2.GetEncodingValue() << 4) | 16915 first.Encode(22, 12) | (len_encoding << 5) | 16916 (rn.GetCode() << 16)); 16917 AdvanceIT(); 16918 return; 16919 } 16920 } 16921 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 16922 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 16923 (nreglist.GetLength() == 1) && operand.IsOffset() && 16924 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 16925 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16926 const DRegister& first = nreglist.GetFirstDRegister(); 16927 EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) | 16928 (encoded_align_3.GetEncodingValue() << 4) | 16929 first.Encode(22, 12) | (rn.GetCode() << 16)); 16930 AdvanceIT(); 16931 return; 16932 } 16933 } 16934 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 16935 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 16936 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 16937 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 16938 if (cond.Is(al) || AllowStronglyDiscouraged()) { 16939 const DRegister& first = nreglist.GetFirstDRegister(); 16940 EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) | 16941 (encoded_align_3.GetEncodingValue() << 4) | 16942 first.Encode(22, 12) | (rn.GetCode() << 16)); 16943 AdvanceIT(); 16944 return; 16945 } 16946 } 16947 } else { 16948 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 16949 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 16950 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 16951 operand.IsOffset() && encoded_align_1.IsValid() && 16952 (!rn.IsPC() || AllowUnpredictable())) { 16953 if (cond.Is(al)) { 16954 const DRegister& first = nreglist.GetFirstDRegister(); 16955 uint32_t len_encoding; 16956 switch (nreglist.GetLength()) { 16957 default: 16958 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 16959 case 1: 16960 len_encoding = 0x7; 16961 break; 16962 case 2: 16963 len_encoding = 0xa; 16964 break; 16965 case 3: 16966 len_encoding = 0x6; 16967 break; 16968 case 4: 16969 len_encoding = 0x2; 16970 break; 16971 } 16972 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 16973 (encoded_align_1.GetEncodingValue() << 4) | 16974 first.Encode(22, 12) | (len_encoding << 8) | 16975 (rn.GetCode() << 16)); 16976 return; 16977 } 16978 } 16979 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 16980 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 16981 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 16982 operand.IsPostIndex() && encoded_align_1.IsValid() && 16983 (!rn.IsPC() || AllowUnpredictable())) { 16984 if (cond.Is(al)) { 16985 const DRegister& first = nreglist.GetFirstDRegister(); 16986 uint32_t len_encoding; 16987 switch (nreglist.GetLength()) { 16988 default: 16989 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 16990 case 1: 16991 len_encoding = 0x7; 16992 break; 16993 case 2: 16994 len_encoding = 0xa; 16995 break; 16996 case 3: 16997 len_encoding = 0x6; 16998 break; 16999 case 4: 17000 len_encoding = 0x2; 17001 break; 17002 } 17003 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 17004 (encoded_align_1.GetEncodingValue() << 4) | 17005 first.Encode(22, 12) | (len_encoding << 8) | 17006 (rn.GetCode() << 16)); 17007 return; 17008 } 17009 } 17010 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 17011 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 17012 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 17013 operand.IsOffset() && encoded_align_2.IsValid() && 17014 (!rn.IsPC() || AllowUnpredictable())) { 17015 if (cond.Is(al)) { 17016 const DRegister& first = nreglist.GetFirstDRegister(); 17017 uint32_t len_encoding = nreglist.GetLength() - 1; 17018 EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) | 17019 (encoded_align_2.GetEncodingValue() << 4) | 17020 first.Encode(22, 12) | (len_encoding << 5) | 17021 (rn.GetCode() << 16)); 17022 return; 17023 } 17024 } 17025 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 17026 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 17027 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 17028 operand.IsPostIndex() && encoded_align_2.IsValid() && 17029 (!rn.IsPC() || AllowUnpredictable())) { 17030 if (cond.Is(al)) { 17031 const DRegister& first = nreglist.GetFirstDRegister(); 17032 uint32_t len_encoding = nreglist.GetLength() - 1; 17033 EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) | 17034 (encoded_align_2.GetEncodingValue() << 4) | 17035 first.Encode(22, 12) | (len_encoding << 5) | 17036 (rn.GetCode() << 16)); 17037 return; 17038 } 17039 } 17040 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 17041 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 17042 (nreglist.GetLength() == 1) && operand.IsOffset() && 17043 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 17044 if (cond.Is(al)) { 17045 const DRegister& first = nreglist.GetFirstDRegister(); 17046 EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) | 17047 (encoded_align_3.GetEncodingValue() << 4) | 17048 first.Encode(22, 12) | (rn.GetCode() << 16)); 17049 return; 17050 } 17051 } 17052 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 17053 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 17054 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 17055 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 17056 if (cond.Is(al)) { 17057 const DRegister& first = nreglist.GetFirstDRegister(); 17058 EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) | 17059 (encoded_align_3.GetEncodingValue() << 4) | 17060 first.Encode(22, 12) | (rn.GetCode() << 16)); 17061 return; 17062 } 17063 } 17064 } 17065 } 17066 if (operand.IsPlainRegister()) { 17067 Register rn = operand.GetBaseRegister(); 17068 Alignment align = operand.GetAlignment(); 17069 Register rm = operand.GetOffsetRegister(); 17070 Dt_size_6 encoded_dt(dt); 17071 Dt_size_7 encoded_dt_2(dt); 17072 Align_align_1 encoded_align_1(align, nreglist); 17073 Align_a_1 encoded_align_2(align, dt); 17074 Align_index_align_1 encoded_align_3(align, nreglist, dt); 17075 if (IsUsingT32()) { 17076 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 17077 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17078 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 17079 !rm.IsPC() && !rm.IsSP()) { 17080 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17081 const DRegister& first = nreglist.GetFirstDRegister(); 17082 uint32_t len_encoding; 17083 switch (nreglist.GetLength()) { 17084 default: 17085 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 17086 case 1: 17087 len_encoding = 0x7; 17088 break; 17089 case 2: 17090 len_encoding = 0xa; 17091 break; 17092 case 3: 17093 len_encoding = 0x6; 17094 break; 17095 case 4: 17096 len_encoding = 0x2; 17097 break; 17098 } 17099 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 17100 (encoded_align_1.GetEncodingValue() << 4) | 17101 first.Encode(22, 12) | (len_encoding << 8) | 17102 (rn.GetCode() << 16) | rm.GetCode()); 17103 AdvanceIT(); 17104 return; 17105 } 17106 } 17107 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 17108 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 17109 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 17110 !rm.IsPC() && !rm.IsSP()) { 17111 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17112 const DRegister& first = nreglist.GetFirstDRegister(); 17113 uint32_t len_encoding = nreglist.GetLength() - 1; 17114 EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) | 17115 (encoded_align_2.GetEncodingValue() << 4) | 17116 first.Encode(22, 12) | (len_encoding << 5) | 17117 (rn.GetCode() << 16) | rm.GetCode()); 17118 AdvanceIT(); 17119 return; 17120 } 17121 } 17122 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 17123 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 17124 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) { 17125 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17126 const DRegister& first = nreglist.GetFirstDRegister(); 17127 EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) | 17128 (encoded_align_3.GetEncodingValue() << 4) | 17129 first.Encode(22, 12) | (rn.GetCode() << 16) | 17130 rm.GetCode()); 17131 AdvanceIT(); 17132 return; 17133 } 17134 } 17135 } else { 17136 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 17137 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17138 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 17139 !rm.IsPC() && !rm.IsSP()) { 17140 if (cond.Is(al)) { 17141 const DRegister& first = nreglist.GetFirstDRegister(); 17142 uint32_t len_encoding; 17143 switch (nreglist.GetLength()) { 17144 default: 17145 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 17146 case 1: 17147 len_encoding = 0x7; 17148 break; 17149 case 2: 17150 len_encoding = 0xa; 17151 break; 17152 case 3: 17153 len_encoding = 0x6; 17154 break; 17155 case 4: 17156 len_encoding = 0x2; 17157 break; 17158 } 17159 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 17160 (encoded_align_1.GetEncodingValue() << 4) | 17161 first.Encode(22, 12) | (len_encoding << 8) | 17162 (rn.GetCode() << 16) | rm.GetCode()); 17163 return; 17164 } 17165 } 17166 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 17167 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 17168 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) && 17169 !rm.IsPC() && !rm.IsSP()) { 17170 if (cond.Is(al)) { 17171 const DRegister& first = nreglist.GetFirstDRegister(); 17172 uint32_t len_encoding = nreglist.GetLength() - 1; 17173 EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) | 17174 (encoded_align_2.GetEncodingValue() << 4) | 17175 first.Encode(22, 12) | (len_encoding << 5) | 17176 (rn.GetCode() << 16) | rm.GetCode()); 17177 return; 17178 } 17179 } 17180 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 17181 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 17182 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) { 17183 if (cond.Is(al)) { 17184 const DRegister& first = nreglist.GetFirstDRegister(); 17185 EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) | 17186 (encoded_align_3.GetEncodingValue() << 4) | 17187 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 17188 return; 17189 } 17190 } 17191 } 17192 } 17193 Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand); 17194 } 17195 17196 void Assembler::vld2(Condition cond, 17197 DataType dt, 17198 const NeonRegisterList& nreglist, 17199 const AlignedMemOperand& operand) { 17200 VIXL_ASSERT(AllowAssembler()); 17201 CheckIT(cond); 17202 if (operand.IsImmediateZero()) { 17203 Register rn = operand.GetBaseRegister(); 17204 Alignment align = operand.GetAlignment(); 17205 Dt_size_7 encoded_dt(dt); 17206 Align_align_2 encoded_align_1(align, nreglist); 17207 Align_a_2 encoded_align_2(align, dt); 17208 Align_index_align_2 encoded_align_3(align, nreglist, dt); 17209 if (IsUsingT32()) { 17210 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 17211 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17212 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17213 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 17214 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 17215 operand.IsOffset() && encoded_align_1.IsValid() && 17216 (!rn.IsPC() || AllowUnpredictable())) { 17217 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17218 const DRegister& first = nreglist.GetFirstDRegister(); 17219 uint32_t len_encoding; 17220 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 17221 len_encoding = 0x8; 17222 } 17223 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 17224 len_encoding = 0x9; 17225 } 17226 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 17227 len_encoding = 0x3; 17228 } 17229 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 17230 (encoded_align_1.GetEncodingValue() << 4) | 17231 first.Encode(22, 12) | (len_encoding << 8) | 17232 (rn.GetCode() << 16)); 17233 AdvanceIT(); 17234 return; 17235 } 17236 } 17237 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 17238 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17239 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17240 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 17241 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 17242 operand.IsPostIndex() && encoded_align_1.IsValid() && 17243 (!rn.IsPC() || AllowUnpredictable())) { 17244 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17245 const DRegister& first = nreglist.GetFirstDRegister(); 17246 uint32_t len_encoding; 17247 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 17248 len_encoding = 0x8; 17249 } 17250 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 17251 len_encoding = 0x9; 17252 } 17253 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 17254 len_encoding = 0x3; 17255 } 17256 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 17257 (encoded_align_1.GetEncodingValue() << 4) | 17258 first.Encode(22, 12) | (len_encoding << 8) | 17259 (rn.GetCode() << 16)); 17260 AdvanceIT(); 17261 return; 17262 } 17263 } 17264 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 17265 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17266 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17267 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17268 operand.IsOffset() && encoded_align_2.IsValid() && 17269 (!rn.IsPC() || AllowUnpredictable())) { 17270 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17271 const DRegister& first = nreglist.GetFirstDRegister(); 17272 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17273 EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) | 17274 (encoded_align_2.GetEncodingValue() << 4) | 17275 first.Encode(22, 12) | (len_encoding << 5) | 17276 (rn.GetCode() << 16)); 17277 AdvanceIT(); 17278 return; 17279 } 17280 } 17281 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 17282 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17283 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17284 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17285 operand.IsPostIndex() && encoded_align_2.IsValid() && 17286 (!rn.IsPC() || AllowUnpredictable())) { 17287 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17288 const DRegister& first = nreglist.GetFirstDRegister(); 17289 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17290 EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) | 17291 (encoded_align_2.GetEncodingValue() << 4) | 17292 first.Encode(22, 12) | (len_encoding << 5) | 17293 (rn.GetCode() << 16)); 17294 AdvanceIT(); 17295 return; 17296 } 17297 } 17298 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 17299 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17300 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17301 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17302 operand.IsOffset() && encoded_align_3.IsValid() && 17303 (!rn.IsPC() || AllowUnpredictable())) { 17304 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17305 const DRegister& first = nreglist.GetFirstDRegister(); 17306 EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) | 17307 (encoded_align_3.GetEncodingValue() << 4) | 17308 first.Encode(22, 12) | (rn.GetCode() << 16)); 17309 AdvanceIT(); 17310 return; 17311 } 17312 } 17313 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 17314 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17315 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17316 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17317 operand.IsPostIndex() && encoded_align_3.IsValid() && 17318 (!rn.IsPC() || AllowUnpredictable())) { 17319 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17320 const DRegister& first = nreglist.GetFirstDRegister(); 17321 EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) | 17322 (encoded_align_3.GetEncodingValue() << 4) | 17323 first.Encode(22, 12) | (rn.GetCode() << 16)); 17324 AdvanceIT(); 17325 return; 17326 } 17327 } 17328 } else { 17329 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 17330 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17331 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17332 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 17333 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 17334 operand.IsOffset() && encoded_align_1.IsValid() && 17335 (!rn.IsPC() || AllowUnpredictable())) { 17336 if (cond.Is(al)) { 17337 const DRegister& first = nreglist.GetFirstDRegister(); 17338 uint32_t len_encoding; 17339 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 17340 len_encoding = 0x8; 17341 } 17342 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 17343 len_encoding = 0x9; 17344 } 17345 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 17346 len_encoding = 0x3; 17347 } 17348 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 17349 (encoded_align_1.GetEncodingValue() << 4) | 17350 first.Encode(22, 12) | (len_encoding << 8) | 17351 (rn.GetCode() << 16)); 17352 return; 17353 } 17354 } 17355 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 17356 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17357 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17358 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 17359 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 17360 operand.IsPostIndex() && encoded_align_1.IsValid() && 17361 (!rn.IsPC() || AllowUnpredictable())) { 17362 if (cond.Is(al)) { 17363 const DRegister& first = nreglist.GetFirstDRegister(); 17364 uint32_t len_encoding; 17365 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 17366 len_encoding = 0x8; 17367 } 17368 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 17369 len_encoding = 0x9; 17370 } 17371 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 17372 len_encoding = 0x3; 17373 } 17374 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 17375 (encoded_align_1.GetEncodingValue() << 4) | 17376 first.Encode(22, 12) | (len_encoding << 8) | 17377 (rn.GetCode() << 16)); 17378 return; 17379 } 17380 } 17381 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 17382 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17383 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17384 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17385 operand.IsOffset() && encoded_align_2.IsValid() && 17386 (!rn.IsPC() || AllowUnpredictable())) { 17387 if (cond.Is(al)) { 17388 const DRegister& first = nreglist.GetFirstDRegister(); 17389 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17390 EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) | 17391 (encoded_align_2.GetEncodingValue() << 4) | 17392 first.Encode(22, 12) | (len_encoding << 5) | 17393 (rn.GetCode() << 16)); 17394 return; 17395 } 17396 } 17397 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 17398 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17399 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17400 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17401 operand.IsPostIndex() && encoded_align_2.IsValid() && 17402 (!rn.IsPC() || AllowUnpredictable())) { 17403 if (cond.Is(al)) { 17404 const DRegister& first = nreglist.GetFirstDRegister(); 17405 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17406 EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) | 17407 (encoded_align_2.GetEncodingValue() << 4) | 17408 first.Encode(22, 12) | (len_encoding << 5) | 17409 (rn.GetCode() << 16)); 17410 return; 17411 } 17412 } 17413 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 17414 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17415 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17416 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17417 operand.IsOffset() && encoded_align_3.IsValid() && 17418 (!rn.IsPC() || AllowUnpredictable())) { 17419 if (cond.Is(al)) { 17420 const DRegister& first = nreglist.GetFirstDRegister(); 17421 EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) | 17422 (encoded_align_3.GetEncodingValue() << 4) | 17423 first.Encode(22, 12) | (rn.GetCode() << 16)); 17424 return; 17425 } 17426 } 17427 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 17428 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17429 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17430 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17431 operand.IsPostIndex() && encoded_align_3.IsValid() && 17432 (!rn.IsPC() || AllowUnpredictable())) { 17433 if (cond.Is(al)) { 17434 const DRegister& first = nreglist.GetFirstDRegister(); 17435 EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) | 17436 (encoded_align_3.GetEncodingValue() << 4) | 17437 first.Encode(22, 12) | (rn.GetCode() << 16)); 17438 return; 17439 } 17440 } 17441 } 17442 } 17443 if (operand.IsPlainRegister()) { 17444 Register rn = operand.GetBaseRegister(); 17445 Alignment align = operand.GetAlignment(); 17446 Register rm = operand.GetOffsetRegister(); 17447 Dt_size_7 encoded_dt(dt); 17448 Align_align_2 encoded_align_1(align, nreglist); 17449 Align_a_2 encoded_align_2(align, dt); 17450 Align_index_align_2 encoded_align_3(align, nreglist, dt); 17451 if (IsUsingT32()) { 17452 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 17453 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17454 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17455 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 17456 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 17457 !rm.IsPC() && !rm.IsSP()) { 17458 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17459 const DRegister& first = nreglist.GetFirstDRegister(); 17460 uint32_t len_encoding; 17461 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 17462 len_encoding = 0x8; 17463 } 17464 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 17465 len_encoding = 0x9; 17466 } 17467 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 17468 len_encoding = 0x3; 17469 } 17470 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 17471 (encoded_align_1.GetEncodingValue() << 4) | 17472 first.Encode(22, 12) | (len_encoding << 8) | 17473 (rn.GetCode() << 16) | rm.GetCode()); 17474 AdvanceIT(); 17475 return; 17476 } 17477 } 17478 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 17479 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17480 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17481 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17482 !rm.IsPC() && !rm.IsSP()) { 17483 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17484 const DRegister& first = nreglist.GetFirstDRegister(); 17485 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17486 EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) | 17487 (encoded_align_2.GetEncodingValue() << 4) | 17488 first.Encode(22, 12) | (len_encoding << 5) | 17489 (rn.GetCode() << 16) | rm.GetCode()); 17490 AdvanceIT(); 17491 return; 17492 } 17493 } 17494 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 17495 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17496 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17497 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17498 !rm.IsPC() && !rm.IsSP()) { 17499 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17500 const DRegister& first = nreglist.GetFirstDRegister(); 17501 EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) | 17502 (encoded_align_3.GetEncodingValue() << 4) | 17503 first.Encode(22, 12) | (rn.GetCode() << 16) | 17504 rm.GetCode()); 17505 AdvanceIT(); 17506 return; 17507 } 17508 } 17509 } else { 17510 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 17511 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17512 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17513 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 17514 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 17515 !rm.IsPC() && !rm.IsSP()) { 17516 if (cond.Is(al)) { 17517 const DRegister& first = nreglist.GetFirstDRegister(); 17518 uint32_t len_encoding; 17519 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 17520 len_encoding = 0x8; 17521 } 17522 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 17523 len_encoding = 0x9; 17524 } 17525 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 17526 len_encoding = 0x3; 17527 } 17528 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 17529 (encoded_align_1.GetEncodingValue() << 4) | 17530 first.Encode(22, 12) | (len_encoding << 8) | 17531 (rn.GetCode() << 16) | rm.GetCode()); 17532 return; 17533 } 17534 } 17535 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 17536 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17537 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17538 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17539 !rm.IsPC() && !rm.IsSP()) { 17540 if (cond.Is(al)) { 17541 const DRegister& first = nreglist.GetFirstDRegister(); 17542 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17543 EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) | 17544 (encoded_align_2.GetEncodingValue() << 4) | 17545 first.Encode(22, 12) | (len_encoding << 5) | 17546 (rn.GetCode() << 16) | rm.GetCode()); 17547 return; 17548 } 17549 } 17550 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 17551 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17552 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 17553 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 17554 !rm.IsPC() && !rm.IsSP()) { 17555 if (cond.Is(al)) { 17556 const DRegister& first = nreglist.GetFirstDRegister(); 17557 EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) | 17558 (encoded_align_3.GetEncodingValue() << 4) | 17559 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 17560 return; 17561 } 17562 } 17563 } 17564 } 17565 Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand); 17566 } 17567 17568 void Assembler::vld3(Condition cond, 17569 DataType dt, 17570 const NeonRegisterList& nreglist, 17571 const AlignedMemOperand& operand) { 17572 VIXL_ASSERT(AllowAssembler()); 17573 CheckIT(cond); 17574 if (operand.IsImmediateZero()) { 17575 Register rn = operand.GetBaseRegister(); 17576 Alignment align = operand.GetAlignment(); 17577 Dt_size_7 encoded_dt(dt); 17578 Align_align_3 encoded_align_1(align); 17579 if (IsUsingT32()) { 17580 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 17581 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17582 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17583 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17584 operand.IsOffset() && encoded_align_1.IsValid() && 17585 (!rn.IsPC() || AllowUnpredictable())) { 17586 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17587 const DRegister& first = nreglist.GetFirstDRegister(); 17588 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 17589 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 17590 (encoded_align_1.GetEncodingValue() << 4) | 17591 first.Encode(22, 12) | (len_encoding << 8) | 17592 (rn.GetCode() << 16)); 17593 AdvanceIT(); 17594 return; 17595 } 17596 } 17597 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 17598 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17599 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17600 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17601 operand.IsPostIndex() && encoded_align_1.IsValid() && 17602 (!rn.IsPC() || AllowUnpredictable())) { 17603 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17604 const DRegister& first = nreglist.GetFirstDRegister(); 17605 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 17606 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 17607 (encoded_align_1.GetEncodingValue() << 4) | 17608 first.Encode(22, 12) | (len_encoding << 8) | 17609 (rn.GetCode() << 16)); 17610 AdvanceIT(); 17611 return; 17612 } 17613 } 17614 } else { 17615 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 17616 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17617 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17618 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17619 operand.IsOffset() && encoded_align_1.IsValid() && 17620 (!rn.IsPC() || AllowUnpredictable())) { 17621 if (cond.Is(al)) { 17622 const DRegister& first = nreglist.GetFirstDRegister(); 17623 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 17624 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 17625 (encoded_align_1.GetEncodingValue() << 4) | 17626 first.Encode(22, 12) | (len_encoding << 8) | 17627 (rn.GetCode() << 16)); 17628 return; 17629 } 17630 } 17631 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 17632 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17633 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17634 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17635 operand.IsPostIndex() && encoded_align_1.IsValid() && 17636 (!rn.IsPC() || AllowUnpredictable())) { 17637 if (cond.Is(al)) { 17638 const DRegister& first = nreglist.GetFirstDRegister(); 17639 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 17640 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 17641 (encoded_align_1.GetEncodingValue() << 4) | 17642 first.Encode(22, 12) | (len_encoding << 8) | 17643 (rn.GetCode() << 16)); 17644 return; 17645 } 17646 } 17647 } 17648 } 17649 if (operand.IsPlainRegister()) { 17650 Register rn = operand.GetBaseRegister(); 17651 Alignment align = operand.GetAlignment(); 17652 Register rm = operand.GetOffsetRegister(); 17653 Dt_size_7 encoded_dt(dt); 17654 Align_align_3 encoded_align_1(align); 17655 if (IsUsingT32()) { 17656 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 17657 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17658 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17659 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17660 !rm.IsPC() && !rm.IsSP()) { 17661 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17662 const DRegister& first = nreglist.GetFirstDRegister(); 17663 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 17664 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 17665 (encoded_align_1.GetEncodingValue() << 4) | 17666 first.Encode(22, 12) | (len_encoding << 8) | 17667 (rn.GetCode() << 16) | rm.GetCode()); 17668 AdvanceIT(); 17669 return; 17670 } 17671 } 17672 } else { 17673 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 17674 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17675 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17676 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17677 !rm.IsPC() && !rm.IsSP()) { 17678 if (cond.Is(al)) { 17679 const DRegister& first = nreglist.GetFirstDRegister(); 17680 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 17681 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 17682 (encoded_align_1.GetEncodingValue() << 4) | 17683 first.Encode(22, 12) | (len_encoding << 8) | 17684 (rn.GetCode() << 16) | rm.GetCode()); 17685 return; 17686 } 17687 } 17688 } 17689 } 17690 Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand); 17691 } 17692 17693 void Assembler::vld3(Condition cond, 17694 DataType dt, 17695 const NeonRegisterList& nreglist, 17696 const MemOperand& operand) { 17697 VIXL_ASSERT(AllowAssembler()); 17698 CheckIT(cond); 17699 if (operand.IsImmediateZero()) { 17700 Register rn = operand.GetBaseRegister(); 17701 Dt_size_7 encoded_dt(dt); 17702 Index_1 encoded_align_1(nreglist, dt); 17703 if (IsUsingT32()) { 17704 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 17705 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17706 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17707 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17708 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 17709 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17710 const DRegister& first = nreglist.GetFirstDRegister(); 17711 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17712 EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) | 17713 first.Encode(22, 12) | (len_encoding << 5) | 17714 (rn.GetCode() << 16)); 17715 AdvanceIT(); 17716 return; 17717 } 17718 } 17719 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 17720 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17721 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17722 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17723 operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) { 17724 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17725 const DRegister& first = nreglist.GetFirstDRegister(); 17726 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17727 EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) | 17728 first.Encode(22, 12) | (len_encoding << 5) | 17729 (rn.GetCode() << 16)); 17730 AdvanceIT(); 17731 return; 17732 } 17733 } 17734 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 17735 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17736 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17737 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17738 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 17739 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17740 const DRegister& first = nreglist.GetFirstDRegister(); 17741 EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) | 17742 (encoded_align_1.GetEncodingValue() << 4) | 17743 first.Encode(22, 12) | (rn.GetCode() << 16)); 17744 AdvanceIT(); 17745 return; 17746 } 17747 } 17748 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 17749 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17750 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17751 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17752 operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) { 17753 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17754 const DRegister& first = nreglist.GetFirstDRegister(); 17755 EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) | 17756 (encoded_align_1.GetEncodingValue() << 4) | 17757 first.Encode(22, 12) | (rn.GetCode() << 16)); 17758 AdvanceIT(); 17759 return; 17760 } 17761 } 17762 } else { 17763 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 17764 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17765 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17766 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17767 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 17768 if (cond.Is(al)) { 17769 const DRegister& first = nreglist.GetFirstDRegister(); 17770 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17771 EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) | 17772 first.Encode(22, 12) | (len_encoding << 5) | 17773 (rn.GetCode() << 16)); 17774 return; 17775 } 17776 } 17777 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 17778 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17779 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17780 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17781 operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) { 17782 if (cond.Is(al)) { 17783 const DRegister& first = nreglist.GetFirstDRegister(); 17784 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17785 EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) | 17786 first.Encode(22, 12) | (len_encoding << 5) | 17787 (rn.GetCode() << 16)); 17788 return; 17789 } 17790 } 17791 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 17792 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17793 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17794 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17795 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 17796 if (cond.Is(al)) { 17797 const DRegister& first = nreglist.GetFirstDRegister(); 17798 EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) | 17799 (encoded_align_1.GetEncodingValue() << 4) | 17800 first.Encode(22, 12) | (rn.GetCode() << 16)); 17801 return; 17802 } 17803 } 17804 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 17805 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17806 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17807 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17808 operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) { 17809 if (cond.Is(al)) { 17810 const DRegister& first = nreglist.GetFirstDRegister(); 17811 EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) | 17812 (encoded_align_1.GetEncodingValue() << 4) | 17813 first.Encode(22, 12) | (rn.GetCode() << 16)); 17814 return; 17815 } 17816 } 17817 } 17818 } 17819 if (operand.IsPlainRegister()) { 17820 Register rn = operand.GetBaseRegister(); 17821 Sign sign = operand.GetSign(); 17822 Register rm = operand.GetOffsetRegister(); 17823 Dt_size_7 encoded_dt(dt); 17824 Index_1 encoded_align_1(nreglist, dt); 17825 if (IsUsingT32()) { 17826 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 17827 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17828 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17829 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17830 sign.IsPlus() && operand.IsPostIndex()) { 17831 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17832 const DRegister& first = nreglist.GetFirstDRegister(); 17833 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17834 EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) | 17835 first.Encode(22, 12) | (len_encoding << 5) | 17836 (rn.GetCode() << 16) | rm.GetCode()); 17837 AdvanceIT(); 17838 return; 17839 } 17840 } 17841 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 17842 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17843 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17844 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17845 sign.IsPlus() && operand.IsPostIndex()) { 17846 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17847 const DRegister& first = nreglist.GetFirstDRegister(); 17848 EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) | 17849 (encoded_align_1.GetEncodingValue() << 4) | 17850 first.Encode(22, 12) | (rn.GetCode() << 16) | 17851 rm.GetCode()); 17852 AdvanceIT(); 17853 return; 17854 } 17855 } 17856 } else { 17857 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 17858 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() && 17859 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17860 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17861 sign.IsPlus() && operand.IsPostIndex()) { 17862 if (cond.Is(al)) { 17863 const DRegister& first = nreglist.GetFirstDRegister(); 17864 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17865 EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) | 17866 first.Encode(22, 12) | (len_encoding << 5) | 17867 (rn.GetCode() << 16) | rm.GetCode()); 17868 return; 17869 } 17870 } 17871 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 17872 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17873 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 17874 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 17875 sign.IsPlus() && operand.IsPostIndex()) { 17876 if (cond.Is(al)) { 17877 const DRegister& first = nreglist.GetFirstDRegister(); 17878 EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) | 17879 (encoded_align_1.GetEncodingValue() << 4) | 17880 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 17881 return; 17882 } 17883 } 17884 } 17885 } 17886 Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand); 17887 } 17888 17889 void Assembler::vld4(Condition cond, 17890 DataType dt, 17891 const NeonRegisterList& nreglist, 17892 const AlignedMemOperand& operand) { 17893 VIXL_ASSERT(AllowAssembler()); 17894 CheckIT(cond); 17895 if (operand.IsImmediateZero()) { 17896 Register rn = operand.GetBaseRegister(); 17897 Alignment align = operand.GetAlignment(); 17898 Dt_size_7 encoded_dt(dt); 17899 Dt_size_8 encoded_dt_2(dt, align); 17900 Align_align_4 encoded_align_1(align); 17901 Align_a_3 encoded_align_2(align, dt); 17902 Align_index_align_3 encoded_align_3(align, nreglist, dt); 17903 if (IsUsingT32()) { 17904 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 17905 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17906 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 17907 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 17908 operand.IsOffset() && encoded_align_1.IsValid() && 17909 (!rn.IsPC() || AllowUnpredictable())) { 17910 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17911 const DRegister& first = nreglist.GetFirstDRegister(); 17912 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17913 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) | 17914 (encoded_align_1.GetEncodingValue() << 4) | 17915 first.Encode(22, 12) | (len_encoding << 8) | 17916 (rn.GetCode() << 16)); 17917 AdvanceIT(); 17918 return; 17919 } 17920 } 17921 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 17922 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 17923 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 17924 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 17925 operand.IsPostIndex() && encoded_align_1.IsValid() && 17926 (!rn.IsPC() || AllowUnpredictable())) { 17927 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17928 const DRegister& first = nreglist.GetFirstDRegister(); 17929 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17930 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) | 17931 (encoded_align_1.GetEncodingValue() << 4) | 17932 first.Encode(22, 12) | (len_encoding << 8) | 17933 (rn.GetCode() << 16)); 17934 AdvanceIT(); 17935 return; 17936 } 17937 } 17938 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 17939 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 17940 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 17941 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 17942 operand.IsOffset() && encoded_align_2.IsValid() && 17943 (!rn.IsPC() || AllowUnpredictable())) { 17944 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17945 const DRegister& first = nreglist.GetFirstDRegister(); 17946 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17947 EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) | 17948 (encoded_align_2.GetEncodingValue() << 4) | 17949 first.Encode(22, 12) | (len_encoding << 5) | 17950 (rn.GetCode() << 16)); 17951 AdvanceIT(); 17952 return; 17953 } 17954 } 17955 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 17956 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 17957 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 17958 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 17959 operand.IsPostIndex() && encoded_align_2.IsValid() && 17960 (!rn.IsPC() || AllowUnpredictable())) { 17961 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17962 const DRegister& first = nreglist.GetFirstDRegister(); 17963 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 17964 EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) | 17965 (encoded_align_2.GetEncodingValue() << 4) | 17966 first.Encode(22, 12) | (len_encoding << 5) | 17967 (rn.GetCode() << 16)); 17968 AdvanceIT(); 17969 return; 17970 } 17971 } 17972 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 17973 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17974 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 17975 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 17976 operand.IsOffset() && encoded_align_3.IsValid() && 17977 (!rn.IsPC() || AllowUnpredictable())) { 17978 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17979 const DRegister& first = nreglist.GetFirstDRegister(); 17980 EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) | 17981 (encoded_align_3.GetEncodingValue() << 4) | 17982 first.Encode(22, 12) | (rn.GetCode() << 16)); 17983 AdvanceIT(); 17984 return; 17985 } 17986 } 17987 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 17988 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 17989 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 17990 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 17991 operand.IsPostIndex() && encoded_align_3.IsValid() && 17992 (!rn.IsPC() || AllowUnpredictable())) { 17993 if (cond.Is(al) || AllowStronglyDiscouraged()) { 17994 const DRegister& first = nreglist.GetFirstDRegister(); 17995 EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) | 17996 (encoded_align_3.GetEncodingValue() << 4) | 17997 first.Encode(22, 12) | (rn.GetCode() << 16)); 17998 AdvanceIT(); 17999 return; 18000 } 18001 } 18002 } else { 18003 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18004 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18005 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18006 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18007 operand.IsOffset() && encoded_align_1.IsValid() && 18008 (!rn.IsPC() || AllowUnpredictable())) { 18009 if (cond.Is(al)) { 18010 const DRegister& first = nreglist.GetFirstDRegister(); 18011 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18012 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) | 18013 (encoded_align_1.GetEncodingValue() << 4) | 18014 first.Encode(22, 12) | (len_encoding << 8) | 18015 (rn.GetCode() << 16)); 18016 return; 18017 } 18018 } 18019 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18020 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18021 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18022 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18023 operand.IsPostIndex() && encoded_align_1.IsValid() && 18024 (!rn.IsPC() || AllowUnpredictable())) { 18025 if (cond.Is(al)) { 18026 const DRegister& first = nreglist.GetFirstDRegister(); 18027 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18028 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) | 18029 (encoded_align_1.GetEncodingValue() << 4) | 18030 first.Encode(22, 12) | (len_encoding << 8) | 18031 (rn.GetCode() << 16)); 18032 return; 18033 } 18034 } 18035 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18036 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18037 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18038 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18039 operand.IsOffset() && encoded_align_2.IsValid() && 18040 (!rn.IsPC() || AllowUnpredictable())) { 18041 if (cond.Is(al)) { 18042 const DRegister& first = nreglist.GetFirstDRegister(); 18043 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18044 EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) | 18045 (encoded_align_2.GetEncodingValue() << 4) | 18046 first.Encode(22, 12) | (len_encoding << 5) | 18047 (rn.GetCode() << 16)); 18048 return; 18049 } 18050 } 18051 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18052 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18053 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18054 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18055 operand.IsPostIndex() && encoded_align_2.IsValid() && 18056 (!rn.IsPC() || AllowUnpredictable())) { 18057 if (cond.Is(al)) { 18058 const DRegister& first = nreglist.GetFirstDRegister(); 18059 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18060 EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) | 18061 (encoded_align_2.GetEncodingValue() << 4) | 18062 first.Encode(22, 12) | (len_encoding << 5) | 18063 (rn.GetCode() << 16)); 18064 return; 18065 } 18066 } 18067 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 18068 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18069 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18070 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18071 operand.IsOffset() && encoded_align_3.IsValid() && 18072 (!rn.IsPC() || AllowUnpredictable())) { 18073 if (cond.Is(al)) { 18074 const DRegister& first = nreglist.GetFirstDRegister(); 18075 EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) | 18076 (encoded_align_3.GetEncodingValue() << 4) | 18077 first.Encode(22, 12) | (rn.GetCode() << 16)); 18078 return; 18079 } 18080 } 18081 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 18082 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18083 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18084 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18085 operand.IsPostIndex() && encoded_align_3.IsValid() && 18086 (!rn.IsPC() || AllowUnpredictable())) { 18087 if (cond.Is(al)) { 18088 const DRegister& first = nreglist.GetFirstDRegister(); 18089 EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) | 18090 (encoded_align_3.GetEncodingValue() << 4) | 18091 first.Encode(22, 12) | (rn.GetCode() << 16)); 18092 return; 18093 } 18094 } 18095 } 18096 } 18097 if (operand.IsPlainRegister()) { 18098 Register rn = operand.GetBaseRegister(); 18099 Alignment align = operand.GetAlignment(); 18100 Register rm = operand.GetOffsetRegister(); 18101 Dt_size_7 encoded_dt(dt); 18102 Dt_size_8 encoded_dt_2(dt, align); 18103 Align_align_4 encoded_align_1(align); 18104 Align_a_3 encoded_align_2(align, dt); 18105 Align_index_align_3 encoded_align_3(align, nreglist, dt); 18106 if (IsUsingT32()) { 18107 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18108 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18109 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18110 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18111 !rm.IsPC() && !rm.IsSP()) { 18112 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18113 const DRegister& first = nreglist.GetFirstDRegister(); 18114 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18115 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) | 18116 (encoded_align_1.GetEncodingValue() << 4) | 18117 first.Encode(22, 12) | (len_encoding << 8) | 18118 (rn.GetCode() << 16) | rm.GetCode()); 18119 AdvanceIT(); 18120 return; 18121 } 18122 } 18123 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18124 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18125 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18126 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18127 !rm.IsPC() && !rm.IsSP()) { 18128 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18129 const DRegister& first = nreglist.GetFirstDRegister(); 18130 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18131 EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) | 18132 (encoded_align_2.GetEncodingValue() << 4) | 18133 first.Encode(22, 12) | (len_encoding << 5) | 18134 (rn.GetCode() << 16) | rm.GetCode()); 18135 AdvanceIT(); 18136 return; 18137 } 18138 } 18139 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 18140 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18141 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18142 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18143 !rm.IsPC() && !rm.IsSP()) { 18144 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18145 const DRegister& first = nreglist.GetFirstDRegister(); 18146 EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) | 18147 (encoded_align_3.GetEncodingValue() << 4) | 18148 first.Encode(22, 12) | (rn.GetCode() << 16) | 18149 rm.GetCode()); 18150 AdvanceIT(); 18151 return; 18152 } 18153 } 18154 } else { 18155 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18156 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 18157 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18158 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18159 !rm.IsPC() && !rm.IsSP()) { 18160 if (cond.Is(al)) { 18161 const DRegister& first = nreglist.GetFirstDRegister(); 18162 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18163 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) | 18164 (encoded_align_1.GetEncodingValue() << 4) | 18165 first.Encode(22, 12) | (len_encoding << 8) | 18166 (rn.GetCode() << 16) | rm.GetCode()); 18167 return; 18168 } 18169 } 18170 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18171 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() && 18172 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18173 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18174 !rm.IsPC() && !rm.IsSP()) { 18175 if (cond.Is(al)) { 18176 const DRegister& first = nreglist.GetFirstDRegister(); 18177 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 18178 EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) | 18179 (encoded_align_2.GetEncodingValue() << 4) | 18180 first.Encode(22, 12) | (len_encoding << 5) | 18181 (rn.GetCode() << 16) | rm.GetCode()); 18182 return; 18183 } 18184 } 18185 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 18186 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 18187 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 18188 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 18189 !rm.IsPC() && !rm.IsSP()) { 18190 if (cond.Is(al)) { 18191 const DRegister& first = nreglist.GetFirstDRegister(); 18192 EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) | 18193 (encoded_align_3.GetEncodingValue() << 4) | 18194 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 18195 return; 18196 } 18197 } 18198 } 18199 } 18200 Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand); 18201 } 18202 18203 void Assembler::vldm(Condition cond, 18204 DataType dt, 18205 Register rn, 18206 WriteBack write_back, 18207 DRegisterList dreglist) { 18208 VIXL_ASSERT(AllowAssembler()); 18209 CheckIT(cond); 18210 USE(dt); 18211 if (IsUsingT32()) { 18212 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 18213 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 18214 const DRegister& dreg = dreglist.GetFirstDRegister(); 18215 unsigned len = dreglist.GetLength() * 2; 18216 EmitT32_32(0xec900b00U | (rn.GetCode() << 16) | 18217 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 18218 (len & 0xff)); 18219 AdvanceIT(); 18220 return; 18221 } 18222 } else { 18223 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 18224 if (cond.IsNotNever() && 18225 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 18226 const DRegister& dreg = dreglist.GetFirstDRegister(); 18227 unsigned len = dreglist.GetLength() * 2; 18228 EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 18229 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 18230 (len & 0xff)); 18231 return; 18232 } 18233 } 18234 Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist); 18235 } 18236 18237 void Assembler::vldm(Condition cond, 18238 DataType dt, 18239 Register rn, 18240 WriteBack write_back, 18241 SRegisterList sreglist) { 18242 VIXL_ASSERT(AllowAssembler()); 18243 CheckIT(cond); 18244 USE(dt); 18245 if (IsUsingT32()) { 18246 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 18247 const SRegister& sreg = sreglist.GetFirstSRegister(); 18248 unsigned len = sreglist.GetLength(); 18249 EmitT32_32(0xec900a00U | (rn.GetCode() << 16) | 18250 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 18251 (len & 0xff)); 18252 AdvanceIT(); 18253 return; 18254 } else { 18255 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 18256 if (cond.IsNotNever()) { 18257 const SRegister& sreg = sreglist.GetFirstSRegister(); 18258 unsigned len = sreglist.GetLength(); 18259 EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 18260 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 18261 (len & 0xff)); 18262 return; 18263 } 18264 } 18265 Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist); 18266 } 18267 18268 void Assembler::vldmdb(Condition cond, 18269 DataType dt, 18270 Register rn, 18271 WriteBack write_back, 18272 DRegisterList dreglist) { 18273 VIXL_ASSERT(AllowAssembler()); 18274 CheckIT(cond); 18275 USE(dt); 18276 if (IsUsingT32()) { 18277 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1 18278 if (write_back.DoesWriteBack() && 18279 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 18280 const DRegister& dreg = dreglist.GetFirstDRegister(); 18281 unsigned len = dreglist.GetLength() * 2; 18282 EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 18283 (len & 0xff)); 18284 AdvanceIT(); 18285 return; 18286 } 18287 } else { 18288 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1 18289 if (write_back.DoesWriteBack() && cond.IsNotNever() && 18290 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 18291 const DRegister& dreg = dreglist.GetFirstDRegister(); 18292 unsigned len = dreglist.GetLength() * 2; 18293 EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 18294 dreg.Encode(22, 12) | (len & 0xff)); 18295 return; 18296 } 18297 } 18298 Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist); 18299 } 18300 18301 void Assembler::vldmdb(Condition cond, 18302 DataType dt, 18303 Register rn, 18304 WriteBack write_back, 18305 SRegisterList sreglist) { 18306 VIXL_ASSERT(AllowAssembler()); 18307 CheckIT(cond); 18308 USE(dt); 18309 if (IsUsingT32()) { 18310 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2 18311 if (write_back.DoesWriteBack()) { 18312 const SRegister& sreg = sreglist.GetFirstSRegister(); 18313 unsigned len = sreglist.GetLength(); 18314 EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) | 18315 (len & 0xff)); 18316 AdvanceIT(); 18317 return; 18318 } 18319 } else { 18320 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2 18321 if (write_back.DoesWriteBack() && cond.IsNotNever()) { 18322 const SRegister& sreg = sreglist.GetFirstSRegister(); 18323 unsigned len = sreglist.GetLength(); 18324 EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 18325 sreg.Encode(22, 12) | (len & 0xff)); 18326 return; 18327 } 18328 } 18329 Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist); 18330 } 18331 18332 void Assembler::vldmia(Condition cond, 18333 DataType dt, 18334 Register rn, 18335 WriteBack write_back, 18336 DRegisterList dreglist) { 18337 VIXL_ASSERT(AllowAssembler()); 18338 CheckIT(cond); 18339 USE(dt); 18340 if (IsUsingT32()) { 18341 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 18342 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 18343 const DRegister& dreg = dreglist.GetFirstDRegister(); 18344 unsigned len = dreglist.GetLength() * 2; 18345 EmitT32_32(0xec900b00U | (rn.GetCode() << 16) | 18346 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 18347 (len & 0xff)); 18348 AdvanceIT(); 18349 return; 18350 } 18351 } else { 18352 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 18353 if (cond.IsNotNever() && 18354 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 18355 const DRegister& dreg = dreglist.GetFirstDRegister(); 18356 unsigned len = dreglist.GetLength() * 2; 18357 EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 18358 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 18359 (len & 0xff)); 18360 return; 18361 } 18362 } 18363 Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist); 18364 } 18365 18366 void Assembler::vldmia(Condition cond, 18367 DataType dt, 18368 Register rn, 18369 WriteBack write_back, 18370 SRegisterList sreglist) { 18371 VIXL_ASSERT(AllowAssembler()); 18372 CheckIT(cond); 18373 USE(dt); 18374 if (IsUsingT32()) { 18375 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 18376 const SRegister& sreg = sreglist.GetFirstSRegister(); 18377 unsigned len = sreglist.GetLength(); 18378 EmitT32_32(0xec900a00U | (rn.GetCode() << 16) | 18379 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 18380 (len & 0xff)); 18381 AdvanceIT(); 18382 return; 18383 } else { 18384 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 18385 if (cond.IsNotNever()) { 18386 const SRegister& sreg = sreglist.GetFirstSRegister(); 18387 unsigned len = sreglist.GetLength(); 18388 EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 18389 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 18390 (len & 0xff)); 18391 return; 18392 } 18393 } 18394 Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist); 18395 } 18396 18397 void Assembler::vldr(Condition cond, DataType dt, DRegister rd, Label* label) { 18398 VIXL_ASSERT(AllowAssembler()); 18399 CheckIT(cond); 18400 Label::Offset offset = 18401 label->IsBound() 18402 ? label->GetLocation() - 18403 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 18404 : 0; 18405 if (IsUsingT32()) { 18406 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1 18407 if (dt.IsNoneOr(Untyped64) && 18408 ((label->IsBound() && (offset >= -1020) && (offset <= 1020) && 18409 ((offset & 0x3) == 0)) || 18410 !label->IsBound())) { 18411 static class EmitOp : public Label::LabelEmitOperator { 18412 public: 18413 EmitOp() : Label::LabelEmitOperator(-1020, 1020) {} 18414 virtual uint32_t Encode(uint32_t instr, 18415 Label::Offset pc, 18416 const Label* label) const VIXL_OVERRIDE { 18417 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 18418 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 18419 ((offset & 0x3) == 0)); 18420 int32_t target = offset >> 2; 18421 uint32_t U = (target >= 0) && !label->IsMinusZero(); 18422 target = abs(target) | (U << 8); 18423 return instr | (target & 0xff) | ((target & 0x100) << 15); 18424 } 18425 } immop; 18426 EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12), label, immop)); 18427 AdvanceIT(); 18428 return; 18429 } 18430 } else { 18431 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1 18432 if (dt.IsNoneOr(Untyped64) && 18433 ((label->IsBound() && (offset >= -1020) && (offset <= 1020) && 18434 ((offset & 0x3) == 0)) || 18435 !label->IsBound()) && 18436 cond.IsNotNever()) { 18437 static class EmitOp : public Label::LabelEmitOperator { 18438 public: 18439 EmitOp() : Label::LabelEmitOperator(-1020, 1020) {} 18440 virtual uint32_t Encode(uint32_t instr, 18441 Label::Offset pc, 18442 const Label* label) const VIXL_OVERRIDE { 18443 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 18444 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 18445 ((offset & 0x3) == 0)); 18446 int32_t target = offset >> 2; 18447 uint32_t U = (target >= 0) && !label->IsMinusZero(); 18448 target = abs(target) | (U << 8); 18449 return instr | (target & 0xff) | ((target & 0x100) << 15); 18450 } 18451 } immop; 18452 EmitA32( 18453 Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12), 18454 label, 18455 immop)); 18456 return; 18457 } 18458 } 18459 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label); 18460 } 18461 18462 void Assembler::vldr(Condition cond, 18463 DataType dt, 18464 DRegister rd, 18465 const MemOperand& operand) { 18466 VIXL_ASSERT(AllowAssembler()); 18467 CheckIT(cond); 18468 if (operand.IsImmediate()) { 18469 Register rn = operand.GetBaseRegister(); 18470 int32_t offset = operand.GetOffsetImmediate(); 18471 if (IsUsingT32()) { 18472 // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1 18473 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 18474 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) { 18475 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 18476 uint32_t offset_ = abs(offset) >> 2; 18477 EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23)); 18478 AdvanceIT(); 18479 return; 18480 } 18481 // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1 18482 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 18483 ((offset % 4) == 0) && operand.IsOffset() && 18484 ((rn.GetCode() & 0xf) != 0xf)) { 18485 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 18486 uint32_t offset_ = abs(offset) >> 2; 18487 EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 18488 offset_ | (sign << 23)); 18489 AdvanceIT(); 18490 return; 18491 } 18492 } else { 18493 // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1 18494 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 18495 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() && 18496 cond.IsNotNever()) { 18497 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 18498 uint32_t offset_ = abs(offset) >> 2; 18499 EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 18500 offset_ | (sign << 23)); 18501 return; 18502 } 18503 // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1 18504 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 18505 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() && 18506 ((rn.GetCode() & 0xf) != 0xf)) { 18507 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 18508 uint32_t offset_ = abs(offset) >> 2; 18509 EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 18510 (rn.GetCode() << 16) | offset_ | (sign << 23)); 18511 return; 18512 } 18513 } 18514 } 18515 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand); 18516 } 18517 18518 void Assembler::vldr(Condition cond, DataType dt, SRegister rd, Label* label) { 18519 VIXL_ASSERT(AllowAssembler()); 18520 CheckIT(cond); 18521 Label::Offset offset = 18522 label->IsBound() 18523 ? label->GetLocation() - 18524 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4) 18525 : 0; 18526 if (IsUsingT32()) { 18527 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2 18528 if (dt.IsNoneOr(Untyped32) && 18529 ((label->IsBound() && (offset >= -1020) && (offset <= 1020) && 18530 ((offset & 0x3) == 0)) || 18531 !label->IsBound())) { 18532 static class EmitOp : public Label::LabelEmitOperator { 18533 public: 18534 EmitOp() : Label::LabelEmitOperator(-1020, 1020) {} 18535 virtual uint32_t Encode(uint32_t instr, 18536 Label::Offset pc, 18537 const Label* label) const VIXL_OVERRIDE { 18538 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 18539 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 18540 ((offset & 0x3) == 0)); 18541 int32_t target = offset >> 2; 18542 uint32_t U = (target >= 0) && !label->IsMinusZero(); 18543 target = abs(target) | (U << 8); 18544 return instr | (target & 0xff) | ((target & 0x100) << 15); 18545 } 18546 } immop; 18547 EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12), label, immop)); 18548 AdvanceIT(); 18549 return; 18550 } 18551 } else { 18552 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2 18553 if (dt.IsNoneOr(Untyped32) && 18554 ((label->IsBound() && (offset >= -1020) && (offset <= 1020) && 18555 ((offset & 0x3) == 0)) || 18556 !label->IsBound()) && 18557 cond.IsNotNever()) { 18558 static class EmitOp : public Label::LabelEmitOperator { 18559 public: 18560 EmitOp() : Label::LabelEmitOperator(-1020, 1020) {} 18561 virtual uint32_t Encode(uint32_t instr, 18562 Label::Offset pc, 18563 const Label* label) const VIXL_OVERRIDE { 18564 Label::Offset offset = label->GetLocation() - AlignDown(pc, 4); 18565 VIXL_ASSERT((offset >= -1020) && (offset <= 1020) && 18566 ((offset & 0x3) == 0)); 18567 int32_t target = offset >> 2; 18568 uint32_t U = (target >= 0) && !label->IsMinusZero(); 18569 target = abs(target) | (U << 8); 18570 return instr | (target & 0xff) | ((target & 0x100) << 15); 18571 } 18572 } immop; 18573 EmitA32( 18574 Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12), 18575 label, 18576 immop)); 18577 return; 18578 } 18579 } 18580 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label); 18581 } 18582 18583 void Assembler::vldr(Condition cond, 18584 DataType dt, 18585 SRegister rd, 18586 const MemOperand& operand) { 18587 VIXL_ASSERT(AllowAssembler()); 18588 CheckIT(cond); 18589 if (operand.IsImmediate()) { 18590 Register rn = operand.GetBaseRegister(); 18591 int32_t offset = operand.GetOffsetImmediate(); 18592 if (IsUsingT32()) { 18593 // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2 18594 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 18595 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) { 18596 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 18597 uint32_t offset_ = abs(offset) >> 2; 18598 EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23)); 18599 AdvanceIT(); 18600 return; 18601 } 18602 // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2 18603 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 18604 ((offset % 4) == 0) && operand.IsOffset() && 18605 ((rn.GetCode() & 0xf) != 0xf)) { 18606 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 18607 uint32_t offset_ = abs(offset) >> 2; 18608 EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 18609 offset_ | (sign << 23)); 18610 AdvanceIT(); 18611 return; 18612 } 18613 } else { 18614 // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2 18615 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 18616 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() && 18617 cond.IsNotNever()) { 18618 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 18619 uint32_t offset_ = abs(offset) >> 2; 18620 EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 18621 offset_ | (sign << 23)); 18622 return; 18623 } 18624 // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2 18625 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 18626 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() && 18627 ((rn.GetCode() & 0xf) != 0xf)) { 18628 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 18629 uint32_t offset_ = abs(offset) >> 2; 18630 EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 18631 (rn.GetCode() << 16) | offset_ | (sign << 23)); 18632 return; 18633 } 18634 } 18635 } 18636 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand); 18637 } 18638 18639 void Assembler::vmax( 18640 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 18641 VIXL_ASSERT(AllowAssembler()); 18642 CheckIT(cond); 18643 Dt_U_size_1 encoded_dt(dt); 18644 if (IsUsingT32()) { 18645 // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 18646 if (dt.Is(F32)) { 18647 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18648 EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18649 rm.Encode(5, 0)); 18650 AdvanceIT(); 18651 return; 18652 } 18653 } 18654 // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 18655 if (encoded_dt.IsValid()) { 18656 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18657 EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 18658 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 18659 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 18660 AdvanceIT(); 18661 return; 18662 } 18663 } 18664 } else { 18665 // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 18666 if (dt.Is(F32)) { 18667 if (cond.Is(al)) { 18668 EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18669 rm.Encode(5, 0)); 18670 return; 18671 } 18672 } 18673 // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 18674 if (encoded_dt.IsValid()) { 18675 if (cond.Is(al)) { 18676 EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 18677 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 18678 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 18679 return; 18680 } 18681 } 18682 } 18683 Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm); 18684 } 18685 18686 void Assembler::vmax( 18687 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 18688 VIXL_ASSERT(AllowAssembler()); 18689 CheckIT(cond); 18690 Dt_U_size_1 encoded_dt(dt); 18691 if (IsUsingT32()) { 18692 // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 18693 if (dt.Is(F32)) { 18694 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18695 EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18696 rm.Encode(5, 0)); 18697 AdvanceIT(); 18698 return; 18699 } 18700 } 18701 // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 18702 if (encoded_dt.IsValid()) { 18703 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18704 EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 18705 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 18706 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 18707 AdvanceIT(); 18708 return; 18709 } 18710 } 18711 } else { 18712 // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 18713 if (dt.Is(F32)) { 18714 if (cond.Is(al)) { 18715 EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18716 rm.Encode(5, 0)); 18717 return; 18718 } 18719 } 18720 // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 18721 if (encoded_dt.IsValid()) { 18722 if (cond.Is(al)) { 18723 EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 18724 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 18725 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 18726 return; 18727 } 18728 } 18729 } 18730 Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm); 18731 } 18732 18733 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 18734 VIXL_ASSERT(AllowAssembler()); 18735 CheckIT(al); 18736 if (IsUsingT32()) { 18737 // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 18738 if (OutsideITBlock() && dt.Is(F32)) { 18739 EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18740 rm.Encode(5, 0)); 18741 AdvanceIT(); 18742 return; 18743 } 18744 // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 18745 if (OutsideITBlock() && dt.Is(F64)) { 18746 EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18747 rm.Encode(5, 0)); 18748 AdvanceIT(); 18749 return; 18750 } 18751 } else { 18752 // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 18753 if (dt.Is(F32)) { 18754 EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18755 rm.Encode(5, 0)); 18756 return; 18757 } 18758 // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 18759 if (dt.Is(F64)) { 18760 EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18761 rm.Encode(5, 0)); 18762 return; 18763 } 18764 } 18765 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 18766 } 18767 18768 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) { 18769 VIXL_ASSERT(AllowAssembler()); 18770 CheckIT(al); 18771 if (IsUsingT32()) { 18772 // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 18773 if (OutsideITBlock() && dt.Is(F32)) { 18774 EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18775 rm.Encode(5, 0)); 18776 AdvanceIT(); 18777 return; 18778 } 18779 } else { 18780 // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 18781 if (dt.Is(F32)) { 18782 EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18783 rm.Encode(5, 0)); 18784 return; 18785 } 18786 } 18787 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 18788 } 18789 18790 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 18791 VIXL_ASSERT(AllowAssembler()); 18792 CheckIT(al); 18793 if (IsUsingT32()) { 18794 // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 18795 if (OutsideITBlock() && dt.Is(F32)) { 18796 EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18797 rm.Encode(5, 0)); 18798 AdvanceIT(); 18799 return; 18800 } 18801 } else { 18802 // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 18803 if (dt.Is(F32)) { 18804 EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18805 rm.Encode(5, 0)); 18806 return; 18807 } 18808 } 18809 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm); 18810 } 18811 18812 void Assembler::vmin( 18813 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 18814 VIXL_ASSERT(AllowAssembler()); 18815 CheckIT(cond); 18816 Dt_U_size_1 encoded_dt(dt); 18817 if (IsUsingT32()) { 18818 // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 18819 if (dt.Is(F32)) { 18820 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18821 EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18822 rm.Encode(5, 0)); 18823 AdvanceIT(); 18824 return; 18825 } 18826 } 18827 // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 18828 if (encoded_dt.IsValid()) { 18829 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18830 EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 18831 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 18832 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 18833 AdvanceIT(); 18834 return; 18835 } 18836 } 18837 } else { 18838 // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 18839 if (dt.Is(F32)) { 18840 if (cond.Is(al)) { 18841 EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18842 rm.Encode(5, 0)); 18843 return; 18844 } 18845 } 18846 // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 18847 if (encoded_dt.IsValid()) { 18848 if (cond.Is(al)) { 18849 EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 18850 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 18851 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 18852 return; 18853 } 18854 } 18855 } 18856 Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm); 18857 } 18858 18859 void Assembler::vmin( 18860 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 18861 VIXL_ASSERT(AllowAssembler()); 18862 CheckIT(cond); 18863 Dt_U_size_1 encoded_dt(dt); 18864 if (IsUsingT32()) { 18865 // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 18866 if (dt.Is(F32)) { 18867 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18868 EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18869 rm.Encode(5, 0)); 18870 AdvanceIT(); 18871 return; 18872 } 18873 } 18874 // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 18875 if (encoded_dt.IsValid()) { 18876 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18877 EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 18878 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 18879 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 18880 AdvanceIT(); 18881 return; 18882 } 18883 } 18884 } else { 18885 // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 18886 if (dt.Is(F32)) { 18887 if (cond.Is(al)) { 18888 EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18889 rm.Encode(5, 0)); 18890 return; 18891 } 18892 } 18893 // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 18894 if (encoded_dt.IsValid()) { 18895 if (cond.Is(al)) { 18896 EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 18897 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 18898 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 18899 return; 18900 } 18901 } 18902 } 18903 Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm); 18904 } 18905 18906 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 18907 VIXL_ASSERT(AllowAssembler()); 18908 CheckIT(al); 18909 if (IsUsingT32()) { 18910 // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 18911 if (OutsideITBlock() && dt.Is(F32)) { 18912 EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18913 rm.Encode(5, 0)); 18914 AdvanceIT(); 18915 return; 18916 } 18917 // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 18918 if (OutsideITBlock() && dt.Is(F64)) { 18919 EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18920 rm.Encode(5, 0)); 18921 AdvanceIT(); 18922 return; 18923 } 18924 } else { 18925 // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 18926 if (dt.Is(F32)) { 18927 EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18928 rm.Encode(5, 0)); 18929 return; 18930 } 18931 // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 18932 if (dt.Is(F64)) { 18933 EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18934 rm.Encode(5, 0)); 18935 return; 18936 } 18937 } 18938 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 18939 } 18940 18941 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) { 18942 VIXL_ASSERT(AllowAssembler()); 18943 CheckIT(al); 18944 if (IsUsingT32()) { 18945 // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 18946 if (OutsideITBlock() && dt.Is(F32)) { 18947 EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18948 rm.Encode(5, 0)); 18949 AdvanceIT(); 18950 return; 18951 } 18952 } else { 18953 // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 18954 if (dt.Is(F32)) { 18955 EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18956 rm.Encode(5, 0)); 18957 return; 18958 } 18959 } 18960 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 18961 } 18962 18963 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 18964 VIXL_ASSERT(AllowAssembler()); 18965 CheckIT(al); 18966 if (IsUsingT32()) { 18967 // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 18968 if (OutsideITBlock() && dt.Is(F32)) { 18969 EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18970 rm.Encode(5, 0)); 18971 AdvanceIT(); 18972 return; 18973 } 18974 } else { 18975 // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 18976 if (dt.Is(F32)) { 18977 EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 18978 rm.Encode(5, 0)); 18979 return; 18980 } 18981 } 18982 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm); 18983 } 18984 18985 void Assembler::vmla( 18986 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 18987 VIXL_ASSERT(AllowAssembler()); 18988 CheckIT(cond); 18989 Dt_size_9 encoded_dt(dt); 18990 if (IsUsingT32()) { 18991 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1 18992 if (encoded_dt.IsValid() && 18993 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 18994 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 18995 (rm.GetLane() <= 1)))) { 18996 if (cond.Is(al) || AllowStronglyDiscouraged()) { 18997 EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 18998 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 18999 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19000 AdvanceIT(); 19001 return; 19002 } 19003 } 19004 } else { 19005 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1 19006 if (encoded_dt.IsValid() && 19007 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19008 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19009 (rm.GetLane() <= 1)))) { 19010 if (cond.Is(al)) { 19011 EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 19012 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19013 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19014 return; 19015 } 19016 } 19017 } 19018 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 19019 } 19020 19021 void Assembler::vmla( 19022 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 19023 VIXL_ASSERT(AllowAssembler()); 19024 CheckIT(cond); 19025 Dt_size_9 encoded_dt(dt); 19026 if (IsUsingT32()) { 19027 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1 19028 if (encoded_dt.IsValid() && 19029 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19030 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19031 (rm.GetLane() <= 1)))) { 19032 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19033 EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 19034 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19035 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19036 AdvanceIT(); 19037 return; 19038 } 19039 } 19040 } else { 19041 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1 19042 if (encoded_dt.IsValid() && 19043 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19044 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19045 (rm.GetLane() <= 1)))) { 19046 if (cond.Is(al)) { 19047 EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) | 19048 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19049 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19050 return; 19051 } 19052 } 19053 } 19054 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 19055 } 19056 19057 void Assembler::vmla( 19058 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 19059 VIXL_ASSERT(AllowAssembler()); 19060 CheckIT(cond); 19061 Dt_size_10 encoded_dt(dt); 19062 if (IsUsingT32()) { 19063 // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 19064 if (dt.Is(F32)) { 19065 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19066 EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19067 rm.Encode(5, 0)); 19068 AdvanceIT(); 19069 return; 19070 } 19071 } 19072 // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 19073 if (dt.Is(F64)) { 19074 EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19075 rm.Encode(5, 0)); 19076 AdvanceIT(); 19077 return; 19078 } 19079 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1 19080 if (encoded_dt.IsValid()) { 19081 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19082 EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) | 19083 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19084 AdvanceIT(); 19085 return; 19086 } 19087 } 19088 } else { 19089 // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 19090 if (dt.Is(F32)) { 19091 if (cond.Is(al)) { 19092 EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19093 rm.Encode(5, 0)); 19094 return; 19095 } 19096 } 19097 // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 19098 if (dt.Is(F64) && cond.IsNotNever()) { 19099 EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19100 rn.Encode(7, 16) | rm.Encode(5, 0)); 19101 return; 19102 } 19103 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1 19104 if (encoded_dt.IsValid()) { 19105 if (cond.Is(al)) { 19106 EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) | 19107 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19108 return; 19109 } 19110 } 19111 } 19112 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 19113 } 19114 19115 void Assembler::vmla( 19116 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 19117 VIXL_ASSERT(AllowAssembler()); 19118 CheckIT(cond); 19119 Dt_size_10 encoded_dt(dt); 19120 if (IsUsingT32()) { 19121 // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 19122 if (dt.Is(F32)) { 19123 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19124 EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19125 rm.Encode(5, 0)); 19126 AdvanceIT(); 19127 return; 19128 } 19129 } 19130 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1 19131 if (encoded_dt.IsValid()) { 19132 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19133 EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) | 19134 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19135 AdvanceIT(); 19136 return; 19137 } 19138 } 19139 } else { 19140 // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 19141 if (dt.Is(F32)) { 19142 if (cond.Is(al)) { 19143 EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19144 rm.Encode(5, 0)); 19145 return; 19146 } 19147 } 19148 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1 19149 if (encoded_dt.IsValid()) { 19150 if (cond.Is(al)) { 19151 EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) | 19152 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19153 return; 19154 } 19155 } 19156 } 19157 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 19158 } 19159 19160 void Assembler::vmla( 19161 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 19162 VIXL_ASSERT(AllowAssembler()); 19163 CheckIT(cond); 19164 if (IsUsingT32()) { 19165 // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 19166 if (dt.Is(F32)) { 19167 EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19168 rm.Encode(5, 0)); 19169 AdvanceIT(); 19170 return; 19171 } 19172 } else { 19173 // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 19174 if (dt.Is(F32) && cond.IsNotNever()) { 19175 EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19176 rn.Encode(7, 16) | rm.Encode(5, 0)); 19177 return; 19178 } 19179 } 19180 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm); 19181 } 19182 19183 void Assembler::vmlal( 19184 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 19185 VIXL_ASSERT(AllowAssembler()); 19186 CheckIT(cond); 19187 Dt_size_11 encoded_dt(dt); 19188 if (IsUsingT32()) { 19189 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1 19190 if (encoded_dt.IsValid() && 19191 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19192 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19193 (rm.GetLane() <= 1)))) { 19194 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19195 EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) | 19196 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19197 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19198 AdvanceIT(); 19199 return; 19200 } 19201 } 19202 } else { 19203 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1 19204 if (encoded_dt.IsValid() && 19205 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19206 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19207 (rm.GetLane() <= 1)))) { 19208 if (cond.Is(al)) { 19209 EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) | 19210 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19211 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19212 return; 19213 } 19214 } 19215 } 19216 Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm); 19217 } 19218 19219 void Assembler::vmlal( 19220 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 19221 VIXL_ASSERT(AllowAssembler()); 19222 CheckIT(cond); 19223 Dt_size_12 encoded_dt(dt); 19224 if (IsUsingT32()) { 19225 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1 19226 if (encoded_dt.IsValid()) { 19227 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19228 EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) | 19229 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19230 rn.Encode(7, 16) | rm.Encode(5, 0)); 19231 AdvanceIT(); 19232 return; 19233 } 19234 } 19235 } else { 19236 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1 19237 if (encoded_dt.IsValid()) { 19238 if (cond.Is(al)) { 19239 EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) | 19240 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19241 rn.Encode(7, 16) | rm.Encode(5, 0)); 19242 return; 19243 } 19244 } 19245 } 19246 Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm); 19247 } 19248 19249 void Assembler::vmls( 19250 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 19251 VIXL_ASSERT(AllowAssembler()); 19252 CheckIT(cond); 19253 Dt_size_9 encoded_dt(dt); 19254 if (IsUsingT32()) { 19255 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1 19256 if (encoded_dt.IsValid() && 19257 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19258 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19259 (rm.GetLane() <= 1)))) { 19260 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19261 EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 19262 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19263 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19264 AdvanceIT(); 19265 return; 19266 } 19267 } 19268 } else { 19269 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1 19270 if (encoded_dt.IsValid() && 19271 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19272 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19273 (rm.GetLane() <= 1)))) { 19274 if (cond.Is(al)) { 19275 EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 19276 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19277 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19278 return; 19279 } 19280 } 19281 } 19282 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 19283 } 19284 19285 void Assembler::vmls( 19286 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 19287 VIXL_ASSERT(AllowAssembler()); 19288 CheckIT(cond); 19289 Dt_size_9 encoded_dt(dt); 19290 if (IsUsingT32()) { 19291 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1 19292 if (encoded_dt.IsValid() && 19293 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19294 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19295 (rm.GetLane() <= 1)))) { 19296 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19297 EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 19298 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19299 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19300 AdvanceIT(); 19301 return; 19302 } 19303 } 19304 } else { 19305 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1 19306 if (encoded_dt.IsValid() && 19307 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19308 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19309 (rm.GetLane() <= 1)))) { 19310 if (cond.Is(al)) { 19311 EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) | 19312 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19313 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19314 return; 19315 } 19316 } 19317 } 19318 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 19319 } 19320 19321 void Assembler::vmls( 19322 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 19323 VIXL_ASSERT(AllowAssembler()); 19324 CheckIT(cond); 19325 Dt_size_10 encoded_dt(dt); 19326 if (IsUsingT32()) { 19327 // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1 19328 if (dt.Is(F32)) { 19329 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19330 EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19331 rm.Encode(5, 0)); 19332 AdvanceIT(); 19333 return; 19334 } 19335 } 19336 // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2 19337 if (dt.Is(F64)) { 19338 EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19339 rm.Encode(5, 0)); 19340 AdvanceIT(); 19341 return; 19342 } 19343 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1 19344 if (encoded_dt.IsValid()) { 19345 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19346 EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) | 19347 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19348 AdvanceIT(); 19349 return; 19350 } 19351 } 19352 } else { 19353 // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1 19354 if (dt.Is(F32)) { 19355 if (cond.Is(al)) { 19356 EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19357 rm.Encode(5, 0)); 19358 return; 19359 } 19360 } 19361 // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2 19362 if (dt.Is(F64) && cond.IsNotNever()) { 19363 EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19364 rn.Encode(7, 16) | rm.Encode(5, 0)); 19365 return; 19366 } 19367 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1 19368 if (encoded_dt.IsValid()) { 19369 if (cond.Is(al)) { 19370 EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) | 19371 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19372 return; 19373 } 19374 } 19375 } 19376 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 19377 } 19378 19379 void Assembler::vmls( 19380 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 19381 VIXL_ASSERT(AllowAssembler()); 19382 CheckIT(cond); 19383 Dt_size_10 encoded_dt(dt); 19384 if (IsUsingT32()) { 19385 // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1 19386 if (dt.Is(F32)) { 19387 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19388 EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19389 rm.Encode(5, 0)); 19390 AdvanceIT(); 19391 return; 19392 } 19393 } 19394 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1 19395 if (encoded_dt.IsValid()) { 19396 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19397 EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) | 19398 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19399 AdvanceIT(); 19400 return; 19401 } 19402 } 19403 } else { 19404 // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1 19405 if (dt.Is(F32)) { 19406 if (cond.Is(al)) { 19407 EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19408 rm.Encode(5, 0)); 19409 return; 19410 } 19411 } 19412 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1 19413 if (encoded_dt.IsValid()) { 19414 if (cond.Is(al)) { 19415 EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) | 19416 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 19417 return; 19418 } 19419 } 19420 } 19421 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 19422 } 19423 19424 void Assembler::vmls( 19425 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 19426 VIXL_ASSERT(AllowAssembler()); 19427 CheckIT(cond); 19428 if (IsUsingT32()) { 19429 // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2 19430 if (dt.Is(F32)) { 19431 EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 19432 rm.Encode(5, 0)); 19433 AdvanceIT(); 19434 return; 19435 } 19436 } else { 19437 // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2 19438 if (dt.Is(F32) && cond.IsNotNever()) { 19439 EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19440 rn.Encode(7, 16) | rm.Encode(5, 0)); 19441 return; 19442 } 19443 } 19444 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm); 19445 } 19446 19447 void Assembler::vmlsl( 19448 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 19449 VIXL_ASSERT(AllowAssembler()); 19450 CheckIT(cond); 19451 Dt_size_11 encoded_dt(dt); 19452 if (IsUsingT32()) { 19453 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1 19454 if (encoded_dt.IsValid() && 19455 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19456 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19457 (rm.GetLane() <= 1)))) { 19458 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19459 EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) | 19460 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19461 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19462 AdvanceIT(); 19463 return; 19464 } 19465 } 19466 } else { 19467 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1 19468 if (encoded_dt.IsValid() && 19469 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 19470 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 19471 (rm.GetLane() <= 1)))) { 19472 if (cond.Is(al)) { 19473 EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) | 19474 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19475 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 19476 return; 19477 } 19478 } 19479 } 19480 Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm); 19481 } 19482 19483 void Assembler::vmlsl( 19484 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 19485 VIXL_ASSERT(AllowAssembler()); 19486 CheckIT(cond); 19487 Dt_size_12 encoded_dt(dt); 19488 if (IsUsingT32()) { 19489 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1 19490 if (encoded_dt.IsValid()) { 19491 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19492 EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) | 19493 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19494 rn.Encode(7, 16) | rm.Encode(5, 0)); 19495 AdvanceIT(); 19496 return; 19497 } 19498 } 19499 } else { 19500 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1 19501 if (encoded_dt.IsValid()) { 19502 if (cond.Is(al)) { 19503 EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) | 19504 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) | 19505 rn.Encode(7, 16) | rm.Encode(5, 0)); 19506 return; 19507 } 19508 } 19509 } 19510 Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm); 19511 } 19512 19513 void Assembler::vmov(Condition cond, Register rt, SRegister rn) { 19514 VIXL_ASSERT(AllowAssembler()); 19515 CheckIT(cond); 19516 if (IsUsingT32()) { 19517 // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1 19518 EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16)); 19519 AdvanceIT(); 19520 return; 19521 } else { 19522 // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1 19523 if (cond.IsNotNever()) { 19524 EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 19525 rn.Encode(7, 16)); 19526 return; 19527 } 19528 } 19529 Delegate(kVmov, &Assembler::vmov, cond, rt, rn); 19530 } 19531 19532 void Assembler::vmov(Condition cond, SRegister rn, Register rt) { 19533 VIXL_ASSERT(AllowAssembler()); 19534 CheckIT(cond); 19535 if (IsUsingT32()) { 19536 // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1 19537 EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12)); 19538 AdvanceIT(); 19539 return; 19540 } else { 19541 // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1 19542 if (cond.IsNotNever()) { 19543 EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) | 19544 (rt.GetCode() << 12)); 19545 return; 19546 } 19547 } 19548 Delegate(kVmov, &Assembler::vmov, cond, rn, rt); 19549 } 19550 19551 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) { 19552 VIXL_ASSERT(AllowAssembler()); 19553 CheckIT(cond); 19554 if (IsUsingT32()) { 19555 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1 19556 EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) | 19557 rm.Encode(5, 0)); 19558 AdvanceIT(); 19559 return; 19560 } else { 19561 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1 19562 if (cond.IsNotNever()) { 19563 EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 19564 (rt2.GetCode() << 16) | rm.Encode(5, 0)); 19565 return; 19566 } 19567 } 19568 Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm); 19569 } 19570 19571 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) { 19572 VIXL_ASSERT(AllowAssembler()); 19573 CheckIT(cond); 19574 if (IsUsingT32()) { 19575 // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1 19576 EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) | 19577 (rt2.GetCode() << 16)); 19578 AdvanceIT(); 19579 return; 19580 } else { 19581 // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1 19582 if (cond.IsNotNever()) { 19583 EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) | 19584 (rt.GetCode() << 12) | (rt2.GetCode() << 16)); 19585 return; 19586 } 19587 } 19588 Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2); 19589 } 19590 19591 void Assembler::vmov( 19592 Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) { 19593 VIXL_ASSERT(AllowAssembler()); 19594 CheckIT(cond); 19595 if (IsUsingT32()) { 19596 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1 19597 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) { 19598 EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) | 19599 rm.Encode(5, 0)); 19600 AdvanceIT(); 19601 return; 19602 } 19603 } else { 19604 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1 19605 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 19606 cond.IsNotNever()) { 19607 EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 19608 (rt2.GetCode() << 16) | rm.Encode(5, 0)); 19609 return; 19610 } 19611 } 19612 Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1); 19613 } 19614 19615 void Assembler::vmov( 19616 Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) { 19617 VIXL_ASSERT(AllowAssembler()); 19618 CheckIT(cond); 19619 if (IsUsingT32()) { 19620 // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1 19621 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) { 19622 EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) | 19623 (rt2.GetCode() << 16)); 19624 AdvanceIT(); 19625 return; 19626 } 19627 } else { 19628 // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1 19629 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) && 19630 cond.IsNotNever()) { 19631 EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) | 19632 (rt.GetCode() << 12) | (rt2.GetCode() << 16)); 19633 return; 19634 } 19635 } 19636 Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2); 19637 } 19638 19639 void Assembler::vmov(Condition cond, 19640 DataType dt, 19641 DRegisterLane rd, 19642 Register rt) { 19643 VIXL_ASSERT(AllowAssembler()); 19644 CheckIT(cond); 19645 Dt_opc1_opc2_1 encoded_dt(dt, rd); 19646 if (IsUsingT32()) { 19647 // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1 19648 if (encoded_dt.IsValid()) { 19649 EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 19650 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 19651 rd.Encode(7, 16) | (rt.GetCode() << 12)); 19652 AdvanceIT(); 19653 return; 19654 } 19655 } else { 19656 // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1 19657 if (encoded_dt.IsValid() && cond.IsNotNever()) { 19658 EmitA32(0x0e000b10U | (cond.GetCondition() << 28) | 19659 ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 19660 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) | 19661 (rt.GetCode() << 12)); 19662 return; 19663 } 19664 } 19665 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt); 19666 } 19667 19668 void Assembler::vmov(Condition cond, 19669 DataType dt, 19670 DRegister rd, 19671 const DOperand& operand) { 19672 VIXL_ASSERT(AllowAssembler()); 19673 CheckIT(cond); 19674 if (operand.IsImmediate()) { 19675 ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate()); 19676 ImmediateVFP vfp(operand.GetNeonImmediate()); 19677 if (IsUsingT32()) { 19678 // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 19679 if (encoded_dt.IsValid()) { 19680 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19681 EmitT32_32( 19682 0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 19683 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 19684 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 19685 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 19686 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 19687 AdvanceIT(); 19688 return; 19689 } 19690 } 19691 // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2 19692 if (dt.Is(F64) && vfp.IsValid()) { 19693 EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) | 19694 (vfp.GetEncodingValue() & 0xf) | 19695 ((vfp.GetEncodingValue() & 0xf0) << 12)); 19696 AdvanceIT(); 19697 return; 19698 } 19699 } else { 19700 // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 19701 if (encoded_dt.IsValid()) { 19702 if (cond.Is(al)) { 19703 EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 19704 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 19705 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 19706 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 19707 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 19708 return; 19709 } 19710 } 19711 // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2 19712 if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) { 19713 EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19714 (vfp.GetEncodingValue() & 0xf) | 19715 ((vfp.GetEncodingValue() & 0xf0) << 12)); 19716 return; 19717 } 19718 } 19719 } 19720 if (operand.IsRegister()) { 19721 DRegister rm = operand.GetRegister(); 19722 if (IsUsingT32()) { 19723 // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 19724 if (dt.Is(F64)) { 19725 EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 19726 AdvanceIT(); 19727 return; 19728 } 19729 // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 19730 if (!dt.Is(F64)) { 19731 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19732 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 19733 rm.Encode(5, 0)); 19734 AdvanceIT(); 19735 return; 19736 } 19737 } 19738 } else { 19739 // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 19740 if (dt.Is(F64) && cond.IsNotNever()) { 19741 EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19742 rm.Encode(5, 0)); 19743 return; 19744 } 19745 // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 19746 if (!dt.Is(F64)) { 19747 if (cond.Is(al)) { 19748 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 19749 rm.Encode(5, 0)); 19750 return; 19751 } 19752 } 19753 } 19754 } 19755 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 19756 } 19757 19758 void Assembler::vmov(Condition cond, 19759 DataType dt, 19760 QRegister rd, 19761 const QOperand& operand) { 19762 VIXL_ASSERT(AllowAssembler()); 19763 CheckIT(cond); 19764 if (operand.IsImmediate()) { 19765 ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate()); 19766 if (IsUsingT32()) { 19767 // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 19768 if (encoded_dt.IsValid()) { 19769 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19770 EmitT32_32( 19771 0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 19772 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 19773 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 19774 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 19775 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 19776 AdvanceIT(); 19777 return; 19778 } 19779 } 19780 } else { 19781 // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 19782 if (encoded_dt.IsValid()) { 19783 if (cond.Is(al)) { 19784 EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) | 19785 ((encoded_dt.GetEncodingValue() & 0x10) << 1) | 19786 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 19787 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 19788 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 19789 return; 19790 } 19791 } 19792 } 19793 } 19794 if (operand.IsRegister()) { 19795 QRegister rm = operand.GetRegister(); 19796 if (IsUsingT32()) { 19797 // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 19798 if (!dt.Is(F64)) { 19799 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19800 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 19801 rm.Encode(5, 0)); 19802 AdvanceIT(); 19803 return; 19804 } 19805 } 19806 } else { 19807 // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 19808 if (!dt.Is(F64)) { 19809 if (cond.Is(al)) { 19810 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 19811 rm.Encode(5, 0)); 19812 return; 19813 } 19814 } 19815 } 19816 } 19817 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 19818 } 19819 19820 void Assembler::vmov(Condition cond, 19821 DataType dt, 19822 SRegister rd, 19823 const SOperand& operand) { 19824 VIXL_ASSERT(AllowAssembler()); 19825 CheckIT(cond); 19826 if (operand.IsImmediate()) { 19827 ImmediateVFP vfp(operand.GetNeonImmediate()); 19828 if (IsUsingT32()) { 19829 // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2 19830 if (dt.Is(F32) && vfp.IsValid()) { 19831 EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) | 19832 (vfp.GetEncodingValue() & 0xf) | 19833 ((vfp.GetEncodingValue() & 0xf0) << 12)); 19834 AdvanceIT(); 19835 return; 19836 } 19837 } else { 19838 // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2 19839 if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) { 19840 EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19841 (vfp.GetEncodingValue() & 0xf) | 19842 ((vfp.GetEncodingValue() & 0xf0) << 12)); 19843 return; 19844 } 19845 } 19846 } 19847 if (operand.IsRegister()) { 19848 SRegister rm = operand.GetRegister(); 19849 if (IsUsingT32()) { 19850 // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 19851 if (dt.Is(F32)) { 19852 EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 19853 AdvanceIT(); 19854 return; 19855 } 19856 } else { 19857 // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 19858 if (dt.Is(F32) && cond.IsNotNever()) { 19859 EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 19860 rm.Encode(5, 0)); 19861 return; 19862 } 19863 } 19864 } 19865 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand); 19866 } 19867 19868 void Assembler::vmov(Condition cond, 19869 DataType dt, 19870 Register rt, 19871 DRegisterLane rn) { 19872 VIXL_ASSERT(AllowAssembler()); 19873 CheckIT(cond); 19874 Dt_U_opc1_opc2_1 encoded_dt(dt, rn); 19875 if (IsUsingT32()) { 19876 // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1 19877 if (encoded_dt.IsValid()) { 19878 EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 19879 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 19880 ((encoded_dt.GetEncodingValue() & 0x10) << 19) | 19881 (rt.GetCode() << 12) | rn.Encode(7, 16)); 19882 AdvanceIT(); 19883 return; 19884 } 19885 } else { 19886 // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1 19887 if (encoded_dt.IsValid() && cond.IsNotNever()) { 19888 EmitA32(0x0e100b10U | (cond.GetCondition() << 28) | 19889 ((encoded_dt.GetEncodingValue() & 0x3) << 5) | 19890 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | 19891 ((encoded_dt.GetEncodingValue() & 0x10) << 19) | 19892 (rt.GetCode() << 12) | rn.Encode(7, 16)); 19893 return; 19894 } 19895 } 19896 Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn); 19897 } 19898 19899 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) { 19900 VIXL_ASSERT(AllowAssembler()); 19901 CheckIT(cond); 19902 Dt_U_imm3H_1 encoded_dt(dt); 19903 if (IsUsingT32()) { 19904 // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1 19905 if (encoded_dt.IsValid()) { 19906 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19907 EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 19908 ((encoded_dt.GetEncodingValue() & 0x8) << 25) | 19909 rd.Encode(22, 12) | rm.Encode(5, 0)); 19910 AdvanceIT(); 19911 return; 19912 } 19913 } 19914 } else { 19915 // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1 19916 if (encoded_dt.IsValid()) { 19917 if (cond.Is(al)) { 19918 EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 19919 ((encoded_dt.GetEncodingValue() & 0x8) << 21) | 19920 rd.Encode(22, 12) | rm.Encode(5, 0)); 19921 return; 19922 } 19923 } 19924 } 19925 Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm); 19926 } 19927 19928 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) { 19929 VIXL_ASSERT(AllowAssembler()); 19930 CheckIT(cond); 19931 Dt_size_3 encoded_dt(dt); 19932 if (IsUsingT32()) { 19933 // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 19934 if (encoded_dt.IsValid()) { 19935 if (cond.Is(al) || AllowStronglyDiscouraged()) { 19936 EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) | 19937 rd.Encode(22, 12) | rm.Encode(5, 0)); 19938 AdvanceIT(); 19939 return; 19940 } 19941 } 19942 } else { 19943 // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 19944 if (encoded_dt.IsValid()) { 19945 if (cond.Is(al)) { 19946 EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) | 19947 rd.Encode(22, 12) | rm.Encode(5, 0)); 19948 return; 19949 } 19950 } 19951 } 19952 Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm); 19953 } 19954 19955 void Assembler::vmrs(Condition cond, 19956 RegisterOrAPSR_nzcv rt, 19957 SpecialFPRegister spec_reg) { 19958 VIXL_ASSERT(AllowAssembler()); 19959 CheckIT(cond); 19960 if (IsUsingT32()) { 19961 // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1 19962 EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16)); 19963 AdvanceIT(); 19964 return; 19965 } else { 19966 // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1 19967 if (cond.IsNotNever()) { 19968 EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) | 19969 (spec_reg.GetReg() << 16)); 19970 return; 19971 } 19972 } 19973 Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg); 19974 } 19975 19976 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) { 19977 VIXL_ASSERT(AllowAssembler()); 19978 CheckIT(cond); 19979 if (IsUsingT32()) { 19980 // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1 19981 EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) | (rt.GetCode() << 12)); 19982 AdvanceIT(); 19983 return; 19984 } else { 19985 // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1 19986 if (cond.IsNotNever()) { 19987 EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) | 19988 (spec_reg.GetReg() << 16) | (rt.GetCode() << 12)); 19989 return; 19990 } 19991 } 19992 Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt); 19993 } 19994 19995 void Assembler::vmul(Condition cond, 19996 DataType dt, 19997 DRegister rd, 19998 DRegister rn, 19999 DRegister dm, 20000 unsigned index) { 20001 VIXL_ASSERT(AllowAssembler()); 20002 CheckIT(cond); 20003 Dt_F_size_3 encoded_dt(dt); 20004 if (IsUsingT32()) { 20005 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1 20006 if (encoded_dt.IsValid() && 20007 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 20008 (!dt.Is(I16) && (index <= 1)))) { 20009 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20010 uint32_t shift = 4; 20011 if (dt.Is(I16)) { 20012 shift = 3; 20013 } 20014 uint32_t mvm = dm.GetCode() | index << shift; 20015 EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20016 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 20017 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 20018 ((mvm & 0x10) << 1)); 20019 AdvanceIT(); 20020 return; 20021 } 20022 } 20023 } else { 20024 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1 20025 if (encoded_dt.IsValid() && 20026 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 20027 (!dt.Is(I16) && (index <= 1)))) { 20028 if (cond.Is(al)) { 20029 uint32_t shift = 4; 20030 if (dt.Is(I16)) { 20031 shift = 3; 20032 } 20033 uint32_t mvm = dm.GetCode() | index << shift; 20034 EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20035 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 20036 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 20037 ((mvm & 0x10) << 1)); 20038 return; 20039 } 20040 } 20041 } 20042 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index); 20043 } 20044 20045 void Assembler::vmul(Condition cond, 20046 DataType dt, 20047 QRegister rd, 20048 QRegister rn, 20049 DRegister dm, 20050 unsigned index) { 20051 VIXL_ASSERT(AllowAssembler()); 20052 CheckIT(cond); 20053 Dt_F_size_3 encoded_dt(dt); 20054 if (IsUsingT32()) { 20055 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1 20056 if (encoded_dt.IsValid() && 20057 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 20058 (!dt.Is(I16) && (index <= 1)))) { 20059 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20060 uint32_t shift = 4; 20061 if (dt.Is(I16)) { 20062 shift = 3; 20063 } 20064 uint32_t mvm = dm.GetCode() | index << shift; 20065 EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20066 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 20067 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 20068 ((mvm & 0x10) << 1)); 20069 AdvanceIT(); 20070 return; 20071 } 20072 } 20073 } else { 20074 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1 20075 if (encoded_dt.IsValid() && 20076 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) || 20077 (!dt.Is(I16) && (index <= 1)))) { 20078 if (cond.Is(al)) { 20079 uint32_t shift = 4; 20080 if (dt.Is(I16)) { 20081 shift = 3; 20082 } 20083 uint32_t mvm = dm.GetCode() | index << shift; 20084 EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20085 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 20086 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 20087 ((mvm & 0x10) << 1)); 20088 return; 20089 } 20090 } 20091 } 20092 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index); 20093 } 20094 20095 void Assembler::vmul( 20096 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20097 VIXL_ASSERT(AllowAssembler()); 20098 CheckIT(cond); 20099 Dt_op_size_1 encoded_dt(dt); 20100 if (IsUsingT32()) { 20101 // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 20102 if (dt.Is(F32)) { 20103 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20104 EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20105 rm.Encode(5, 0)); 20106 AdvanceIT(); 20107 return; 20108 } 20109 } 20110 // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 20111 if (dt.Is(F64)) { 20112 EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20113 rm.Encode(5, 0)); 20114 AdvanceIT(); 20115 return; 20116 } 20117 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 20118 if (encoded_dt.IsValid()) { 20119 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20120 EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20121 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 20122 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20123 AdvanceIT(); 20124 return; 20125 } 20126 } 20127 } else { 20128 // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 20129 if (dt.Is(F32)) { 20130 if (cond.Is(al)) { 20131 EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20132 rm.Encode(5, 0)); 20133 return; 20134 } 20135 } 20136 // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 20137 if (dt.Is(F64) && cond.IsNotNever()) { 20138 EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20139 rn.Encode(7, 16) | rm.Encode(5, 0)); 20140 return; 20141 } 20142 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 20143 if (encoded_dt.IsValid()) { 20144 if (cond.Is(al)) { 20145 EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20146 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20147 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20148 return; 20149 } 20150 } 20151 } 20152 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 20153 } 20154 20155 void Assembler::vmul( 20156 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 20157 VIXL_ASSERT(AllowAssembler()); 20158 CheckIT(cond); 20159 Dt_op_size_1 encoded_dt(dt); 20160 if (IsUsingT32()) { 20161 // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 20162 if (dt.Is(F32)) { 20163 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20164 EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20165 rm.Encode(5, 0)); 20166 AdvanceIT(); 20167 return; 20168 } 20169 } 20170 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 20171 if (encoded_dt.IsValid()) { 20172 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20173 EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20174 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 20175 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20176 AdvanceIT(); 20177 return; 20178 } 20179 } 20180 } else { 20181 // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 20182 if (dt.Is(F32)) { 20183 if (cond.Is(al)) { 20184 EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20185 rm.Encode(5, 0)); 20186 return; 20187 } 20188 } 20189 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 20190 if (encoded_dt.IsValid()) { 20191 if (cond.Is(al)) { 20192 EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20193 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20194 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20195 return; 20196 } 20197 } 20198 } 20199 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 20200 } 20201 20202 void Assembler::vmul( 20203 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20204 VIXL_ASSERT(AllowAssembler()); 20205 CheckIT(cond); 20206 if (IsUsingT32()) { 20207 // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 20208 if (dt.Is(F32)) { 20209 EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20210 rm.Encode(5, 0)); 20211 AdvanceIT(); 20212 return; 20213 } 20214 } else { 20215 // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 20216 if (dt.Is(F32) && cond.IsNotNever()) { 20217 EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20218 rn.Encode(7, 16) | rm.Encode(5, 0)); 20219 return; 20220 } 20221 } 20222 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm); 20223 } 20224 20225 void Assembler::vmull(Condition cond, 20226 DataType dt, 20227 QRegister rd, 20228 DRegister rn, 20229 DRegister dm, 20230 unsigned index) { 20231 VIXL_ASSERT(AllowAssembler()); 20232 CheckIT(cond); 20233 Dt_U_size_2 encoded_dt(dt); 20234 if (IsUsingT32()) { 20235 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1 20236 if (encoded_dt.IsValid() && 20237 (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) || 20238 (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) { 20239 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20240 uint32_t shift = 4; 20241 if (dt.Is(S16) || dt.Is(U16)) { 20242 shift = 3; 20243 } 20244 uint32_t mvm = dm.GetCode() | index << shift; 20245 EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20246 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 20247 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 20248 ((mvm & 0x10) << 1)); 20249 AdvanceIT(); 20250 return; 20251 } 20252 } 20253 } else { 20254 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1 20255 if (encoded_dt.IsValid() && 20256 (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) || 20257 (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) { 20258 if (cond.Is(al)) { 20259 uint32_t shift = 4; 20260 if (dt.Is(S16) || dt.Is(U16)) { 20261 shift = 3; 20262 } 20263 uint32_t mvm = dm.GetCode() | index << shift; 20264 EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20265 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20266 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 20267 ((mvm & 0x10) << 1)); 20268 return; 20269 } 20270 } 20271 } 20272 Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index); 20273 } 20274 20275 void Assembler::vmull( 20276 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 20277 VIXL_ASSERT(AllowAssembler()); 20278 CheckIT(cond); 20279 Dt_op_U_size_1 encoded_dt(dt); 20280 if (IsUsingT32()) { 20281 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 20282 if (encoded_dt.IsValid()) { 20283 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20284 EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20285 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 20286 ((encoded_dt.GetEncodingValue() & 0x8) << 6) | 20287 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20288 AdvanceIT(); 20289 return; 20290 } 20291 } 20292 } else { 20293 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 20294 if (encoded_dt.IsValid()) { 20295 if (cond.Is(al)) { 20296 EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 20297 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 20298 ((encoded_dt.GetEncodingValue() & 0x8) << 6) | 20299 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20300 return; 20301 } 20302 } 20303 } 20304 Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm); 20305 } 20306 20307 void Assembler::vmvn(Condition cond, 20308 DataType dt, 20309 DRegister rd, 20310 const DOperand& operand) { 20311 VIXL_ASSERT(AllowAssembler()); 20312 CheckIT(cond); 20313 if (operand.IsImmediate()) { 20314 ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate()); 20315 if (IsUsingT32()) { 20316 // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 20317 if (encoded_dt.IsValid()) { 20318 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20319 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) | 20320 rd.Encode(22, 12) | 20321 (encoded_dt.GetEncodedImmediate() & 0xf) | 20322 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20323 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 20324 AdvanceIT(); 20325 return; 20326 } 20327 } 20328 } else { 20329 // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 20330 if (encoded_dt.IsValid()) { 20331 if (cond.Is(al)) { 20332 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) | 20333 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20334 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20335 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 20336 return; 20337 } 20338 } 20339 } 20340 } 20341 if (operand.IsRegister()) { 20342 DRegister rm = operand.GetRegister(); 20343 USE(dt); 20344 if (IsUsingT32()) { 20345 // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 20346 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20347 EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 20348 AdvanceIT(); 20349 return; 20350 } 20351 } else { 20352 // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 20353 if (cond.Is(al)) { 20354 EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 20355 return; 20356 } 20357 } 20358 } 20359 Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand); 20360 } 20361 20362 void Assembler::vmvn(Condition cond, 20363 DataType dt, 20364 QRegister rd, 20365 const QOperand& operand) { 20366 VIXL_ASSERT(AllowAssembler()); 20367 CheckIT(cond); 20368 if (operand.IsImmediate()) { 20369 ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate()); 20370 if (IsUsingT32()) { 20371 // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 20372 if (encoded_dt.IsValid()) { 20373 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20374 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) | 20375 rd.Encode(22, 12) | 20376 (encoded_dt.GetEncodedImmediate() & 0xf) | 20377 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20378 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 20379 AdvanceIT(); 20380 return; 20381 } 20382 } 20383 } else { 20384 // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 20385 if (encoded_dt.IsValid()) { 20386 if (cond.Is(al)) { 20387 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) | 20388 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20389 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20390 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 20391 return; 20392 } 20393 } 20394 } 20395 } 20396 if (operand.IsRegister()) { 20397 QRegister rm = operand.GetRegister(); 20398 USE(dt); 20399 if (IsUsingT32()) { 20400 // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 20401 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20402 EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 20403 AdvanceIT(); 20404 return; 20405 } 20406 } else { 20407 // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 20408 if (cond.Is(al)) { 20409 EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 20410 return; 20411 } 20412 } 20413 } 20414 Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand); 20415 } 20416 20417 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) { 20418 VIXL_ASSERT(AllowAssembler()); 20419 CheckIT(cond); 20420 Dt_F_size_1 encoded_dt(dt); 20421 if (IsUsingT32()) { 20422 // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 20423 if (encoded_dt.IsValid()) { 20424 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20425 EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20426 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 20427 rd.Encode(22, 12) | rm.Encode(5, 0)); 20428 AdvanceIT(); 20429 return; 20430 } 20431 } 20432 // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2 20433 if (dt.Is(F64)) { 20434 EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 20435 AdvanceIT(); 20436 return; 20437 } 20438 } else { 20439 // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 20440 if (encoded_dt.IsValid()) { 20441 if (cond.Is(al)) { 20442 EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20443 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 20444 rd.Encode(22, 12) | rm.Encode(5, 0)); 20445 return; 20446 } 20447 } 20448 // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2 20449 if (dt.Is(F64) && cond.IsNotNever()) { 20450 EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20451 rm.Encode(5, 0)); 20452 return; 20453 } 20454 } 20455 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 20456 } 20457 20458 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) { 20459 VIXL_ASSERT(AllowAssembler()); 20460 CheckIT(cond); 20461 Dt_F_size_1 encoded_dt(dt); 20462 if (IsUsingT32()) { 20463 // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 20464 if (encoded_dt.IsValid()) { 20465 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20466 EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20467 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 20468 rd.Encode(22, 12) | rm.Encode(5, 0)); 20469 AdvanceIT(); 20470 return; 20471 } 20472 } 20473 } else { 20474 // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 20475 if (encoded_dt.IsValid()) { 20476 if (cond.Is(al)) { 20477 EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20478 ((encoded_dt.GetEncodingValue() & 0x4) << 8) | 20479 rd.Encode(22, 12) | rm.Encode(5, 0)); 20480 return; 20481 } 20482 } 20483 } 20484 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 20485 } 20486 20487 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) { 20488 VIXL_ASSERT(AllowAssembler()); 20489 CheckIT(cond); 20490 if (IsUsingT32()) { 20491 // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2 20492 if (dt.Is(F32)) { 20493 EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 20494 AdvanceIT(); 20495 return; 20496 } 20497 } else { 20498 // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2 20499 if (dt.Is(F32) && cond.IsNotNever()) { 20500 EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20501 rm.Encode(5, 0)); 20502 return; 20503 } 20504 } 20505 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm); 20506 } 20507 20508 void Assembler::vnmla( 20509 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20510 VIXL_ASSERT(AllowAssembler()); 20511 CheckIT(cond); 20512 if (IsUsingT32()) { 20513 // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 20514 if (dt.Is(F32)) { 20515 EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20516 rm.Encode(5, 0)); 20517 AdvanceIT(); 20518 return; 20519 } 20520 } else { 20521 // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 20522 if (dt.Is(F32) && cond.IsNotNever()) { 20523 EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20524 rn.Encode(7, 16) | rm.Encode(5, 0)); 20525 return; 20526 } 20527 } 20528 Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm); 20529 } 20530 20531 void Assembler::vnmla( 20532 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20533 VIXL_ASSERT(AllowAssembler()); 20534 CheckIT(cond); 20535 if (IsUsingT32()) { 20536 // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 20537 if (dt.Is(F64)) { 20538 EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20539 rm.Encode(5, 0)); 20540 AdvanceIT(); 20541 return; 20542 } 20543 } else { 20544 // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 20545 if (dt.Is(F64) && cond.IsNotNever()) { 20546 EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20547 rn.Encode(7, 16) | rm.Encode(5, 0)); 20548 return; 20549 } 20550 } 20551 Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm); 20552 } 20553 20554 void Assembler::vnmls( 20555 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20556 VIXL_ASSERT(AllowAssembler()); 20557 CheckIT(cond); 20558 if (IsUsingT32()) { 20559 // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1 20560 if (dt.Is(F32)) { 20561 EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20562 rm.Encode(5, 0)); 20563 AdvanceIT(); 20564 return; 20565 } 20566 } else { 20567 // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1 20568 if (dt.Is(F32) && cond.IsNotNever()) { 20569 EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20570 rn.Encode(7, 16) | rm.Encode(5, 0)); 20571 return; 20572 } 20573 } 20574 Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm); 20575 } 20576 20577 void Assembler::vnmls( 20578 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20579 VIXL_ASSERT(AllowAssembler()); 20580 CheckIT(cond); 20581 if (IsUsingT32()) { 20582 // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1 20583 if (dt.Is(F64)) { 20584 EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20585 rm.Encode(5, 0)); 20586 AdvanceIT(); 20587 return; 20588 } 20589 } else { 20590 // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1 20591 if (dt.Is(F64) && cond.IsNotNever()) { 20592 EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20593 rn.Encode(7, 16) | rm.Encode(5, 0)); 20594 return; 20595 } 20596 } 20597 Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm); 20598 } 20599 20600 void Assembler::vnmul( 20601 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 20602 VIXL_ASSERT(AllowAssembler()); 20603 CheckIT(cond); 20604 if (IsUsingT32()) { 20605 // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1 20606 if (dt.Is(F32)) { 20607 EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20608 rm.Encode(5, 0)); 20609 AdvanceIT(); 20610 return; 20611 } 20612 } else { 20613 // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1 20614 if (dt.Is(F32) && cond.IsNotNever()) { 20615 EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20616 rn.Encode(7, 16) | rm.Encode(5, 0)); 20617 return; 20618 } 20619 } 20620 Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm); 20621 } 20622 20623 void Assembler::vnmul( 20624 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20625 VIXL_ASSERT(AllowAssembler()); 20626 CheckIT(cond); 20627 if (IsUsingT32()) { 20628 // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1 20629 if (dt.Is(F64)) { 20630 EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20631 rm.Encode(5, 0)); 20632 AdvanceIT(); 20633 return; 20634 } 20635 } else { 20636 // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1 20637 if (dt.Is(F64) && cond.IsNotNever()) { 20638 EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 20639 rn.Encode(7, 16) | rm.Encode(5, 0)); 20640 return; 20641 } 20642 } 20643 Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm); 20644 } 20645 20646 void Assembler::vorn(Condition cond, 20647 DataType dt, 20648 DRegister rd, 20649 DRegister rn, 20650 const DOperand& operand) { 20651 VIXL_ASSERT(AllowAssembler()); 20652 CheckIT(cond); 20653 if (operand.IsImmediate()) { 20654 ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate()); 20655 if (IsUsingT32()) { 20656 // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 20657 if (encoded_dt.IsValid() && rd.Is(rn)) { 20658 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20659 EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) | 20660 rd.Encode(22, 12) | 20661 (encoded_dt.GetEncodedImmediate() & 0xf) | 20662 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20663 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 20664 AdvanceIT(); 20665 return; 20666 } 20667 } 20668 } else { 20669 // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 20670 if (encoded_dt.IsValid() && rd.Is(rn)) { 20671 if (cond.Is(al)) { 20672 EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) | 20673 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20674 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20675 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 20676 return; 20677 } 20678 } 20679 } 20680 } 20681 if (operand.IsRegister()) { 20682 DRegister rm = operand.GetRegister(); 20683 USE(dt); 20684 if (IsUsingT32()) { 20685 // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 20686 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20687 EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20688 rm.Encode(5, 0)); 20689 AdvanceIT(); 20690 return; 20691 } 20692 } else { 20693 // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 20694 if (cond.Is(al)) { 20695 EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20696 rm.Encode(5, 0)); 20697 return; 20698 } 20699 } 20700 } 20701 Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand); 20702 } 20703 20704 void Assembler::vorn(Condition cond, 20705 DataType dt, 20706 QRegister rd, 20707 QRegister rn, 20708 const QOperand& operand) { 20709 VIXL_ASSERT(AllowAssembler()); 20710 CheckIT(cond); 20711 if (operand.IsImmediate()) { 20712 ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate()); 20713 if (IsUsingT32()) { 20714 // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 20715 if (encoded_dt.IsValid() && rd.Is(rn)) { 20716 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20717 EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) | 20718 rd.Encode(22, 12) | 20719 (encoded_dt.GetEncodedImmediate() & 0xf) | 20720 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20721 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 20722 AdvanceIT(); 20723 return; 20724 } 20725 } 20726 } else { 20727 // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 20728 if (encoded_dt.IsValid() && rd.Is(rn)) { 20729 if (cond.Is(al)) { 20730 EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) | 20731 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20732 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20733 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 20734 return; 20735 } 20736 } 20737 } 20738 } 20739 if (operand.IsRegister()) { 20740 QRegister rm = operand.GetRegister(); 20741 USE(dt); 20742 if (IsUsingT32()) { 20743 // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 20744 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20745 EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20746 rm.Encode(5, 0)); 20747 AdvanceIT(); 20748 return; 20749 } 20750 } else { 20751 // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 20752 if (cond.Is(al)) { 20753 EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20754 rm.Encode(5, 0)); 20755 return; 20756 } 20757 } 20758 } 20759 Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand); 20760 } 20761 20762 void Assembler::vorr(Condition cond, 20763 DataType dt, 20764 DRegister rd, 20765 DRegister rn, 20766 const DOperand& operand) { 20767 VIXL_ASSERT(AllowAssembler()); 20768 CheckIT(cond); 20769 if (operand.IsRegister()) { 20770 DRegister rm = operand.GetRegister(); 20771 USE(dt); 20772 if (IsUsingT32()) { 20773 // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1 20774 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20775 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20776 rm.Encode(5, 0)); 20777 AdvanceIT(); 20778 return; 20779 } 20780 } else { 20781 // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1 20782 if (cond.Is(al)) { 20783 EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20784 rm.Encode(5, 0)); 20785 return; 20786 } 20787 } 20788 } 20789 if (operand.IsImmediate()) { 20790 ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate()); 20791 if (IsUsingT32()) { 20792 // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 20793 if (encoded_dt.IsValid() && rd.Is(rn)) { 20794 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20795 EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) | 20796 rd.Encode(22, 12) | 20797 (encoded_dt.GetEncodedImmediate() & 0xf) | 20798 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20799 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 20800 AdvanceIT(); 20801 return; 20802 } 20803 } 20804 } else { 20805 // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 20806 if (encoded_dt.IsValid() && rd.Is(rn)) { 20807 if (cond.Is(al)) { 20808 EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) | 20809 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20810 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20811 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 20812 return; 20813 } 20814 } 20815 } 20816 } 20817 Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand); 20818 } 20819 20820 void Assembler::vorr(Condition cond, 20821 DataType dt, 20822 QRegister rd, 20823 QRegister rn, 20824 const QOperand& operand) { 20825 VIXL_ASSERT(AllowAssembler()); 20826 CheckIT(cond); 20827 if (operand.IsRegister()) { 20828 QRegister rm = operand.GetRegister(); 20829 USE(dt); 20830 if (IsUsingT32()) { 20831 // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1 20832 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20833 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20834 rm.Encode(5, 0)); 20835 AdvanceIT(); 20836 return; 20837 } 20838 } else { 20839 // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1 20840 if (cond.Is(al)) { 20841 EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20842 rm.Encode(5, 0)); 20843 return; 20844 } 20845 } 20846 } 20847 if (operand.IsImmediate()) { 20848 ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate()); 20849 if (IsUsingT32()) { 20850 // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 20851 if (encoded_dt.IsValid() && rd.Is(rn)) { 20852 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20853 EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) | 20854 rd.Encode(22, 12) | 20855 (encoded_dt.GetEncodedImmediate() & 0xf) | 20856 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20857 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21)); 20858 AdvanceIT(); 20859 return; 20860 } 20861 } 20862 } else { 20863 // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 20864 if (encoded_dt.IsValid() && rd.Is(rn)) { 20865 if (cond.Is(al)) { 20866 EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) | 20867 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) | 20868 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) | 20869 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17)); 20870 return; 20871 } 20872 } 20873 } 20874 } 20875 Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand); 20876 } 20877 20878 void Assembler::vpadal(Condition cond, 20879 DataType dt, 20880 DRegister rd, 20881 DRegister rm) { 20882 VIXL_ASSERT(AllowAssembler()); 20883 CheckIT(cond); 20884 Dt_op_size_2 encoded_dt(dt); 20885 if (IsUsingT32()) { 20886 // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 20887 if (encoded_dt.IsValid()) { 20888 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20889 EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20890 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 20891 rd.Encode(22, 12) | rm.Encode(5, 0)); 20892 AdvanceIT(); 20893 return; 20894 } 20895 } 20896 } else { 20897 // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 20898 if (encoded_dt.IsValid()) { 20899 if (cond.Is(al)) { 20900 EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20901 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 20902 rd.Encode(22, 12) | rm.Encode(5, 0)); 20903 return; 20904 } 20905 } 20906 } 20907 Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm); 20908 } 20909 20910 void Assembler::vpadal(Condition cond, 20911 DataType dt, 20912 QRegister rd, 20913 QRegister rm) { 20914 VIXL_ASSERT(AllowAssembler()); 20915 CheckIT(cond); 20916 Dt_op_size_2 encoded_dt(dt); 20917 if (IsUsingT32()) { 20918 // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 20919 if (encoded_dt.IsValid()) { 20920 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20921 EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20922 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 20923 rd.Encode(22, 12) | rm.Encode(5, 0)); 20924 AdvanceIT(); 20925 return; 20926 } 20927 } 20928 } else { 20929 // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 20930 if (encoded_dt.IsValid()) { 20931 if (cond.Is(al)) { 20932 EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20933 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 20934 rd.Encode(22, 12) | rm.Encode(5, 0)); 20935 return; 20936 } 20937 } 20938 } 20939 Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm); 20940 } 20941 20942 void Assembler::vpadd( 20943 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 20944 VIXL_ASSERT(AllowAssembler()); 20945 CheckIT(cond); 20946 Dt_size_4 encoded_dt(dt); 20947 if (IsUsingT32()) { 20948 // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 20949 if (dt.Is(F32)) { 20950 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20951 EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20952 rm.Encode(5, 0)); 20953 AdvanceIT(); 20954 return; 20955 } 20956 } 20957 // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 20958 if (encoded_dt.IsValid()) { 20959 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20960 EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) | 20961 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20962 AdvanceIT(); 20963 return; 20964 } 20965 } 20966 } else { 20967 // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 20968 if (dt.Is(F32)) { 20969 if (cond.Is(al)) { 20970 EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 20971 rm.Encode(5, 0)); 20972 return; 20973 } 20974 } 20975 // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 20976 if (encoded_dt.IsValid()) { 20977 if (cond.Is(al)) { 20978 EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) | 20979 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 20980 return; 20981 } 20982 } 20983 } 20984 Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm); 20985 } 20986 20987 void Assembler::vpaddl(Condition cond, 20988 DataType dt, 20989 DRegister rd, 20990 DRegister rm) { 20991 VIXL_ASSERT(AllowAssembler()); 20992 CheckIT(cond); 20993 Dt_op_size_2 encoded_dt(dt); 20994 if (IsUsingT32()) { 20995 // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 20996 if (encoded_dt.IsValid()) { 20997 if (cond.Is(al) || AllowStronglyDiscouraged()) { 20998 EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 20999 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 21000 rd.Encode(22, 12) | rm.Encode(5, 0)); 21001 AdvanceIT(); 21002 return; 21003 } 21004 } 21005 } else { 21006 // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 21007 if (encoded_dt.IsValid()) { 21008 if (cond.Is(al)) { 21009 EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21010 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 21011 rd.Encode(22, 12) | rm.Encode(5, 0)); 21012 return; 21013 } 21014 } 21015 } 21016 Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm); 21017 } 21018 21019 void Assembler::vpaddl(Condition cond, 21020 DataType dt, 21021 QRegister rd, 21022 QRegister rm) { 21023 VIXL_ASSERT(AllowAssembler()); 21024 CheckIT(cond); 21025 Dt_op_size_2 encoded_dt(dt); 21026 if (IsUsingT32()) { 21027 // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 21028 if (encoded_dt.IsValid()) { 21029 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21030 EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21031 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 21032 rd.Encode(22, 12) | rm.Encode(5, 0)); 21033 AdvanceIT(); 21034 return; 21035 } 21036 } 21037 } else { 21038 // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 21039 if (encoded_dt.IsValid()) { 21040 if (cond.Is(al)) { 21041 EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21042 ((encoded_dt.GetEncodingValue() & 0x4) << 5) | 21043 rd.Encode(22, 12) | rm.Encode(5, 0)); 21044 return; 21045 } 21046 } 21047 } 21048 Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm); 21049 } 21050 21051 void Assembler::vpmax( 21052 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21053 VIXL_ASSERT(AllowAssembler()); 21054 CheckIT(cond); 21055 Dt_U_size_1 encoded_dt(dt); 21056 if (IsUsingT32()) { 21057 // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 21058 if (dt.Is(F32)) { 21059 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21060 EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21061 rm.Encode(5, 0)); 21062 AdvanceIT(); 21063 return; 21064 } 21065 } 21066 // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 21067 if (encoded_dt.IsValid()) { 21068 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21069 EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21070 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21071 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21072 AdvanceIT(); 21073 return; 21074 } 21075 } 21076 } else { 21077 // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 21078 if (dt.Is(F32)) { 21079 if (cond.Is(al)) { 21080 EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21081 rm.Encode(5, 0)); 21082 return; 21083 } 21084 } 21085 // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 21086 if (encoded_dt.IsValid()) { 21087 if (cond.Is(al)) { 21088 EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21089 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21090 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21091 return; 21092 } 21093 } 21094 } 21095 Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm); 21096 } 21097 21098 void Assembler::vpmin( 21099 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21100 VIXL_ASSERT(AllowAssembler()); 21101 CheckIT(cond); 21102 Dt_U_size_1 encoded_dt(dt); 21103 if (IsUsingT32()) { 21104 // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 21105 if (dt.Is(F32)) { 21106 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21107 EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21108 rm.Encode(5, 0)); 21109 AdvanceIT(); 21110 return; 21111 } 21112 } 21113 // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 21114 if (encoded_dt.IsValid()) { 21115 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21116 EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21117 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21118 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21119 AdvanceIT(); 21120 return; 21121 } 21122 } 21123 } else { 21124 // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 21125 if (dt.Is(F32)) { 21126 if (cond.Is(al)) { 21127 EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 21128 rm.Encode(5, 0)); 21129 return; 21130 } 21131 } 21132 // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 21133 if (encoded_dt.IsValid()) { 21134 if (cond.Is(al)) { 21135 EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21136 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21137 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21138 return; 21139 } 21140 } 21141 } 21142 Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm); 21143 } 21144 21145 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) { 21146 VIXL_ASSERT(AllowAssembler()); 21147 CheckIT(cond); 21148 USE(dt); 21149 if (IsUsingT32()) { 21150 // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1 21151 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 21152 const DRegister& dreg = dreglist.GetFirstDRegister(); 21153 unsigned len = dreglist.GetLength() * 2; 21154 EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff)); 21155 AdvanceIT(); 21156 return; 21157 } 21158 } else { 21159 // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1 21160 if (cond.IsNotNever() && 21161 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 21162 const DRegister& dreg = dreglist.GetFirstDRegister(); 21163 unsigned len = dreglist.GetLength() * 2; 21164 EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) | 21165 (len & 0xff)); 21166 return; 21167 } 21168 } 21169 Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist); 21170 } 21171 21172 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) { 21173 VIXL_ASSERT(AllowAssembler()); 21174 CheckIT(cond); 21175 USE(dt); 21176 if (IsUsingT32()) { 21177 // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2 21178 const SRegister& sreg = sreglist.GetFirstSRegister(); 21179 unsigned len = sreglist.GetLength(); 21180 EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff)); 21181 AdvanceIT(); 21182 return; 21183 } else { 21184 // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2 21185 if (cond.IsNotNever()) { 21186 const SRegister& sreg = sreglist.GetFirstSRegister(); 21187 unsigned len = sreglist.GetLength(); 21188 EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) | 21189 (len & 0xff)); 21190 return; 21191 } 21192 } 21193 Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist); 21194 } 21195 21196 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) { 21197 VIXL_ASSERT(AllowAssembler()); 21198 CheckIT(cond); 21199 USE(dt); 21200 if (IsUsingT32()) { 21201 // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1 21202 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 21203 const DRegister& dreg = dreglist.GetFirstDRegister(); 21204 unsigned len = dreglist.GetLength() * 2; 21205 EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff)); 21206 AdvanceIT(); 21207 return; 21208 } 21209 } else { 21210 // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1 21211 if (cond.IsNotNever() && 21212 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 21213 const DRegister& dreg = dreglist.GetFirstDRegister(); 21214 unsigned len = dreglist.GetLength() * 2; 21215 EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) | 21216 (len & 0xff)); 21217 return; 21218 } 21219 } 21220 Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist); 21221 } 21222 21223 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) { 21224 VIXL_ASSERT(AllowAssembler()); 21225 CheckIT(cond); 21226 USE(dt); 21227 if (IsUsingT32()) { 21228 // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2 21229 const SRegister& sreg = sreglist.GetFirstSRegister(); 21230 unsigned len = sreglist.GetLength(); 21231 EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff)); 21232 AdvanceIT(); 21233 return; 21234 } else { 21235 // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2 21236 if (cond.IsNotNever()) { 21237 const SRegister& sreg = sreglist.GetFirstSRegister(); 21238 unsigned len = sreglist.GetLength(); 21239 EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) | 21240 (len & 0xff)); 21241 return; 21242 } 21243 } 21244 Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist); 21245 } 21246 21247 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) { 21248 VIXL_ASSERT(AllowAssembler()); 21249 CheckIT(cond); 21250 Dt_size_5 encoded_dt(dt); 21251 if (IsUsingT32()) { 21252 // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 21253 if (encoded_dt.IsValid()) { 21254 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21255 EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) | 21256 rd.Encode(22, 12) | rm.Encode(5, 0)); 21257 AdvanceIT(); 21258 return; 21259 } 21260 } 21261 } else { 21262 // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 21263 if (encoded_dt.IsValid()) { 21264 if (cond.Is(al)) { 21265 EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) | 21266 rd.Encode(22, 12) | rm.Encode(5, 0)); 21267 return; 21268 } 21269 } 21270 } 21271 Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm); 21272 } 21273 21274 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) { 21275 VIXL_ASSERT(AllowAssembler()); 21276 CheckIT(cond); 21277 Dt_size_5 encoded_dt(dt); 21278 if (IsUsingT32()) { 21279 // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 21280 if (encoded_dt.IsValid()) { 21281 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21282 EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) | 21283 rd.Encode(22, 12) | rm.Encode(5, 0)); 21284 AdvanceIT(); 21285 return; 21286 } 21287 } 21288 } else { 21289 // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 21290 if (encoded_dt.IsValid()) { 21291 if (cond.Is(al)) { 21292 EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) | 21293 rd.Encode(22, 12) | rm.Encode(5, 0)); 21294 return; 21295 } 21296 } 21297 } 21298 Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm); 21299 } 21300 21301 void Assembler::vqadd( 21302 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21303 VIXL_ASSERT(AllowAssembler()); 21304 CheckIT(cond); 21305 Dt_U_size_3 encoded_dt(dt); 21306 if (IsUsingT32()) { 21307 // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 21308 if (encoded_dt.IsValid()) { 21309 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21310 EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21311 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21312 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21313 AdvanceIT(); 21314 return; 21315 } 21316 } 21317 } else { 21318 // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 21319 if (encoded_dt.IsValid()) { 21320 if (cond.Is(al)) { 21321 EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21322 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21323 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21324 return; 21325 } 21326 } 21327 } 21328 Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm); 21329 } 21330 21331 void Assembler::vqadd( 21332 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 21333 VIXL_ASSERT(AllowAssembler()); 21334 CheckIT(cond); 21335 Dt_U_size_3 encoded_dt(dt); 21336 if (IsUsingT32()) { 21337 // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 21338 if (encoded_dt.IsValid()) { 21339 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21340 EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21341 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21342 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21343 AdvanceIT(); 21344 return; 21345 } 21346 } 21347 } else { 21348 // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 21349 if (encoded_dt.IsValid()) { 21350 if (cond.Is(al)) { 21351 EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21352 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21353 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21354 return; 21355 } 21356 } 21357 } 21358 Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm); 21359 } 21360 21361 void Assembler::vqdmlal( 21362 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 21363 VIXL_ASSERT(AllowAssembler()); 21364 CheckIT(cond); 21365 Dt_size_13 encoded_dt(dt); 21366 if (IsUsingT32()) { 21367 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 21368 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 21369 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21370 EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) | 21371 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21372 AdvanceIT(); 21373 return; 21374 } 21375 } 21376 } else { 21377 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 21378 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 21379 if (cond.Is(al)) { 21380 EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) | 21381 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21382 return; 21383 } 21384 } 21385 } 21386 Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm); 21387 } 21388 21389 void Assembler::vqdmlal(Condition cond, 21390 DataType dt, 21391 QRegister rd, 21392 DRegister rn, 21393 DRegister dm, 21394 unsigned index) { 21395 VIXL_ASSERT(AllowAssembler()); 21396 CheckIT(cond); 21397 Dt_size_13 encoded_dt(dt); 21398 if (IsUsingT32()) { 21399 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2 21400 if (encoded_dt.IsValid() && 21401 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 21402 (!dt.Is(S16) && (index <= 1))) && 21403 (dt.Is(S16) || dt.Is(S32))) { 21404 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21405 uint32_t shift = 4; 21406 if (dt.Is(S16)) { 21407 shift = 3; 21408 } 21409 uint32_t mvm = dm.GetCode() | index << shift; 21410 EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) | 21411 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21412 ((mvm & 0x10) << 1)); 21413 AdvanceIT(); 21414 return; 21415 } 21416 } 21417 } else { 21418 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2 21419 if (encoded_dt.IsValid() && 21420 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 21421 (!dt.Is(S16) && (index <= 1))) && 21422 (dt.Is(S16) || dt.Is(S32))) { 21423 if (cond.Is(al)) { 21424 uint32_t shift = 4; 21425 if (dt.Is(S16)) { 21426 shift = 3; 21427 } 21428 uint32_t mvm = dm.GetCode() | index << shift; 21429 EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) | 21430 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21431 ((mvm & 0x10) << 1)); 21432 return; 21433 } 21434 } 21435 } 21436 Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index); 21437 } 21438 21439 void Assembler::vqdmlsl( 21440 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 21441 VIXL_ASSERT(AllowAssembler()); 21442 CheckIT(cond); 21443 Dt_size_13 encoded_dt(dt); 21444 if (IsUsingT32()) { 21445 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 21446 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 21447 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21448 EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) | 21449 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21450 AdvanceIT(); 21451 return; 21452 } 21453 } 21454 } else { 21455 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 21456 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 21457 if (cond.Is(al)) { 21458 EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) | 21459 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21460 return; 21461 } 21462 } 21463 } 21464 Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm); 21465 } 21466 21467 void Assembler::vqdmlsl(Condition cond, 21468 DataType dt, 21469 QRegister rd, 21470 DRegister rn, 21471 DRegister dm, 21472 unsigned index) { 21473 VIXL_ASSERT(AllowAssembler()); 21474 CheckIT(cond); 21475 Dt_size_13 encoded_dt(dt); 21476 if (IsUsingT32()) { 21477 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2 21478 if (encoded_dt.IsValid() && 21479 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 21480 (!dt.Is(S16) && (index <= 1))) && 21481 (dt.Is(S16) || dt.Is(S32))) { 21482 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21483 uint32_t shift = 4; 21484 if (dt.Is(S16)) { 21485 shift = 3; 21486 } 21487 uint32_t mvm = dm.GetCode() | index << shift; 21488 EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) | 21489 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21490 ((mvm & 0x10) << 1)); 21491 AdvanceIT(); 21492 return; 21493 } 21494 } 21495 } else { 21496 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2 21497 if (encoded_dt.IsValid() && 21498 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) || 21499 (!dt.Is(S16) && (index <= 1))) && 21500 (dt.Is(S16) || dt.Is(S32))) { 21501 if (cond.Is(al)) { 21502 uint32_t shift = 4; 21503 if (dt.Is(S16)) { 21504 shift = 3; 21505 } 21506 uint32_t mvm = dm.GetCode() | index << shift; 21507 EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) | 21508 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) | 21509 ((mvm & 0x10) << 1)); 21510 return; 21511 } 21512 } 21513 } 21514 Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index); 21515 } 21516 21517 void Assembler::vqdmulh( 21518 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21519 VIXL_ASSERT(AllowAssembler()); 21520 CheckIT(cond); 21521 Dt_size_13 encoded_dt(dt); 21522 if (IsUsingT32()) { 21523 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 21524 if (encoded_dt.IsValid()) { 21525 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21526 EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) | 21527 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21528 AdvanceIT(); 21529 return; 21530 } 21531 } 21532 } else { 21533 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 21534 if (encoded_dt.IsValid()) { 21535 if (cond.Is(al)) { 21536 EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) | 21537 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21538 return; 21539 } 21540 } 21541 } 21542 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 21543 } 21544 21545 void Assembler::vqdmulh( 21546 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 21547 VIXL_ASSERT(AllowAssembler()); 21548 CheckIT(cond); 21549 Dt_size_13 encoded_dt(dt); 21550 if (IsUsingT32()) { 21551 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 21552 if (encoded_dt.IsValid()) { 21553 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21554 EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) | 21555 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21556 AdvanceIT(); 21557 return; 21558 } 21559 } 21560 } else { 21561 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 21562 if (encoded_dt.IsValid()) { 21563 if (cond.Is(al)) { 21564 EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) | 21565 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21566 return; 21567 } 21568 } 21569 } 21570 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 21571 } 21572 21573 void Assembler::vqdmulh( 21574 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 21575 VIXL_ASSERT(AllowAssembler()); 21576 CheckIT(cond); 21577 Dt_size_13 encoded_dt(dt); 21578 if (IsUsingT32()) { 21579 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2 21580 if (encoded_dt.IsValid() && 21581 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21582 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21583 (rm.GetLane() <= 1))) && 21584 (dt.Is(S16) || dt.Is(S32))) { 21585 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21586 EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) | 21587 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21588 AdvanceIT(); 21589 return; 21590 } 21591 } 21592 } else { 21593 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2 21594 if (encoded_dt.IsValid() && 21595 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21596 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21597 (rm.GetLane() <= 1))) && 21598 (dt.Is(S16) || dt.Is(S32))) { 21599 if (cond.Is(al)) { 21600 EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) | 21601 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21602 return; 21603 } 21604 } 21605 } 21606 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 21607 } 21608 21609 void Assembler::vqdmulh( 21610 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 21611 VIXL_ASSERT(AllowAssembler()); 21612 CheckIT(cond); 21613 Dt_size_13 encoded_dt(dt); 21614 if (IsUsingT32()) { 21615 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2 21616 if (encoded_dt.IsValid() && 21617 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21618 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21619 (rm.GetLane() <= 1))) && 21620 (dt.Is(S16) || dt.Is(S32))) { 21621 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21622 EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) | 21623 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21624 AdvanceIT(); 21625 return; 21626 } 21627 } 21628 } else { 21629 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2 21630 if (encoded_dt.IsValid() && 21631 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21632 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21633 (rm.GetLane() <= 1))) && 21634 (dt.Is(S16) || dt.Is(S32))) { 21635 if (cond.Is(al)) { 21636 EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) | 21637 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21638 return; 21639 } 21640 } 21641 } 21642 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm); 21643 } 21644 21645 void Assembler::vqdmull( 21646 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 21647 VIXL_ASSERT(AllowAssembler()); 21648 CheckIT(cond); 21649 Dt_size_13 encoded_dt(dt); 21650 if (IsUsingT32()) { 21651 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 21652 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 21653 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21654 EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) | 21655 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21656 AdvanceIT(); 21657 return; 21658 } 21659 } 21660 } else { 21661 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 21662 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) { 21663 if (cond.Is(al)) { 21664 EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) | 21665 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21666 return; 21667 } 21668 } 21669 } 21670 Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm); 21671 } 21672 21673 void Assembler::vqdmull( 21674 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) { 21675 VIXL_ASSERT(AllowAssembler()); 21676 CheckIT(cond); 21677 Dt_size_13 encoded_dt(dt); 21678 if (IsUsingT32()) { 21679 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2 21680 if (encoded_dt.IsValid() && 21681 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21682 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21683 (rm.GetLane() <= 1))) && 21684 (dt.Is(S16) || dt.Is(S32))) { 21685 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21686 EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) | 21687 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21688 AdvanceIT(); 21689 return; 21690 } 21691 } 21692 } else { 21693 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2 21694 if (encoded_dt.IsValid() && 21695 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21696 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21697 (rm.GetLane() <= 1))) && 21698 (dt.Is(S16) || dt.Is(S32))) { 21699 if (cond.Is(al)) { 21700 EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) | 21701 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21702 return; 21703 } 21704 } 21705 } 21706 Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm); 21707 } 21708 21709 void Assembler::vqmovn(Condition cond, 21710 DataType dt, 21711 DRegister rd, 21712 QRegister rm) { 21713 VIXL_ASSERT(AllowAssembler()); 21714 CheckIT(cond); 21715 Dt_op_size_3 encoded_dt(dt); 21716 if (IsUsingT32()) { 21717 // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 21718 if (encoded_dt.IsValid()) { 21719 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21720 EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21721 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 21722 rd.Encode(22, 12) | rm.Encode(5, 0)); 21723 AdvanceIT(); 21724 return; 21725 } 21726 } 21727 } else { 21728 // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 21729 if (encoded_dt.IsValid()) { 21730 if (cond.Is(al)) { 21731 EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 21732 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 21733 rd.Encode(22, 12) | rm.Encode(5, 0)); 21734 return; 21735 } 21736 } 21737 } 21738 Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm); 21739 } 21740 21741 void Assembler::vqmovun(Condition cond, 21742 DataType dt, 21743 DRegister rd, 21744 QRegister rm) { 21745 VIXL_ASSERT(AllowAssembler()); 21746 CheckIT(cond); 21747 Dt_size_14 encoded_dt(dt); 21748 if (IsUsingT32()) { 21749 // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 21750 if (encoded_dt.IsValid()) { 21751 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21752 EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) | 21753 rd.Encode(22, 12) | rm.Encode(5, 0)); 21754 AdvanceIT(); 21755 return; 21756 } 21757 } 21758 } else { 21759 // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1 21760 if (encoded_dt.IsValid()) { 21761 if (cond.Is(al)) { 21762 EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) | 21763 rd.Encode(22, 12) | rm.Encode(5, 0)); 21764 return; 21765 } 21766 } 21767 } 21768 Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm); 21769 } 21770 21771 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) { 21772 VIXL_ASSERT(AllowAssembler()); 21773 CheckIT(cond); 21774 Dt_size_5 encoded_dt(dt); 21775 if (IsUsingT32()) { 21776 // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 21777 if (encoded_dt.IsValid()) { 21778 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21779 EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) | 21780 rd.Encode(22, 12) | rm.Encode(5, 0)); 21781 AdvanceIT(); 21782 return; 21783 } 21784 } 21785 } else { 21786 // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 21787 if (encoded_dt.IsValid()) { 21788 if (cond.Is(al)) { 21789 EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) | 21790 rd.Encode(22, 12) | rm.Encode(5, 0)); 21791 return; 21792 } 21793 } 21794 } 21795 Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm); 21796 } 21797 21798 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) { 21799 VIXL_ASSERT(AllowAssembler()); 21800 CheckIT(cond); 21801 Dt_size_5 encoded_dt(dt); 21802 if (IsUsingT32()) { 21803 // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 21804 if (encoded_dt.IsValid()) { 21805 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21806 EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) | 21807 rd.Encode(22, 12) | rm.Encode(5, 0)); 21808 AdvanceIT(); 21809 return; 21810 } 21811 } 21812 } else { 21813 // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 21814 if (encoded_dt.IsValid()) { 21815 if (cond.Is(al)) { 21816 EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) | 21817 rd.Encode(22, 12) | rm.Encode(5, 0)); 21818 return; 21819 } 21820 } 21821 } 21822 Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm); 21823 } 21824 21825 void Assembler::vqrdmulh( 21826 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 21827 VIXL_ASSERT(AllowAssembler()); 21828 CheckIT(cond); 21829 Dt_size_13 encoded_dt(dt); 21830 if (IsUsingT32()) { 21831 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 21832 if (encoded_dt.IsValid()) { 21833 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21834 EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) | 21835 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21836 AdvanceIT(); 21837 return; 21838 } 21839 } 21840 } else { 21841 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 21842 if (encoded_dt.IsValid()) { 21843 if (cond.Is(al)) { 21844 EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) | 21845 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21846 return; 21847 } 21848 } 21849 } 21850 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 21851 } 21852 21853 void Assembler::vqrdmulh( 21854 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 21855 VIXL_ASSERT(AllowAssembler()); 21856 CheckIT(cond); 21857 Dt_size_13 encoded_dt(dt); 21858 if (IsUsingT32()) { 21859 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 21860 if (encoded_dt.IsValid()) { 21861 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21862 EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) | 21863 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21864 AdvanceIT(); 21865 return; 21866 } 21867 } 21868 } else { 21869 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 21870 if (encoded_dt.IsValid()) { 21871 if (cond.Is(al)) { 21872 EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) | 21873 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 21874 return; 21875 } 21876 } 21877 } 21878 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 21879 } 21880 21881 void Assembler::vqrdmulh( 21882 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) { 21883 VIXL_ASSERT(AllowAssembler()); 21884 CheckIT(cond); 21885 Dt_size_13 encoded_dt(dt); 21886 if (IsUsingT32()) { 21887 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2 21888 if (encoded_dt.IsValid() && 21889 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21890 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21891 (rm.GetLane() <= 1))) && 21892 (dt.Is(S16) || dt.Is(S32))) { 21893 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21894 EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) | 21895 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21896 AdvanceIT(); 21897 return; 21898 } 21899 } 21900 } else { 21901 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2 21902 if (encoded_dt.IsValid() && 21903 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21904 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21905 (rm.GetLane() <= 1))) && 21906 (dt.Is(S16) || dt.Is(S32))) { 21907 if (cond.Is(al)) { 21908 EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) | 21909 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21910 return; 21911 } 21912 } 21913 } 21914 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 21915 } 21916 21917 void Assembler::vqrdmulh( 21918 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) { 21919 VIXL_ASSERT(AllowAssembler()); 21920 CheckIT(cond); 21921 Dt_size_13 encoded_dt(dt); 21922 if (IsUsingT32()) { 21923 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2 21924 if (encoded_dt.IsValid() && 21925 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21926 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21927 (rm.GetLane() <= 1))) && 21928 (dt.Is(S16) || dt.Is(S32))) { 21929 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21930 EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) | 21931 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21932 AdvanceIT(); 21933 return; 21934 } 21935 } 21936 } else { 21937 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2 21938 if (encoded_dt.IsValid() && 21939 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) || 21940 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) && 21941 (rm.GetLane() <= 1))) && 21942 (dt.Is(S16) || dt.Is(S32))) { 21943 if (cond.Is(al)) { 21944 EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) | 21945 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0)); 21946 return; 21947 } 21948 } 21949 } 21950 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm); 21951 } 21952 21953 void Assembler::vqrshl( 21954 Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) { 21955 VIXL_ASSERT(AllowAssembler()); 21956 CheckIT(cond); 21957 Dt_U_size_3 encoded_dt(dt); 21958 if (IsUsingT32()) { 21959 // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 21960 if (encoded_dt.IsValid()) { 21961 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21962 EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21963 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21964 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 21965 AdvanceIT(); 21966 return; 21967 } 21968 } 21969 } else { 21970 // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 21971 if (encoded_dt.IsValid()) { 21972 if (cond.Is(al)) { 21973 EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21974 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 21975 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 21976 return; 21977 } 21978 } 21979 } 21980 Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn); 21981 } 21982 21983 void Assembler::vqrshl( 21984 Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) { 21985 VIXL_ASSERT(AllowAssembler()); 21986 CheckIT(cond); 21987 Dt_U_size_3 encoded_dt(dt); 21988 if (IsUsingT32()) { 21989 // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 21990 if (encoded_dt.IsValid()) { 21991 if (cond.Is(al) || AllowStronglyDiscouraged()) { 21992 EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 21993 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 21994 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 21995 AdvanceIT(); 21996 return; 21997 } 21998 } 21999 } else { 22000 // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 22001 if (encoded_dt.IsValid()) { 22002 if (cond.Is(al)) { 22003 EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22004 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22005 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 22006 return; 22007 } 22008 } 22009 } 22010 Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn); 22011 } 22012 22013 void Assembler::vqrshrn(Condition cond, 22014 DataType dt, 22015 DRegister rd, 22016 QRegister rm, 22017 const QOperand& operand) { 22018 VIXL_ASSERT(AllowAssembler()); 22019 CheckIT(cond); 22020 if (operand.IsImmediate()) { 22021 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 22022 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 22023 Dt_op_size_3 encoded_dt(dt); 22024 Dt_imm6_1 encoded_dt_2(dt); 22025 if (IsUsingT32()) { 22026 // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 22027 if (encoded_dt.IsValid() && (imm == 0)) { 22028 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22029 EmitT32_32(0xffb20280U | 22030 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22031 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 22032 rd.Encode(22, 12) | rm.Encode(5, 0)); 22033 AdvanceIT(); 22034 return; 22035 } 22036 } 22037 // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 22038 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 22039 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22040 uint32_t imm6 = dt.GetSize() / 2 - imm; 22041 EmitT32_32(0xef800950U | 22042 (encoded_dt_2.GetTypeEncodingValue() << 28) | 22043 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 22044 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22045 AdvanceIT(); 22046 return; 22047 } 22048 } 22049 } else { 22050 // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 22051 if (encoded_dt.IsValid() && (imm == 0)) { 22052 if (cond.Is(al)) { 22053 EmitA32(0xf3b20280U | 22054 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22055 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 22056 rd.Encode(22, 12) | rm.Encode(5, 0)); 22057 return; 22058 } 22059 } 22060 // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 22061 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 22062 if (cond.Is(al)) { 22063 uint32_t imm6 = dt.GetSize() / 2 - imm; 22064 EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) | 22065 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 22066 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22067 return; 22068 } 22069 } 22070 } 22071 } 22072 } 22073 Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand); 22074 } 22075 22076 void Assembler::vqrshrun(Condition cond, 22077 DataType dt, 22078 DRegister rd, 22079 QRegister rm, 22080 const QOperand& operand) { 22081 VIXL_ASSERT(AllowAssembler()); 22082 CheckIT(cond); 22083 if (operand.IsImmediate()) { 22084 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 22085 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 22086 Dt_imm6_2 encoded_dt(dt); 22087 Dt_size_14 encoded_dt_2(dt); 22088 if (IsUsingT32()) { 22089 // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 22090 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 22091 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22092 uint32_t imm6 = dt.GetSize() / 2 - imm; 22093 EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) | 22094 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22095 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22096 AdvanceIT(); 22097 return; 22098 } 22099 } 22100 // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 22101 if (encoded_dt_2.IsValid() && (imm == 0)) { 22102 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22103 EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) | 22104 rd.Encode(22, 12) | rm.Encode(5, 0)); 22105 AdvanceIT(); 22106 return; 22107 } 22108 } 22109 } else { 22110 // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 22111 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 22112 if (cond.Is(al)) { 22113 uint32_t imm6 = dt.GetSize() / 2 - imm; 22114 EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) | 22115 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22116 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22117 return; 22118 } 22119 } 22120 // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 22121 if (encoded_dt_2.IsValid() && (imm == 0)) { 22122 if (cond.Is(al)) { 22123 EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) | 22124 rd.Encode(22, 12) | rm.Encode(5, 0)); 22125 return; 22126 } 22127 } 22128 } 22129 } 22130 } 22131 Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand); 22132 } 22133 22134 void Assembler::vqshl(Condition cond, 22135 DataType dt, 22136 DRegister rd, 22137 DRegister rm, 22138 const DOperand& operand) { 22139 VIXL_ASSERT(AllowAssembler()); 22140 CheckIT(cond); 22141 if (operand.IsRegister()) { 22142 DRegister rn = operand.GetRegister(); 22143 Dt_U_size_3 encoded_dt(dt); 22144 if (IsUsingT32()) { 22145 // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 22146 if (encoded_dt.IsValid()) { 22147 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22148 EmitT32_32(0xef000410U | 22149 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22150 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22151 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 22152 AdvanceIT(); 22153 return; 22154 } 22155 } 22156 } else { 22157 // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 22158 if (encoded_dt.IsValid()) { 22159 if (cond.Is(al)) { 22160 EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22161 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22162 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 22163 return; 22164 } 22165 } 22166 } 22167 } 22168 if (operand.IsImmediate()) { 22169 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 22170 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 22171 Dt_L_imm6_1 encoded_dt(dt); 22172 if (IsUsingT32()) { 22173 // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 22174 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 22175 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22176 uint32_t imm6 = imm; 22177 EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) | 22178 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22179 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 22180 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22181 AdvanceIT(); 22182 return; 22183 } 22184 } 22185 } else { 22186 // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 22187 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 22188 if (cond.Is(al)) { 22189 uint32_t imm6 = imm; 22190 EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) | 22191 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22192 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 22193 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22194 return; 22195 } 22196 } 22197 } 22198 } 22199 } 22200 Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand); 22201 } 22202 22203 void Assembler::vqshl(Condition cond, 22204 DataType dt, 22205 QRegister rd, 22206 QRegister rm, 22207 const QOperand& operand) { 22208 VIXL_ASSERT(AllowAssembler()); 22209 CheckIT(cond); 22210 if (operand.IsRegister()) { 22211 QRegister rn = operand.GetRegister(); 22212 Dt_U_size_3 encoded_dt(dt); 22213 if (IsUsingT32()) { 22214 // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 22215 if (encoded_dt.IsValid()) { 22216 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22217 EmitT32_32(0xef000450U | 22218 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22219 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22220 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 22221 AdvanceIT(); 22222 return; 22223 } 22224 } 22225 } else { 22226 // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 22227 if (encoded_dt.IsValid()) { 22228 if (cond.Is(al)) { 22229 EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22230 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22231 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 22232 return; 22233 } 22234 } 22235 } 22236 } 22237 if (operand.IsImmediate()) { 22238 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 22239 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 22240 Dt_L_imm6_1 encoded_dt(dt); 22241 if (IsUsingT32()) { 22242 // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 22243 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 22244 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22245 uint32_t imm6 = imm; 22246 EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) | 22247 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22248 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 22249 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22250 AdvanceIT(); 22251 return; 22252 } 22253 } 22254 } else { 22255 // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 22256 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 22257 if (cond.Is(al)) { 22258 uint32_t imm6 = imm; 22259 EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) | 22260 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22261 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 22262 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22263 return; 22264 } 22265 } 22266 } 22267 } 22268 } 22269 Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand); 22270 } 22271 22272 void Assembler::vqshlu(Condition cond, 22273 DataType dt, 22274 DRegister rd, 22275 DRegister rm, 22276 const DOperand& operand) { 22277 VIXL_ASSERT(AllowAssembler()); 22278 CheckIT(cond); 22279 if (operand.IsImmediate()) { 22280 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 22281 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 22282 Dt_L_imm6_2 encoded_dt(dt); 22283 if (IsUsingT32()) { 22284 // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 22285 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 22286 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22287 uint32_t imm6 = imm; 22288 EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) | 22289 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22290 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 22291 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22292 AdvanceIT(); 22293 return; 22294 } 22295 } 22296 } else { 22297 // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 22298 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 22299 if (cond.Is(al)) { 22300 uint32_t imm6 = imm; 22301 EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) | 22302 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22303 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 22304 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22305 return; 22306 } 22307 } 22308 } 22309 } 22310 } 22311 Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand); 22312 } 22313 22314 void Assembler::vqshlu(Condition cond, 22315 DataType dt, 22316 QRegister rd, 22317 QRegister rm, 22318 const QOperand& operand) { 22319 VIXL_ASSERT(AllowAssembler()); 22320 CheckIT(cond); 22321 if (operand.IsImmediate()) { 22322 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 22323 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 22324 Dt_L_imm6_2 encoded_dt(dt); 22325 if (IsUsingT32()) { 22326 // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 22327 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 22328 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22329 uint32_t imm6 = imm; 22330 EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) | 22331 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22332 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 22333 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22334 AdvanceIT(); 22335 return; 22336 } 22337 } 22338 } else { 22339 // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 22340 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 22341 if (cond.Is(al)) { 22342 uint32_t imm6 = imm; 22343 EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) | 22344 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22345 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 22346 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22347 return; 22348 } 22349 } 22350 } 22351 } 22352 } 22353 Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand); 22354 } 22355 22356 void Assembler::vqshrn(Condition cond, 22357 DataType dt, 22358 DRegister rd, 22359 QRegister rm, 22360 const QOperand& operand) { 22361 VIXL_ASSERT(AllowAssembler()); 22362 CheckIT(cond); 22363 if (operand.IsImmediate()) { 22364 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 22365 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 22366 Dt_op_size_3 encoded_dt(dt); 22367 Dt_imm6_1 encoded_dt_2(dt); 22368 if (IsUsingT32()) { 22369 // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 22370 if (encoded_dt.IsValid() && (imm == 0)) { 22371 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22372 EmitT32_32(0xffb20280U | 22373 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22374 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 22375 rd.Encode(22, 12) | rm.Encode(5, 0)); 22376 AdvanceIT(); 22377 return; 22378 } 22379 } 22380 // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 22381 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 22382 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22383 uint32_t imm6 = dt.GetSize() / 2 - imm; 22384 EmitT32_32(0xef800910U | 22385 (encoded_dt_2.GetTypeEncodingValue() << 28) | 22386 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 22387 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22388 AdvanceIT(); 22389 return; 22390 } 22391 } 22392 } else { 22393 // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 22394 if (encoded_dt.IsValid() && (imm == 0)) { 22395 if (cond.Is(al)) { 22396 EmitA32(0xf3b20280U | 22397 ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22398 ((encoded_dt.GetEncodingValue() & 0xc) << 4) | 22399 rd.Encode(22, 12) | rm.Encode(5, 0)); 22400 return; 22401 } 22402 } 22403 // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 22404 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 22405 if (cond.Is(al)) { 22406 uint32_t imm6 = dt.GetSize() / 2 - imm; 22407 EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) | 22408 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) | 22409 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22410 return; 22411 } 22412 } 22413 } 22414 } 22415 } 22416 Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand); 22417 } 22418 22419 void Assembler::vqshrun(Condition cond, 22420 DataType dt, 22421 DRegister rd, 22422 QRegister rm, 22423 const QOperand& operand) { 22424 VIXL_ASSERT(AllowAssembler()); 22425 CheckIT(cond); 22426 if (operand.IsImmediate()) { 22427 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 22428 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 22429 Dt_imm6_2 encoded_dt(dt); 22430 Dt_size_14 encoded_dt_2(dt); 22431 if (IsUsingT32()) { 22432 // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 22433 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 22434 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22435 uint32_t imm6 = dt.GetSize() / 2 - imm; 22436 EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) | 22437 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22438 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22439 AdvanceIT(); 22440 return; 22441 } 22442 } 22443 // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 22444 if (encoded_dt_2.IsValid() && (imm == 0)) { 22445 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22446 EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) | 22447 rd.Encode(22, 12) | rm.Encode(5, 0)); 22448 AdvanceIT(); 22449 return; 22450 } 22451 } 22452 } else { 22453 // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 22454 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 22455 if (cond.Is(al)) { 22456 uint32_t imm6 = dt.GetSize() / 2 - imm; 22457 EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) | 22458 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 22459 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 22460 return; 22461 } 22462 } 22463 // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 22464 if (encoded_dt_2.IsValid() && (imm == 0)) { 22465 if (cond.Is(al)) { 22466 EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) | 22467 rd.Encode(22, 12) | rm.Encode(5, 0)); 22468 return; 22469 } 22470 } 22471 } 22472 } 22473 } 22474 Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand); 22475 } 22476 22477 void Assembler::vqsub( 22478 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22479 VIXL_ASSERT(AllowAssembler()); 22480 CheckIT(cond); 22481 Dt_U_size_3 encoded_dt(dt); 22482 if (IsUsingT32()) { 22483 // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22484 if (encoded_dt.IsValid()) { 22485 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22486 EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22487 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22488 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22489 AdvanceIT(); 22490 return; 22491 } 22492 } 22493 } else { 22494 // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22495 if (encoded_dt.IsValid()) { 22496 if (cond.Is(al)) { 22497 EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22498 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22499 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22500 return; 22501 } 22502 } 22503 } 22504 Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm); 22505 } 22506 22507 void Assembler::vqsub( 22508 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 22509 VIXL_ASSERT(AllowAssembler()); 22510 CheckIT(cond); 22511 Dt_U_size_3 encoded_dt(dt); 22512 if (IsUsingT32()) { 22513 // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 22514 if (encoded_dt.IsValid()) { 22515 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22516 EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22517 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22518 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22519 AdvanceIT(); 22520 return; 22521 } 22522 } 22523 } else { 22524 // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 22525 if (encoded_dt.IsValid()) { 22526 if (cond.Is(al)) { 22527 EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22528 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22529 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22530 return; 22531 } 22532 } 22533 } 22534 Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm); 22535 } 22536 22537 void Assembler::vraddhn( 22538 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 22539 VIXL_ASSERT(AllowAssembler()); 22540 CheckIT(cond); 22541 Dt_size_3 encoded_dt(dt); 22542 if (IsUsingT32()) { 22543 // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 22544 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 22545 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22546 EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) | 22547 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22548 AdvanceIT(); 22549 return; 22550 } 22551 } 22552 } else { 22553 // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 22554 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 22555 if (cond.Is(al)) { 22556 EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) | 22557 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22558 return; 22559 } 22560 } 22561 } 22562 Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm); 22563 } 22564 22565 void Assembler::vrecpe(Condition cond, 22566 DataType dt, 22567 DRegister rd, 22568 DRegister rm) { 22569 VIXL_ASSERT(AllowAssembler()); 22570 CheckIT(cond); 22571 Dt_F_size_4 encoded_dt(dt); 22572 if (IsUsingT32()) { 22573 // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22574 if (encoded_dt.IsValid()) { 22575 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22576 EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22577 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 22578 rd.Encode(22, 12) | rm.Encode(5, 0)); 22579 AdvanceIT(); 22580 return; 22581 } 22582 } 22583 } else { 22584 // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22585 if (encoded_dt.IsValid()) { 22586 if (cond.Is(al)) { 22587 EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22588 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 22589 rd.Encode(22, 12) | rm.Encode(5, 0)); 22590 return; 22591 } 22592 } 22593 } 22594 Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm); 22595 } 22596 22597 void Assembler::vrecpe(Condition cond, 22598 DataType dt, 22599 QRegister rd, 22600 QRegister rm) { 22601 VIXL_ASSERT(AllowAssembler()); 22602 CheckIT(cond); 22603 Dt_F_size_4 encoded_dt(dt); 22604 if (IsUsingT32()) { 22605 // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22606 if (encoded_dt.IsValid()) { 22607 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22608 EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22609 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 22610 rd.Encode(22, 12) | rm.Encode(5, 0)); 22611 AdvanceIT(); 22612 return; 22613 } 22614 } 22615 } else { 22616 // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22617 if (encoded_dt.IsValid()) { 22618 if (cond.Is(al)) { 22619 EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 22620 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 22621 rd.Encode(22, 12) | rm.Encode(5, 0)); 22622 return; 22623 } 22624 } 22625 } 22626 Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm); 22627 } 22628 22629 void Assembler::vrecps( 22630 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22631 VIXL_ASSERT(AllowAssembler()); 22632 CheckIT(cond); 22633 if (IsUsingT32()) { 22634 // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 22635 if (dt.Is(F32)) { 22636 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22637 EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22638 rm.Encode(5, 0)); 22639 AdvanceIT(); 22640 return; 22641 } 22642 } 22643 } else { 22644 // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 22645 if (dt.Is(F32)) { 22646 if (cond.Is(al)) { 22647 EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22648 rm.Encode(5, 0)); 22649 return; 22650 } 22651 } 22652 } 22653 Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm); 22654 } 22655 22656 void Assembler::vrecps( 22657 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 22658 VIXL_ASSERT(AllowAssembler()); 22659 CheckIT(cond); 22660 if (IsUsingT32()) { 22661 // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 22662 if (dt.Is(F32)) { 22663 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22664 EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22665 rm.Encode(5, 0)); 22666 AdvanceIT(); 22667 return; 22668 } 22669 } 22670 } else { 22671 // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 22672 if (dt.Is(F32)) { 22673 if (cond.Is(al)) { 22674 EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 22675 rm.Encode(5, 0)); 22676 return; 22677 } 22678 } 22679 } 22680 Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm); 22681 } 22682 22683 void Assembler::vrev16(Condition cond, 22684 DataType dt, 22685 DRegister rd, 22686 DRegister rm) { 22687 VIXL_ASSERT(AllowAssembler()); 22688 CheckIT(cond); 22689 Dt_size_1 encoded_dt(dt); 22690 if (IsUsingT32()) { 22691 // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22692 if (encoded_dt.IsValid()) { 22693 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22694 EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) | 22695 rd.Encode(22, 12) | rm.Encode(5, 0)); 22696 AdvanceIT(); 22697 return; 22698 } 22699 } 22700 } else { 22701 // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22702 if (encoded_dt.IsValid()) { 22703 if (cond.Is(al)) { 22704 EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) | 22705 rd.Encode(22, 12) | rm.Encode(5, 0)); 22706 return; 22707 } 22708 } 22709 } 22710 Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm); 22711 } 22712 22713 void Assembler::vrev16(Condition cond, 22714 DataType dt, 22715 QRegister rd, 22716 QRegister rm) { 22717 VIXL_ASSERT(AllowAssembler()); 22718 CheckIT(cond); 22719 Dt_size_1 encoded_dt(dt); 22720 if (IsUsingT32()) { 22721 // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22722 if (encoded_dt.IsValid()) { 22723 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22724 EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) | 22725 rd.Encode(22, 12) | rm.Encode(5, 0)); 22726 AdvanceIT(); 22727 return; 22728 } 22729 } 22730 } else { 22731 // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22732 if (encoded_dt.IsValid()) { 22733 if (cond.Is(al)) { 22734 EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) | 22735 rd.Encode(22, 12) | rm.Encode(5, 0)); 22736 return; 22737 } 22738 } 22739 } 22740 Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm); 22741 } 22742 22743 void Assembler::vrev32(Condition cond, 22744 DataType dt, 22745 DRegister rd, 22746 DRegister rm) { 22747 VIXL_ASSERT(AllowAssembler()); 22748 CheckIT(cond); 22749 Dt_size_15 encoded_dt(dt); 22750 if (IsUsingT32()) { 22751 // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22752 if (encoded_dt.IsValid()) { 22753 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22754 EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) | 22755 rd.Encode(22, 12) | rm.Encode(5, 0)); 22756 AdvanceIT(); 22757 return; 22758 } 22759 } 22760 } else { 22761 // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22762 if (encoded_dt.IsValid()) { 22763 if (cond.Is(al)) { 22764 EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) | 22765 rd.Encode(22, 12) | rm.Encode(5, 0)); 22766 return; 22767 } 22768 } 22769 } 22770 Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm); 22771 } 22772 22773 void Assembler::vrev32(Condition cond, 22774 DataType dt, 22775 QRegister rd, 22776 QRegister rm) { 22777 VIXL_ASSERT(AllowAssembler()); 22778 CheckIT(cond); 22779 Dt_size_15 encoded_dt(dt); 22780 if (IsUsingT32()) { 22781 // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22782 if (encoded_dt.IsValid()) { 22783 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22784 EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) | 22785 rd.Encode(22, 12) | rm.Encode(5, 0)); 22786 AdvanceIT(); 22787 return; 22788 } 22789 } 22790 } else { 22791 // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22792 if (encoded_dt.IsValid()) { 22793 if (cond.Is(al)) { 22794 EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) | 22795 rd.Encode(22, 12) | rm.Encode(5, 0)); 22796 return; 22797 } 22798 } 22799 } 22800 Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm); 22801 } 22802 22803 void Assembler::vrev64(Condition cond, 22804 DataType dt, 22805 DRegister rd, 22806 DRegister rm) { 22807 VIXL_ASSERT(AllowAssembler()); 22808 CheckIT(cond); 22809 Dt_size_7 encoded_dt(dt); 22810 if (IsUsingT32()) { 22811 // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 22812 if (encoded_dt.IsValid()) { 22813 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22814 EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) | 22815 rd.Encode(22, 12) | rm.Encode(5, 0)); 22816 AdvanceIT(); 22817 return; 22818 } 22819 } 22820 } else { 22821 // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 22822 if (encoded_dt.IsValid()) { 22823 if (cond.Is(al)) { 22824 EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) | 22825 rd.Encode(22, 12) | rm.Encode(5, 0)); 22826 return; 22827 } 22828 } 22829 } 22830 Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm); 22831 } 22832 22833 void Assembler::vrev64(Condition cond, 22834 DataType dt, 22835 QRegister rd, 22836 QRegister rm) { 22837 VIXL_ASSERT(AllowAssembler()); 22838 CheckIT(cond); 22839 Dt_size_7 encoded_dt(dt); 22840 if (IsUsingT32()) { 22841 // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 22842 if (encoded_dt.IsValid()) { 22843 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22844 EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) | 22845 rd.Encode(22, 12) | rm.Encode(5, 0)); 22846 AdvanceIT(); 22847 return; 22848 } 22849 } 22850 } else { 22851 // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 22852 if (encoded_dt.IsValid()) { 22853 if (cond.Is(al)) { 22854 EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) | 22855 rd.Encode(22, 12) | rm.Encode(5, 0)); 22856 return; 22857 } 22858 } 22859 } 22860 Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm); 22861 } 22862 22863 void Assembler::vrhadd( 22864 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 22865 VIXL_ASSERT(AllowAssembler()); 22866 CheckIT(cond); 22867 Dt_U_size_1 encoded_dt(dt); 22868 if (IsUsingT32()) { 22869 // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 22870 if (encoded_dt.IsValid()) { 22871 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22872 EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22873 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22874 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22875 AdvanceIT(); 22876 return; 22877 } 22878 } 22879 } else { 22880 // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 22881 if (encoded_dt.IsValid()) { 22882 if (cond.Is(al)) { 22883 EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22884 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22885 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22886 return; 22887 } 22888 } 22889 } 22890 Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm); 22891 } 22892 22893 void Assembler::vrhadd( 22894 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 22895 VIXL_ASSERT(AllowAssembler()); 22896 CheckIT(cond); 22897 Dt_U_size_1 encoded_dt(dt); 22898 if (IsUsingT32()) { 22899 // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 22900 if (encoded_dt.IsValid()) { 22901 if (cond.Is(al) || AllowStronglyDiscouraged()) { 22902 EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22903 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 22904 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22905 AdvanceIT(); 22906 return; 22907 } 22908 } 22909 } else { 22910 // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 22911 if (encoded_dt.IsValid()) { 22912 if (cond.Is(al)) { 22913 EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 22914 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 22915 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 22916 return; 22917 } 22918 } 22919 } 22920 Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm); 22921 } 22922 22923 void Assembler::vrinta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 22924 VIXL_ASSERT(AllowAssembler()); 22925 CheckIT(al); 22926 if (IsUsingT32()) { 22927 // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; T1 22928 if (dt1.Is(F32) && dt2.Is(F32)) { 22929 EmitT32_32(0xffba0500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 22930 AdvanceIT(); 22931 return; 22932 } 22933 // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; T1 22934 if (dt1.Is(F64) && dt2.Is(F64)) { 22935 EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 22936 AdvanceIT(); 22937 return; 22938 } 22939 } else { 22940 // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; A1 22941 if (dt1.Is(F32) && dt2.Is(F32)) { 22942 EmitA32(0xf3ba0500U | rd.Encode(22, 12) | rm.Encode(5, 0)); 22943 return; 22944 } 22945 // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; A1 22946 if (dt1.Is(F64) && dt2.Is(F64)) { 22947 EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 22948 return; 22949 } 22950 } 22951 Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm); 22952 } 22953 22954 void Assembler::vrinta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 22955 VIXL_ASSERT(AllowAssembler()); 22956 CheckIT(al); 22957 if (IsUsingT32()) { 22958 // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; T1 22959 if (dt1.Is(F32) && dt2.Is(F32)) { 22960 EmitT32_32(0xffba0540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 22961 AdvanceIT(); 22962 return; 22963 } 22964 } else { 22965 // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; A1 22966 if (dt1.Is(F32) && dt2.Is(F32)) { 22967 EmitA32(0xf3ba0540U | rd.Encode(22, 12) | rm.Encode(5, 0)); 22968 return; 22969 } 22970 } 22971 Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm); 22972 } 22973 22974 void Assembler::vrinta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 22975 VIXL_ASSERT(AllowAssembler()); 22976 CheckIT(al); 22977 if (IsUsingT32()) { 22978 // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; T1 22979 if (dt1.Is(F32) && dt2.Is(F32)) { 22980 EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 22981 AdvanceIT(); 22982 return; 22983 } 22984 } else { 22985 // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; A1 22986 if (dt1.Is(F32) && dt2.Is(F32)) { 22987 EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 22988 return; 22989 } 22990 } 22991 Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm); 22992 } 22993 22994 void Assembler::vrintm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 22995 VIXL_ASSERT(AllowAssembler()); 22996 CheckIT(al); 22997 if (IsUsingT32()) { 22998 // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; T1 22999 if (dt1.Is(F32) && dt2.Is(F32)) { 23000 EmitT32_32(0xffba0680U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23001 AdvanceIT(); 23002 return; 23003 } 23004 // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; T1 23005 if (dt1.Is(F64) && dt2.Is(F64)) { 23006 EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23007 AdvanceIT(); 23008 return; 23009 } 23010 } else { 23011 // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; A1 23012 if (dt1.Is(F32) && dt2.Is(F32)) { 23013 EmitA32(0xf3ba0680U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23014 return; 23015 } 23016 // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; A1 23017 if (dt1.Is(F64) && dt2.Is(F64)) { 23018 EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23019 return; 23020 } 23021 } 23022 Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm); 23023 } 23024 23025 void Assembler::vrintm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 23026 VIXL_ASSERT(AllowAssembler()); 23027 CheckIT(al); 23028 if (IsUsingT32()) { 23029 // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; T1 23030 if (dt1.Is(F32) && dt2.Is(F32)) { 23031 EmitT32_32(0xffba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23032 AdvanceIT(); 23033 return; 23034 } 23035 } else { 23036 // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; A1 23037 if (dt1.Is(F32) && dt2.Is(F32)) { 23038 EmitA32(0xf3ba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23039 return; 23040 } 23041 } 23042 Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm); 23043 } 23044 23045 void Assembler::vrintm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 23046 VIXL_ASSERT(AllowAssembler()); 23047 CheckIT(al); 23048 if (IsUsingT32()) { 23049 // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; T1 23050 if (dt1.Is(F32) && dt2.Is(F32)) { 23051 EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23052 AdvanceIT(); 23053 return; 23054 } 23055 } else { 23056 // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; A1 23057 if (dt1.Is(F32) && dt2.Is(F32)) { 23058 EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23059 return; 23060 } 23061 } 23062 Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm); 23063 } 23064 23065 void Assembler::vrintn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 23066 VIXL_ASSERT(AllowAssembler()); 23067 CheckIT(al); 23068 if (IsUsingT32()) { 23069 // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; T1 23070 if (dt1.Is(F32) && dt2.Is(F32)) { 23071 EmitT32_32(0xffba0400U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23072 AdvanceIT(); 23073 return; 23074 } 23075 // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; T1 23076 if (dt1.Is(F64) && dt2.Is(F64)) { 23077 EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23078 AdvanceIT(); 23079 return; 23080 } 23081 } else { 23082 // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; A1 23083 if (dt1.Is(F32) && dt2.Is(F32)) { 23084 EmitA32(0xf3ba0400U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23085 return; 23086 } 23087 // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; A1 23088 if (dt1.Is(F64) && dt2.Is(F64)) { 23089 EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23090 return; 23091 } 23092 } 23093 Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm); 23094 } 23095 23096 void Assembler::vrintn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 23097 VIXL_ASSERT(AllowAssembler()); 23098 CheckIT(al); 23099 if (IsUsingT32()) { 23100 // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; T1 23101 if (dt1.Is(F32) && dt2.Is(F32)) { 23102 EmitT32_32(0xffba0440U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23103 AdvanceIT(); 23104 return; 23105 } 23106 } else { 23107 // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; A1 23108 if (dt1.Is(F32) && dt2.Is(F32)) { 23109 EmitA32(0xf3ba0440U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23110 return; 23111 } 23112 } 23113 Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm); 23114 } 23115 23116 void Assembler::vrintn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 23117 VIXL_ASSERT(AllowAssembler()); 23118 CheckIT(al); 23119 if (IsUsingT32()) { 23120 // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; T1 23121 if (dt1.Is(F32) && dt2.Is(F32)) { 23122 EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23123 AdvanceIT(); 23124 return; 23125 } 23126 } else { 23127 // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; A1 23128 if (dt1.Is(F32) && dt2.Is(F32)) { 23129 EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23130 return; 23131 } 23132 } 23133 Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm); 23134 } 23135 23136 void Assembler::vrintp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 23137 VIXL_ASSERT(AllowAssembler()); 23138 CheckIT(al); 23139 if (IsUsingT32()) { 23140 // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; T1 23141 if (dt1.Is(F32) && dt2.Is(F32)) { 23142 EmitT32_32(0xffba0780U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23143 AdvanceIT(); 23144 return; 23145 } 23146 // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; T1 23147 if (dt1.Is(F64) && dt2.Is(F64)) { 23148 EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23149 AdvanceIT(); 23150 return; 23151 } 23152 } else { 23153 // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; A1 23154 if (dt1.Is(F32) && dt2.Is(F32)) { 23155 EmitA32(0xf3ba0780U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23156 return; 23157 } 23158 // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; A1 23159 if (dt1.Is(F64) && dt2.Is(F64)) { 23160 EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23161 return; 23162 } 23163 } 23164 Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm); 23165 } 23166 23167 void Assembler::vrintp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 23168 VIXL_ASSERT(AllowAssembler()); 23169 CheckIT(al); 23170 if (IsUsingT32()) { 23171 // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; T1 23172 if (dt1.Is(F32) && dt2.Is(F32)) { 23173 EmitT32_32(0xffba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23174 AdvanceIT(); 23175 return; 23176 } 23177 } else { 23178 // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; A1 23179 if (dt1.Is(F32) && dt2.Is(F32)) { 23180 EmitA32(0xf3ba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23181 return; 23182 } 23183 } 23184 Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm); 23185 } 23186 23187 void Assembler::vrintp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 23188 VIXL_ASSERT(AllowAssembler()); 23189 CheckIT(al); 23190 if (IsUsingT32()) { 23191 // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; T1 23192 if (dt1.Is(F32) && dt2.Is(F32)) { 23193 EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23194 AdvanceIT(); 23195 return; 23196 } 23197 } else { 23198 // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; A1 23199 if (dt1.Is(F32) && dt2.Is(F32)) { 23200 EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23201 return; 23202 } 23203 } 23204 Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm); 23205 } 23206 23207 void Assembler::vrintr( 23208 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 23209 VIXL_ASSERT(AllowAssembler()); 23210 CheckIT(cond); 23211 if (IsUsingT32()) { 23212 // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1 23213 if (dt1.Is(F32) && dt2.Is(F32)) { 23214 EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23215 AdvanceIT(); 23216 return; 23217 } 23218 } else { 23219 // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1 23220 if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) { 23221 EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 23222 rm.Encode(5, 0)); 23223 return; 23224 } 23225 } 23226 Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm); 23227 } 23228 23229 void Assembler::vrintr( 23230 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 23231 VIXL_ASSERT(AllowAssembler()); 23232 CheckIT(cond); 23233 if (IsUsingT32()) { 23234 // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1 23235 if (dt1.Is(F64) && dt2.Is(F64)) { 23236 EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23237 AdvanceIT(); 23238 return; 23239 } 23240 } else { 23241 // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1 23242 if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) { 23243 EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 23244 rm.Encode(5, 0)); 23245 return; 23246 } 23247 } 23248 Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm); 23249 } 23250 23251 void Assembler::vrintx( 23252 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 23253 VIXL_ASSERT(AllowAssembler()); 23254 CheckIT(cond); 23255 if (IsUsingT32()) { 23256 // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; T1 23257 if (dt1.Is(F32) && dt2.Is(F32)) { 23258 EmitT32_32(0xffba0480U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23259 AdvanceIT(); 23260 return; 23261 } 23262 // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1 23263 if (dt1.Is(F64) && dt2.Is(F64)) { 23264 EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23265 AdvanceIT(); 23266 return; 23267 } 23268 } else { 23269 // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; A1 23270 if (dt1.Is(F32) && dt2.Is(F32)) { 23271 EmitA32(0xf3ba0480U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23272 return; 23273 } 23274 // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1 23275 if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) { 23276 EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 23277 rm.Encode(5, 0)); 23278 return; 23279 } 23280 } 23281 Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm); 23282 } 23283 23284 void Assembler::vrintx(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 23285 VIXL_ASSERT(AllowAssembler()); 23286 CheckIT(al); 23287 if (IsUsingT32()) { 23288 // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; T1 23289 if (dt1.Is(F32) && dt2.Is(F32)) { 23290 EmitT32_32(0xffba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23291 AdvanceIT(); 23292 return; 23293 } 23294 } else { 23295 // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; A1 23296 if (dt1.Is(F32) && dt2.Is(F32)) { 23297 EmitA32(0xf3ba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23298 return; 23299 } 23300 } 23301 Delegate(kVrintx, &Assembler::vrintx, dt1, dt2, rd, rm); 23302 } 23303 23304 void Assembler::vrintx( 23305 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 23306 VIXL_ASSERT(AllowAssembler()); 23307 CheckIT(cond); 23308 if (IsUsingT32()) { 23309 // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1 23310 if (dt1.Is(F32) && dt2.Is(F32)) { 23311 EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23312 AdvanceIT(); 23313 return; 23314 } 23315 } else { 23316 // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1 23317 if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) { 23318 EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 23319 rm.Encode(5, 0)); 23320 return; 23321 } 23322 } 23323 Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm); 23324 } 23325 23326 void Assembler::vrintz( 23327 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) { 23328 VIXL_ASSERT(AllowAssembler()); 23329 CheckIT(cond); 23330 if (IsUsingT32()) { 23331 // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; T1 23332 if (dt1.Is(F32) && dt2.Is(F32)) { 23333 EmitT32_32(0xffba0580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23334 AdvanceIT(); 23335 return; 23336 } 23337 // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1 23338 if (dt1.Is(F64) && dt2.Is(F64)) { 23339 EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23340 AdvanceIT(); 23341 return; 23342 } 23343 } else { 23344 // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; A1 23345 if (dt1.Is(F32) && dt2.Is(F32)) { 23346 EmitA32(0xf3ba0580U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23347 return; 23348 } 23349 // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1 23350 if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) { 23351 EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 23352 rm.Encode(5, 0)); 23353 return; 23354 } 23355 } 23356 Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm); 23357 } 23358 23359 void Assembler::vrintz(DataType dt1, DataType dt2, QRegister rd, QRegister rm) { 23360 VIXL_ASSERT(AllowAssembler()); 23361 CheckIT(al); 23362 if (IsUsingT32()) { 23363 // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; T1 23364 if (dt1.Is(F32) && dt2.Is(F32)) { 23365 EmitT32_32(0xffba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23366 AdvanceIT(); 23367 return; 23368 } 23369 } else { 23370 // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; A1 23371 if (dt1.Is(F32) && dt2.Is(F32)) { 23372 EmitA32(0xf3ba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23373 return; 23374 } 23375 } 23376 Delegate(kVrintz, &Assembler::vrintz, dt1, dt2, rd, rm); 23377 } 23378 23379 void Assembler::vrintz( 23380 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) { 23381 VIXL_ASSERT(AllowAssembler()); 23382 CheckIT(cond); 23383 if (IsUsingT32()) { 23384 // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1 23385 if (dt1.Is(F32) && dt2.Is(F32)) { 23386 EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 23387 AdvanceIT(); 23388 return; 23389 } 23390 } else { 23391 // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1 23392 if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) { 23393 EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 23394 rm.Encode(5, 0)); 23395 return; 23396 } 23397 } 23398 Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm); 23399 } 23400 23401 void Assembler::vrshl( 23402 Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) { 23403 VIXL_ASSERT(AllowAssembler()); 23404 CheckIT(cond); 23405 Dt_U_size_3 encoded_dt(dt); 23406 if (IsUsingT32()) { 23407 // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 23408 if (encoded_dt.IsValid()) { 23409 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23410 EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23411 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23412 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23413 AdvanceIT(); 23414 return; 23415 } 23416 } 23417 } else { 23418 // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 23419 if (encoded_dt.IsValid()) { 23420 if (cond.Is(al)) { 23421 EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23422 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23423 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23424 return; 23425 } 23426 } 23427 } 23428 Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn); 23429 } 23430 23431 void Assembler::vrshl( 23432 Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) { 23433 VIXL_ASSERT(AllowAssembler()); 23434 CheckIT(cond); 23435 Dt_U_size_3 encoded_dt(dt); 23436 if (IsUsingT32()) { 23437 // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 23438 if (encoded_dt.IsValid()) { 23439 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23440 EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23441 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 23442 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23443 AdvanceIT(); 23444 return; 23445 } 23446 } 23447 } else { 23448 // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 23449 if (encoded_dt.IsValid()) { 23450 if (cond.Is(al)) { 23451 EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 23452 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 23453 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 23454 return; 23455 } 23456 } 23457 } 23458 Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn); 23459 } 23460 23461 void Assembler::vrshr(Condition cond, 23462 DataType dt, 23463 DRegister rd, 23464 DRegister rm, 23465 const DOperand& operand) { 23466 VIXL_ASSERT(AllowAssembler()); 23467 CheckIT(cond); 23468 if (operand.IsImmediate()) { 23469 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23470 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23471 Dt_L_imm6_1 encoded_dt(dt); 23472 if (IsUsingT32()) { 23473 // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 23474 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 23475 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23476 uint32_t imm6 = dt.GetSize() - imm; 23477 EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) | 23478 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23479 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23480 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23481 AdvanceIT(); 23482 return; 23483 } 23484 } 23485 // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1 23486 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 23487 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23488 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 23489 rm.Encode(5, 0)); 23490 AdvanceIT(); 23491 return; 23492 } 23493 } 23494 } else { 23495 // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 23496 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 23497 if (cond.Is(al)) { 23498 uint32_t imm6 = dt.GetSize() - imm; 23499 EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) | 23500 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23501 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23502 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23503 return; 23504 } 23505 } 23506 // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1 23507 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 23508 if (cond.Is(al)) { 23509 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 23510 rm.Encode(5, 0)); 23511 return; 23512 } 23513 } 23514 } 23515 } 23516 } 23517 Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand); 23518 } 23519 23520 void Assembler::vrshr(Condition cond, 23521 DataType dt, 23522 QRegister rd, 23523 QRegister rm, 23524 const QOperand& operand) { 23525 VIXL_ASSERT(AllowAssembler()); 23526 CheckIT(cond); 23527 if (operand.IsImmediate()) { 23528 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23529 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23530 Dt_L_imm6_1 encoded_dt(dt); 23531 if (IsUsingT32()) { 23532 // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 23533 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 23534 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23535 uint32_t imm6 = dt.GetSize() - imm; 23536 EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) | 23537 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23538 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23539 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23540 AdvanceIT(); 23541 return; 23542 } 23543 } 23544 // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1 23545 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 23546 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23547 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 23548 rm.Encode(5, 0)); 23549 AdvanceIT(); 23550 return; 23551 } 23552 } 23553 } else { 23554 // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 23555 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 23556 if (cond.Is(al)) { 23557 uint32_t imm6 = dt.GetSize() - imm; 23558 EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) | 23559 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23560 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23561 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23562 return; 23563 } 23564 } 23565 // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1 23566 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 23567 if (cond.Is(al)) { 23568 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 23569 rm.Encode(5, 0)); 23570 return; 23571 } 23572 } 23573 } 23574 } 23575 } 23576 Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand); 23577 } 23578 23579 void Assembler::vrshrn(Condition cond, 23580 DataType dt, 23581 DRegister rd, 23582 QRegister rm, 23583 const QOperand& operand) { 23584 VIXL_ASSERT(AllowAssembler()); 23585 CheckIT(cond); 23586 if (operand.IsImmediate()) { 23587 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23588 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23589 Dt_imm6_3 encoded_dt(dt); 23590 Dt_size_3 encoded_dt_2(dt); 23591 if (IsUsingT32()) { 23592 // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 23593 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23594 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23595 uint32_t imm6 = dt.GetSize() / 2 - imm; 23596 EmitT32_32(0xef800850U | 23597 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23598 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23599 AdvanceIT(); 23600 return; 23601 } 23602 } 23603 // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 23604 if (encoded_dt_2.IsValid() && (imm == 0)) { 23605 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23606 EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) | 23607 rd.Encode(22, 12) | rm.Encode(5, 0)); 23608 AdvanceIT(); 23609 return; 23610 } 23611 } 23612 } else { 23613 // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 23614 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 23615 if (cond.Is(al)) { 23616 uint32_t imm6 = dt.GetSize() / 2 - imm; 23617 EmitA32(0xf2800850U | 23618 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23619 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23620 return; 23621 } 23622 } 23623 // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 23624 if (encoded_dt_2.IsValid() && (imm == 0)) { 23625 if (cond.Is(al)) { 23626 EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) | 23627 rd.Encode(22, 12) | rm.Encode(5, 0)); 23628 return; 23629 } 23630 } 23631 } 23632 } 23633 } 23634 Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand); 23635 } 23636 23637 void Assembler::vrsqrte(Condition cond, 23638 DataType dt, 23639 DRegister rd, 23640 DRegister rm) { 23641 VIXL_ASSERT(AllowAssembler()); 23642 CheckIT(cond); 23643 Dt_F_size_4 encoded_dt(dt); 23644 if (IsUsingT32()) { 23645 // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 23646 if (encoded_dt.IsValid()) { 23647 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23648 EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23649 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23650 rd.Encode(22, 12) | rm.Encode(5, 0)); 23651 AdvanceIT(); 23652 return; 23653 } 23654 } 23655 } else { 23656 // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 23657 if (encoded_dt.IsValid()) { 23658 if (cond.Is(al)) { 23659 EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23660 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23661 rd.Encode(22, 12) | rm.Encode(5, 0)); 23662 return; 23663 } 23664 } 23665 } 23666 Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm); 23667 } 23668 23669 void Assembler::vrsqrte(Condition cond, 23670 DataType dt, 23671 QRegister rd, 23672 QRegister rm) { 23673 VIXL_ASSERT(AllowAssembler()); 23674 CheckIT(cond); 23675 Dt_F_size_4 encoded_dt(dt); 23676 if (IsUsingT32()) { 23677 // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 23678 if (encoded_dt.IsValid()) { 23679 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23680 EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23681 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23682 rd.Encode(22, 12) | rm.Encode(5, 0)); 23683 AdvanceIT(); 23684 return; 23685 } 23686 } 23687 } else { 23688 // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 23689 if (encoded_dt.IsValid()) { 23690 if (cond.Is(al)) { 23691 EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) | 23692 ((encoded_dt.GetEncodingValue() & 0x4) << 6) | 23693 rd.Encode(22, 12) | rm.Encode(5, 0)); 23694 return; 23695 } 23696 } 23697 } 23698 Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm); 23699 } 23700 23701 void Assembler::vrsqrts( 23702 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23703 VIXL_ASSERT(AllowAssembler()); 23704 CheckIT(cond); 23705 if (IsUsingT32()) { 23706 // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 23707 if (dt.Is(F32)) { 23708 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23709 EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23710 rm.Encode(5, 0)); 23711 AdvanceIT(); 23712 return; 23713 } 23714 } 23715 } else { 23716 // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 23717 if (dt.Is(F32)) { 23718 if (cond.Is(al)) { 23719 EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23720 rm.Encode(5, 0)); 23721 return; 23722 } 23723 } 23724 } 23725 Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm); 23726 } 23727 23728 void Assembler::vrsqrts( 23729 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 23730 VIXL_ASSERT(AllowAssembler()); 23731 CheckIT(cond); 23732 if (IsUsingT32()) { 23733 // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 23734 if (dt.Is(F32)) { 23735 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23736 EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23737 rm.Encode(5, 0)); 23738 AdvanceIT(); 23739 return; 23740 } 23741 } 23742 } else { 23743 // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 23744 if (dt.Is(F32)) { 23745 if (cond.Is(al)) { 23746 EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23747 rm.Encode(5, 0)); 23748 return; 23749 } 23750 } 23751 } 23752 Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm); 23753 } 23754 23755 void Assembler::vrsra(Condition cond, 23756 DataType dt, 23757 DRegister rd, 23758 DRegister rm, 23759 const DOperand& operand) { 23760 VIXL_ASSERT(AllowAssembler()); 23761 CheckIT(cond); 23762 if (operand.IsImmediate()) { 23763 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23764 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23765 Dt_L_imm6_1 encoded_dt(dt); 23766 if (IsUsingT32()) { 23767 // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 23768 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 23769 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23770 uint32_t imm6 = dt.GetSize() - imm; 23771 EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) | 23772 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23773 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23774 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23775 AdvanceIT(); 23776 return; 23777 } 23778 } 23779 } else { 23780 // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 23781 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 23782 if (cond.Is(al)) { 23783 uint32_t imm6 = dt.GetSize() - imm; 23784 EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) | 23785 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23786 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23787 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23788 return; 23789 } 23790 } 23791 } 23792 } 23793 } 23794 Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand); 23795 } 23796 23797 void Assembler::vrsra(Condition cond, 23798 DataType dt, 23799 QRegister rd, 23800 QRegister rm, 23801 const QOperand& operand) { 23802 VIXL_ASSERT(AllowAssembler()); 23803 CheckIT(cond); 23804 if (operand.IsImmediate()) { 23805 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 23806 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 23807 Dt_L_imm6_1 encoded_dt(dt); 23808 if (IsUsingT32()) { 23809 // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 23810 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 23811 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23812 uint32_t imm6 = dt.GetSize() - imm; 23813 EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) | 23814 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23815 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23816 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23817 AdvanceIT(); 23818 return; 23819 } 23820 } 23821 } else { 23822 // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 23823 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 23824 if (cond.Is(al)) { 23825 uint32_t imm6 = dt.GetSize() - imm; 23826 EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) | 23827 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 23828 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 23829 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 23830 return; 23831 } 23832 } 23833 } 23834 } 23835 } 23836 Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand); 23837 } 23838 23839 void Assembler::vrsubhn( 23840 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 23841 VIXL_ASSERT(AllowAssembler()); 23842 CheckIT(cond); 23843 Dt_size_3 encoded_dt(dt); 23844 if (IsUsingT32()) { 23845 // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 23846 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 23847 if (cond.Is(al) || AllowStronglyDiscouraged()) { 23848 EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) | 23849 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23850 AdvanceIT(); 23851 return; 23852 } 23853 } 23854 } else { 23855 // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 23856 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 23857 if (cond.Is(al)) { 23858 EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) | 23859 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 23860 return; 23861 } 23862 } 23863 } 23864 Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm); 23865 } 23866 23867 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23868 VIXL_ASSERT(AllowAssembler()); 23869 CheckIT(al); 23870 if (IsUsingT32()) { 23871 // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1 23872 if (OutsideITBlock() && dt.Is(F64)) { 23873 EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23874 rm.Encode(5, 0)); 23875 AdvanceIT(); 23876 return; 23877 } 23878 } else { 23879 // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1 23880 if (dt.Is(F64)) { 23881 EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23882 rm.Encode(5, 0)); 23883 return; 23884 } 23885 } 23886 Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm); 23887 } 23888 23889 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 23890 VIXL_ASSERT(AllowAssembler()); 23891 CheckIT(al); 23892 if (IsUsingT32()) { 23893 // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1 23894 if (OutsideITBlock() && dt.Is(F32)) { 23895 EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23896 rm.Encode(5, 0)); 23897 AdvanceIT(); 23898 return; 23899 } 23900 } else { 23901 // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1 23902 if (dt.Is(F32)) { 23903 EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23904 rm.Encode(5, 0)); 23905 return; 23906 } 23907 } 23908 Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm); 23909 } 23910 23911 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23912 VIXL_ASSERT(AllowAssembler()); 23913 CheckIT(al); 23914 if (IsUsingT32()) { 23915 // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1 23916 if (OutsideITBlock() && dt.Is(F64)) { 23917 EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23918 rm.Encode(5, 0)); 23919 AdvanceIT(); 23920 return; 23921 } 23922 } else { 23923 // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1 23924 if (dt.Is(F64)) { 23925 EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23926 rm.Encode(5, 0)); 23927 return; 23928 } 23929 } 23930 Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm); 23931 } 23932 23933 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 23934 VIXL_ASSERT(AllowAssembler()); 23935 CheckIT(al); 23936 if (IsUsingT32()) { 23937 // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1 23938 if (OutsideITBlock() && dt.Is(F32)) { 23939 EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23940 rm.Encode(5, 0)); 23941 AdvanceIT(); 23942 return; 23943 } 23944 } else { 23945 // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1 23946 if (dt.Is(F32)) { 23947 EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23948 rm.Encode(5, 0)); 23949 return; 23950 } 23951 } 23952 Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm); 23953 } 23954 23955 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 23956 VIXL_ASSERT(AllowAssembler()); 23957 CheckIT(al); 23958 if (IsUsingT32()) { 23959 // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1 23960 if (OutsideITBlock() && dt.Is(F64)) { 23961 EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23962 rm.Encode(5, 0)); 23963 AdvanceIT(); 23964 return; 23965 } 23966 } else { 23967 // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1 23968 if (dt.Is(F64)) { 23969 EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23970 rm.Encode(5, 0)); 23971 return; 23972 } 23973 } 23974 Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm); 23975 } 23976 23977 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 23978 VIXL_ASSERT(AllowAssembler()); 23979 CheckIT(al); 23980 if (IsUsingT32()) { 23981 // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1 23982 if (OutsideITBlock() && dt.Is(F32)) { 23983 EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23984 rm.Encode(5, 0)); 23985 AdvanceIT(); 23986 return; 23987 } 23988 } else { 23989 // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1 23990 if (dt.Is(F32)) { 23991 EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 23992 rm.Encode(5, 0)); 23993 return; 23994 } 23995 } 23996 Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm); 23997 } 23998 23999 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) { 24000 VIXL_ASSERT(AllowAssembler()); 24001 CheckIT(al); 24002 if (IsUsingT32()) { 24003 // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1 24004 if (OutsideITBlock() && dt.Is(F64)) { 24005 EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 24006 rm.Encode(5, 0)); 24007 AdvanceIT(); 24008 return; 24009 } 24010 } else { 24011 // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1 24012 if (dt.Is(F64)) { 24013 EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 24014 rm.Encode(5, 0)); 24015 return; 24016 } 24017 } 24018 Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm); 24019 } 24020 24021 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) { 24022 VIXL_ASSERT(AllowAssembler()); 24023 CheckIT(al); 24024 if (IsUsingT32()) { 24025 // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1 24026 if (OutsideITBlock() && dt.Is(F32)) { 24027 EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 24028 rm.Encode(5, 0)); 24029 AdvanceIT(); 24030 return; 24031 } 24032 } else { 24033 // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1 24034 if (dt.Is(F32)) { 24035 EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 24036 rm.Encode(5, 0)); 24037 return; 24038 } 24039 } 24040 Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm); 24041 } 24042 24043 void Assembler::vshl(Condition cond, 24044 DataType dt, 24045 DRegister rd, 24046 DRegister rm, 24047 const DOperand& operand) { 24048 VIXL_ASSERT(AllowAssembler()); 24049 CheckIT(cond); 24050 if (operand.IsImmediate()) { 24051 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24052 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24053 Dt_L_imm6_3 encoded_dt(dt); 24054 if (IsUsingT32()) { 24055 // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1 24056 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 24057 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24058 uint32_t imm6 = imm; 24059 EmitT32_32(0xef800510U | 24060 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24061 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24062 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24063 AdvanceIT(); 24064 return; 24065 } 24066 } 24067 } else { 24068 // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1 24069 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 24070 if (cond.Is(al)) { 24071 uint32_t imm6 = imm; 24072 EmitA32(0xf2800510U | 24073 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24074 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24075 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24076 return; 24077 } 24078 } 24079 } 24080 } 24081 } 24082 if (operand.IsRegister()) { 24083 DRegister rn = operand.GetRegister(); 24084 Dt_U_size_3 encoded_dt(dt); 24085 if (IsUsingT32()) { 24086 // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1 24087 if (encoded_dt.IsValid()) { 24088 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24089 EmitT32_32(0xef000400U | 24090 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24091 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24092 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24093 AdvanceIT(); 24094 return; 24095 } 24096 } 24097 } else { 24098 // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1 24099 if (encoded_dt.IsValid()) { 24100 if (cond.Is(al)) { 24101 EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24102 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24103 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24104 return; 24105 } 24106 } 24107 } 24108 } 24109 Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand); 24110 } 24111 24112 void Assembler::vshl(Condition cond, 24113 DataType dt, 24114 QRegister rd, 24115 QRegister rm, 24116 const QOperand& operand) { 24117 VIXL_ASSERT(AllowAssembler()); 24118 CheckIT(cond); 24119 if (operand.IsImmediate()) { 24120 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24121 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24122 Dt_L_imm6_3 encoded_dt(dt); 24123 if (IsUsingT32()) { 24124 // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1 24125 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 24126 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24127 uint32_t imm6 = imm; 24128 EmitT32_32(0xef800550U | 24129 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24130 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24131 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24132 AdvanceIT(); 24133 return; 24134 } 24135 } 24136 } else { 24137 // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1 24138 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 24139 if (cond.Is(al)) { 24140 uint32_t imm6 = imm; 24141 EmitA32(0xf2800550U | 24142 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24143 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24144 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24145 return; 24146 } 24147 } 24148 } 24149 } 24150 } 24151 if (operand.IsRegister()) { 24152 QRegister rn = operand.GetRegister(); 24153 Dt_U_size_3 encoded_dt(dt); 24154 if (IsUsingT32()) { 24155 // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1 24156 if (encoded_dt.IsValid()) { 24157 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24158 EmitT32_32(0xef000440U | 24159 ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24160 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 24161 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24162 AdvanceIT(); 24163 return; 24164 } 24165 } 24166 } else { 24167 // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1 24168 if (encoded_dt.IsValid()) { 24169 if (cond.Is(al)) { 24170 EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 24171 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 24172 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16)); 24173 return; 24174 } 24175 } 24176 } 24177 } 24178 Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand); 24179 } 24180 24181 void Assembler::vshll(Condition cond, 24182 DataType dt, 24183 QRegister rd, 24184 DRegister rm, 24185 const DOperand& operand) { 24186 VIXL_ASSERT(AllowAssembler()); 24187 CheckIT(cond); 24188 if (operand.IsImmediate()) { 24189 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24190 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24191 Dt_imm6_4 encoded_dt(dt); 24192 Dt_size_16 encoded_dt_2(dt); 24193 if (IsUsingT32()) { 24194 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 24195 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) { 24196 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24197 uint32_t imm6 = dt.GetSize() + imm; 24198 EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) | 24199 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24200 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24201 AdvanceIT(); 24202 return; 24203 } 24204 } 24205 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2 24206 if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) { 24207 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24208 EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) | 24209 rd.Encode(22, 12) | rm.Encode(5, 0)); 24210 AdvanceIT(); 24211 return; 24212 } 24213 } 24214 } else { 24215 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 24216 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) { 24217 if (cond.Is(al)) { 24218 uint32_t imm6 = dt.GetSize() + imm; 24219 EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) | 24220 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24221 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24222 return; 24223 } 24224 } 24225 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2 24226 if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) { 24227 if (cond.Is(al)) { 24228 EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) | 24229 rd.Encode(22, 12) | rm.Encode(5, 0)); 24230 return; 24231 } 24232 } 24233 } 24234 } 24235 } 24236 Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand); 24237 } 24238 24239 void Assembler::vshr(Condition cond, 24240 DataType dt, 24241 DRegister rd, 24242 DRegister rm, 24243 const DOperand& operand) { 24244 VIXL_ASSERT(AllowAssembler()); 24245 CheckIT(cond); 24246 if (operand.IsImmediate()) { 24247 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24248 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24249 Dt_L_imm6_1 encoded_dt(dt); 24250 if (IsUsingT32()) { 24251 // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 24252 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24253 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24254 uint32_t imm6 = dt.GetSize() - imm; 24255 EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) | 24256 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24257 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24258 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24259 AdvanceIT(); 24260 return; 24261 } 24262 } 24263 // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1 24264 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24265 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24266 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24267 rm.Encode(5, 0)); 24268 AdvanceIT(); 24269 return; 24270 } 24271 } 24272 } else { 24273 // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 24274 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24275 if (cond.Is(al)) { 24276 uint32_t imm6 = dt.GetSize() - imm; 24277 EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) | 24278 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24279 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24280 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24281 return; 24282 } 24283 } 24284 // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1 24285 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24286 if (cond.Is(al)) { 24287 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24288 rm.Encode(5, 0)); 24289 return; 24290 } 24291 } 24292 } 24293 } 24294 } 24295 Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand); 24296 } 24297 24298 void Assembler::vshr(Condition cond, 24299 DataType dt, 24300 QRegister rd, 24301 QRegister rm, 24302 const QOperand& operand) { 24303 VIXL_ASSERT(AllowAssembler()); 24304 CheckIT(cond); 24305 if (operand.IsImmediate()) { 24306 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24307 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24308 Dt_L_imm6_1 encoded_dt(dt); 24309 if (IsUsingT32()) { 24310 // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 24311 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24312 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24313 uint32_t imm6 = dt.GetSize() - imm; 24314 EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) | 24315 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24316 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24317 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24318 AdvanceIT(); 24319 return; 24320 } 24321 } 24322 // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1 24323 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24324 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24325 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24326 rm.Encode(5, 0)); 24327 AdvanceIT(); 24328 return; 24329 } 24330 } 24331 } else { 24332 // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 24333 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24334 if (cond.Is(al)) { 24335 uint32_t imm6 = dt.GetSize() - imm; 24336 EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) | 24337 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24338 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24339 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24340 return; 24341 } 24342 } 24343 // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1 24344 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) { 24345 if (cond.Is(al)) { 24346 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) | 24347 rm.Encode(5, 0)); 24348 return; 24349 } 24350 } 24351 } 24352 } 24353 } 24354 Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand); 24355 } 24356 24357 void Assembler::vshrn(Condition cond, 24358 DataType dt, 24359 DRegister rd, 24360 QRegister rm, 24361 const QOperand& operand) { 24362 VIXL_ASSERT(AllowAssembler()); 24363 CheckIT(cond); 24364 if (operand.IsImmediate()) { 24365 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24366 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24367 Dt_imm6_3 encoded_dt(dt); 24368 Dt_size_3 encoded_dt_2(dt); 24369 if (IsUsingT32()) { 24370 // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 24371 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 24372 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24373 uint32_t imm6 = dt.GetSize() / 2 - imm; 24374 EmitT32_32(0xef800810U | 24375 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24376 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24377 AdvanceIT(); 24378 return; 24379 } 24380 } 24381 // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1 24382 if (encoded_dt_2.IsValid() && (imm == 0)) { 24383 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24384 EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) | 24385 rd.Encode(22, 12) | rm.Encode(5, 0)); 24386 AdvanceIT(); 24387 return; 24388 } 24389 } 24390 } else { 24391 // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 24392 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) { 24393 if (cond.Is(al)) { 24394 uint32_t imm6 = dt.GetSize() / 2 - imm; 24395 EmitA32(0xf2800810U | 24396 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24397 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24398 return; 24399 } 24400 } 24401 // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1 24402 if (encoded_dt_2.IsValid() && (imm == 0)) { 24403 if (cond.Is(al)) { 24404 EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) | 24405 rd.Encode(22, 12) | rm.Encode(5, 0)); 24406 return; 24407 } 24408 } 24409 } 24410 } 24411 } 24412 Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand); 24413 } 24414 24415 void Assembler::vsli(Condition cond, 24416 DataType dt, 24417 DRegister rd, 24418 DRegister rm, 24419 const DOperand& operand) { 24420 VIXL_ASSERT(AllowAssembler()); 24421 CheckIT(cond); 24422 if (operand.IsImmediate()) { 24423 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24424 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24425 Dt_L_imm6_4 encoded_dt(dt); 24426 if (IsUsingT32()) { 24427 // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1 24428 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 24429 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24430 uint32_t imm6 = imm; 24431 EmitT32_32(0xff800510U | 24432 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24433 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24434 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24435 AdvanceIT(); 24436 return; 24437 } 24438 } 24439 } else { 24440 // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1 24441 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 24442 if (cond.Is(al)) { 24443 uint32_t imm6 = imm; 24444 EmitA32(0xf3800510U | 24445 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24446 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24447 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24448 return; 24449 } 24450 } 24451 } 24452 } 24453 } 24454 Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand); 24455 } 24456 24457 void Assembler::vsli(Condition cond, 24458 DataType dt, 24459 QRegister rd, 24460 QRegister rm, 24461 const QOperand& operand) { 24462 VIXL_ASSERT(AllowAssembler()); 24463 CheckIT(cond); 24464 if (operand.IsImmediate()) { 24465 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24466 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24467 Dt_L_imm6_4 encoded_dt(dt); 24468 if (IsUsingT32()) { 24469 // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1 24470 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 24471 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24472 uint32_t imm6 = imm; 24473 EmitT32_32(0xff800550U | 24474 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24475 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24476 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24477 AdvanceIT(); 24478 return; 24479 } 24480 } 24481 } else { 24482 // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1 24483 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) { 24484 if (cond.Is(al)) { 24485 uint32_t imm6 = imm; 24486 EmitA32(0xf3800550U | 24487 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24488 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24489 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24490 return; 24491 } 24492 } 24493 } 24494 } 24495 } 24496 Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand); 24497 } 24498 24499 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) { 24500 VIXL_ASSERT(AllowAssembler()); 24501 CheckIT(cond); 24502 if (IsUsingT32()) { 24503 // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1 24504 if (dt.Is(F32)) { 24505 EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24506 AdvanceIT(); 24507 return; 24508 } 24509 } else { 24510 // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1 24511 if (dt.Is(F32) && cond.IsNotNever()) { 24512 EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24513 rm.Encode(5, 0)); 24514 return; 24515 } 24516 } 24517 Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm); 24518 } 24519 24520 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) { 24521 VIXL_ASSERT(AllowAssembler()); 24522 CheckIT(cond); 24523 if (IsUsingT32()) { 24524 // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1 24525 if (dt.Is(F64)) { 24526 EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); 24527 AdvanceIT(); 24528 return; 24529 } 24530 } else { 24531 // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1 24532 if (dt.Is(F64) && cond.IsNotNever()) { 24533 EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 24534 rm.Encode(5, 0)); 24535 return; 24536 } 24537 } 24538 Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm); 24539 } 24540 24541 void Assembler::vsra(Condition cond, 24542 DataType dt, 24543 DRegister rd, 24544 DRegister rm, 24545 const DOperand& operand) { 24546 VIXL_ASSERT(AllowAssembler()); 24547 CheckIT(cond); 24548 if (operand.IsImmediate()) { 24549 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24550 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24551 Dt_L_imm6_1 encoded_dt(dt); 24552 if (IsUsingT32()) { 24553 // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 24554 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24555 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24556 uint32_t imm6 = dt.GetSize() - imm; 24557 EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) | 24558 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24559 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24560 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24561 AdvanceIT(); 24562 return; 24563 } 24564 } 24565 } else { 24566 // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 24567 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24568 if (cond.Is(al)) { 24569 uint32_t imm6 = dt.GetSize() - imm; 24570 EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) | 24571 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24572 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24573 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24574 return; 24575 } 24576 } 24577 } 24578 } 24579 } 24580 Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand); 24581 } 24582 24583 void Assembler::vsra(Condition cond, 24584 DataType dt, 24585 QRegister rd, 24586 QRegister rm, 24587 const QOperand& operand) { 24588 VIXL_ASSERT(AllowAssembler()); 24589 CheckIT(cond); 24590 if (operand.IsImmediate()) { 24591 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24592 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24593 Dt_L_imm6_1 encoded_dt(dt); 24594 if (IsUsingT32()) { 24595 // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 24596 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24597 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24598 uint32_t imm6 = dt.GetSize() - imm; 24599 EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) | 24600 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24601 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24602 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24603 AdvanceIT(); 24604 return; 24605 } 24606 } 24607 } else { 24608 // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 24609 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24610 if (cond.Is(al)) { 24611 uint32_t imm6 = dt.GetSize() - imm; 24612 EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) | 24613 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24614 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24615 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24616 return; 24617 } 24618 } 24619 } 24620 } 24621 } 24622 Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand); 24623 } 24624 24625 void Assembler::vsri(Condition cond, 24626 DataType dt, 24627 DRegister rd, 24628 DRegister rm, 24629 const DOperand& operand) { 24630 VIXL_ASSERT(AllowAssembler()); 24631 CheckIT(cond); 24632 if (operand.IsImmediate()) { 24633 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24634 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24635 Dt_L_imm6_4 encoded_dt(dt); 24636 if (IsUsingT32()) { 24637 // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1 24638 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24639 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24640 uint32_t imm6 = dt.GetSize() - imm; 24641 EmitT32_32(0xff800410U | 24642 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24643 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24644 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24645 AdvanceIT(); 24646 return; 24647 } 24648 } 24649 } else { 24650 // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1 24651 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24652 if (cond.Is(al)) { 24653 uint32_t imm6 = dt.GetSize() - imm; 24654 EmitA32(0xf3800410U | 24655 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24656 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24657 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24658 return; 24659 } 24660 } 24661 } 24662 } 24663 } 24664 Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand); 24665 } 24666 24667 void Assembler::vsri(Condition cond, 24668 DataType dt, 24669 QRegister rd, 24670 QRegister rm, 24671 const QOperand& operand) { 24672 VIXL_ASSERT(AllowAssembler()); 24673 CheckIT(cond); 24674 if (operand.IsImmediate()) { 24675 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) { 24676 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>(); 24677 Dt_L_imm6_4 encoded_dt(dt); 24678 if (IsUsingT32()) { 24679 // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1 24680 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24681 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24682 uint32_t imm6 = dt.GetSize() - imm; 24683 EmitT32_32(0xff800450U | 24684 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24685 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24686 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24687 AdvanceIT(); 24688 return; 24689 } 24690 } 24691 } else { 24692 // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1 24693 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) { 24694 if (cond.Is(al)) { 24695 uint32_t imm6 = dt.GetSize() - imm; 24696 EmitA32(0xf3800450U | 24697 ((encoded_dt.GetEncodingValue() & 0x7) << 19) | 24698 ((encoded_dt.GetEncodingValue() & 0x8) << 4) | 24699 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16)); 24700 return; 24701 } 24702 } 24703 } 24704 } 24705 } 24706 Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand); 24707 } 24708 24709 void Assembler::vst1(Condition cond, 24710 DataType dt, 24711 const NeonRegisterList& nreglist, 24712 const AlignedMemOperand& operand) { 24713 VIXL_ASSERT(AllowAssembler()); 24714 CheckIT(cond); 24715 if (operand.IsImmediateZero()) { 24716 Register rn = operand.GetBaseRegister(); 24717 Alignment align = operand.GetAlignment(); 24718 Dt_size_6 encoded_dt(dt); 24719 Dt_size_7 encoded_dt_2(dt); 24720 Align_align_5 encoded_align_1(align, nreglist); 24721 Align_index_align_1 encoded_align_2(align, nreglist, dt); 24722 if (IsUsingT32()) { 24723 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 24724 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 24725 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 24726 operand.IsOffset() && encoded_align_1.IsValid() && 24727 (!rn.IsPC() || AllowUnpredictable())) { 24728 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24729 const DRegister& first = nreglist.GetFirstDRegister(); 24730 uint32_t len_encoding; 24731 switch (nreglist.GetLength()) { 24732 default: 24733 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 24734 case 1: 24735 len_encoding = 0x7; 24736 break; 24737 case 2: 24738 len_encoding = 0xa; 24739 break; 24740 case 3: 24741 len_encoding = 0x6; 24742 break; 24743 case 4: 24744 len_encoding = 0x2; 24745 break; 24746 } 24747 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 24748 (encoded_align_1.GetEncodingValue() << 4) | 24749 first.Encode(22, 12) | (len_encoding << 8) | 24750 (rn.GetCode() << 16)); 24751 AdvanceIT(); 24752 return; 24753 } 24754 } 24755 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 24756 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 24757 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 24758 operand.IsPostIndex() && encoded_align_1.IsValid() && 24759 (!rn.IsPC() || AllowUnpredictable())) { 24760 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24761 const DRegister& first = nreglist.GetFirstDRegister(); 24762 uint32_t len_encoding; 24763 switch (nreglist.GetLength()) { 24764 default: 24765 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 24766 case 1: 24767 len_encoding = 0x7; 24768 break; 24769 case 2: 24770 len_encoding = 0xa; 24771 break; 24772 case 3: 24773 len_encoding = 0x6; 24774 break; 24775 case 4: 24776 len_encoding = 0x2; 24777 break; 24778 } 24779 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 24780 (encoded_align_1.GetEncodingValue() << 4) | 24781 first.Encode(22, 12) | (len_encoding << 8) | 24782 (rn.GetCode() << 16)); 24783 AdvanceIT(); 24784 return; 24785 } 24786 } 24787 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 24788 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 24789 (nreglist.GetLength() == 1) && operand.IsOffset() && 24790 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 24791 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24792 const DRegister& first = nreglist.GetFirstDRegister(); 24793 EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) | 24794 (encoded_align_2.GetEncodingValue() << 4) | 24795 first.Encode(22, 12) | (rn.GetCode() << 16)); 24796 AdvanceIT(); 24797 return; 24798 } 24799 } 24800 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 24801 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 24802 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 24803 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 24804 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24805 const DRegister& first = nreglist.GetFirstDRegister(); 24806 EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) | 24807 (encoded_align_2.GetEncodingValue() << 4) | 24808 first.Encode(22, 12) | (rn.GetCode() << 16)); 24809 AdvanceIT(); 24810 return; 24811 } 24812 } 24813 } else { 24814 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 24815 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 24816 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 24817 operand.IsOffset() && encoded_align_1.IsValid() && 24818 (!rn.IsPC() || AllowUnpredictable())) { 24819 if (cond.Is(al)) { 24820 const DRegister& first = nreglist.GetFirstDRegister(); 24821 uint32_t len_encoding; 24822 switch (nreglist.GetLength()) { 24823 default: 24824 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 24825 case 1: 24826 len_encoding = 0x7; 24827 break; 24828 case 2: 24829 len_encoding = 0xa; 24830 break; 24831 case 3: 24832 len_encoding = 0x6; 24833 break; 24834 case 4: 24835 len_encoding = 0x2; 24836 break; 24837 } 24838 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 24839 (encoded_align_1.GetEncodingValue() << 4) | 24840 first.Encode(22, 12) | (len_encoding << 8) | 24841 (rn.GetCode() << 16)); 24842 return; 24843 } 24844 } 24845 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 24846 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 24847 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 24848 operand.IsPostIndex() && encoded_align_1.IsValid() && 24849 (!rn.IsPC() || AllowUnpredictable())) { 24850 if (cond.Is(al)) { 24851 const DRegister& first = nreglist.GetFirstDRegister(); 24852 uint32_t len_encoding; 24853 switch (nreglist.GetLength()) { 24854 default: 24855 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 24856 case 1: 24857 len_encoding = 0x7; 24858 break; 24859 case 2: 24860 len_encoding = 0xa; 24861 break; 24862 case 3: 24863 len_encoding = 0x6; 24864 break; 24865 case 4: 24866 len_encoding = 0x2; 24867 break; 24868 } 24869 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 24870 (encoded_align_1.GetEncodingValue() << 4) | 24871 first.Encode(22, 12) | (len_encoding << 8) | 24872 (rn.GetCode() << 16)); 24873 return; 24874 } 24875 } 24876 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 24877 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 24878 (nreglist.GetLength() == 1) && operand.IsOffset() && 24879 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 24880 if (cond.Is(al)) { 24881 const DRegister& first = nreglist.GetFirstDRegister(); 24882 EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) | 24883 (encoded_align_2.GetEncodingValue() << 4) | 24884 first.Encode(22, 12) | (rn.GetCode() << 16)); 24885 return; 24886 } 24887 } 24888 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 24889 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 24890 (nreglist.GetLength() == 1) && operand.IsPostIndex() && 24891 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) { 24892 if (cond.Is(al)) { 24893 const DRegister& first = nreglist.GetFirstDRegister(); 24894 EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) | 24895 (encoded_align_2.GetEncodingValue() << 4) | 24896 first.Encode(22, 12) | (rn.GetCode() << 16)); 24897 return; 24898 } 24899 } 24900 } 24901 } 24902 if (operand.IsPlainRegister()) { 24903 Register rn = operand.GetBaseRegister(); 24904 Alignment align = operand.GetAlignment(); 24905 Register rm = operand.GetOffsetRegister(); 24906 Dt_size_6 encoded_dt(dt); 24907 Dt_size_7 encoded_dt_2(dt); 24908 Align_align_5 encoded_align_1(align, nreglist); 24909 Align_index_align_1 encoded_align_2(align, nreglist, dt); 24910 if (IsUsingT32()) { 24911 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 24912 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 24913 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 24914 !rm.IsPC() && !rm.IsSP()) { 24915 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24916 const DRegister& first = nreglist.GetFirstDRegister(); 24917 uint32_t len_encoding; 24918 switch (nreglist.GetLength()) { 24919 default: 24920 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 24921 case 1: 24922 len_encoding = 0x7; 24923 break; 24924 case 2: 24925 len_encoding = 0xa; 24926 break; 24927 case 3: 24928 len_encoding = 0x6; 24929 break; 24930 case 4: 24931 len_encoding = 0x2; 24932 break; 24933 } 24934 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 24935 (encoded_align_1.GetEncodingValue() << 4) | 24936 first.Encode(22, 12) | (len_encoding << 8) | 24937 (rn.GetCode() << 16) | rm.GetCode()); 24938 AdvanceIT(); 24939 return; 24940 } 24941 } 24942 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 24943 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 24944 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) { 24945 if (cond.Is(al) || AllowStronglyDiscouraged()) { 24946 const DRegister& first = nreglist.GetFirstDRegister(); 24947 EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) | 24948 (encoded_align_2.GetEncodingValue() << 4) | 24949 first.Encode(22, 12) | (rn.GetCode() << 16) | 24950 rm.GetCode()); 24951 AdvanceIT(); 24952 return; 24953 } 24954 } 24955 } else { 24956 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 24957 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 24958 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) && 24959 !rm.IsPC() && !rm.IsSP()) { 24960 if (cond.Is(al)) { 24961 const DRegister& first = nreglist.GetFirstDRegister(); 24962 uint32_t len_encoding; 24963 switch (nreglist.GetLength()) { 24964 default: 24965 VIXL_UNREACHABLE_OR_FALLTHROUGH(); 24966 case 1: 24967 len_encoding = 0x7; 24968 break; 24969 case 2: 24970 len_encoding = 0xa; 24971 break; 24972 case 3: 24973 len_encoding = 0x6; 24974 break; 24975 case 4: 24976 len_encoding = 0x2; 24977 break; 24978 } 24979 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 24980 (encoded_align_1.GetEncodingValue() << 4) | 24981 first.Encode(22, 12) | (len_encoding << 8) | 24982 (rn.GetCode() << 16) | rm.GetCode()); 24983 return; 24984 } 24985 } 24986 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 24987 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() && 24988 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) { 24989 if (cond.Is(al)) { 24990 const DRegister& first = nreglist.GetFirstDRegister(); 24991 EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) | 24992 (encoded_align_2.GetEncodingValue() << 4) | 24993 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 24994 return; 24995 } 24996 } 24997 } 24998 } 24999 Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand); 25000 } 25001 25002 void Assembler::vst2(Condition cond, 25003 DataType dt, 25004 const NeonRegisterList& nreglist, 25005 const AlignedMemOperand& operand) { 25006 VIXL_ASSERT(AllowAssembler()); 25007 CheckIT(cond); 25008 if (operand.IsImmediateZero()) { 25009 Register rn = operand.GetBaseRegister(); 25010 Alignment align = operand.GetAlignment(); 25011 Dt_size_7 encoded_dt(dt); 25012 Align_align_2 encoded_align_1(align, nreglist); 25013 Align_index_align_2 encoded_align_2(align, nreglist, dt); 25014 if (IsUsingT32()) { 25015 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 25016 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25017 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25018 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 25019 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 25020 operand.IsOffset() && encoded_align_1.IsValid() && 25021 (!rn.IsPC() || AllowUnpredictable())) { 25022 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25023 const DRegister& first = nreglist.GetFirstDRegister(); 25024 uint32_t len_encoding; 25025 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 25026 len_encoding = 0x8; 25027 } 25028 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 25029 len_encoding = 0x9; 25030 } 25031 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 25032 len_encoding = 0x3; 25033 } 25034 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 25035 (encoded_align_1.GetEncodingValue() << 4) | 25036 first.Encode(22, 12) | (len_encoding << 8) | 25037 (rn.GetCode() << 16)); 25038 AdvanceIT(); 25039 return; 25040 } 25041 } 25042 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 25043 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25044 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25045 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 25046 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 25047 operand.IsPostIndex() && encoded_align_1.IsValid() && 25048 (!rn.IsPC() || AllowUnpredictable())) { 25049 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25050 const DRegister& first = nreglist.GetFirstDRegister(); 25051 uint32_t len_encoding; 25052 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 25053 len_encoding = 0x8; 25054 } 25055 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 25056 len_encoding = 0x9; 25057 } 25058 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 25059 len_encoding = 0x3; 25060 } 25061 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 25062 (encoded_align_1.GetEncodingValue() << 4) | 25063 first.Encode(22, 12) | (len_encoding << 8) | 25064 (rn.GetCode() << 16)); 25065 AdvanceIT(); 25066 return; 25067 } 25068 } 25069 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 25070 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25071 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25072 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 25073 operand.IsOffset() && encoded_align_2.IsValid() && 25074 (!rn.IsPC() || AllowUnpredictable())) { 25075 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25076 const DRegister& first = nreglist.GetFirstDRegister(); 25077 EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) | 25078 (encoded_align_2.GetEncodingValue() << 4) | 25079 first.Encode(22, 12) | (rn.GetCode() << 16)); 25080 AdvanceIT(); 25081 return; 25082 } 25083 } 25084 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 25085 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25086 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25087 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 25088 operand.IsPostIndex() && encoded_align_2.IsValid() && 25089 (!rn.IsPC() || AllowUnpredictable())) { 25090 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25091 const DRegister& first = nreglist.GetFirstDRegister(); 25092 EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) | 25093 (encoded_align_2.GetEncodingValue() << 4) | 25094 first.Encode(22, 12) | (rn.GetCode() << 16)); 25095 AdvanceIT(); 25096 return; 25097 } 25098 } 25099 } else { 25100 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 25101 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25102 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25103 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 25104 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 25105 operand.IsOffset() && encoded_align_1.IsValid() && 25106 (!rn.IsPC() || AllowUnpredictable())) { 25107 if (cond.Is(al)) { 25108 const DRegister& first = nreglist.GetFirstDRegister(); 25109 uint32_t len_encoding; 25110 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 25111 len_encoding = 0x8; 25112 } 25113 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 25114 len_encoding = 0x9; 25115 } 25116 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 25117 len_encoding = 0x3; 25118 } 25119 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 25120 (encoded_align_1.GetEncodingValue() << 4) | 25121 first.Encode(22, 12) | (len_encoding << 8) | 25122 (rn.GetCode() << 16)); 25123 return; 25124 } 25125 } 25126 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 25127 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25128 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25129 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 25130 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 25131 operand.IsPostIndex() && encoded_align_1.IsValid() && 25132 (!rn.IsPC() || AllowUnpredictable())) { 25133 if (cond.Is(al)) { 25134 const DRegister& first = nreglist.GetFirstDRegister(); 25135 uint32_t len_encoding; 25136 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 25137 len_encoding = 0x8; 25138 } 25139 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 25140 len_encoding = 0x9; 25141 } 25142 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 25143 len_encoding = 0x3; 25144 } 25145 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 25146 (encoded_align_1.GetEncodingValue() << 4) | 25147 first.Encode(22, 12) | (len_encoding << 8) | 25148 (rn.GetCode() << 16)); 25149 return; 25150 } 25151 } 25152 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 25153 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25154 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25155 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 25156 operand.IsOffset() && encoded_align_2.IsValid() && 25157 (!rn.IsPC() || AllowUnpredictable())) { 25158 if (cond.Is(al)) { 25159 const DRegister& first = nreglist.GetFirstDRegister(); 25160 EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) | 25161 (encoded_align_2.GetEncodingValue() << 4) | 25162 first.Encode(22, 12) | (rn.GetCode() << 16)); 25163 return; 25164 } 25165 } 25166 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 25167 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25168 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25169 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 25170 operand.IsPostIndex() && encoded_align_2.IsValid() && 25171 (!rn.IsPC() || AllowUnpredictable())) { 25172 if (cond.Is(al)) { 25173 const DRegister& first = nreglist.GetFirstDRegister(); 25174 EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) | 25175 (encoded_align_2.GetEncodingValue() << 4) | 25176 first.Encode(22, 12) | (rn.GetCode() << 16)); 25177 return; 25178 } 25179 } 25180 } 25181 } 25182 if (operand.IsPlainRegister()) { 25183 Register rn = operand.GetBaseRegister(); 25184 Alignment align = operand.GetAlignment(); 25185 Register rm = operand.GetOffsetRegister(); 25186 Dt_size_7 encoded_dt(dt); 25187 Align_align_2 encoded_align_1(align, nreglist); 25188 Align_index_align_2 encoded_align_2(align, nreglist, dt); 25189 if (IsUsingT32()) { 25190 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 25191 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25192 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25193 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 25194 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 25195 !rm.IsPC() && !rm.IsSP()) { 25196 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25197 const DRegister& first = nreglist.GetFirstDRegister(); 25198 uint32_t len_encoding; 25199 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 25200 len_encoding = 0x8; 25201 } 25202 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 25203 len_encoding = 0x9; 25204 } 25205 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 25206 len_encoding = 0x3; 25207 } 25208 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 25209 (encoded_align_1.GetEncodingValue() << 4) | 25210 first.Encode(22, 12) | (len_encoding << 8) | 25211 (rn.GetCode() << 16) | rm.GetCode()); 25212 AdvanceIT(); 25213 return; 25214 } 25215 } 25216 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 25217 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25218 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25219 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 25220 !rm.IsPC() && !rm.IsSP()) { 25221 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25222 const DRegister& first = nreglist.GetFirstDRegister(); 25223 EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) | 25224 (encoded_align_2.GetEncodingValue() << 4) | 25225 first.Encode(22, 12) | (rn.GetCode() << 16) | 25226 rm.GetCode()); 25227 AdvanceIT(); 25228 return; 25229 } 25230 } 25231 } else { 25232 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 25233 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25234 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25235 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) || 25236 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) && 25237 !rm.IsPC() && !rm.IsSP()) { 25238 if (cond.Is(al)) { 25239 const DRegister& first = nreglist.GetFirstDRegister(); 25240 uint32_t len_encoding; 25241 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) { 25242 len_encoding = 0x8; 25243 } 25244 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) { 25245 len_encoding = 0x9; 25246 } 25247 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) { 25248 len_encoding = 0x3; 25249 } 25250 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 25251 (encoded_align_1.GetEncodingValue() << 4) | 25252 first.Encode(22, 12) | (len_encoding << 8) | 25253 (rn.GetCode() << 16) | rm.GetCode()); 25254 return; 25255 } 25256 } 25257 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 25258 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25259 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) || 25260 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) && 25261 !rm.IsPC() && !rm.IsSP()) { 25262 if (cond.Is(al)) { 25263 const DRegister& first = nreglist.GetFirstDRegister(); 25264 EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) | 25265 (encoded_align_2.GetEncodingValue() << 4) | 25266 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 25267 return; 25268 } 25269 } 25270 } 25271 } 25272 Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand); 25273 } 25274 25275 void Assembler::vst3(Condition cond, 25276 DataType dt, 25277 const NeonRegisterList& nreglist, 25278 const AlignedMemOperand& operand) { 25279 VIXL_ASSERT(AllowAssembler()); 25280 CheckIT(cond); 25281 if (operand.IsImmediateZero()) { 25282 Register rn = operand.GetBaseRegister(); 25283 Alignment align = operand.GetAlignment(); 25284 Dt_size_7 encoded_dt(dt); 25285 Align_align_3 encoded_align_1(align); 25286 if (IsUsingT32()) { 25287 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 25288 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25289 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25290 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25291 operand.IsOffset() && encoded_align_1.IsValid() && 25292 (!rn.IsPC() || AllowUnpredictable())) { 25293 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25294 const DRegister& first = nreglist.GetFirstDRegister(); 25295 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 25296 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 25297 (encoded_align_1.GetEncodingValue() << 4) | 25298 first.Encode(22, 12) | (len_encoding << 8) | 25299 (rn.GetCode() << 16)); 25300 AdvanceIT(); 25301 return; 25302 } 25303 } 25304 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 25305 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25306 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25307 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25308 operand.IsPostIndex() && encoded_align_1.IsValid() && 25309 (!rn.IsPC() || AllowUnpredictable())) { 25310 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25311 const DRegister& first = nreglist.GetFirstDRegister(); 25312 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 25313 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 25314 (encoded_align_1.GetEncodingValue() << 4) | 25315 first.Encode(22, 12) | (len_encoding << 8) | 25316 (rn.GetCode() << 16)); 25317 AdvanceIT(); 25318 return; 25319 } 25320 } 25321 } else { 25322 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 25323 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25324 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25325 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25326 operand.IsOffset() && encoded_align_1.IsValid() && 25327 (!rn.IsPC() || AllowUnpredictable())) { 25328 if (cond.Is(al)) { 25329 const DRegister& first = nreglist.GetFirstDRegister(); 25330 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 25331 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 25332 (encoded_align_1.GetEncodingValue() << 4) | 25333 first.Encode(22, 12) | (len_encoding << 8) | 25334 (rn.GetCode() << 16)); 25335 return; 25336 } 25337 } 25338 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 25339 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25340 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25341 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25342 operand.IsPostIndex() && encoded_align_1.IsValid() && 25343 (!rn.IsPC() || AllowUnpredictable())) { 25344 if (cond.Is(al)) { 25345 const DRegister& first = nreglist.GetFirstDRegister(); 25346 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 25347 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 25348 (encoded_align_1.GetEncodingValue() << 4) | 25349 first.Encode(22, 12) | (len_encoding << 8) | 25350 (rn.GetCode() << 16)); 25351 return; 25352 } 25353 } 25354 } 25355 } 25356 if (operand.IsPlainRegister()) { 25357 Register rn = operand.GetBaseRegister(); 25358 Alignment align = operand.GetAlignment(); 25359 Register rm = operand.GetOffsetRegister(); 25360 Dt_size_7 encoded_dt(dt); 25361 Align_align_3 encoded_align_1(align); 25362 if (IsUsingT32()) { 25363 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 25364 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25365 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25366 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25367 !rm.IsPC() && !rm.IsSP()) { 25368 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25369 const DRegister& first = nreglist.GetFirstDRegister(); 25370 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 25371 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 25372 (encoded_align_1.GetEncodingValue() << 4) | 25373 first.Encode(22, 12) | (len_encoding << 8) | 25374 (rn.GetCode() << 16) | rm.GetCode()); 25375 AdvanceIT(); 25376 return; 25377 } 25378 } 25379 } else { 25380 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 25381 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25382 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25383 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25384 !rm.IsPC() && !rm.IsSP()) { 25385 if (cond.Is(al)) { 25386 const DRegister& first = nreglist.GetFirstDRegister(); 25387 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5; 25388 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 25389 (encoded_align_1.GetEncodingValue() << 4) | 25390 first.Encode(22, 12) | (len_encoding << 8) | 25391 (rn.GetCode() << 16) | rm.GetCode()); 25392 return; 25393 } 25394 } 25395 } 25396 } 25397 Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand); 25398 } 25399 25400 void Assembler::vst3(Condition cond, 25401 DataType dt, 25402 const NeonRegisterList& nreglist, 25403 const MemOperand& operand) { 25404 VIXL_ASSERT(AllowAssembler()); 25405 CheckIT(cond); 25406 if (operand.IsImmediateZero()) { 25407 Register rn = operand.GetBaseRegister(); 25408 Dt_size_7 encoded_dt(dt); 25409 Index_1 encoded_align_1(nreglist, dt); 25410 if (IsUsingT32()) { 25411 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 25412 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25413 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25414 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25415 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 25416 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25417 const DRegister& first = nreglist.GetFirstDRegister(); 25418 EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) | 25419 (encoded_align_1.GetEncodingValue() << 4) | 25420 first.Encode(22, 12) | (rn.GetCode() << 16)); 25421 AdvanceIT(); 25422 return; 25423 } 25424 } 25425 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 25426 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25427 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25428 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25429 operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) { 25430 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25431 const DRegister& first = nreglist.GetFirstDRegister(); 25432 EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) | 25433 (encoded_align_1.GetEncodingValue() << 4) | 25434 first.Encode(22, 12) | (rn.GetCode() << 16)); 25435 AdvanceIT(); 25436 return; 25437 } 25438 } 25439 } else { 25440 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1 25441 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25442 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25443 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25444 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) { 25445 if (cond.Is(al)) { 25446 const DRegister& first = nreglist.GetFirstDRegister(); 25447 EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) | 25448 (encoded_align_1.GetEncodingValue() << 4) | 25449 first.Encode(22, 12) | (rn.GetCode() << 16)); 25450 return; 25451 } 25452 } 25453 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1 25454 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25455 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25456 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25457 operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) { 25458 if (cond.Is(al)) { 25459 const DRegister& first = nreglist.GetFirstDRegister(); 25460 EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) | 25461 (encoded_align_1.GetEncodingValue() << 4) | 25462 first.Encode(22, 12) | (rn.GetCode() << 16)); 25463 return; 25464 } 25465 } 25466 } 25467 } 25468 if (operand.IsPlainRegister()) { 25469 Register rn = operand.GetBaseRegister(); 25470 Sign sign = operand.GetSign(); 25471 Register rm = operand.GetOffsetRegister(); 25472 Dt_size_7 encoded_dt(dt); 25473 Index_1 encoded_align_1(nreglist, dt); 25474 if (IsUsingT32()) { 25475 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 25476 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25477 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25478 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25479 sign.IsPlus() && operand.IsPostIndex()) { 25480 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25481 const DRegister& first = nreglist.GetFirstDRegister(); 25482 EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) | 25483 (encoded_align_1.GetEncodingValue() << 4) | 25484 first.Encode(22, 12) | (rn.GetCode() << 16) | 25485 rm.GetCode()); 25486 AdvanceIT(); 25487 return; 25488 } 25489 } 25490 } else { 25491 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 25492 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25493 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) || 25494 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) && 25495 sign.IsPlus() && operand.IsPostIndex()) { 25496 if (cond.Is(al)) { 25497 const DRegister& first = nreglist.GetFirstDRegister(); 25498 EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) | 25499 (encoded_align_1.GetEncodingValue() << 4) | 25500 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 25501 return; 25502 } 25503 } 25504 } 25505 } 25506 Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand); 25507 } 25508 25509 void Assembler::vst4(Condition cond, 25510 DataType dt, 25511 const NeonRegisterList& nreglist, 25512 const AlignedMemOperand& operand) { 25513 VIXL_ASSERT(AllowAssembler()); 25514 CheckIT(cond); 25515 if (operand.IsImmediateZero()) { 25516 Register rn = operand.GetBaseRegister(); 25517 Alignment align = operand.GetAlignment(); 25518 Dt_size_7 encoded_dt(dt); 25519 Align_align_4 encoded_align_1(align); 25520 Align_index_align_3 encoded_align_2(align, nreglist, dt); 25521 if (IsUsingT32()) { 25522 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 25523 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25524 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25525 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25526 operand.IsOffset() && encoded_align_1.IsValid() && 25527 (!rn.IsPC() || AllowUnpredictable())) { 25528 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25529 const DRegister& first = nreglist.GetFirstDRegister(); 25530 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 25531 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) | 25532 (encoded_align_1.GetEncodingValue() << 4) | 25533 first.Encode(22, 12) | (len_encoding << 8) | 25534 (rn.GetCode() << 16)); 25535 AdvanceIT(); 25536 return; 25537 } 25538 } 25539 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 25540 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25541 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25542 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25543 operand.IsPostIndex() && encoded_align_1.IsValid() && 25544 (!rn.IsPC() || AllowUnpredictable())) { 25545 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25546 const DRegister& first = nreglist.GetFirstDRegister(); 25547 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 25548 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) | 25549 (encoded_align_1.GetEncodingValue() << 4) | 25550 first.Encode(22, 12) | (len_encoding << 8) | 25551 (rn.GetCode() << 16)); 25552 AdvanceIT(); 25553 return; 25554 } 25555 } 25556 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 25557 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25558 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25559 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25560 operand.IsOffset() && encoded_align_2.IsValid() && 25561 (!rn.IsPC() || AllowUnpredictable())) { 25562 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25563 const DRegister& first = nreglist.GetFirstDRegister(); 25564 EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) | 25565 (encoded_align_2.GetEncodingValue() << 4) | 25566 first.Encode(22, 12) | (rn.GetCode() << 16)); 25567 AdvanceIT(); 25568 return; 25569 } 25570 } 25571 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 25572 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25573 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25574 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25575 operand.IsPostIndex() && encoded_align_2.IsValid() && 25576 (!rn.IsPC() || AllowUnpredictable())) { 25577 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25578 const DRegister& first = nreglist.GetFirstDRegister(); 25579 EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) | 25580 (encoded_align_2.GetEncodingValue() << 4) | 25581 first.Encode(22, 12) | (rn.GetCode() << 16)); 25582 AdvanceIT(); 25583 return; 25584 } 25585 } 25586 } else { 25587 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 25588 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25589 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25590 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25591 operand.IsOffset() && encoded_align_1.IsValid() && 25592 (!rn.IsPC() || AllowUnpredictable())) { 25593 if (cond.Is(al)) { 25594 const DRegister& first = nreglist.GetFirstDRegister(); 25595 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 25596 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) | 25597 (encoded_align_1.GetEncodingValue() << 4) | 25598 first.Encode(22, 12) | (len_encoding << 8) | 25599 (rn.GetCode() << 16)); 25600 return; 25601 } 25602 } 25603 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 25604 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25605 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25606 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25607 operand.IsPostIndex() && encoded_align_1.IsValid() && 25608 (!rn.IsPC() || AllowUnpredictable())) { 25609 if (cond.Is(al)) { 25610 const DRegister& first = nreglist.GetFirstDRegister(); 25611 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 25612 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) | 25613 (encoded_align_1.GetEncodingValue() << 4) | 25614 first.Encode(22, 12) | (len_encoding << 8) | 25615 (rn.GetCode() << 16)); 25616 return; 25617 } 25618 } 25619 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 25620 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25621 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25622 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25623 operand.IsOffset() && encoded_align_2.IsValid() && 25624 (!rn.IsPC() || AllowUnpredictable())) { 25625 if (cond.Is(al)) { 25626 const DRegister& first = nreglist.GetFirstDRegister(); 25627 EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) | 25628 (encoded_align_2.GetEncodingValue() << 4) | 25629 first.Encode(22, 12) | (rn.GetCode() << 16)); 25630 return; 25631 } 25632 } 25633 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 25634 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25635 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25636 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25637 operand.IsPostIndex() && encoded_align_2.IsValid() && 25638 (!rn.IsPC() || AllowUnpredictable())) { 25639 if (cond.Is(al)) { 25640 const DRegister& first = nreglist.GetFirstDRegister(); 25641 EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) | 25642 (encoded_align_2.GetEncodingValue() << 4) | 25643 first.Encode(22, 12) | (rn.GetCode() << 16)); 25644 return; 25645 } 25646 } 25647 } 25648 } 25649 if (operand.IsPlainRegister()) { 25650 Register rn = operand.GetBaseRegister(); 25651 Alignment align = operand.GetAlignment(); 25652 Register rm = operand.GetOffsetRegister(); 25653 Dt_size_7 encoded_dt(dt); 25654 Align_align_4 encoded_align_1(align); 25655 Align_index_align_3 encoded_align_2(align, nreglist, dt); 25656 if (IsUsingT32()) { 25657 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 25658 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25659 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25660 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25661 !rm.IsPC() && !rm.IsSP()) { 25662 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25663 const DRegister& first = nreglist.GetFirstDRegister(); 25664 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 25665 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) | 25666 (encoded_align_1.GetEncodingValue() << 4) | 25667 first.Encode(22, 12) | (len_encoding << 8) | 25668 (rn.GetCode() << 16) | rm.GetCode()); 25669 AdvanceIT(); 25670 return; 25671 } 25672 } 25673 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 25674 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25675 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25676 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25677 !rm.IsPC() && !rm.IsSP()) { 25678 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25679 const DRegister& first = nreglist.GetFirstDRegister(); 25680 EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) | 25681 (encoded_align_2.GetEncodingValue() << 4) | 25682 first.Encode(22, 12) | (rn.GetCode() << 16) | 25683 rm.GetCode()); 25684 AdvanceIT(); 25685 return; 25686 } 25687 } 25688 } else { 25689 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 25690 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() && 25691 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25692 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25693 !rm.IsPC() && !rm.IsSP()) { 25694 if (cond.Is(al)) { 25695 const DRegister& first = nreglist.GetFirstDRegister(); 25696 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1; 25697 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) | 25698 (encoded_align_1.GetEncodingValue() << 4) | 25699 first.Encode(22, 12) | (len_encoding << 8) | 25700 (rn.GetCode() << 16) | rm.GetCode()); 25701 return; 25702 } 25703 } 25704 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 25705 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() && 25706 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) || 25707 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) && 25708 !rm.IsPC() && !rm.IsSP()) { 25709 if (cond.Is(al)) { 25710 const DRegister& first = nreglist.GetFirstDRegister(); 25711 EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) | 25712 (encoded_align_2.GetEncodingValue() << 4) | 25713 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode()); 25714 return; 25715 } 25716 } 25717 } 25718 } 25719 Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand); 25720 } 25721 25722 void Assembler::vstm(Condition cond, 25723 DataType dt, 25724 Register rn, 25725 WriteBack write_back, 25726 DRegisterList dreglist) { 25727 VIXL_ASSERT(AllowAssembler()); 25728 CheckIT(cond); 25729 USE(dt); 25730 if (IsUsingT32()) { 25731 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 25732 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 25733 const DRegister& dreg = dreglist.GetFirstDRegister(); 25734 unsigned len = dreglist.GetLength() * 2; 25735 EmitT32_32(0xec800b00U | (rn.GetCode() << 16) | 25736 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 25737 (len & 0xff)); 25738 AdvanceIT(); 25739 return; 25740 } 25741 } else { 25742 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 25743 if (cond.IsNotNever() && 25744 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 25745 const DRegister& dreg = dreglist.GetFirstDRegister(); 25746 unsigned len = dreglist.GetLength() * 2; 25747 EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 25748 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 25749 (len & 0xff)); 25750 return; 25751 } 25752 } 25753 Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist); 25754 } 25755 25756 void Assembler::vstm(Condition cond, 25757 DataType dt, 25758 Register rn, 25759 WriteBack write_back, 25760 SRegisterList sreglist) { 25761 VIXL_ASSERT(AllowAssembler()); 25762 CheckIT(cond); 25763 USE(dt); 25764 if (IsUsingT32()) { 25765 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 25766 const SRegister& sreg = sreglist.GetFirstSRegister(); 25767 unsigned len = sreglist.GetLength(); 25768 EmitT32_32(0xec800a00U | (rn.GetCode() << 16) | 25769 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 25770 (len & 0xff)); 25771 AdvanceIT(); 25772 return; 25773 } else { 25774 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 25775 if (cond.IsNotNever()) { 25776 const SRegister& sreg = sreglist.GetFirstSRegister(); 25777 unsigned len = sreglist.GetLength(); 25778 EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 25779 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 25780 (len & 0xff)); 25781 return; 25782 } 25783 } 25784 Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist); 25785 } 25786 25787 void Assembler::vstmdb(Condition cond, 25788 DataType dt, 25789 Register rn, 25790 WriteBack write_back, 25791 DRegisterList dreglist) { 25792 VIXL_ASSERT(AllowAssembler()); 25793 CheckIT(cond); 25794 USE(dt); 25795 if (IsUsingT32()) { 25796 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1 25797 if (write_back.DoesWriteBack() && 25798 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 25799 const DRegister& dreg = dreglist.GetFirstDRegister(); 25800 unsigned len = dreglist.GetLength() * 2; 25801 EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) | 25802 (len & 0xff)); 25803 AdvanceIT(); 25804 return; 25805 } 25806 } else { 25807 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1 25808 if (write_back.DoesWriteBack() && cond.IsNotNever() && 25809 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 25810 const DRegister& dreg = dreglist.GetFirstDRegister(); 25811 unsigned len = dreglist.GetLength() * 2; 25812 EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 25813 dreg.Encode(22, 12) | (len & 0xff)); 25814 return; 25815 } 25816 } 25817 Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist); 25818 } 25819 25820 void Assembler::vstmdb(Condition cond, 25821 DataType dt, 25822 Register rn, 25823 WriteBack write_back, 25824 SRegisterList sreglist) { 25825 VIXL_ASSERT(AllowAssembler()); 25826 CheckIT(cond); 25827 USE(dt); 25828 if (IsUsingT32()) { 25829 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2 25830 if (write_back.DoesWriteBack()) { 25831 const SRegister& sreg = sreglist.GetFirstSRegister(); 25832 unsigned len = sreglist.GetLength(); 25833 EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) | 25834 (len & 0xff)); 25835 AdvanceIT(); 25836 return; 25837 } 25838 } else { 25839 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2 25840 if (write_back.DoesWriteBack() && cond.IsNotNever()) { 25841 const SRegister& sreg = sreglist.GetFirstSRegister(); 25842 unsigned len = sreglist.GetLength(); 25843 EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 25844 sreg.Encode(22, 12) | (len & 0xff)); 25845 return; 25846 } 25847 } 25848 Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist); 25849 } 25850 25851 void Assembler::vstmia(Condition cond, 25852 DataType dt, 25853 Register rn, 25854 WriteBack write_back, 25855 DRegisterList dreglist) { 25856 VIXL_ASSERT(AllowAssembler()); 25857 CheckIT(cond); 25858 USE(dt); 25859 if (IsUsingT32()) { 25860 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1 25861 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 25862 const DRegister& dreg = dreglist.GetFirstDRegister(); 25863 unsigned len = dreglist.GetLength() * 2; 25864 EmitT32_32(0xec800b00U | (rn.GetCode() << 16) | 25865 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 25866 (len & 0xff)); 25867 AdvanceIT(); 25868 return; 25869 } 25870 } else { 25871 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1 25872 if (cond.IsNotNever() && 25873 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) { 25874 const DRegister& dreg = dreglist.GetFirstDRegister(); 25875 unsigned len = dreglist.GetLength() * 2; 25876 EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 25877 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) | 25878 (len & 0xff)); 25879 return; 25880 } 25881 } 25882 Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist); 25883 } 25884 25885 void Assembler::vstmia(Condition cond, 25886 DataType dt, 25887 Register rn, 25888 WriteBack write_back, 25889 SRegisterList sreglist) { 25890 VIXL_ASSERT(AllowAssembler()); 25891 CheckIT(cond); 25892 USE(dt); 25893 if (IsUsingT32()) { 25894 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2 25895 const SRegister& sreg = sreglist.GetFirstSRegister(); 25896 unsigned len = sreglist.GetLength(); 25897 EmitT32_32(0xec800a00U | (rn.GetCode() << 16) | 25898 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 25899 (len & 0xff)); 25900 AdvanceIT(); 25901 return; 25902 } else { 25903 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2 25904 if (cond.IsNotNever()) { 25905 const SRegister& sreg = sreglist.GetFirstSRegister(); 25906 unsigned len = sreglist.GetLength(); 25907 EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) | 25908 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) | 25909 (len & 0xff)); 25910 return; 25911 } 25912 } 25913 Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist); 25914 } 25915 25916 void Assembler::vstr(Condition cond, 25917 DataType dt, 25918 DRegister rd, 25919 const MemOperand& operand) { 25920 VIXL_ASSERT(AllowAssembler()); 25921 CheckIT(cond); 25922 if (operand.IsImmediate()) { 25923 Register rn = operand.GetBaseRegister(); 25924 int32_t offset = operand.GetOffsetImmediate(); 25925 if (IsUsingT32()) { 25926 // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1 25927 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 25928 ((offset % 4) == 0) && operand.IsOffset()) { 25929 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 25930 uint32_t offset_ = abs(offset) >> 2; 25931 EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 25932 offset_ | (sign << 23)); 25933 AdvanceIT(); 25934 return; 25935 } 25936 } else { 25937 // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1 25938 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) && 25939 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) { 25940 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 25941 uint32_t offset_ = abs(offset) >> 2; 25942 EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 25943 (rn.GetCode() << 16) | offset_ | (sign << 23)); 25944 return; 25945 } 25946 } 25947 } 25948 Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand); 25949 } 25950 25951 void Assembler::vstr(Condition cond, 25952 DataType dt, 25953 SRegister rd, 25954 const MemOperand& operand) { 25955 VIXL_ASSERT(AllowAssembler()); 25956 CheckIT(cond); 25957 if (operand.IsImmediate()) { 25958 Register rn = operand.GetBaseRegister(); 25959 int32_t offset = operand.GetOffsetImmediate(); 25960 if (IsUsingT32()) { 25961 // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2 25962 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 25963 ((offset % 4) == 0) && operand.IsOffset()) { 25964 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 25965 uint32_t offset_ = abs(offset) >> 2; 25966 EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) | 25967 offset_ | (sign << 23)); 25968 AdvanceIT(); 25969 return; 25970 } 25971 } else { 25972 // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2 25973 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) && 25974 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) { 25975 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0; 25976 uint32_t offset_ = abs(offset) >> 2; 25977 EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 25978 (rn.GetCode() << 16) | offset_ | (sign << 23)); 25979 return; 25980 } 25981 } 25982 } 25983 Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand); 25984 } 25985 25986 void Assembler::vsub( 25987 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 25988 VIXL_ASSERT(AllowAssembler()); 25989 CheckIT(cond); 25990 Dt_size_2 encoded_dt(dt); 25991 if (IsUsingT32()) { 25992 // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1 25993 if (dt.Is(F32)) { 25994 if (cond.Is(al) || AllowStronglyDiscouraged()) { 25995 EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 25996 rm.Encode(5, 0)); 25997 AdvanceIT(); 25998 return; 25999 } 26000 } 26001 // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2 26002 if (dt.Is(F64)) { 26003 EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 26004 rm.Encode(5, 0)); 26005 AdvanceIT(); 26006 return; 26007 } 26008 // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 26009 if (encoded_dt.IsValid()) { 26010 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26011 EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) | 26012 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26013 AdvanceIT(); 26014 return; 26015 } 26016 } 26017 } else { 26018 // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1 26019 if (dt.Is(F32)) { 26020 if (cond.Is(al)) { 26021 EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) | 26022 rm.Encode(5, 0)); 26023 return; 26024 } 26025 } 26026 // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2 26027 if (dt.Is(F64) && cond.IsNotNever()) { 26028 EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 26029 rn.Encode(7, 16) | rm.Encode(5, 0)); 26030 return; 26031 } 26032 // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 26033 if (encoded_dt.IsValid()) { 26034 if (cond.Is(al)) { 26035 EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) | 26036 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26037 return; 26038 } 26039 } 26040 } 26041 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 26042 } 26043 26044 void Assembler::vsub( 26045 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 26046 VIXL_ASSERT(AllowAssembler()); 26047 CheckIT(cond); 26048 Dt_size_2 encoded_dt(dt); 26049 if (IsUsingT32()) { 26050 // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1 26051 if (dt.Is(F32)) { 26052 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26053 EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 26054 rm.Encode(5, 0)); 26055 AdvanceIT(); 26056 return; 26057 } 26058 } 26059 // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 26060 if (encoded_dt.IsValid()) { 26061 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26062 EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) | 26063 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26064 AdvanceIT(); 26065 return; 26066 } 26067 } 26068 } else { 26069 // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1 26070 if (dt.Is(F32)) { 26071 if (cond.Is(al)) { 26072 EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 26073 rm.Encode(5, 0)); 26074 return; 26075 } 26076 } 26077 // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 26078 if (encoded_dt.IsValid()) { 26079 if (cond.Is(al)) { 26080 EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) | 26081 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26082 return; 26083 } 26084 } 26085 } 26086 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 26087 } 26088 26089 void Assembler::vsub( 26090 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) { 26091 VIXL_ASSERT(AllowAssembler()); 26092 CheckIT(cond); 26093 if (IsUsingT32()) { 26094 // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2 26095 if (dt.Is(F32)) { 26096 EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) | 26097 rm.Encode(5, 0)); 26098 AdvanceIT(); 26099 return; 26100 } 26101 } else { 26102 // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2 26103 if (dt.Is(F32) && cond.IsNotNever()) { 26104 EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | 26105 rn.Encode(7, 16) | rm.Encode(5, 0)); 26106 return; 26107 } 26108 } 26109 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm); 26110 } 26111 26112 void Assembler::vsubhn( 26113 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) { 26114 VIXL_ASSERT(AllowAssembler()); 26115 CheckIT(cond); 26116 Dt_size_3 encoded_dt(dt); 26117 if (IsUsingT32()) { 26118 // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 26119 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 26120 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26121 EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) | 26122 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26123 AdvanceIT(); 26124 return; 26125 } 26126 } 26127 } else { 26128 // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1 26129 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) { 26130 if (cond.Is(al)) { 26131 EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) | 26132 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26133 return; 26134 } 26135 } 26136 } 26137 Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm); 26138 } 26139 26140 void Assembler::vsubl( 26141 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) { 26142 VIXL_ASSERT(AllowAssembler()); 26143 CheckIT(cond); 26144 Dt_U_size_1 encoded_dt(dt); 26145 if (IsUsingT32()) { 26146 // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 26147 if (encoded_dt.IsValid()) { 26148 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26149 EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 26150 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 26151 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26152 AdvanceIT(); 26153 return; 26154 } 26155 } 26156 } else { 26157 // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1 26158 if (encoded_dt.IsValid()) { 26159 if (cond.Is(al)) { 26160 EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 26161 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 26162 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26163 return; 26164 } 26165 } 26166 } 26167 Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm); 26168 } 26169 26170 void Assembler::vsubw( 26171 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) { 26172 VIXL_ASSERT(AllowAssembler()); 26173 CheckIT(cond); 26174 Dt_U_size_1 encoded_dt(dt); 26175 if (IsUsingT32()) { 26176 // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1 26177 if (encoded_dt.IsValid()) { 26178 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26179 EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 26180 ((encoded_dt.GetEncodingValue() & 0x4) << 26) | 26181 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26182 AdvanceIT(); 26183 return; 26184 } 26185 } 26186 } else { 26187 // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1 26188 if (encoded_dt.IsValid()) { 26189 if (cond.Is(al)) { 26190 EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) | 26191 ((encoded_dt.GetEncodingValue() & 0x4) << 22) | 26192 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26193 return; 26194 } 26195 } 26196 } 26197 Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm); 26198 } 26199 26200 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) { 26201 VIXL_ASSERT(AllowAssembler()); 26202 CheckIT(cond); 26203 USE(dt); 26204 if (IsUsingT32()) { 26205 // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 26206 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26207 EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0)); 26208 AdvanceIT(); 26209 return; 26210 } 26211 } else { 26212 // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1 26213 if (cond.Is(al)) { 26214 EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0)); 26215 return; 26216 } 26217 } 26218 Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm); 26219 } 26220 26221 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) { 26222 VIXL_ASSERT(AllowAssembler()); 26223 CheckIT(cond); 26224 USE(dt); 26225 if (IsUsingT32()) { 26226 // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 26227 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26228 EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0)); 26229 AdvanceIT(); 26230 return; 26231 } 26232 } else { 26233 // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1 26234 if (cond.Is(al)) { 26235 EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0)); 26236 return; 26237 } 26238 } 26239 Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm); 26240 } 26241 26242 void Assembler::vtbl(Condition cond, 26243 DataType dt, 26244 DRegister rd, 26245 const NeonRegisterList& nreglist, 26246 DRegister rm) { 26247 VIXL_ASSERT(AllowAssembler()); 26248 CheckIT(cond); 26249 if (IsUsingT32()) { 26250 // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1 26251 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 26252 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 26253 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26254 const DRegister& first = nreglist.GetFirstDRegister(); 26255 uint32_t len_encoding = nreglist.GetLength() - 1; 26256 EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) | 26257 (len_encoding << 8) | rm.Encode(5, 0)); 26258 AdvanceIT(); 26259 return; 26260 } 26261 } 26262 } else { 26263 // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1 26264 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 26265 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 26266 if (cond.Is(al)) { 26267 const DRegister& first = nreglist.GetFirstDRegister(); 26268 uint32_t len_encoding = nreglist.GetLength() - 1; 26269 EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) | 26270 (len_encoding << 8) | rm.Encode(5, 0)); 26271 return; 26272 } 26273 } 26274 } 26275 Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm); 26276 } 26277 26278 void Assembler::vtbx(Condition cond, 26279 DataType dt, 26280 DRegister rd, 26281 const NeonRegisterList& nreglist, 26282 DRegister rm) { 26283 VIXL_ASSERT(AllowAssembler()); 26284 CheckIT(cond); 26285 if (IsUsingT32()) { 26286 // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1 26287 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 26288 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 26289 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26290 const DRegister& first = nreglist.GetFirstDRegister(); 26291 uint32_t len_encoding = nreglist.GetLength() - 1; 26292 EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) | 26293 (len_encoding << 8) | rm.Encode(5, 0)); 26294 AdvanceIT(); 26295 return; 26296 } 26297 } 26298 } else { 26299 // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1 26300 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() && 26301 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) { 26302 if (cond.Is(al)) { 26303 const DRegister& first = nreglist.GetFirstDRegister(); 26304 uint32_t len_encoding = nreglist.GetLength() - 1; 26305 EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) | 26306 (len_encoding << 8) | rm.Encode(5, 0)); 26307 return; 26308 } 26309 } 26310 } 26311 Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm); 26312 } 26313 26314 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) { 26315 VIXL_ASSERT(AllowAssembler()); 26316 CheckIT(cond); 26317 Dt_size_7 encoded_dt(dt); 26318 if (IsUsingT32()) { 26319 // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 26320 if (encoded_dt.IsValid()) { 26321 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26322 EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) | 26323 rd.Encode(22, 12) | rm.Encode(5, 0)); 26324 AdvanceIT(); 26325 return; 26326 } 26327 } 26328 } else { 26329 // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 26330 if (encoded_dt.IsValid()) { 26331 if (cond.Is(al)) { 26332 EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) | 26333 rd.Encode(22, 12) | rm.Encode(5, 0)); 26334 return; 26335 } 26336 } 26337 } 26338 Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm); 26339 } 26340 26341 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) { 26342 VIXL_ASSERT(AllowAssembler()); 26343 CheckIT(cond); 26344 Dt_size_7 encoded_dt(dt); 26345 if (IsUsingT32()) { 26346 // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 26347 if (encoded_dt.IsValid()) { 26348 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26349 EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) | 26350 rd.Encode(22, 12) | rm.Encode(5, 0)); 26351 AdvanceIT(); 26352 return; 26353 } 26354 } 26355 } else { 26356 // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 26357 if (encoded_dt.IsValid()) { 26358 if (cond.Is(al)) { 26359 EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) | 26360 rd.Encode(22, 12) | rm.Encode(5, 0)); 26361 return; 26362 } 26363 } 26364 } 26365 Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm); 26366 } 26367 26368 void Assembler::vtst( 26369 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) { 26370 VIXL_ASSERT(AllowAssembler()); 26371 CheckIT(cond); 26372 Dt_size_7 encoded_dt(dt); 26373 if (IsUsingT32()) { 26374 // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1 26375 if (encoded_dt.IsValid()) { 26376 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26377 EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) | 26378 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26379 AdvanceIT(); 26380 return; 26381 } 26382 } 26383 } else { 26384 // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1 26385 if (encoded_dt.IsValid()) { 26386 if (cond.Is(al)) { 26387 EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) | 26388 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26389 return; 26390 } 26391 } 26392 } 26393 Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm); 26394 } 26395 26396 void Assembler::vtst( 26397 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) { 26398 VIXL_ASSERT(AllowAssembler()); 26399 CheckIT(cond); 26400 Dt_size_7 encoded_dt(dt); 26401 if (IsUsingT32()) { 26402 // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1 26403 if (encoded_dt.IsValid()) { 26404 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26405 EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) | 26406 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26407 AdvanceIT(); 26408 return; 26409 } 26410 } 26411 } else { 26412 // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1 26413 if (encoded_dt.IsValid()) { 26414 if (cond.Is(al)) { 26415 EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) | 26416 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0)); 26417 return; 26418 } 26419 } 26420 } 26421 Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm); 26422 } 26423 26424 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) { 26425 VIXL_ASSERT(AllowAssembler()); 26426 CheckIT(cond); 26427 Dt_size_15 encoded_dt(dt); 26428 if (IsUsingT32()) { 26429 // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 26430 if (encoded_dt.IsValid()) { 26431 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26432 EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) | 26433 rd.Encode(22, 12) | rm.Encode(5, 0)); 26434 AdvanceIT(); 26435 return; 26436 } 26437 } 26438 // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1 26439 if (dt.Is(Untyped32)) { 26440 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26441 EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 26442 AdvanceIT(); 26443 return; 26444 } 26445 } 26446 } else { 26447 // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 26448 if (encoded_dt.IsValid()) { 26449 if (cond.Is(al)) { 26450 EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) | 26451 rd.Encode(22, 12) | rm.Encode(5, 0)); 26452 return; 26453 } 26454 } 26455 // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1 26456 if (dt.Is(Untyped32)) { 26457 if (cond.Is(al)) { 26458 EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 26459 return; 26460 } 26461 } 26462 } 26463 Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm); 26464 } 26465 26466 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) { 26467 VIXL_ASSERT(AllowAssembler()); 26468 CheckIT(cond); 26469 Dt_size_7 encoded_dt(dt); 26470 if (IsUsingT32()) { 26471 // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 26472 if (encoded_dt.IsValid()) { 26473 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26474 EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) | 26475 rd.Encode(22, 12) | rm.Encode(5, 0)); 26476 AdvanceIT(); 26477 return; 26478 } 26479 } 26480 } else { 26481 // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 26482 if (encoded_dt.IsValid()) { 26483 if (cond.Is(al)) { 26484 EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) | 26485 rd.Encode(22, 12) | rm.Encode(5, 0)); 26486 return; 26487 } 26488 } 26489 } 26490 Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm); 26491 } 26492 26493 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) { 26494 VIXL_ASSERT(AllowAssembler()); 26495 CheckIT(cond); 26496 Dt_size_15 encoded_dt(dt); 26497 if (IsUsingT32()) { 26498 // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 26499 if (encoded_dt.IsValid()) { 26500 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26501 EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) | 26502 rd.Encode(22, 12) | rm.Encode(5, 0)); 26503 AdvanceIT(); 26504 return; 26505 } 26506 } 26507 // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1 26508 if (dt.Is(Untyped32)) { 26509 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26510 EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 26511 AdvanceIT(); 26512 return; 26513 } 26514 } 26515 } else { 26516 // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1 26517 if (encoded_dt.IsValid()) { 26518 if (cond.Is(al)) { 26519 EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) | 26520 rd.Encode(22, 12) | rm.Encode(5, 0)); 26521 return; 26522 } 26523 } 26524 // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1 26525 if (dt.Is(Untyped32)) { 26526 if (cond.Is(al)) { 26527 EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0)); 26528 return; 26529 } 26530 } 26531 } 26532 Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm); 26533 } 26534 26535 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) { 26536 VIXL_ASSERT(AllowAssembler()); 26537 CheckIT(cond); 26538 Dt_size_7 encoded_dt(dt); 26539 if (IsUsingT32()) { 26540 // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 26541 if (encoded_dt.IsValid()) { 26542 if (cond.Is(al) || AllowStronglyDiscouraged()) { 26543 EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) | 26544 rd.Encode(22, 12) | rm.Encode(5, 0)); 26545 AdvanceIT(); 26546 return; 26547 } 26548 } 26549 } else { 26550 // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1 26551 if (encoded_dt.IsValid()) { 26552 if (cond.Is(al)) { 26553 EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) | 26554 rd.Encode(22, 12) | rm.Encode(5, 0)); 26555 return; 26556 } 26557 } 26558 } 26559 Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm); 26560 } 26561 26562 void Assembler::yield(Condition cond, EncodingSize size) { 26563 VIXL_ASSERT(AllowAssembler()); 26564 CheckIT(cond); 26565 if (IsUsingT32()) { 26566 // YIELD{<c>}{<q>} ; T1 26567 if (!size.IsWide()) { 26568 EmitT32_16(0xbf10); 26569 AdvanceIT(); 26570 return; 26571 } 26572 // YIELD{<c>}.W ; T2 26573 if (!size.IsNarrow()) { 26574 EmitT32_32(0xf3af8001U); 26575 AdvanceIT(); 26576 return; 26577 } 26578 } else { 26579 // YIELD{<c>}{<q>} ; A1 26580 if (cond.IsNotNever()) { 26581 EmitA32(0x0320f001U | (cond.GetCondition() << 28)); 26582 return; 26583 } 26584 } 26585 Delegate(kYield, &Assembler::yield, cond, size); 26586 } 26587 // End of generated code. 26588 26589 } // namespace aarch32 26590 } // namespace vixl 26591