duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

assembler-aarch32.cc (1002206B)


      1 // Copyright 2017, VIXL authors
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 extern "C" {
     28 #include <stdint.h>
     29 }
     30 
     31 #include <cassert>
     32 #include <cstdio>
     33 #include <cstdlib>
     34 #include <cstring>
     35 #include <iostream>
     36 
     37 #include "utils-vixl.h"
     38 #include "aarch32/assembler-aarch32.h"
     39 #include "aarch32/constants-aarch32.h"
     40 #include "aarch32/instructions-aarch32.h"
     41 #include "aarch32/operands-aarch32.h"
     42 
     43 namespace vixl {
     44 namespace aarch32 {
     45 
     46 void Assembler::EmitT32_16(uint16_t instr) {
     47   VIXL_ASSERT(buffer_.Is16bitAligned());
     48   buffer_.Emit16(instr);
     49 }
     50 
     51 
     52 void Assembler::EmitT32_32(uint32_t instr) {
     53   VIXL_ASSERT(buffer_.Is16bitAligned());
     54   buffer_.Emit16(static_cast<uint16_t>(instr >> 16));
     55   buffer_.Emit16(static_cast<uint16_t>(instr & 0xffff));
     56 }
     57 
     58 
     59 void Assembler::EmitA32(uint32_t instr) {
     60   VIXL_ASSERT(buffer_.Is32bitAligned());
     61   buffer_.Emit32(instr);
     62 }
     63 
     64 
     65 #ifdef VIXL_DEBUG
     66 void Assembler::PerformCheckIT(Condition condition) {
     67   if (it_mask_ == 0) {
     68     VIXL_ASSERT(IsUsingA32() || condition.Is(al));
     69   } else {
     70     VIXL_ASSERT(condition.Is(first_condition_));
     71     // For A32, AdavanceIT() is not called by the assembler. We must call it
     72     // in order to check that IT instructions are used consistently with
     73     // the following conditional instructions.
     74     if (IsUsingA32()) AdvanceIT();
     75   }
     76 }
     77 #endif
     78 
     79 
     80 void Assembler::BindHelper(Label* label) {
     81   VIXL_ASSERT(!label->IsBound());
     82   label->SetLocation(this, GetCursorOffset());
     83   label->MarkBound();
     84 }
     85 
     86 uint32_t Assembler::Link(uint32_t instr,
     87                          Location* location,
     88                          const Location::EmitOperator& op,
     89                          const ReferenceInfo* info) {
     90   location->SetReferenced();
     91   if (location->IsBound()) {
     92     return op.Encode(instr, GetCursorOffset(), location);
     93   }
     94   location->AddForwardRef(GetCursorOffset(), op, info);
     95   return instr;
     96 }
     97 
     98 
     99 // Start of generated code.
    100 class Dt_L_imm6_1 : public EncodingValue {
    101   uint32_t type_;
    102 
    103  public:
    104   explicit Dt_L_imm6_1(DataType dt);
    105   uint32_t GetTypeEncodingValue() const { return type_; }
    106 };
    107 
    108 Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
    109   switch (dt.GetValue()) {
    110     case S8:
    111       type_ = 0x0;
    112       SetEncodingValue(0x1);
    113       break;
    114     case U8:
    115       type_ = 0x1;
    116       SetEncodingValue(0x1);
    117       break;
    118     case S16:
    119       type_ = 0x0;
    120       SetEncodingValue(0x2);
    121       break;
    122     case U16:
    123       type_ = 0x1;
    124       SetEncodingValue(0x2);
    125       break;
    126     case S32:
    127       type_ = 0x0;
    128       SetEncodingValue(0x4);
    129       break;
    130     case U32:
    131       type_ = 0x1;
    132       SetEncodingValue(0x4);
    133       break;
    134     case S64:
    135       type_ = 0x0;
    136       SetEncodingValue(0x8);
    137       break;
    138     case U64:
    139       type_ = 0x1;
    140       SetEncodingValue(0x8);
    141       break;
    142     default:
    143       VIXL_UNREACHABLE();
    144       type_ = 0x0;
    145       break;
    146   }
    147 }
    148 
    149 class Dt_L_imm6_2 : public EncodingValue {
    150   uint32_t type_;
    151 
    152  public:
    153   explicit Dt_L_imm6_2(DataType dt);
    154   uint32_t GetTypeEncodingValue() const { return type_; }
    155 };
    156 
    157 Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
    158   switch (dt.GetValue()) {
    159     case S8:
    160       type_ = 0x1;
    161       SetEncodingValue(0x1);
    162       break;
    163     case S16:
    164       type_ = 0x1;
    165       SetEncodingValue(0x2);
    166       break;
    167     case S32:
    168       type_ = 0x1;
    169       SetEncodingValue(0x4);
    170       break;
    171     case S64:
    172       type_ = 0x1;
    173       SetEncodingValue(0x8);
    174       break;
    175     default:
    176       VIXL_UNREACHABLE();
    177       type_ = 0x0;
    178       break;
    179   }
    180 }
    181 
    182 class Dt_L_imm6_3 : public EncodingValue {
    183  public:
    184   explicit Dt_L_imm6_3(DataType dt);
    185 };
    186 
    187 Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
    188   switch (dt.GetValue()) {
    189     case I8:
    190       SetEncodingValue(0x1);
    191       break;
    192     case I16:
    193       SetEncodingValue(0x2);
    194       break;
    195     case I32:
    196       SetEncodingValue(0x4);
    197       break;
    198     case I64:
    199       SetEncodingValue(0x8);
    200       break;
    201     default:
    202       break;
    203   }
    204 }
    205 
    206 class Dt_L_imm6_4 : public EncodingValue {
    207  public:
    208   explicit Dt_L_imm6_4(DataType dt);
    209 };
    210 
    211 Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
    212   switch (dt.GetValue()) {
    213     case Untyped8:
    214       SetEncodingValue(0x1);
    215       break;
    216     case Untyped16:
    217       SetEncodingValue(0x2);
    218       break;
    219     case Untyped32:
    220       SetEncodingValue(0x4);
    221       break;
    222     case Untyped64:
    223       SetEncodingValue(0x8);
    224       break;
    225     default:
    226       break;
    227   }
    228 }
    229 
    230 class Dt_imm6_1 : public EncodingValue {
    231   uint32_t type_;
    232 
    233  public:
    234   explicit Dt_imm6_1(DataType dt);
    235   uint32_t GetTypeEncodingValue() const { return type_; }
    236 };
    237 
    238 Dt_imm6_1::Dt_imm6_1(DataType dt) {
    239   switch (dt.GetValue()) {
    240     case S16:
    241       type_ = 0x0;
    242       SetEncodingValue(0x1);
    243       break;
    244     case U16:
    245       type_ = 0x1;
    246       SetEncodingValue(0x1);
    247       break;
    248     case S32:
    249       type_ = 0x0;
    250       SetEncodingValue(0x2);
    251       break;
    252     case U32:
    253       type_ = 0x1;
    254       SetEncodingValue(0x2);
    255       break;
    256     case S64:
    257       type_ = 0x0;
    258       SetEncodingValue(0x4);
    259       break;
    260     case U64:
    261       type_ = 0x1;
    262       SetEncodingValue(0x4);
    263       break;
    264     default:
    265       VIXL_UNREACHABLE();
    266       type_ = 0x0;
    267       break;
    268   }
    269 }
    270 
    271 class Dt_imm6_2 : public EncodingValue {
    272   uint32_t type_;
    273 
    274  public:
    275   explicit Dt_imm6_2(DataType dt);
    276   uint32_t GetTypeEncodingValue() const { return type_; }
    277 };
    278 
    279 Dt_imm6_2::Dt_imm6_2(DataType dt) {
    280   switch (dt.GetValue()) {
    281     case S16:
    282       type_ = 0x1;
    283       SetEncodingValue(0x1);
    284       break;
    285     case S32:
    286       type_ = 0x1;
    287       SetEncodingValue(0x2);
    288       break;
    289     case S64:
    290       type_ = 0x1;
    291       SetEncodingValue(0x4);
    292       break;
    293     default:
    294       VIXL_UNREACHABLE();
    295       type_ = 0x0;
    296       break;
    297   }
    298 }
    299 
    300 class Dt_imm6_3 : public EncodingValue {
    301  public:
    302   explicit Dt_imm6_3(DataType dt);
    303 };
    304 
    305 Dt_imm6_3::Dt_imm6_3(DataType dt) {
    306   switch (dt.GetValue()) {
    307     case I16:
    308       SetEncodingValue(0x1);
    309       break;
    310     case I32:
    311       SetEncodingValue(0x2);
    312       break;
    313     case I64:
    314       SetEncodingValue(0x4);
    315       break;
    316     default:
    317       break;
    318   }
    319 }
    320 
    321 class Dt_imm6_4 : public EncodingValue {
    322   uint32_t type_;
    323 
    324  public:
    325   explicit Dt_imm6_4(DataType dt);
    326   uint32_t GetTypeEncodingValue() const { return type_; }
    327 };
    328 
    329 Dt_imm6_4::Dt_imm6_4(DataType dt) {
    330   switch (dt.GetValue()) {
    331     case S8:
    332       type_ = 0x0;
    333       SetEncodingValue(0x1);
    334       break;
    335     case U8:
    336       type_ = 0x1;
    337       SetEncodingValue(0x1);
    338       break;
    339     case S16:
    340       type_ = 0x0;
    341       SetEncodingValue(0x2);
    342       break;
    343     case U16:
    344       type_ = 0x1;
    345       SetEncodingValue(0x2);
    346       break;
    347     case S32:
    348       type_ = 0x0;
    349       SetEncodingValue(0x4);
    350       break;
    351     case U32:
    352       type_ = 0x1;
    353       SetEncodingValue(0x4);
    354       break;
    355     default:
    356       VIXL_UNREACHABLE();
    357       type_ = 0x0;
    358       break;
    359   }
    360 }
    361 
    362 class Dt_op_U_size_1 : public EncodingValue {
    363  public:
    364   explicit Dt_op_U_size_1(DataType dt);
    365 };
    366 
    367 Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
    368   switch (dt.GetValue()) {
    369     case S8:
    370       SetEncodingValue(0x0);
    371       break;
    372     case S16:
    373       SetEncodingValue(0x1);
    374       break;
    375     case S32:
    376       SetEncodingValue(0x2);
    377       break;
    378     case U8:
    379       SetEncodingValue(0x4);
    380       break;
    381     case U16:
    382       SetEncodingValue(0x5);
    383       break;
    384     case U32:
    385       SetEncodingValue(0x6);
    386       break;
    387     case P8:
    388       SetEncodingValue(0x8);
    389       break;
    390     case P64:
    391       SetEncodingValue(0xa);
    392       break;
    393     default:
    394       break;
    395   }
    396 }
    397 
    398 class Dt_op_size_1 : public EncodingValue {
    399  public:
    400   explicit Dt_op_size_1(DataType dt);
    401 };
    402 
    403 Dt_op_size_1::Dt_op_size_1(DataType dt) {
    404   switch (dt.GetValue()) {
    405     case I8:
    406       SetEncodingValue(0x0);
    407       break;
    408     case I16:
    409       SetEncodingValue(0x1);
    410       break;
    411     case I32:
    412       SetEncodingValue(0x2);
    413       break;
    414     case P8:
    415       SetEncodingValue(0x4);
    416       break;
    417     default:
    418       break;
    419   }
    420 }
    421 
    422 class Dt_op_size_2 : public EncodingValue {
    423  public:
    424   explicit Dt_op_size_2(DataType dt);
    425 };
    426 
    427 Dt_op_size_2::Dt_op_size_2(DataType dt) {
    428   switch (dt.GetValue()) {
    429     case S8:
    430       SetEncodingValue(0x0);
    431       break;
    432     case S16:
    433       SetEncodingValue(0x1);
    434       break;
    435     case S32:
    436       SetEncodingValue(0x2);
    437       break;
    438     case U8:
    439       SetEncodingValue(0x4);
    440       break;
    441     case U16:
    442       SetEncodingValue(0x5);
    443       break;
    444     case U32:
    445       SetEncodingValue(0x6);
    446       break;
    447     default:
    448       break;
    449   }
    450 }
    451 
    452 class Dt_op_size_3 : public EncodingValue {
    453  public:
    454   explicit Dt_op_size_3(DataType dt);
    455 };
    456 
    457 Dt_op_size_3::Dt_op_size_3(DataType dt) {
    458   switch (dt.GetValue()) {
    459     case S16:
    460       SetEncodingValue(0x0);
    461       break;
    462     case S32:
    463       SetEncodingValue(0x1);
    464       break;
    465     case S64:
    466       SetEncodingValue(0x2);
    467       break;
    468     case U16:
    469       SetEncodingValue(0x4);
    470       break;
    471     case U32:
    472       SetEncodingValue(0x5);
    473       break;
    474     case U64:
    475       SetEncodingValue(0x6);
    476       break;
    477     default:
    478       break;
    479   }
    480 }
    481 
    482 class Dt_U_imm3H_1 : public EncodingValue {
    483  public:
    484   explicit Dt_U_imm3H_1(DataType dt);
    485 };
    486 
    487 Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
    488   switch (dt.GetValue()) {
    489     case S8:
    490       SetEncodingValue(0x1);
    491       break;
    492     case S16:
    493       SetEncodingValue(0x2);
    494       break;
    495     case S32:
    496       SetEncodingValue(0x4);
    497       break;
    498     case U8:
    499       SetEncodingValue(0x9);
    500       break;
    501     case U16:
    502       SetEncodingValue(0xa);
    503       break;
    504     case U32:
    505       SetEncodingValue(0xc);
    506       break;
    507     default:
    508       break;
    509   }
    510 }
    511 
    512 class Dt_U_opc1_opc2_1 : public EncodingValue {
    513  public:
    514   explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
    515 };
    516 
    517 Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
    518   switch (dt.GetValue()) {
    519     case S8:
    520       if ((lane.GetLane() & 7) != lane.GetLane()) {
    521         return;
    522       }
    523       SetEncodingValue(0x8 | lane.GetLane());
    524       break;
    525     case S16:
    526       if ((lane.GetLane() & 3) != lane.GetLane()) {
    527         return;
    528       }
    529       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    530       break;
    531     case U8:
    532       if ((lane.GetLane() & 7) != lane.GetLane()) {
    533         return;
    534       }
    535       SetEncodingValue(0x18 | lane.GetLane());
    536       break;
    537     case U16:
    538       if ((lane.GetLane() & 3) != lane.GetLane()) {
    539         return;
    540       }
    541       SetEncodingValue(0x11 | (lane.GetLane() << 1));
    542       break;
    543     case Untyped32:
    544       if ((lane.GetLane() & 1) != lane.GetLane()) {
    545         return;
    546       }
    547       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    548       break;
    549     case kDataTypeValueNone:
    550       if ((lane.GetLane() & 1) != lane.GetLane()) {
    551         return;
    552       }
    553       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    554       break;
    555     default:
    556       break;
    557   }
    558 }
    559 
    560 class Dt_opc1_opc2_1 : public EncodingValue {
    561  public:
    562   explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
    563 };
    564 
    565 Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
    566   switch (dt.GetValue()) {
    567     case Untyped8:
    568       if ((lane.GetLane() & 7) != lane.GetLane()) {
    569         return;
    570       }
    571       SetEncodingValue(0x8 | lane.GetLane());
    572       break;
    573     case Untyped16:
    574       if ((lane.GetLane() & 3) != lane.GetLane()) {
    575         return;
    576       }
    577       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    578       break;
    579     case Untyped32:
    580       if ((lane.GetLane() & 1) != lane.GetLane()) {
    581         return;
    582       }
    583       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    584       break;
    585     case kDataTypeValueNone:
    586       if ((lane.GetLane() & 1) != lane.GetLane()) {
    587         return;
    588       }
    589       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    590       break;
    591     default:
    592       break;
    593   }
    594 }
    595 
    596 class Dt_imm4_1 : public EncodingValue {
    597  public:
    598   explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
    599 };
    600 
    601 Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
    602   switch (dt.GetValue()) {
    603     case Untyped8:
    604       if ((lane.GetLane() & 7) != lane.GetLane()) {
    605         return;
    606       }
    607       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    608       break;
    609     case Untyped16:
    610       if ((lane.GetLane() & 3) != lane.GetLane()) {
    611         return;
    612       }
    613       SetEncodingValue(0x2 | (lane.GetLane() << 2));
    614       break;
    615     case Untyped32:
    616       if ((lane.GetLane() & 1) != lane.GetLane()) {
    617         return;
    618       }
    619       SetEncodingValue(0x4 | (lane.GetLane() << 3));
    620       break;
    621     default:
    622       break;
    623   }
    624 }
    625 
    626 class Dt_B_E_1 : public EncodingValue {
    627  public:
    628   explicit Dt_B_E_1(DataType dt);
    629 };
    630 
    631 Dt_B_E_1::Dt_B_E_1(DataType dt) {
    632   switch (dt.GetValue()) {
    633     case Untyped8:
    634       SetEncodingValue(0x2);
    635       break;
    636     case Untyped16:
    637       SetEncodingValue(0x1);
    638       break;
    639     case Untyped32:
    640       SetEncodingValue(0x0);
    641       break;
    642     default:
    643       break;
    644   }
    645 }
    646 
    647 class Dt_op_1 : public EncodingValue {
    648  public:
    649   Dt_op_1(DataType dt1, DataType dt2);
    650 };
    651 
    652 Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
    653   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
    654     SetEncodingValue(0x0);
    655     return;
    656   }
    657   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
    658     SetEncodingValue(0x1);
    659     return;
    660   }
    661   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
    662     SetEncodingValue(0x2);
    663     return;
    664   }
    665   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
    666     SetEncodingValue(0x3);
    667     return;
    668   }
    669 }
    670 
    671 class Dt_op_2 : public EncodingValue {
    672  public:
    673   explicit Dt_op_2(DataType dt);
    674 };
    675 
    676 Dt_op_2::Dt_op_2(DataType dt) {
    677   switch (dt.GetValue()) {
    678     case U32:
    679       SetEncodingValue(0x0);
    680       break;
    681     case S32:
    682       SetEncodingValue(0x1);
    683       break;
    684     default:
    685       break;
    686   }
    687 }
    688 
    689 class Dt_op_3 : public EncodingValue {
    690  public:
    691   explicit Dt_op_3(DataType dt);
    692 };
    693 
    694 Dt_op_3::Dt_op_3(DataType dt) {
    695   switch (dt.GetValue()) {
    696     case S32:
    697       SetEncodingValue(0x0);
    698       break;
    699     case U32:
    700       SetEncodingValue(0x1);
    701       break;
    702     default:
    703       break;
    704   }
    705 }
    706 
    707 class Dt_U_sx_1 : public EncodingValue {
    708  public:
    709   explicit Dt_U_sx_1(DataType dt);
    710 };
    711 
    712 Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
    713   switch (dt.GetValue()) {
    714     case S16:
    715       SetEncodingValue(0x0);
    716       break;
    717     case S32:
    718       SetEncodingValue(0x1);
    719       break;
    720     case U16:
    721       SetEncodingValue(0x2);
    722       break;
    723     case U32:
    724       SetEncodingValue(0x3);
    725       break;
    726     default:
    727       break;
    728   }
    729 }
    730 
    731 class Dt_op_U_1 : public EncodingValue {
    732  public:
    733   Dt_op_U_1(DataType dt1, DataType dt2);
    734 };
    735 
    736 Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
    737   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
    738     SetEncodingValue(0x0);
    739     return;
    740   }
    741   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
    742     SetEncodingValue(0x1);
    743     return;
    744   }
    745   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
    746     SetEncodingValue(0x2);
    747     return;
    748   }
    749   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
    750     SetEncodingValue(0x3);
    751     return;
    752   }
    753 }
    754 
    755 class Dt_sz_1 : public EncodingValue {
    756  public:
    757   explicit Dt_sz_1(DataType dt);
    758 };
    759 
    760 Dt_sz_1::Dt_sz_1(DataType dt) {
    761   switch (dt.GetValue()) {
    762     case F32:
    763       SetEncodingValue(0x0);
    764       break;
    765     default:
    766       break;
    767   }
    768 }
    769 
    770 class Dt_F_size_1 : public EncodingValue {
    771  public:
    772   explicit Dt_F_size_1(DataType dt);
    773 };
    774 
    775 Dt_F_size_1::Dt_F_size_1(DataType dt) {
    776   switch (dt.GetValue()) {
    777     case S8:
    778       SetEncodingValue(0x0);
    779       break;
    780     case S16:
    781       SetEncodingValue(0x1);
    782       break;
    783     case S32:
    784       SetEncodingValue(0x2);
    785       break;
    786     case F32:
    787       SetEncodingValue(0x6);
    788       break;
    789     default:
    790       break;
    791   }
    792 }
    793 
    794 class Dt_F_size_2 : public EncodingValue {
    795  public:
    796   explicit Dt_F_size_2(DataType dt);
    797 };
    798 
    799 Dt_F_size_2::Dt_F_size_2(DataType dt) {
    800   switch (dt.GetValue()) {
    801     case I8:
    802       SetEncodingValue(0x0);
    803       break;
    804     case I16:
    805       SetEncodingValue(0x1);
    806       break;
    807     case I32:
    808       SetEncodingValue(0x2);
    809       break;
    810     case F32:
    811       SetEncodingValue(0x6);
    812       break;
    813     default:
    814       break;
    815   }
    816 }
    817 
    818 class Dt_F_size_3 : public EncodingValue {
    819  public:
    820   explicit Dt_F_size_3(DataType dt);
    821 };
    822 
    823 Dt_F_size_3::Dt_F_size_3(DataType dt) {
    824   switch (dt.GetValue()) {
    825     case I16:
    826       SetEncodingValue(0x1);
    827       break;
    828     case I32:
    829       SetEncodingValue(0x2);
    830       break;
    831     case F32:
    832       SetEncodingValue(0x6);
    833       break;
    834     default:
    835       break;
    836   }
    837 }
    838 
    839 class Dt_F_size_4 : public EncodingValue {
    840  public:
    841   explicit Dt_F_size_4(DataType dt);
    842 };
    843 
    844 Dt_F_size_4::Dt_F_size_4(DataType dt) {
    845   switch (dt.GetValue()) {
    846     case U32:
    847       SetEncodingValue(0x2);
    848       break;
    849     case F32:
    850       SetEncodingValue(0x6);
    851       break;
    852     default:
    853       break;
    854   }
    855 }
    856 
    857 class Dt_U_size_1 : public EncodingValue {
    858  public:
    859   explicit Dt_U_size_1(DataType dt);
    860 };
    861 
    862 Dt_U_size_1::Dt_U_size_1(DataType dt) {
    863   switch (dt.GetValue()) {
    864     case S8:
    865       SetEncodingValue(0x0);
    866       break;
    867     case S16:
    868       SetEncodingValue(0x1);
    869       break;
    870     case S32:
    871       SetEncodingValue(0x2);
    872       break;
    873     case U8:
    874       SetEncodingValue(0x4);
    875       break;
    876     case U16:
    877       SetEncodingValue(0x5);
    878       break;
    879     case U32:
    880       SetEncodingValue(0x6);
    881       break;
    882     default:
    883       break;
    884   }
    885 }
    886 
    887 class Dt_U_size_2 : public EncodingValue {
    888  public:
    889   explicit Dt_U_size_2(DataType dt);
    890 };
    891 
    892 Dt_U_size_2::Dt_U_size_2(DataType dt) {
    893   switch (dt.GetValue()) {
    894     case S16:
    895       SetEncodingValue(0x1);
    896       break;
    897     case S32:
    898       SetEncodingValue(0x2);
    899       break;
    900     case U16:
    901       SetEncodingValue(0x5);
    902       break;
    903     case U32:
    904       SetEncodingValue(0x6);
    905       break;
    906     default:
    907       break;
    908   }
    909 }
    910 
    911 class Dt_U_size_3 : public EncodingValue {
    912  public:
    913   explicit Dt_U_size_3(DataType dt);
    914 };
    915 
    916 Dt_U_size_3::Dt_U_size_3(DataType dt) {
    917   switch (dt.GetValue()) {
    918     case S8:
    919       SetEncodingValue(0x0);
    920       break;
    921     case S16:
    922       SetEncodingValue(0x1);
    923       break;
    924     case S32:
    925       SetEncodingValue(0x2);
    926       break;
    927     case S64:
    928       SetEncodingValue(0x3);
    929       break;
    930     case U8:
    931       SetEncodingValue(0x4);
    932       break;
    933     case U16:
    934       SetEncodingValue(0x5);
    935       break;
    936     case U32:
    937       SetEncodingValue(0x6);
    938       break;
    939     case U64:
    940       SetEncodingValue(0x7);
    941       break;
    942     default:
    943       break;
    944   }
    945 }
    946 
    947 class Dt_size_1 : public EncodingValue {
    948  public:
    949   explicit Dt_size_1(DataType dt);
    950 };
    951 
    952 Dt_size_1::Dt_size_1(DataType dt) {
    953   switch (dt.GetValue()) {
    954     case Untyped8:
    955       SetEncodingValue(0x0);
    956       break;
    957     default:
    958       break;
    959   }
    960 }
    961 
    962 class Dt_size_2 : public EncodingValue {
    963  public:
    964   explicit Dt_size_2(DataType dt);
    965 };
    966 
    967 Dt_size_2::Dt_size_2(DataType dt) {
    968   switch (dt.GetValue()) {
    969     case I8:
    970       SetEncodingValue(0x0);
    971       break;
    972     case I16:
    973       SetEncodingValue(0x1);
    974       break;
    975     case I32:
    976       SetEncodingValue(0x2);
    977       break;
    978     case I64:
    979       SetEncodingValue(0x3);
    980       break;
    981     default:
    982       break;
    983   }
    984 }
    985 
    986 class Dt_size_3 : public EncodingValue {
    987  public:
    988   explicit Dt_size_3(DataType dt);
    989 };
    990 
    991 Dt_size_3::Dt_size_3(DataType dt) {
    992   switch (dt.GetValue()) {
    993     case I16:
    994       SetEncodingValue(0x0);
    995       break;
    996     case I32:
    997       SetEncodingValue(0x1);
    998       break;
    999     case I64:
   1000       SetEncodingValue(0x2);
   1001       break;
   1002     default:
   1003       break;
   1004   }
   1005 }
   1006 
   1007 class Dt_size_4 : public EncodingValue {
   1008  public:
   1009   explicit Dt_size_4(DataType dt);
   1010 };
   1011 
   1012 Dt_size_4::Dt_size_4(DataType dt) {
   1013   switch (dt.GetValue()) {
   1014     case I8:
   1015       SetEncodingValue(0x0);
   1016       break;
   1017     case I16:
   1018       SetEncodingValue(0x1);
   1019       break;
   1020     case I32:
   1021       SetEncodingValue(0x2);
   1022       break;
   1023     default:
   1024       break;
   1025   }
   1026 }
   1027 
   1028 class Dt_size_5 : public EncodingValue {
   1029  public:
   1030   explicit Dt_size_5(DataType dt);
   1031 };
   1032 
   1033 Dt_size_5::Dt_size_5(DataType dt) {
   1034   switch (dt.GetValue()) {
   1035     case S8:
   1036       SetEncodingValue(0x0);
   1037       break;
   1038     case S16:
   1039       SetEncodingValue(0x1);
   1040       break;
   1041     case S32:
   1042       SetEncodingValue(0x2);
   1043       break;
   1044     default:
   1045       break;
   1046   }
   1047 }
   1048 
   1049 class Dt_size_6 : public EncodingValue {
   1050  public:
   1051   explicit Dt_size_6(DataType dt);
   1052 };
   1053 
   1054 Dt_size_6::Dt_size_6(DataType dt) {
   1055   switch (dt.GetValue()) {
   1056     case Untyped8:
   1057       SetEncodingValue(0x0);
   1058       break;
   1059     case Untyped16:
   1060       SetEncodingValue(0x1);
   1061       break;
   1062     case Untyped32:
   1063       SetEncodingValue(0x2);
   1064       break;
   1065     case Untyped64:
   1066       SetEncodingValue(0x3);
   1067       break;
   1068     default:
   1069       break;
   1070   }
   1071 }
   1072 
   1073 class Dt_size_7 : public EncodingValue {
   1074  public:
   1075   explicit Dt_size_7(DataType dt);
   1076 };
   1077 
   1078 Dt_size_7::Dt_size_7(DataType dt) {
   1079   switch (dt.GetValue()) {
   1080     case Untyped8:
   1081       SetEncodingValue(0x0);
   1082       break;
   1083     case Untyped16:
   1084       SetEncodingValue(0x1);
   1085       break;
   1086     case Untyped32:
   1087       SetEncodingValue(0x2);
   1088       break;
   1089     default:
   1090       break;
   1091   }
   1092 }
   1093 
   1094 class Dt_size_8 : public EncodingValue {
   1095  public:
   1096   Dt_size_8(DataType dt, Alignment align);
   1097 };
   1098 
   1099 Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
   1100   switch (dt.GetValue()) {
   1101     case Untyped8:
   1102       SetEncodingValue(0x0);
   1103       break;
   1104     case Untyped16:
   1105       SetEncodingValue(0x1);
   1106       break;
   1107     case Untyped32:
   1108       if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
   1109         SetEncodingValue(0x2);
   1110       } else if (align.Is(k128BitAlign)) {
   1111         SetEncodingValue(0x3);
   1112       }
   1113       break;
   1114     default:
   1115       break;
   1116   }
   1117 }
   1118 
   1119 class Dt_size_9 : public EncodingValue {
   1120   uint32_t type_;
   1121 
   1122  public:
   1123   explicit Dt_size_9(DataType dt);
   1124   uint32_t GetTypeEncodingValue() const { return type_; }
   1125 };
   1126 
   1127 Dt_size_9::Dt_size_9(DataType dt) {
   1128   switch (dt.GetValue()) {
   1129     case I16:
   1130       type_ = 0x0;
   1131       SetEncodingValue(0x1);
   1132       break;
   1133     case I32:
   1134       type_ = 0x0;
   1135       SetEncodingValue(0x2);
   1136       break;
   1137     case F32:
   1138       type_ = 0x1;
   1139       SetEncodingValue(0x2);
   1140       break;
   1141     default:
   1142       VIXL_UNREACHABLE();
   1143       type_ = 0x0;
   1144       break;
   1145   }
   1146 }
   1147 
   1148 class Dt_size_10 : public EncodingValue {
   1149  public:
   1150   explicit Dt_size_10(DataType dt);
   1151 };
   1152 
   1153 Dt_size_10::Dt_size_10(DataType dt) {
   1154   switch (dt.GetValue()) {
   1155     case S8:
   1156     case U8:
   1157     case I8:
   1158       SetEncodingValue(0x0);
   1159       break;
   1160     case S16:
   1161     case U16:
   1162     case I16:
   1163       SetEncodingValue(0x1);
   1164       break;
   1165     case S32:
   1166     case U32:
   1167     case I32:
   1168       SetEncodingValue(0x2);
   1169       break;
   1170     default:
   1171       break;
   1172   }
   1173 }
   1174 
   1175 class Dt_size_11 : public EncodingValue {
   1176   uint32_t type_;
   1177 
   1178  public:
   1179   explicit Dt_size_11(DataType dt);
   1180   uint32_t GetTypeEncodingValue() const { return type_; }
   1181 };
   1182 
   1183 Dt_size_11::Dt_size_11(DataType dt) {
   1184   switch (dt.GetValue()) {
   1185     case S16:
   1186       type_ = 0x0;
   1187       SetEncodingValue(0x1);
   1188       break;
   1189     case U16:
   1190       type_ = 0x1;
   1191       SetEncodingValue(0x1);
   1192       break;
   1193     case S32:
   1194       type_ = 0x0;
   1195       SetEncodingValue(0x2);
   1196       break;
   1197     case U32:
   1198       type_ = 0x1;
   1199       SetEncodingValue(0x2);
   1200       break;
   1201     default:
   1202       VIXL_UNREACHABLE();
   1203       type_ = 0x0;
   1204       break;
   1205   }
   1206 }
   1207 
   1208 class Dt_size_12 : public EncodingValue {
   1209   uint32_t type_;
   1210 
   1211  public:
   1212   explicit Dt_size_12(DataType dt);
   1213   uint32_t GetTypeEncodingValue() const { return type_; }
   1214 };
   1215 
   1216 Dt_size_12::Dt_size_12(DataType dt) {
   1217   switch (dt.GetValue()) {
   1218     case S8:
   1219       type_ = 0x0;
   1220       SetEncodingValue(0x0);
   1221       break;
   1222     case U8:
   1223       type_ = 0x1;
   1224       SetEncodingValue(0x0);
   1225       break;
   1226     case S16:
   1227       type_ = 0x0;
   1228       SetEncodingValue(0x1);
   1229       break;
   1230     case U16:
   1231       type_ = 0x1;
   1232       SetEncodingValue(0x1);
   1233       break;
   1234     case S32:
   1235       type_ = 0x0;
   1236       SetEncodingValue(0x2);
   1237       break;
   1238     case U32:
   1239       type_ = 0x1;
   1240       SetEncodingValue(0x2);
   1241       break;
   1242     default:
   1243       VIXL_UNREACHABLE();
   1244       type_ = 0x0;
   1245       break;
   1246   }
   1247 }
   1248 
   1249 class Dt_size_13 : public EncodingValue {
   1250  public:
   1251   explicit Dt_size_13(DataType dt);
   1252 };
   1253 
   1254 Dt_size_13::Dt_size_13(DataType dt) {
   1255   switch (dt.GetValue()) {
   1256     case S16:
   1257       SetEncodingValue(0x1);
   1258       break;
   1259     case S32:
   1260       SetEncodingValue(0x2);
   1261       break;
   1262     default:
   1263       break;
   1264   }
   1265 }
   1266 
   1267 class Dt_size_14 : public EncodingValue {
   1268  public:
   1269   explicit Dt_size_14(DataType dt);
   1270 };
   1271 
   1272 Dt_size_14::Dt_size_14(DataType dt) {
   1273   switch (dt.GetValue()) {
   1274     case S16:
   1275       SetEncodingValue(0x0);
   1276       break;
   1277     case S32:
   1278       SetEncodingValue(0x1);
   1279       break;
   1280     case S64:
   1281       SetEncodingValue(0x2);
   1282       break;
   1283     default:
   1284       break;
   1285   }
   1286 }
   1287 
   1288 class Dt_size_15 : public EncodingValue {
   1289  public:
   1290   explicit Dt_size_15(DataType dt);
   1291 };
   1292 
   1293 Dt_size_15::Dt_size_15(DataType dt) {
   1294   switch (dt.GetValue()) {
   1295     case Untyped8:
   1296       SetEncodingValue(0x0);
   1297       break;
   1298     case Untyped16:
   1299       SetEncodingValue(0x1);
   1300       break;
   1301     default:
   1302       break;
   1303   }
   1304 }
   1305 
   1306 class Dt_size_16 : public EncodingValue {
   1307  public:
   1308   explicit Dt_size_16(DataType dt);
   1309 };
   1310 
   1311 Dt_size_16::Dt_size_16(DataType dt) {
   1312   switch (dt.GetValue()) {
   1313     case F32:
   1314       SetEncodingValue(0x2);
   1315       break;
   1316     default:
   1317       break;
   1318   }
   1319 }
   1320 
   1321 class Dt_size_17 : public EncodingValue {
   1322  public:
   1323   explicit Dt_size_17(DataType dt);
   1324 };
   1325 
   1326 Dt_size_17::Dt_size_17(DataType dt) {
   1327   switch (dt.GetValue()) {
   1328     case I8:
   1329       SetEncodingValue(0x0);
   1330       break;
   1331     case I16:
   1332       SetEncodingValue(0x1);
   1333       break;
   1334     case I32:
   1335       SetEncodingValue(0x2);
   1336       break;
   1337     default:
   1338       break;
   1339   }
   1340 }
   1341 
   1342 class Index_1 : public EncodingValue {
   1343  public:
   1344   Index_1(const NeonRegisterList& nreglist, DataType dt);
   1345 };
   1346 
   1347 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
   1348   switch (dt.GetValue()) {
   1349     case Untyped8: {
   1350       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1351         return;
   1352       }
   1353       uint32_t value = nreglist.GetTransferLane() << 1;
   1354       if (!nreglist.IsSingleSpaced()) return;
   1355       SetEncodingValue(value);
   1356       break;
   1357     }
   1358     case Untyped16: {
   1359       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1360         return;
   1361       }
   1362       uint32_t value = nreglist.GetTransferLane() << 2;
   1363       if (nreglist.IsDoubleSpaced()) value |= 2;
   1364       SetEncodingValue(value);
   1365       break;
   1366     }
   1367     case Untyped32: {
   1368       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1369         return;
   1370       }
   1371       uint32_t value = nreglist.GetTransferLane() << 3;
   1372       if (nreglist.IsDoubleSpaced()) value |= 4;
   1373       SetEncodingValue(value);
   1374       break;
   1375     }
   1376     default:
   1377       break;
   1378   }
   1379 }
   1380 
   1381 class Align_index_align_1 : public EncodingValue {
   1382  public:
   1383   Align_index_align_1(Alignment align,
   1384                       const NeonRegisterList& nreglist,
   1385                       DataType dt);
   1386 };
   1387 
   1388 Align_index_align_1::Align_index_align_1(Alignment align,
   1389                                          const NeonRegisterList& nreglist,
   1390                                          DataType dt) {
   1391   switch (dt.GetValue()) {
   1392     case Untyped8: {
   1393       uint32_t value;
   1394       if (align.GetType() == kNoAlignment) {
   1395         value = 0;
   1396       } else {
   1397         return;
   1398       }
   1399       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1400         return;
   1401       }
   1402       value |= nreglist.GetTransferLane() << 1;
   1403       SetEncodingValue(value);
   1404       break;
   1405     }
   1406     case Untyped16: {
   1407       uint32_t value;
   1408       if (align.GetType() == k16BitAlign) {
   1409         value = 1;
   1410       } else if (align.GetType() == kNoAlignment) {
   1411         value = 0;
   1412       } else {
   1413         return;
   1414       }
   1415       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1416         return;
   1417       }
   1418       value |= nreglist.GetTransferLane() << 2;
   1419       SetEncodingValue(value);
   1420       break;
   1421     }
   1422     case Untyped32: {
   1423       uint32_t value;
   1424       if (align.GetType() == k32BitAlign) {
   1425         value = 3;
   1426       } else if (align.GetType() == kNoAlignment) {
   1427         value = 0;
   1428       } else {
   1429         return;
   1430       }
   1431       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1432         return;
   1433       }
   1434       value |= nreglist.GetTransferLane() << 3;
   1435       SetEncodingValue(value);
   1436       break;
   1437     }
   1438     default:
   1439       break;
   1440   }
   1441 }
   1442 
   1443 class Align_index_align_2 : public EncodingValue {
   1444  public:
   1445   Align_index_align_2(Alignment align,
   1446                       const NeonRegisterList& nreglist,
   1447                       DataType dt);
   1448 };
   1449 
   1450 Align_index_align_2::Align_index_align_2(Alignment align,
   1451                                          const NeonRegisterList& nreglist,
   1452                                          DataType dt) {
   1453   switch (dt.GetValue()) {
   1454     case Untyped8: {
   1455       uint32_t value;
   1456       if (align.GetType() == k16BitAlign) {
   1457         value = 1;
   1458       } else if (align.GetType() == kNoAlignment) {
   1459         value = 0;
   1460       } else {
   1461         return;
   1462       }
   1463       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1464         return;
   1465       }
   1466       value |= nreglist.GetTransferLane() << 1;
   1467       if (!nreglist.IsSingleSpaced()) return;
   1468       SetEncodingValue(value);
   1469       break;
   1470     }
   1471     case Untyped16: {
   1472       uint32_t value;
   1473       if (align.GetType() == k32BitAlign) {
   1474         value = 1;
   1475       } else if (align.GetType() == kNoAlignment) {
   1476         value = 0;
   1477       } else {
   1478         return;
   1479       }
   1480       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1481         return;
   1482       }
   1483       value |= nreglist.GetTransferLane() << 2;
   1484       if (nreglist.IsDoubleSpaced()) value |= 2;
   1485       SetEncodingValue(value);
   1486       break;
   1487     }
   1488     case Untyped32: {
   1489       uint32_t value;
   1490       if (align.GetType() == k64BitAlign) {
   1491         value = 1;
   1492       } else if (align.GetType() == kNoAlignment) {
   1493         value = 0;
   1494       } else {
   1495         return;
   1496       }
   1497       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1498         return;
   1499       }
   1500       value |= nreglist.GetTransferLane() << 3;
   1501       if (nreglist.IsDoubleSpaced()) value |= 4;
   1502       SetEncodingValue(value);
   1503       break;
   1504     }
   1505     default:
   1506       break;
   1507   }
   1508 }
   1509 
   1510 class Align_index_align_3 : public EncodingValue {
   1511  public:
   1512   Align_index_align_3(Alignment align,
   1513                       const NeonRegisterList& nreglist,
   1514                       DataType dt);
   1515 };
   1516 
   1517 Align_index_align_3::Align_index_align_3(Alignment align,
   1518                                          const NeonRegisterList& nreglist,
   1519                                          DataType dt) {
   1520   switch (dt.GetValue()) {
   1521     case Untyped8: {
   1522       uint32_t value;
   1523       if (align.GetType() == k32BitAlign) {
   1524         value = 1;
   1525       } else if (align.GetType() == kNoAlignment) {
   1526         value = 0;
   1527       } else {
   1528         return;
   1529       }
   1530       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1531         return;
   1532       }
   1533       value |= nreglist.GetTransferLane() << 1;
   1534       if (!nreglist.IsSingleSpaced()) return;
   1535       SetEncodingValue(value);
   1536       break;
   1537     }
   1538     case Untyped16: {
   1539       uint32_t value;
   1540       if (align.GetType() == k64BitAlign) {
   1541         value = 1;
   1542       } else if (align.GetType() == kNoAlignment) {
   1543         value = 0;
   1544       } else {
   1545         return;
   1546       }
   1547       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1548         return;
   1549       }
   1550       value |= nreglist.GetTransferLane() << 2;
   1551       if (nreglist.IsDoubleSpaced()) value |= 2;
   1552       SetEncodingValue(value);
   1553       break;
   1554     }
   1555     case Untyped32: {
   1556       uint32_t value;
   1557       if (align.GetType() == k64BitAlign) {
   1558         value = 1;
   1559       } else if (align.GetType() == k128BitAlign) {
   1560         value = 2;
   1561       } else if (align.GetType() == kNoAlignment) {
   1562         value = 0;
   1563       } else {
   1564         return;
   1565       }
   1566       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1567         return;
   1568       }
   1569       value |= nreglist.GetTransferLane() << 3;
   1570       if (nreglist.IsDoubleSpaced()) value |= 4;
   1571       SetEncodingValue(value);
   1572       break;
   1573     }
   1574     default:
   1575       break;
   1576   }
   1577 }
   1578 
   1579 class Align_a_1 : public EncodingValue {
   1580  public:
   1581   Align_a_1(Alignment align, DataType dt);
   1582 };
   1583 
   1584 Align_a_1::Align_a_1(Alignment align, DataType dt) {
   1585   switch (align.GetType()) {
   1586     case k16BitAlign:
   1587       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
   1588       break;
   1589     case k32BitAlign:
   1590       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1591       break;
   1592     case kNoAlignment:
   1593       SetEncodingValue(0x0);
   1594       break;
   1595     default:
   1596       break;
   1597   }
   1598 }
   1599 
   1600 class Align_a_2 : public EncodingValue {
   1601  public:
   1602   Align_a_2(Alignment align, DataType dt);
   1603 };
   1604 
   1605 Align_a_2::Align_a_2(Alignment align, DataType dt) {
   1606   switch (align.GetType()) {
   1607     case k16BitAlign:
   1608       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
   1609       break;
   1610     case k32BitAlign:
   1611       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
   1612       break;
   1613     case k64BitAlign:
   1614       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1615       break;
   1616     case kNoAlignment:
   1617       SetEncodingValue(0x0);
   1618       break;
   1619     default:
   1620       break;
   1621   }
   1622 }
   1623 
   1624 class Align_a_3 : public EncodingValue {
   1625  public:
   1626   Align_a_3(Alignment align, DataType dt);
   1627 };
   1628 
   1629 Align_a_3::Align_a_3(Alignment align, DataType dt) {
   1630   switch (align.GetType()) {
   1631     case k32BitAlign:
   1632       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
   1633       break;
   1634     case k64BitAlign:
   1635       if (dt.Is(Untyped16))
   1636         SetEncodingValue(0x1);
   1637       else if (dt.Is(Untyped32))
   1638         SetEncodingValue(0x1);
   1639       break;
   1640     case k128BitAlign:
   1641       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1642       break;
   1643     case kNoAlignment:
   1644       SetEncodingValue(0x0);
   1645       break;
   1646     default:
   1647       break;
   1648   }
   1649 }
   1650 
   1651 class Align_align_1 : public EncodingValue {
   1652  public:
   1653   Align_align_1(Alignment align, const NeonRegisterList& nreglist);
   1654 };
   1655 
   1656 Align_align_1::Align_align_1(Alignment align,
   1657                              const NeonRegisterList& nreglist) {
   1658   switch (align.GetType()) {
   1659     case k64BitAlign:
   1660       SetEncodingValue(0x1);
   1661       break;
   1662     case k128BitAlign:
   1663       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1664         SetEncodingValue(0x2);
   1665       break;
   1666     case k256BitAlign:
   1667       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1668         SetEncodingValue(0x3);
   1669       break;
   1670     case kNoAlignment:
   1671       SetEncodingValue(0x0);
   1672       break;
   1673     default:
   1674       break;
   1675   }
   1676 }
   1677 
   1678 class Align_align_2 : public EncodingValue {
   1679  public:
   1680   Align_align_2(Alignment align, const NeonRegisterList& nreglist);
   1681 };
   1682 
   1683 Align_align_2::Align_align_2(Alignment align,
   1684                              const NeonRegisterList& nreglist) {
   1685   switch (align.GetType()) {
   1686     case k64BitAlign:
   1687       SetEncodingValue(0x1);
   1688       break;
   1689     case k128BitAlign:
   1690       SetEncodingValue(0x2);
   1691       break;
   1692     case k256BitAlign:
   1693       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
   1694       break;
   1695     case kNoAlignment:
   1696       SetEncodingValue(0x0);
   1697       break;
   1698     default:
   1699       break;
   1700   }
   1701 }
   1702 
   1703 class Align_align_3 : public EncodingValue {
   1704  public:
   1705   explicit Align_align_3(Alignment align);
   1706 };
   1707 
   1708 Align_align_3::Align_align_3(Alignment align) {
   1709   switch (align.GetType()) {
   1710     case k64BitAlign:
   1711       SetEncodingValue(0x1);
   1712       break;
   1713     case kNoAlignment:
   1714       SetEncodingValue(0x0);
   1715       break;
   1716     default:
   1717       break;
   1718   }
   1719 }
   1720 
   1721 class Align_align_4 : public EncodingValue {
   1722  public:
   1723   explicit Align_align_4(Alignment align);
   1724 };
   1725 
   1726 Align_align_4::Align_align_4(Alignment align) {
   1727   switch (align.GetType()) {
   1728     case k64BitAlign:
   1729       SetEncodingValue(0x1);
   1730       break;
   1731     case k128BitAlign:
   1732       SetEncodingValue(0x2);
   1733       break;
   1734     case k256BitAlign:
   1735       SetEncodingValue(0x3);
   1736       break;
   1737     case kNoAlignment:
   1738       SetEncodingValue(0x0);
   1739       break;
   1740     default:
   1741       break;
   1742   }
   1743 }
   1744 
   1745 class Align_align_5 : public EncodingValue {
   1746  public:
   1747   Align_align_5(Alignment align, const NeonRegisterList& nreglist);
   1748 };
   1749 
   1750 Align_align_5::Align_align_5(Alignment align,
   1751                              const NeonRegisterList& nreglist) {
   1752   switch (align.GetType()) {
   1753     case k64BitAlign:
   1754       SetEncodingValue(0x1);
   1755       break;
   1756     case k128BitAlign:
   1757       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1758         SetEncodingValue(0x2);
   1759       break;
   1760     case k256BitAlign:
   1761       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
   1762       break;
   1763     case kNoAlignment:
   1764       SetEncodingValue(0x0);
   1765       break;
   1766     default:
   1767       break;
   1768   }
   1769 }
   1770 
   1771 
   1772 // CBNZ{<q>} <Rn>, <label> ; T1
   1773 // CBZ{<q>} <Rn>, <label> ; T1
   1774 static const struct ReferenceInfo kT16CbzInfo =
   1775     {k16BitT32InstructionSizeInBytes,
   1776      0,    // Min offset.
   1777      126,  // Max offset.
   1778      2,    // Alignment.
   1779      ReferenceInfo::kDontAlignPc};
   1780 
   1781 
   1782 // B<c>{<q>} <label> ; T1
   1783 static const struct ReferenceInfo kT16ConditionalBranchInfo =
   1784     {k16BitT32InstructionSizeInBytes,
   1785      -256,  // Min offset.
   1786      254,   // Max offset.
   1787      2,     // Alignment.
   1788      ReferenceInfo::kDontAlignPc};
   1789 
   1790 
   1791 // ADR{<c>}{<q>} <Rd>, <label> ; T1
   1792 // LDR{<c>}{<q>} <Rt>, <label> ; T1
   1793 static const struct ReferenceInfo kT16DataInfo =
   1794     {k16BitT32InstructionSizeInBytes,
   1795      0,     // Min offset.
   1796      1020,  // Max offset.
   1797      4,     // Alignment.
   1798      ReferenceInfo::kAlignPc};
   1799 
   1800 
   1801 // B{<c>}{<q>} <label> ; T2
   1802 static const struct ReferenceInfo kT16BranchInfo =
   1803     {k16BitT32InstructionSizeInBytes,
   1804      -2048,  // Min offset.
   1805      2046,   // Max offset.
   1806      2,      // Alignment.
   1807      ReferenceInfo::kDontAlignPc};
   1808 
   1809 
   1810 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
   1811 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
   1812 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
   1813 static const struct ReferenceInfo kT32DataInfo =
   1814     {k32BitT32InstructionSizeInBytes,
   1815      -1020,  // Min offset.
   1816      1020,   // Max offset.
   1817      4,      // Alignment.
   1818      ReferenceInfo::kAlignPc};
   1819 
   1820 
   1821 // ADR{<c>}{<q>} <Rd>, <label> ; T3
   1822 // LDR{<c>}{<q>} <Rt>, <label> ; T2
   1823 // LDRB{<c>}{<q>} <Rt>, <label> ; T1
   1824 // LDRH{<c>}{<q>} <Rt>, <label> ; T1
   1825 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
   1826 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
   1827 // PLD{<c>}{<q>} <label> ; T1
   1828 // PLI{<c>}{<q>} <label> ; T3
   1829 static const struct ReferenceInfo kT32FarDataInfo =
   1830     {k32BitT32InstructionSizeInBytes,
   1831      -4095,  // Min offset.
   1832      4095,   // Max offset.
   1833      1,      // Alignment.
   1834      ReferenceInfo::kAlignPc};
   1835 
   1836 
   1837 // B<c>{<q>} <label> ; T3
   1838 static const struct ReferenceInfo kT32ConditionalBranchInfo =
   1839     {k32BitT32InstructionSizeInBytes,
   1840      -1048576,  // Min offset.
   1841      1048574,   // Max offset.
   1842      2,         // Alignment.
   1843      ReferenceInfo::kDontAlignPc};
   1844 
   1845 
   1846 // B{<c>}{<q>} <label> ; T4
   1847 // BL{<c>}{<q>} <label> ; T1
   1848 static const struct ReferenceInfo kT32BranchInfo =
   1849     {k32BitT32InstructionSizeInBytes,
   1850      -16777216,  // Min offset.
   1851      16777214,   // Max offset.
   1852      2,          // Alignment.
   1853      ReferenceInfo::kDontAlignPc};
   1854 
   1855 
   1856 // BLX{<c>}{<q>} <label> ; T2
   1857 static const struct ReferenceInfo kT32BlxInfo =
   1858     {k32BitT32InstructionSizeInBytes,
   1859      -16777216,  // Min offset.
   1860      16777212,   // Max offset.
   1861      4,          // Alignment.
   1862      ReferenceInfo::kAlignPc};
   1863 
   1864 
   1865 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
   1866 // LDRH{<c>}{<q>} <Rt>, <label> ; A1
   1867 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
   1868 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
   1869 static const struct ReferenceInfo kA32VeryNearDataInfo =
   1870     {kA32InstructionSizeInBytes,
   1871      -255,  // Min offset.
   1872      255,   // Max offset.
   1873      1,     // Alignment.
   1874      ReferenceInfo::kAlignPc};
   1875 
   1876 
   1877 // ADR{<c>}{<q>} <Rd>, <label> ; A1
   1878 static const struct ReferenceInfo kA32AdrInfo = {kA32InstructionSizeInBytes,
   1879                                                  -256,  // Min offset.
   1880                                                  256,   // Max offset.
   1881                                                  1,     // Alignment.
   1882                                                  ReferenceInfo::kAlignPc};
   1883 
   1884 
   1885 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
   1886 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
   1887 static const struct ReferenceInfo kA32DataInfo = {kA32InstructionSizeInBytes,
   1888                                                   -1020,  // Min offset.
   1889                                                   1020,   // Max offset.
   1890                                                   4,      // Alignment.
   1891                                                   ReferenceInfo::kAlignPc};
   1892 
   1893 
   1894 // LDR{<c>}{<q>} <Rt>, <label> ; A1
   1895 // LDRB{<c>}{<q>} <Rt>, <label> ; A1
   1896 // PLD{<c>}{<q>} <label> ; A1
   1897 // PLI{<c>}{<q>} <label> ; A1
   1898 static const struct ReferenceInfo kA32FarDataInfo = {kA32InstructionSizeInBytes,
   1899                                                      -4095,  // Min offset.
   1900                                                      4095,   // Max offset.
   1901                                                      1,      // Alignment.
   1902                                                      ReferenceInfo::kAlignPc};
   1903 
   1904 
   1905 // B{<c>}{<q>} <label> ; A1
   1906 // BL{<c>}{<q>} <label> ; A1
   1907 static const struct ReferenceInfo kA32BranchInfo =
   1908     {kA32InstructionSizeInBytes,
   1909      -33554432,  // Min offset.
   1910      33554428,   // Max offset.
   1911      4,          // Alignment.
   1912      ReferenceInfo::kDontAlignPc};
   1913 
   1914 
   1915 // BLX{<c>}{<q>} <label> ; A2
   1916 static const struct ReferenceInfo kA32BlxInfo = {kA32InstructionSizeInBytes,
   1917                                                  -33554432,  // Min offset.
   1918                                                  33554430,   // Max offset.
   1919                                                  2,          // Alignment.
   1920                                                  ReferenceInfo::kAlignPc};
   1921 
   1922 
   1923 void Assembler::adc(Condition cond,
   1924                     EncodingSize size,
   1925                     Register rd,
   1926                     Register rn,
   1927                     const Operand& operand) {
   1928   VIXL_ASSERT(AllowAssembler());
   1929   CheckIT(cond);
   1930   if (operand.IsImmediate()) {
   1931     uint32_t imm = operand.GetImmediate();
   1932     if (IsUsingT32()) {
   1933       ImmediateT32 immediate_t32(imm);
   1934       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   1935       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   1936           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   1937         EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   1938                    (immediate_t32.GetEncodingValue() & 0xff) |
   1939                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   1940                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   1941         AdvanceIT();
   1942         return;
   1943       }
   1944     } else {
   1945       ImmediateA32 immediate_a32(imm);
   1946       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   1947       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   1948         EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
   1949                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   1950                 immediate_a32.GetEncodingValue());
   1951         return;
   1952       }
   1953     }
   1954   }
   1955   if (operand.IsImmediateShiftedRegister()) {
   1956     Register rm = operand.GetBaseRegister();
   1957     if (operand.IsPlainRegister()) {
   1958       if (IsUsingT32()) {
   1959         // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   1960         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   1961             rm.IsLow()) {
   1962           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
   1963           AdvanceIT();
   1964           return;
   1965         }
   1966       }
   1967     }
   1968     Shift shift = operand.GetShift();
   1969     uint32_t amount = operand.GetShiftAmount();
   1970     if (IsUsingT32()) {
   1971       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   1972       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   1973           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   1974         uint32_t amount_ = amount % 32;
   1975         EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   1976                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   1977                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   1978         AdvanceIT();
   1979         return;
   1980       }
   1981     } else {
   1982       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   1983       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   1984         uint32_t amount_ = amount % 32;
   1985         EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
   1986                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   1987                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   1988         return;
   1989       }
   1990     }
   1991   }
   1992   if (operand.IsRegisterShiftedRegister()) {
   1993     Register rm = operand.GetBaseRegister();
   1994     Shift shift = operand.GetShift();
   1995     Register rs = operand.GetShiftRegister();
   1996     if (IsUsingA32()) {
   1997       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   1998       if (cond.IsNotNever() &&
   1999           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2000            AllowUnpredictable())) {
   2001         EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
   2002                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2003                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2004         return;
   2005       }
   2006     }
   2007   }
   2008   Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
   2009 }
   2010 
   2011 void Assembler::adcs(Condition cond,
   2012                      EncodingSize size,
   2013                      Register rd,
   2014                      Register rn,
   2015                      const Operand& operand) {
   2016   VIXL_ASSERT(AllowAssembler());
   2017   CheckIT(cond);
   2018   if (operand.IsImmediate()) {
   2019     uint32_t imm = operand.GetImmediate();
   2020     if (IsUsingT32()) {
   2021       ImmediateT32 immediate_t32(imm);
   2022       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   2023       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   2024           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   2025         EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2026                    (immediate_t32.GetEncodingValue() & 0xff) |
   2027                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2028                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2029         AdvanceIT();
   2030         return;
   2031       }
   2032     } else {
   2033       ImmediateA32 immediate_a32(imm);
   2034       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2035       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   2036         EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
   2037                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2038                 immediate_a32.GetEncodingValue());
   2039         return;
   2040       }
   2041     }
   2042   }
   2043   if (operand.IsImmediateShiftedRegister()) {
   2044     Register rm = operand.GetBaseRegister();
   2045     if (operand.IsPlainRegister()) {
   2046       if (IsUsingT32()) {
   2047         // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   2048         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2049             rm.IsLow()) {
   2050           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
   2051           AdvanceIT();
   2052           return;
   2053         }
   2054       }
   2055     }
   2056     Shift shift = operand.GetShift();
   2057     uint32_t amount = operand.GetShiftAmount();
   2058     if (IsUsingT32()) {
   2059       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   2060       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   2061           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2062         uint32_t amount_ = amount % 32;
   2063         EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2064                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2065                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2066         AdvanceIT();
   2067         return;
   2068       }
   2069     } else {
   2070       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2071       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2072         uint32_t amount_ = amount % 32;
   2073         EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
   2074                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2075                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2076         return;
   2077       }
   2078     }
   2079   }
   2080   if (operand.IsRegisterShiftedRegister()) {
   2081     Register rm = operand.GetBaseRegister();
   2082     Shift shift = operand.GetShift();
   2083     Register rs = operand.GetShiftRegister();
   2084     if (IsUsingA32()) {
   2085       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2086       if (cond.IsNotNever() &&
   2087           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2088            AllowUnpredictable())) {
   2089         EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
   2090                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2091                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2092         return;
   2093       }
   2094     }
   2095   }
   2096   Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
   2097 }
   2098 
   2099 void Assembler::add(Condition cond,
   2100                     EncodingSize size,
   2101                     Register rd,
   2102                     Register rn,
   2103                     const Operand& operand) {
   2104   VIXL_ASSERT(AllowAssembler());
   2105   CheckIT(cond);
   2106   if (operand.IsImmediate()) {
   2107     uint32_t imm = operand.GetImmediate();
   2108     if (IsUsingT32()) {
   2109       ImmediateT32 immediate_t32(imm);
   2110       // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
   2111       if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
   2112           ((imm % 4) == 0)) {
   2113         uint32_t imm_ = imm >> 2;
   2114         EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
   2115         AdvanceIT();
   2116         return;
   2117       }
   2118       // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
   2119       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2120           (imm <= 7)) {
   2121         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   2122         AdvanceIT();
   2123         return;
   2124       }
   2125       // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   2126       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2127           (imm <= 255)) {
   2128         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2129         AdvanceIT();
   2130         return;
   2131       }
   2132       // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
   2133       if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
   2134           ((imm % 4) == 0)) {
   2135         uint32_t imm_ = imm >> 2;
   2136         EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
   2137         AdvanceIT();
   2138         return;
   2139       }
   2140       // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
   2141       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
   2142           ((imm % 4) == 0)) {
   2143         uint32_t imm_ = imm >> 2;
   2144         EmitT32_16(0xb000 | imm_);
   2145         AdvanceIT();
   2146         return;
   2147       }
   2148       // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
   2149       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
   2150           (!rd.IsPC() || AllowUnpredictable())) {
   2151         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2152                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2153         AdvanceIT();
   2154         return;
   2155       }
   2156       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   2157       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   2158           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   2159         EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2160                    (immediate_t32.GetEncodingValue() & 0xff) |
   2161                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2162                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2163         AdvanceIT();
   2164         return;
   2165       }
   2166       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   2167       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
   2168           (!rd.IsPC() || AllowUnpredictable())) {
   2169         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2170                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2171         AdvanceIT();
   2172         return;
   2173       }
   2174       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
   2175       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   2176           (!rd.IsPC() || AllowUnpredictable())) {
   2177         EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
   2178                    (immediate_t32.GetEncodingValue() & 0xff) |
   2179                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2180                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2181         AdvanceIT();
   2182         return;
   2183       }
   2184       // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
   2185       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
   2186           (!rd.IsPC() || AllowUnpredictable())) {
   2187         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2188                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2189         AdvanceIT();
   2190         return;
   2191       }
   2192     } else {
   2193       ImmediateA32 immediate_a32(imm);
   2194       // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
   2195       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2196         EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
   2197                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2198         return;
   2199       }
   2200       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2201       if (immediate_a32.IsValid() && cond.IsNotNever() &&
   2202           ((rn.GetCode() & 0xd) != 0xd)) {
   2203         EmitA32(0x02800000U | (cond.GetCondition() << 28) |
   2204                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2205                 immediate_a32.GetEncodingValue());
   2206         return;
   2207       }
   2208       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   2209       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2210         EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
   2211                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2212         return;
   2213       }
   2214     }
   2215   }
   2216   if (operand.IsImmediateShiftedRegister()) {
   2217     Register rm = operand.GetBaseRegister();
   2218     if (operand.IsPlainRegister()) {
   2219       if (IsUsingT32()) {
   2220         // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
   2221         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2222             rm.IsLow()) {
   2223           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
   2224                      (rm.GetCode() << 6));
   2225           AdvanceIT();
   2226           return;
   2227         }
   2228         // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
   2229         if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) &&
   2230             (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
   2231               (!rd.IsPC() || !rm.IsPC())) ||
   2232              AllowUnpredictable())) {
   2233           EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
   2234                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   2235           AdvanceIT();
   2236           return;
   2237         }
   2238         // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
   2239         if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) &&
   2240             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   2241              AllowUnpredictable())) {
   2242           EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
   2243                      ((rd.GetCode() & 0x8) << 4));
   2244           AdvanceIT();
   2245           return;
   2246         }
   2247         // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
   2248         if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
   2249           EmitT32_16(0x4485 | (rm.GetCode() << 3));
   2250           AdvanceIT();
   2251           return;
   2252         }
   2253       }
   2254     }
   2255     Shift shift = operand.GetShift();
   2256     uint32_t amount = operand.GetShiftAmount();
   2257     if (IsUsingT32()) {
   2258       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
   2259       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   2260           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2261         uint32_t amount_ = amount % 32;
   2262         EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2263                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2264                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2265         AdvanceIT();
   2266         return;
   2267       }
   2268       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
   2269       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   2270           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2271         uint32_t amount_ = amount % 32;
   2272         EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
   2273                    (operand.GetTypeEncodingValue() << 4) |
   2274                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2275         AdvanceIT();
   2276         return;
   2277       }
   2278     } else {
   2279       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2280       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   2281         uint32_t amount_ = amount % 32;
   2282         EmitA32(0x00800000U | (cond.GetCondition() << 28) |
   2283                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2284                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2285         return;
   2286       }
   2287       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   2288       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2289         uint32_t amount_ = amount % 32;
   2290         EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
   2291                 (rd.GetCode() << 12) | rm.GetCode() |
   2292                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2293         return;
   2294       }
   2295     }
   2296   }
   2297   if (operand.IsRegisterShiftedRegister()) {
   2298     Register rm = operand.GetBaseRegister();
   2299     Shift shift = operand.GetShift();
   2300     Register rs = operand.GetShiftRegister();
   2301     if (IsUsingA32()) {
   2302       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2303       if (cond.IsNotNever() &&
   2304           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2305            AllowUnpredictable())) {
   2306         EmitA32(0x00800010U | (cond.GetCondition() << 28) |
   2307                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2308                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2309         return;
   2310       }
   2311     }
   2312   }
   2313   Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
   2314 }
   2315 
   2316 void Assembler::add(Condition cond, Register rd, const Operand& operand) {
   2317   VIXL_ASSERT(AllowAssembler());
   2318   CheckIT(cond);
   2319   if (operand.IsImmediate()) {
   2320     uint32_t imm = operand.GetImmediate();
   2321     if (IsUsingT32()) {
   2322       // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
   2323       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
   2324         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2325         AdvanceIT();
   2326         return;
   2327       }
   2328     }
   2329   }
   2330   if (operand.IsPlainRegister()) {
   2331     Register rm = operand.GetBaseRegister();
   2332     if (IsUsingT32()) {
   2333       // ADD<c>{<q>} <Rdn>, <Rm> ; T2
   2334       if (InITBlock() && !rm.Is(sp) &&
   2335           (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
   2336             (!rd.IsPC() || !rm.IsPC())) ||
   2337            AllowUnpredictable())) {
   2338         EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
   2339                    (rm.GetCode() << 3));
   2340         AdvanceIT();
   2341         return;
   2342       }
   2343     }
   2344   }
   2345   Delegate(kAdd, &Assembler::add, cond, rd, operand);
   2346 }
   2347 
   2348 void Assembler::adds(Condition cond,
   2349                      EncodingSize size,
   2350                      Register rd,
   2351                      Register rn,
   2352                      const Operand& operand) {
   2353   VIXL_ASSERT(AllowAssembler());
   2354   CheckIT(cond);
   2355   if (operand.IsImmediate()) {
   2356     uint32_t imm = operand.GetImmediate();
   2357     if (IsUsingT32()) {
   2358       ImmediateT32 immediate_t32(imm);
   2359       // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
   2360       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2361           (imm <= 7)) {
   2362         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   2363         AdvanceIT();
   2364         return;
   2365       }
   2366       // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   2367       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2368           (imm <= 255)) {
   2369         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2370         AdvanceIT();
   2371         return;
   2372       }
   2373       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   2374       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   2375           !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
   2376         EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2377                    (immediate_t32.GetEncodingValue() & 0xff) |
   2378                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2379                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2380         AdvanceIT();
   2381         return;
   2382       }
   2383       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
   2384       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   2385           !rd.Is(pc)) {
   2386         EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
   2387                    (immediate_t32.GetEncodingValue() & 0xff) |
   2388                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2389                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2390         AdvanceIT();
   2391         return;
   2392       }
   2393     } else {
   2394       ImmediateA32 immediate_a32(imm);
   2395       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2396       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
   2397         EmitA32(0x02900000U | (cond.GetCondition() << 28) |
   2398                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2399                 immediate_a32.GetEncodingValue());
   2400         return;
   2401       }
   2402       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   2403       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2404         EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
   2405                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2406         return;
   2407       }
   2408     }
   2409   }
   2410   if (operand.IsImmediateShiftedRegister()) {
   2411     Register rm = operand.GetBaseRegister();
   2412     if (operand.IsPlainRegister()) {
   2413       if (IsUsingT32()) {
   2414         // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   2415         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2416             rm.IsLow()) {
   2417           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
   2418                      (rm.GetCode() << 6));
   2419           AdvanceIT();
   2420           return;
   2421         }
   2422       }
   2423     }
   2424     Shift shift = operand.GetShift();
   2425     uint32_t amount = operand.GetShiftAmount();
   2426     if (IsUsingT32()) {
   2427       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
   2428       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   2429           !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2430         uint32_t amount_ = amount % 32;
   2431         EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2432                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2433                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2434         AdvanceIT();
   2435         return;
   2436       }
   2437       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
   2438       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   2439           !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
   2440         uint32_t amount_ = amount % 32;
   2441         EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
   2442                    (operand.GetTypeEncodingValue() << 4) |
   2443                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2444         AdvanceIT();
   2445         return;
   2446       }
   2447     } else {
   2448       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2449       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   2450         uint32_t amount_ = amount % 32;
   2451         EmitA32(0x00900000U | (cond.GetCondition() << 28) |
   2452                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2453                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2454         return;
   2455       }
   2456       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   2457       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2458         uint32_t amount_ = amount % 32;
   2459         EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
   2460                 (rd.GetCode() << 12) | rm.GetCode() |
   2461                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2462         return;
   2463       }
   2464     }
   2465   }
   2466   if (operand.IsRegisterShiftedRegister()) {
   2467     Register rm = operand.GetBaseRegister();
   2468     Shift shift = operand.GetShift();
   2469     Register rs = operand.GetShiftRegister();
   2470     if (IsUsingA32()) {
   2471       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2472       if (cond.IsNotNever() &&
   2473           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2474            AllowUnpredictable())) {
   2475         EmitA32(0x00900010U | (cond.GetCondition() << 28) |
   2476                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2477                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2478         return;
   2479       }
   2480     }
   2481   }
   2482   Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
   2483 }
   2484 
   2485 void Assembler::adds(Register rd, const Operand& operand) {
   2486   VIXL_ASSERT(AllowAssembler());
   2487   CheckIT(al);
   2488   if (operand.IsImmediate()) {
   2489     uint32_t imm = operand.GetImmediate();
   2490     if (IsUsingT32()) {
   2491       // ADDS{<q>} <Rdn>, #<imm8> ; T2
   2492       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
   2493         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2494         AdvanceIT();
   2495         return;
   2496       }
   2497     }
   2498   }
   2499   Delegate(kAdds, &Assembler::adds, rd, operand);
   2500 }
   2501 
   2502 void Assembler::addw(Condition cond,
   2503                      Register rd,
   2504                      Register rn,
   2505                      const Operand& operand) {
   2506   VIXL_ASSERT(AllowAssembler());
   2507   CheckIT(cond);
   2508   if (operand.IsImmediate()) {
   2509     uint32_t imm = operand.GetImmediate();
   2510     if (IsUsingT32()) {
   2511       // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
   2512       if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2513         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2514                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2515         AdvanceIT();
   2516         return;
   2517       }
   2518       // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   2519       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
   2520           (!rd.IsPC() || AllowUnpredictable())) {
   2521         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2522                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2523         AdvanceIT();
   2524         return;
   2525       }
   2526       // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
   2527       if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2528         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2529                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2530         AdvanceIT();
   2531         return;
   2532       }
   2533     }
   2534   }
   2535   Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
   2536 }
   2537 
   2538 void Assembler::adr(Condition cond,
   2539                     EncodingSize size,
   2540                     Register rd,
   2541                     Location* location) {
   2542   VIXL_ASSERT(AllowAssembler());
   2543   CheckIT(cond);
   2544   Location::Offset offset =
   2545       location->IsBound()
   2546           ? location->GetLocation() -
   2547                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   2548           : 0;
   2549   if (IsUsingT32()) {
   2550     int32_t neg_offset = -offset;
   2551     // ADR{<c>}{<q>} <Rd>, <label> ; T1
   2552     if (!size.IsWide() && rd.IsLow() &&
   2553         ((location->IsBound() && (offset >= 0) && (offset <= 1020) &&
   2554           ((offset & 0x3) == 0)) ||
   2555          (!location->IsBound() && size.IsNarrow()))) {
   2556       static class EmitOp : public Location::EmitOperator {
   2557        public:
   2558         EmitOp() : Location::EmitOperator(T32) {}
   2559         virtual uint32_t Encode(uint32_t instr,
   2560                                 Location::Offset program_counter,
   2561                                 const Location* loc) const VIXL_OVERRIDE {
   2562           program_counter += kT32PcDelta;
   2563           Location::Offset off =
   2564               loc->GetLocation() - AlignDown(program_counter, 4);
   2565           VIXL_ASSERT((off >= 0) && (off <= 1020) && ((off & 0x3) == 0));
   2566           const int32_t target = off >> 2;
   2567           return instr | (target & 0xff);
   2568         }
   2569       } immop;
   2570       EmitT32_16(
   2571           Link(0xa000 | (rd.GetCode() << 8), location, immop, &kT16DataInfo));
   2572       AdvanceIT();
   2573       return;
   2574     }
   2575     // ADR{<c>}{<q>} <Rd>, <label> ; T2
   2576     if (!size.IsNarrow() && location->IsBound() && (neg_offset > 0) &&
   2577         (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2578       EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
   2579                  ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
   2580       AdvanceIT();
   2581       return;
   2582     }
   2583     // ADR{<c>}{<q>} <Rd>, <label> ; T3
   2584     if (!size.IsNarrow() &&
   2585         (!location->IsBound() || ((offset >= 0) && (offset <= 4095))) &&
   2586         (!rd.IsPC() || AllowUnpredictable())) {
   2587       static class EmitOp : public Location::EmitOperator {
   2588        public:
   2589         EmitOp() : Location::EmitOperator(T32) {}
   2590         virtual uint32_t Encode(uint32_t instr,
   2591                                 Location::Offset program_counter,
   2592                                 const Location* loc) const VIXL_OVERRIDE {
   2593           program_counter += kT32PcDelta;
   2594           Location::Offset off =
   2595               loc->GetLocation() - AlignDown(program_counter, 4);
   2596           int32_t target;
   2597           if ((off >= 0) && (off <= 4095)) {
   2598             target = off;
   2599           } else {
   2600             target = -off;
   2601             VIXL_ASSERT((target >= 0) && (target <= 4095));
   2602             // Emit the T2 encoding.
   2603             instr |= 0x00a00000;
   2604           }
   2605           return instr | (target & 0xff) | ((target & 0x700) << 4) |
   2606                  ((target & 0x800) << 15);
   2607         }
   2608       } immop;
   2609       EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8),
   2610                       location,
   2611                       immop,
   2612                       &kT32FarDataInfo));
   2613       AdvanceIT();
   2614       return;
   2615     }
   2616   } else {
   2617     ImmediateA32 positive_immediate_a32(offset);
   2618     ImmediateA32 negative_immediate_a32(-offset);
   2619     // ADR{<c>}{<q>} <Rd>, <label> ; A1
   2620     if ((!location->IsBound() || positive_immediate_a32.IsValid()) &&
   2621         cond.IsNotNever()) {
   2622       static class EmitOp : public Location::EmitOperator {
   2623        public:
   2624         EmitOp() : Location::EmitOperator(A32) {}
   2625         virtual uint32_t Encode(uint32_t instr,
   2626                                 Location::Offset program_counter,
   2627                                 const Location* loc) const VIXL_OVERRIDE {
   2628           program_counter += kA32PcDelta;
   2629           Location::Offset off =
   2630               loc->GetLocation() - AlignDown(program_counter, 4);
   2631           int32_t target;
   2632           ImmediateA32 pos_imm_a32(off);
   2633           if (pos_imm_a32.IsValid()) {
   2634             target = pos_imm_a32.GetEncodingValue();
   2635           } else {
   2636             ImmediateA32 neg_imm_a32(-off);
   2637             VIXL_ASSERT(neg_imm_a32.IsValid());
   2638             // Emit the A2 encoding.
   2639             target = neg_imm_a32.GetEncodingValue();
   2640             instr = (instr & ~0x00f00000) | 0x00400000;
   2641           }
   2642           return instr | (target & 0xfff);
   2643         }
   2644       } immop;
   2645       EmitA32(
   2646           Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
   2647                location,
   2648                immop,
   2649                &kA32AdrInfo));
   2650       return;
   2651     }
   2652     // ADR{<c>}{<q>} <Rd>, <label> ; A2
   2653     if (location->IsBound() && negative_immediate_a32.IsValid() &&
   2654         cond.IsNotNever()) {
   2655       EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   2656               negative_immediate_a32.GetEncodingValue());
   2657       return;
   2658     }
   2659   }
   2660   Delegate(kAdr, &Assembler::adr, cond, size, rd, location);
   2661 }
   2662 
   2663 bool Assembler::adr_info(Condition cond,
   2664                          EncodingSize size,
   2665                          Register rd,
   2666                          Location* location,
   2667                          const struct ReferenceInfo** info) {
   2668   VIXL_ASSERT(!location->IsBound());
   2669   USE(location);
   2670   if (IsUsingT32()) {
   2671     // ADR{<c>}{<q>} <Rd>, <label> ; T1
   2672     if (!size.IsWide() && rd.IsLow() && size.IsNarrow()) {
   2673       *info = &kT16DataInfo;
   2674       return true;
   2675     }
   2676     // Skipped T2, as it is a negative offset variant.
   2677     // The minimum offset is included in the corresponding
   2678     // positive variant.
   2679     // ADR{<c>}{<q>} <Rd>, <label> ; T3
   2680     if (!size.IsNarrow()) {
   2681       *info = &kT32FarDataInfo;
   2682       return true;
   2683     }
   2684   } else {
   2685     // ADR{<c>}{<q>} <Rd>, <label> ; A1
   2686     if (cond.IsNotNever()) {
   2687       *info = &kA32AdrInfo;
   2688       return true;
   2689     }
   2690     // Skipped A2, as it is a negative offset variant.
   2691     // The minimum offset is included in the corresponding
   2692     // positive variant.
   2693   }
   2694   return false;
   2695 }
   2696 
   2697 void Assembler::and_(Condition cond,
   2698                      EncodingSize size,
   2699                      Register rd,
   2700                      Register rn,
   2701                      const Operand& operand) {
   2702   VIXL_ASSERT(AllowAssembler());
   2703   CheckIT(cond);
   2704   if (operand.IsImmediate()) {
   2705     uint32_t imm = operand.GetImmediate();
   2706     if (IsUsingT32()) {
   2707       ImmediateT32 immediate_t32(imm);
   2708       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   2709       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   2710           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   2711         EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2712                    (immediate_t32.GetEncodingValue() & 0xff) |
   2713                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2714                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2715         AdvanceIT();
   2716         return;
   2717       }
   2718     } else {
   2719       ImmediateA32 immediate_a32(imm);
   2720       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2721       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   2722         EmitA32(0x02000000U | (cond.GetCondition() << 28) |
   2723                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2724                 immediate_a32.GetEncodingValue());
   2725         return;
   2726       }
   2727     }
   2728   }
   2729   if (operand.IsImmediateShiftedRegister()) {
   2730     Register rm = operand.GetBaseRegister();
   2731     if (operand.IsPlainRegister()) {
   2732       if (IsUsingT32()) {
   2733         // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   2734         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2735             rm.IsLow()) {
   2736           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
   2737           AdvanceIT();
   2738           return;
   2739         }
   2740       }
   2741     }
   2742     Shift shift = operand.GetShift();
   2743     uint32_t amount = operand.GetShiftAmount();
   2744     if (IsUsingT32()) {
   2745       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   2746       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   2747           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2748         uint32_t amount_ = amount % 32;
   2749         EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2750                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2751                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2752         AdvanceIT();
   2753         return;
   2754       }
   2755     } else {
   2756       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2757       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2758         uint32_t amount_ = amount % 32;
   2759         EmitA32(0x00000000U | (cond.GetCondition() << 28) |
   2760                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2761                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2762         return;
   2763       }
   2764     }
   2765   }
   2766   if (operand.IsRegisterShiftedRegister()) {
   2767     Register rm = operand.GetBaseRegister();
   2768     Shift shift = operand.GetShift();
   2769     Register rs = operand.GetShiftRegister();
   2770     if (IsUsingA32()) {
   2771       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2772       if (cond.IsNotNever() &&
   2773           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2774            AllowUnpredictable())) {
   2775         EmitA32(0x00000010U | (cond.GetCondition() << 28) |
   2776                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2777                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2778         return;
   2779       }
   2780     }
   2781   }
   2782   Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
   2783 }
   2784 
   2785 void Assembler::ands(Condition cond,
   2786                      EncodingSize size,
   2787                      Register rd,
   2788                      Register rn,
   2789                      const Operand& operand) {
   2790   VIXL_ASSERT(AllowAssembler());
   2791   CheckIT(cond);
   2792   if (operand.IsImmediate()) {
   2793     uint32_t imm = operand.GetImmediate();
   2794     if (IsUsingT32()) {
   2795       ImmediateT32 immediate_t32(imm);
   2796       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   2797       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) &&
   2798           (!rn.IsPC() || AllowUnpredictable())) {
   2799         EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2800                    (immediate_t32.GetEncodingValue() & 0xff) |
   2801                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2802                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2803         AdvanceIT();
   2804         return;
   2805       }
   2806     } else {
   2807       ImmediateA32 immediate_a32(imm);
   2808       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2809       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   2810         EmitA32(0x02100000U | (cond.GetCondition() << 28) |
   2811                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2812                 immediate_a32.GetEncodingValue());
   2813         return;
   2814       }
   2815     }
   2816   }
   2817   if (operand.IsImmediateShiftedRegister()) {
   2818     Register rm = operand.GetBaseRegister();
   2819     if (operand.IsPlainRegister()) {
   2820       if (IsUsingT32()) {
   2821         // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   2822         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2823             rm.IsLow()) {
   2824           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
   2825           AdvanceIT();
   2826           return;
   2827         }
   2828       }
   2829     }
   2830     Shift shift = operand.GetShift();
   2831     uint32_t amount = operand.GetShiftAmount();
   2832     if (IsUsingT32()) {
   2833       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   2834       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) &&
   2835           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2836         uint32_t amount_ = amount % 32;
   2837         EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2838                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2839                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2840         AdvanceIT();
   2841         return;
   2842       }
   2843     } else {
   2844       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2845       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2846         uint32_t amount_ = amount % 32;
   2847         EmitA32(0x00100000U | (cond.GetCondition() << 28) |
   2848                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2849                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2850         return;
   2851       }
   2852     }
   2853   }
   2854   if (operand.IsRegisterShiftedRegister()) {
   2855     Register rm = operand.GetBaseRegister();
   2856     Shift shift = operand.GetShift();
   2857     Register rs = operand.GetShiftRegister();
   2858     if (IsUsingA32()) {
   2859       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2860       if (cond.IsNotNever() &&
   2861           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2862            AllowUnpredictable())) {
   2863         EmitA32(0x00100010U | (cond.GetCondition() << 28) |
   2864                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2865                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2866         return;
   2867       }
   2868     }
   2869   }
   2870   Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
   2871 }
   2872 
   2873 void Assembler::asr(Condition cond,
   2874                     EncodingSize size,
   2875                     Register rd,
   2876                     Register rm,
   2877                     const Operand& operand) {
   2878   VIXL_ASSERT(AllowAssembler());
   2879   CheckIT(cond);
   2880   if (operand.IsImmediate()) {
   2881     uint32_t imm = operand.GetImmediate();
   2882     if (IsUsingT32()) {
   2883       // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   2884       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   2885           (imm >= 1) && (imm <= 32)) {
   2886         uint32_t amount_ = imm % 32;
   2887         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
   2888                    (amount_ << 6));
   2889         AdvanceIT();
   2890         return;
   2891       }
   2892       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   2893       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
   2894           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2895         uint32_t amount_ = imm % 32;
   2896         EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
   2897                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2898         AdvanceIT();
   2899         return;
   2900       }
   2901     } else {
   2902       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   2903       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   2904         uint32_t amount_ = imm % 32;
   2905         EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
   2906                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   2907         return;
   2908       }
   2909     }
   2910   }
   2911   if (operand.IsPlainRegister()) {
   2912     Register rs = operand.GetBaseRegister();
   2913     if (IsUsingT32()) {
   2914       // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   2915       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   2916           rs.IsLow()) {
   2917         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   2918         AdvanceIT();
   2919         return;
   2920       }
   2921       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   2922       if (!size.IsNarrow() &&
   2923           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   2924         EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   2925                    rs.GetCode());
   2926         AdvanceIT();
   2927         return;
   2928       }
   2929     } else {
   2930       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   2931       if (cond.IsNotNever() &&
   2932           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   2933         EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
   2934                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   2935         return;
   2936       }
   2937     }
   2938   }
   2939   Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
   2940 }
   2941 
   2942 void Assembler::asrs(Condition cond,
   2943                      EncodingSize size,
   2944                      Register rd,
   2945                      Register rm,
   2946                      const Operand& operand) {
   2947   VIXL_ASSERT(AllowAssembler());
   2948   CheckIT(cond);
   2949   if (operand.IsImmediate()) {
   2950     uint32_t imm = operand.GetImmediate();
   2951     if (IsUsingT32()) {
   2952       // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   2953       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   2954           (imm >= 1) && (imm <= 32)) {
   2955         uint32_t amount_ = imm % 32;
   2956         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
   2957                    (amount_ << 6));
   2958         AdvanceIT();
   2959         return;
   2960       }
   2961       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   2962       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
   2963           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2964         uint32_t amount_ = imm % 32;
   2965         EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
   2966                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2967         AdvanceIT();
   2968         return;
   2969       }
   2970     } else {
   2971       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   2972       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   2973         uint32_t amount_ = imm % 32;
   2974         EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
   2975                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   2976         return;
   2977       }
   2978     }
   2979   }
   2980   if (operand.IsPlainRegister()) {
   2981     Register rs = operand.GetBaseRegister();
   2982     if (IsUsingT32()) {
   2983       // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   2984       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   2985           rs.IsLow()) {
   2986         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   2987         AdvanceIT();
   2988         return;
   2989       }
   2990       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   2991       if (!size.IsNarrow() &&
   2992           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   2993         EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   2994                    rs.GetCode());
   2995         AdvanceIT();
   2996         return;
   2997       }
   2998     } else {
   2999       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   3000       if (cond.IsNotNever() &&
   3001           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   3002         EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
   3003                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   3004         return;
   3005       }
   3006     }
   3007   }
   3008   Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
   3009 }
   3010 
   3011 void Assembler::b(Condition cond, EncodingSize size, Location* location) {
   3012   VIXL_ASSERT(AllowAssembler());
   3013   Location::Offset offset =
   3014       location->IsBound()
   3015           ? location->GetLocation() -
   3016                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3017           : 0;
   3018   if (IsUsingT32()) {
   3019     // B<c>{<q>} <label> ; T1
   3020     if (OutsideITBlock() && !size.IsWide() &&
   3021         ((location->IsBound() && (offset >= -256) && (offset <= 254) &&
   3022           ((offset & 0x1) == 0)) ||
   3023          (!location->IsBound() && size.IsNarrow())) &&
   3024         !cond.Is(al) && cond.IsNotNever()) {
   3025       static class EmitOp : public Location::EmitOperator {
   3026        public:
   3027         EmitOp() : Location::EmitOperator(T32) {}
   3028         virtual uint32_t Encode(uint32_t instr,
   3029                                 Location::Offset program_counter,
   3030                                 const Location* loc) const VIXL_OVERRIDE {
   3031           program_counter += kT32PcDelta;
   3032           Location::Offset off = loc->GetLocation() - program_counter;
   3033           VIXL_ASSERT((off >= -256) && (off <= 254) && ((off & 0x1) == 0));
   3034           const int32_t target = off >> 1;
   3035           return instr | (target & 0xff);
   3036         }
   3037       } immop;
   3038       EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8),
   3039                       location,
   3040                       immop,
   3041                       &kT16ConditionalBranchInfo));
   3042       AdvanceIT();
   3043       return;
   3044     }
   3045     // B{<c>}{<q>} <label> ; T2
   3046     if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
   3047         ((location->IsBound() && (offset >= -2048) && (offset <= 2046) &&
   3048           ((offset & 0x1) == 0)) ||
   3049          (!location->IsBound() && size.IsNarrow()))) {
   3050       CheckIT(cond);
   3051       static class EmitOp : public Location::EmitOperator {
   3052        public:
   3053         EmitOp() : Location::EmitOperator(T32) {}
   3054         virtual uint32_t Encode(uint32_t instr,
   3055                                 Location::Offset program_counter,
   3056                                 const Location* loc) const VIXL_OVERRIDE {
   3057           program_counter += kT32PcDelta;
   3058           Location::Offset off = loc->GetLocation() - program_counter;
   3059           VIXL_ASSERT((off >= -2048) && (off <= 2046) && ((off & 0x1) == 0));
   3060           const int32_t target = off >> 1;
   3061           return instr | (target & 0x7ff);
   3062         }
   3063       } immop;
   3064       EmitT32_16(Link(0xe000, location, immop, &kT16BranchInfo));
   3065       AdvanceIT();
   3066       return;
   3067     }
   3068     // B<c>{<q>} <label> ; T3
   3069     if (OutsideITBlock() && !size.IsNarrow() &&
   3070         ((location->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
   3071           ((offset & 0x1) == 0)) ||
   3072          !location->IsBound()) &&
   3073         !cond.Is(al) && cond.IsNotNever()) {
   3074       static class EmitOp : public Location::EmitOperator {
   3075        public:
   3076         EmitOp() : Location::EmitOperator(T32) {}
   3077         virtual uint32_t Encode(uint32_t instr,
   3078                                 Location::Offset program_counter,
   3079                                 const Location* loc) const VIXL_OVERRIDE {
   3080           program_counter += kT32PcDelta;
   3081           Location::Offset off = loc->GetLocation() - program_counter;
   3082           VIXL_ASSERT((off >= -1048576) && (off <= 1048574) &&
   3083                       ((off & 0x1) == 0));
   3084           const int32_t target = off >> 1;
   3085           return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
   3086                  ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
   3087                  ((target & 0x80000) << 7);
   3088         }
   3089       } immop;
   3090       EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22),
   3091                       location,
   3092                       immop,
   3093                       &kT32ConditionalBranchInfo));
   3094       AdvanceIT();
   3095       return;
   3096     }
   3097     // B{<c>}{<q>} <label> ; T4
   3098     if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
   3099         ((location->IsBound() && (offset >= -16777216) &&
   3100           (offset <= 16777214) && ((offset & 0x1) == 0)) ||
   3101          !location->IsBound())) {
   3102       CheckIT(cond);
   3103       static class EmitOp : public Location::EmitOperator {
   3104        public:
   3105         EmitOp() : Location::EmitOperator(T32) {}
   3106         virtual uint32_t Encode(uint32_t instr,
   3107                                 Location::Offset program_counter,
   3108                                 const Location* loc) const VIXL_OVERRIDE {
   3109           program_counter += kT32PcDelta;
   3110           Location::Offset off = loc->GetLocation() - program_counter;
   3111           VIXL_ASSERT((off >= -16777216) && (off <= 16777214) &&
   3112                       ((off & 0x1) == 0));
   3113           int32_t target = off >> 1;
   3114           uint32_t S = target & (1 << 23);
   3115           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
   3116           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
   3117                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
   3118                  ((target & 0x800000) << 3);
   3119         }
   3120       } immop;
   3121       EmitT32_32(Link(0xf0009000U, location, immop, &kT32BranchInfo));
   3122       AdvanceIT();
   3123       return;
   3124     }
   3125   } else {
   3126     // B{<c>}{<q>} <label> ; A1
   3127     if (((location->IsBound() && (offset >= -33554432) &&
   3128           (offset <= 33554428) && ((offset & 0x3) == 0)) ||
   3129          !location->IsBound()) &&
   3130         cond.IsNotNever()) {
   3131       static class EmitOp : public Location::EmitOperator {
   3132        public:
   3133         EmitOp() : Location::EmitOperator(A32) {}
   3134         virtual uint32_t Encode(uint32_t instr,
   3135                                 Location::Offset program_counter,
   3136                                 const Location* loc) const VIXL_OVERRIDE {
   3137           program_counter += kA32PcDelta;
   3138           Location::Offset off = loc->GetLocation() - program_counter;
   3139           VIXL_ASSERT((off >= -33554432) && (off <= 33554428) &&
   3140                       ((off & 0x3) == 0));
   3141           const int32_t target = off >> 2;
   3142           return instr | (target & 0xffffff);
   3143         }
   3144       } immop;
   3145       EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28),
   3146                    location,
   3147                    immop,
   3148                    &kA32BranchInfo));
   3149       return;
   3150     }
   3151   }
   3152   Delegate(kB, &Assembler::b, cond, size, location);
   3153 }
   3154 
   3155 bool Assembler::b_info(Condition cond,
   3156                        EncodingSize size,
   3157                        Location* location,
   3158                        const struct ReferenceInfo** info) {
   3159   VIXL_ASSERT(!location->IsBound());
   3160   USE(location);
   3161   if (IsUsingT32()) {
   3162     // B<c>{<q>} <label> ; T1
   3163     if (OutsideITBlock() && !size.IsWide() && size.IsNarrow() && !cond.Is(al) &&
   3164         cond.IsNotNever()) {
   3165       *info = &kT16ConditionalBranchInfo;
   3166       return true;
   3167     }
   3168     // B{<c>}{<q>} <label> ; T2
   3169     if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && size.IsNarrow()) {
   3170       *info = &kT16BranchInfo;
   3171       return true;
   3172     }
   3173     // B<c>{<q>} <label> ; T3
   3174     if (OutsideITBlock() && !size.IsNarrow() && !cond.Is(al) &&
   3175         cond.IsNotNever()) {
   3176       *info = &kT32ConditionalBranchInfo;
   3177       return true;
   3178     }
   3179     // B{<c>}{<q>} <label> ; T4
   3180     if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow()) {
   3181       *info = &kT32BranchInfo;
   3182       return true;
   3183     }
   3184   } else {
   3185     // B{<c>}{<q>} <label> ; A1
   3186     if (cond.IsNotNever()) {
   3187       *info = &kA32BranchInfo;
   3188       return true;
   3189     }
   3190   }
   3191   return false;
   3192 }
   3193 
   3194 void Assembler::bfc(Condition cond, Register rd, uint32_t lsb, uint32_t width) {
   3195   VIXL_ASSERT(AllowAssembler());
   3196   CheckIT(cond);
   3197   if (IsUsingT32()) {
   3198     // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
   3199     if ((lsb <= 31) && (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
   3200                         AllowUnpredictable())) {
   3201       uint32_t msb = lsb + width - 1;
   3202       EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
   3203                  ((lsb & 0x1c) << 10) | msb);
   3204       AdvanceIT();
   3205       return;
   3206     }
   3207   } else {
   3208     // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
   3209     if ((lsb <= 31) && cond.IsNotNever() &&
   3210         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
   3211          AllowUnpredictable())) {
   3212       uint32_t msb = lsb + width - 1;
   3213       EmitA32(0x07c0001fU | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3214               (lsb << 7) | (msb << 16));
   3215       return;
   3216     }
   3217   }
   3218   Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, width);
   3219 }
   3220 
   3221 void Assembler::bfi(
   3222     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
   3223   VIXL_ASSERT(AllowAssembler());
   3224   CheckIT(cond);
   3225   if (IsUsingT32()) {
   3226     // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
   3227     if ((lsb <= 31) && !rn.Is(pc) &&
   3228         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
   3229          AllowUnpredictable())) {
   3230       uint32_t msb = lsb + width - 1;
   3231       EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3232                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
   3233       AdvanceIT();
   3234       return;
   3235     }
   3236   } else {
   3237     // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
   3238     if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
   3239         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
   3240          AllowUnpredictable())) {
   3241       uint32_t msb = lsb + width - 1;
   3242       EmitA32(0x07c00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3243               rn.GetCode() | (lsb << 7) | (msb << 16));
   3244       return;
   3245     }
   3246   }
   3247   Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, width);
   3248 }
   3249 
   3250 void Assembler::bic(Condition cond,
   3251                     EncodingSize size,
   3252                     Register rd,
   3253                     Register rn,
   3254                     const Operand& operand) {
   3255   VIXL_ASSERT(AllowAssembler());
   3256   CheckIT(cond);
   3257   if (operand.IsImmediate()) {
   3258     uint32_t imm = operand.GetImmediate();
   3259     if (IsUsingT32()) {
   3260       ImmediateT32 immediate_t32(imm);
   3261       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   3262       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   3263           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   3264         EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3265                    (immediate_t32.GetEncodingValue() & 0xff) |
   3266                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3267                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3268         AdvanceIT();
   3269         return;
   3270       }
   3271     } else {
   3272       ImmediateA32 immediate_a32(imm);
   3273       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   3274       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3275         EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
   3276                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   3277                 immediate_a32.GetEncodingValue());
   3278         return;
   3279       }
   3280     }
   3281   }
   3282   if (operand.IsImmediateShiftedRegister()) {
   3283     Register rm = operand.GetBaseRegister();
   3284     if (operand.IsPlainRegister()) {
   3285       if (IsUsingT32()) {
   3286         // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   3287         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   3288             rm.IsLow()) {
   3289           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
   3290           AdvanceIT();
   3291           return;
   3292         }
   3293       }
   3294     }
   3295     Shift shift = operand.GetShift();
   3296     uint32_t amount = operand.GetShiftAmount();
   3297     if (IsUsingT32()) {
   3298       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3299       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   3300           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3301         uint32_t amount_ = amount % 32;
   3302         EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3303                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   3304                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3305         AdvanceIT();
   3306         return;
   3307       }
   3308     } else {
   3309       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3310       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3311         uint32_t amount_ = amount % 32;
   3312         EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
   3313                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3314                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3315         return;
   3316       }
   3317     }
   3318   }
   3319   if (operand.IsRegisterShiftedRegister()) {
   3320     Register rm = operand.GetBaseRegister();
   3321     Shift shift = operand.GetShift();
   3322     Register rs = operand.GetShiftRegister();
   3323     if (IsUsingA32()) {
   3324       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   3325       if (cond.IsNotNever() &&
   3326           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   3327            AllowUnpredictable())) {
   3328         EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
   3329                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3330                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   3331         return;
   3332       }
   3333     }
   3334   }
   3335   Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
   3336 }
   3337 
   3338 void Assembler::bics(Condition cond,
   3339                      EncodingSize size,
   3340                      Register rd,
   3341                      Register rn,
   3342                      const Operand& operand) {
   3343   VIXL_ASSERT(AllowAssembler());
   3344   CheckIT(cond);
   3345   if (operand.IsImmediate()) {
   3346     uint32_t imm = operand.GetImmediate();
   3347     if (IsUsingT32()) {
   3348       ImmediateT32 immediate_t32(imm);
   3349       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   3350       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   3351           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   3352         EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3353                    (immediate_t32.GetEncodingValue() & 0xff) |
   3354                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3355                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3356         AdvanceIT();
   3357         return;
   3358       }
   3359     } else {
   3360       ImmediateA32 immediate_a32(imm);
   3361       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   3362       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3363         EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
   3364                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   3365                 immediate_a32.GetEncodingValue());
   3366         return;
   3367       }
   3368     }
   3369   }
   3370   if (operand.IsImmediateShiftedRegister()) {
   3371     Register rm = operand.GetBaseRegister();
   3372     if (operand.IsPlainRegister()) {
   3373       if (IsUsingT32()) {
   3374         // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   3375         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   3376             rm.IsLow()) {
   3377           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
   3378           AdvanceIT();
   3379           return;
   3380         }
   3381       }
   3382     }
   3383     Shift shift = operand.GetShift();
   3384     uint32_t amount = operand.GetShiftAmount();
   3385     if (IsUsingT32()) {
   3386       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3387       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   3388           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3389         uint32_t amount_ = amount % 32;
   3390         EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3391                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   3392                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3393         AdvanceIT();
   3394         return;
   3395       }
   3396     } else {
   3397       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3398       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3399         uint32_t amount_ = amount % 32;
   3400         EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
   3401                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3402                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3403         return;
   3404       }
   3405     }
   3406   }
   3407   if (operand.IsRegisterShiftedRegister()) {
   3408     Register rm = operand.GetBaseRegister();
   3409     Shift shift = operand.GetShift();
   3410     Register rs = operand.GetShiftRegister();
   3411     if (IsUsingA32()) {
   3412       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   3413       if (cond.IsNotNever() &&
   3414           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   3415            AllowUnpredictable())) {
   3416         EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
   3417                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3418                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   3419         return;
   3420       }
   3421     }
   3422   }
   3423   Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
   3424 }
   3425 
   3426 void Assembler::bkpt(Condition cond, uint32_t imm) {
   3427   VIXL_ASSERT(AllowAssembler());
   3428   CheckIT(cond);
   3429   if (IsUsingT32()) {
   3430     // BKPT{<q>} {#}<imm> ; T1
   3431     if ((imm <= 255)) {
   3432       EmitT32_16(0xbe00 | imm);
   3433       AdvanceIT();
   3434       return;
   3435     }
   3436   } else {
   3437     // BKPT{<q>} {#}<imm> ; A1
   3438     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   3439       EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   3440               ((imm & 0xfff0) << 4));
   3441       return;
   3442     }
   3443   }
   3444   Delegate(kBkpt, &Assembler::bkpt, cond, imm);
   3445 }
   3446 
   3447 void Assembler::bl(Condition cond, Location* location) {
   3448   VIXL_ASSERT(AllowAssembler());
   3449   CheckIT(cond);
   3450   Location::Offset offset =
   3451       location->IsBound()
   3452           ? location->GetLocation() -
   3453                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3454           : 0;
   3455   if (IsUsingT32()) {
   3456     // BL{<c>}{<q>} <label> ; T1
   3457     if (((location->IsBound() && (offset >= -16777216) &&
   3458           (offset <= 16777214) && ((offset & 0x1) == 0)) ||
   3459          !location->IsBound()) &&
   3460         (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
   3461       static class EmitOp : public Location::EmitOperator {
   3462        public:
   3463         EmitOp() : Location::EmitOperator(T32) {}
   3464         virtual uint32_t Encode(uint32_t instr,
   3465                                 Location::Offset program_counter,
   3466                                 const Location* loc) const VIXL_OVERRIDE {
   3467           program_counter += kT32PcDelta;
   3468           Location::Offset off = loc->GetLocation() - program_counter;
   3469           VIXL_ASSERT((off >= -16777216) && (off <= 16777214) &&
   3470                       ((off & 0x1) == 0));
   3471           int32_t target = off >> 1;
   3472           uint32_t S = target & (1 << 23);
   3473           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
   3474           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
   3475                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
   3476                  ((target & 0x800000) << 3);
   3477         }
   3478       } immop;
   3479       EmitT32_32(Link(0xf000d000U, location, immop, &kT32BranchInfo));
   3480       AdvanceIT();
   3481       return;
   3482     }
   3483   } else {
   3484     // BL{<c>}{<q>} <label> ; A1
   3485     if (((location->IsBound() && (offset >= -33554432) &&
   3486           (offset <= 33554428) && ((offset & 0x3) == 0)) ||
   3487          !location->IsBound()) &&
   3488         cond.IsNotNever()) {
   3489       static class EmitOp : public Location::EmitOperator {
   3490        public:
   3491         EmitOp() : Location::EmitOperator(A32) {}
   3492         virtual uint32_t Encode(uint32_t instr,
   3493                                 Location::Offset program_counter,
   3494                                 const Location* loc) const VIXL_OVERRIDE {
   3495           program_counter += kA32PcDelta;
   3496           Location::Offset off = loc->GetLocation() - program_counter;
   3497           VIXL_ASSERT((off >= -33554432) && (off <= 33554428) &&
   3498                       ((off & 0x3) == 0));
   3499           const int32_t target = off >> 2;
   3500           return instr | (target & 0xffffff);
   3501         }
   3502       } immop;
   3503       EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28),
   3504                    location,
   3505                    immop,
   3506                    &kA32BranchInfo));
   3507       return;
   3508     }
   3509   }
   3510   Delegate(kBl, &Assembler::bl, cond, location);
   3511 }
   3512 
   3513 bool Assembler::bl_info(Condition cond,
   3514                         Location* location,
   3515                         const struct ReferenceInfo** info) {
   3516   VIXL_ASSERT(!location->IsBound());
   3517   USE(location);
   3518   if (IsUsingT32()) {
   3519     // BL{<c>}{<q>} <label> ; T1
   3520     if (true) {
   3521       *info = &kT32BranchInfo;
   3522       return true;
   3523     }
   3524   } else {
   3525     // BL{<c>}{<q>} <label> ; A1
   3526     if (cond.IsNotNever()) {
   3527       *info = &kA32BranchInfo;
   3528       return true;
   3529     }
   3530   }
   3531   return false;
   3532 }
   3533 
   3534 void Assembler::blx(Condition cond, Location* location) {
   3535   VIXL_ASSERT(AllowAssembler());
   3536   CheckIT(cond);
   3537   Location::Offset offset =
   3538       location->IsBound()
   3539           ? location->GetLocation() -
   3540                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   3541           : 0;
   3542   if (IsUsingT32()) {
   3543     // BLX{<c>}{<q>} <label> ; T2
   3544     if (((location->IsBound() && (offset >= -16777216) &&
   3545           (offset <= 16777212) && ((offset & 0x3) == 0)) ||
   3546          !location->IsBound()) &&
   3547         (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
   3548       static class EmitOp : public Location::EmitOperator {
   3549        public:
   3550         EmitOp() : Location::EmitOperator(T32) {}
   3551         virtual uint32_t Encode(uint32_t instr,
   3552                                 Location::Offset program_counter,
   3553                                 const Location* loc) const VIXL_OVERRIDE {
   3554           program_counter += kT32PcDelta;
   3555           Location::Offset off =
   3556               loc->GetLocation() - AlignDown(program_counter, 4);
   3557           VIXL_ASSERT((off >= -16777216) && (off <= 16777212) &&
   3558                       ((off & 0x3) == 0));
   3559           int32_t target = off >> 2;
   3560           uint32_t S = target & (1 << 22);
   3561           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
   3562           return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
   3563                  ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
   3564                  ((target & 0x400000) << 4);
   3565         }
   3566       } immop;
   3567       EmitT32_32(Link(0xf000c000U, location, immop, &kT32BlxInfo));
   3568       AdvanceIT();
   3569       return;
   3570     }
   3571   } else {
   3572     // BLX{<c>}{<q>} <label> ; A2
   3573     if (((location->IsBound() && (offset >= -33554432) &&
   3574           (offset <= 33554430) && ((offset & 0x1) == 0)) ||
   3575          !location->IsBound())) {
   3576       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   3577         static class EmitOp : public Location::EmitOperator {
   3578          public:
   3579           EmitOp() : Location::EmitOperator(A32) {}
   3580           virtual uint32_t Encode(uint32_t instr,
   3581                                   Location::Offset program_counter,
   3582                                   const Location* loc) const VIXL_OVERRIDE {
   3583             program_counter += kA32PcDelta;
   3584             Location::Offset off =
   3585                 loc->GetLocation() - AlignDown(program_counter, 4);
   3586             VIXL_ASSERT((off >= -33554432) && (off <= 33554430) &&
   3587                         ((off & 0x1) == 0));
   3588             const int32_t target = off >> 1;
   3589             return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
   3590           }
   3591         } immop;
   3592         EmitA32(Link(0xfa000000U, location, immop, &kA32BlxInfo));
   3593         return;
   3594       }
   3595     }
   3596   }
   3597   Delegate(kBlx, &Assembler::blx, cond, location);
   3598 }
   3599 
   3600 bool Assembler::blx_info(Condition cond,
   3601                          Location* location,
   3602                          const struct ReferenceInfo** info) {
   3603   VIXL_ASSERT(!location->IsBound());
   3604   USE(location);
   3605   USE(cond);
   3606   if (IsUsingT32()) {
   3607     // BLX{<c>}{<q>} <label> ; T2
   3608     if (true) {
   3609       *info = &kT32BlxInfo;
   3610       return true;
   3611     }
   3612   } else {
   3613     // BLX{<c>}{<q>} <label> ; A2
   3614     if (true) {
   3615       *info = &kA32BlxInfo;
   3616       return true;
   3617     }
   3618   }
   3619   return false;
   3620 }
   3621 
   3622 void Assembler::blx(Condition cond, Register rm) {
   3623   VIXL_ASSERT(AllowAssembler());
   3624   CheckIT(cond);
   3625   if (IsUsingT32()) {
   3626     // BLX{<c>}{<q>} <Rm> ; T1
   3627     if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
   3628          AllowUnpredictable())) {
   3629       EmitT32_16(0x4780 | (rm.GetCode() << 3));
   3630       AdvanceIT();
   3631       return;
   3632     }
   3633   } else {
   3634     // BLX{<c>}{<q>} <Rm> ; A1
   3635     if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
   3636       EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
   3637       return;
   3638     }
   3639   }
   3640   Delegate(kBlx, &Assembler::blx, cond, rm);
   3641 }
   3642 
   3643 void Assembler::bx(Condition cond, Register rm) {
   3644   VIXL_ASSERT(AllowAssembler());
   3645   CheckIT(cond);
   3646   if (IsUsingT32()) {
   3647     // BX{<c>}{<q>} <Rm> ; T1
   3648     if ((OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
   3649       EmitT32_16(0x4700 | (rm.GetCode() << 3));
   3650       AdvanceIT();
   3651       return;
   3652     }
   3653   } else {
   3654     // BX{<c>}{<q>} <Rm> ; A1
   3655     if (cond.IsNotNever()) {
   3656       EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
   3657       return;
   3658     }
   3659   }
   3660   Delegate(kBx, &Assembler::bx, cond, rm);
   3661 }
   3662 
   3663 void Assembler::bxj(Condition cond, Register rm) {
   3664   VIXL_ASSERT(AllowAssembler());
   3665   CheckIT(cond);
   3666   if (IsUsingT32()) {
   3667     // BXJ{<c>}{<q>} <Rm> ; T1
   3668     if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
   3669          AllowUnpredictable())) {
   3670       EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
   3671       AdvanceIT();
   3672       return;
   3673     }
   3674   } else {
   3675     // BXJ{<c>}{<q>} <Rm> ; A1
   3676     if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
   3677       EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
   3678       return;
   3679     }
   3680   }
   3681   Delegate(kBxj, &Assembler::bxj, cond, rm);
   3682 }
   3683 
   3684 void Assembler::cbnz(Register rn, Location* location) {
   3685   VIXL_ASSERT(AllowAssembler());
   3686   CheckIT(al);
   3687   Location::Offset offset =
   3688       location->IsBound()
   3689           ? location->GetLocation() -
   3690                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3691           : 0;
   3692   if (IsUsingT32()) {
   3693     // CBNZ{<q>} <Rn>, <label> ; T1
   3694     if (rn.IsLow() && ((location->IsBound() && (offset >= 0) &&
   3695                         (offset <= 126) && ((offset & 0x1) == 0)) ||
   3696                        !location->IsBound())) {
   3697       static class EmitOp : public Location::EmitOperator {
   3698        public:
   3699         EmitOp() : Location::EmitOperator(T32) {}
   3700         virtual uint32_t Encode(uint32_t instr,
   3701                                 Location::Offset program_counter,
   3702                                 const Location* loc) const VIXL_OVERRIDE {
   3703           program_counter += kT32PcDelta;
   3704           Location::Offset off = loc->GetLocation() - program_counter;
   3705           VIXL_ASSERT((off >= 0) && (off <= 126) && ((off & 0x1) == 0));
   3706           const int32_t target = off >> 1;
   3707           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
   3708         }
   3709       } immop;
   3710       EmitT32_16(Link(0xb900 | rn.GetCode(), location, immop, &kT16CbzInfo));
   3711       AdvanceIT();
   3712       return;
   3713     }
   3714   }
   3715   Delegate(kCbnz, &Assembler::cbnz, rn, location);
   3716 }
   3717 
   3718 bool Assembler::cbnz_info(Register rn,
   3719                           Location* location,
   3720                           const struct ReferenceInfo** info) {
   3721   VIXL_ASSERT(!location->IsBound());
   3722   USE(location);
   3723   if (IsUsingT32()) {
   3724     // CBNZ{<q>} <Rn>, <label> ; T1
   3725     if (rn.IsLow()) {
   3726       *info = &kT16CbzInfo;
   3727       return true;
   3728     }
   3729   }
   3730   return false;
   3731 }
   3732 
   3733 void Assembler::cbz(Register rn, Location* location) {
   3734   VIXL_ASSERT(AllowAssembler());
   3735   CheckIT(al);
   3736   Location::Offset offset =
   3737       location->IsBound()
   3738           ? location->GetLocation() -
   3739                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3740           : 0;
   3741   if (IsUsingT32()) {
   3742     // CBZ{<q>} <Rn>, <label> ; T1
   3743     if (rn.IsLow() && ((location->IsBound() && (offset >= 0) &&
   3744                         (offset <= 126) && ((offset & 0x1) == 0)) ||
   3745                        !location->IsBound())) {
   3746       static class EmitOp : public Location::EmitOperator {
   3747        public:
   3748         EmitOp() : Location::EmitOperator(T32) {}
   3749         virtual uint32_t Encode(uint32_t instr,
   3750                                 Location::Offset program_counter,
   3751                                 const Location* loc) const VIXL_OVERRIDE {
   3752           program_counter += kT32PcDelta;
   3753           Location::Offset off = loc->GetLocation() - program_counter;
   3754           VIXL_ASSERT((off >= 0) && (off <= 126) && ((off & 0x1) == 0));
   3755           const int32_t target = off >> 1;
   3756           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
   3757         }
   3758       } immop;
   3759       EmitT32_16(Link(0xb100 | rn.GetCode(), location, immop, &kT16CbzInfo));
   3760       AdvanceIT();
   3761       return;
   3762     }
   3763   }
   3764   Delegate(kCbz, &Assembler::cbz, rn, location);
   3765 }
   3766 
   3767 bool Assembler::cbz_info(Register rn,
   3768                          Location* location,
   3769                          const struct ReferenceInfo** info) {
   3770   VIXL_ASSERT(!location->IsBound());
   3771   USE(location);
   3772   if (IsUsingT32()) {
   3773     // CBZ{<q>} <Rn>, <label> ; T1
   3774     if (rn.IsLow()) {
   3775       *info = &kT16CbzInfo;
   3776       return true;
   3777     }
   3778   }
   3779   return false;
   3780 }
   3781 
   3782 void Assembler::clrex(Condition cond) {
   3783   VIXL_ASSERT(AllowAssembler());
   3784   CheckIT(cond);
   3785   if (IsUsingT32()) {
   3786     // CLREX{<c>}{<q>} ; T1
   3787     EmitT32_32(0xf3bf8f2fU);
   3788     AdvanceIT();
   3789     return;
   3790   } else {
   3791     // CLREX{<c>}{<q>} ; A1
   3792     if (cond.Is(al)) {
   3793       EmitA32(0xf57ff01fU);
   3794       return;
   3795     }
   3796   }
   3797   Delegate(kClrex, &Assembler::clrex, cond);
   3798 }
   3799 
   3800 void Assembler::clz(Condition cond, Register rd, Register rm) {
   3801   VIXL_ASSERT(AllowAssembler());
   3802   CheckIT(cond);
   3803   if (IsUsingT32()) {
   3804     // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
   3805     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3806       EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
   3807                  (rm.GetCode() << 16));
   3808       AdvanceIT();
   3809       return;
   3810     }
   3811   } else {
   3812     // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
   3813     if (cond.IsNotNever() &&
   3814         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3815       EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3816               rm.GetCode());
   3817       return;
   3818     }
   3819   }
   3820   Delegate(kClz, &Assembler::clz, cond, rd, rm);
   3821 }
   3822 
   3823 void Assembler::cmn(Condition cond,
   3824                     EncodingSize size,
   3825                     Register rn,
   3826                     const Operand& operand) {
   3827   VIXL_ASSERT(AllowAssembler());
   3828   CheckIT(cond);
   3829   if (operand.IsImmediate()) {
   3830     uint32_t imm = operand.GetImmediate();
   3831     if (IsUsingT32()) {
   3832       ImmediateT32 immediate_t32(imm);
   3833       // CMN{<c>}{<q>} <Rn>, #<const> ; T1
   3834       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   3835           (!rn.IsPC() || AllowUnpredictable())) {
   3836         EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
   3837                    (immediate_t32.GetEncodingValue() & 0xff) |
   3838                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3839                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3840         AdvanceIT();
   3841         return;
   3842       }
   3843     } else {
   3844       ImmediateA32 immediate_a32(imm);
   3845       // CMN{<c>}{<q>} <Rn>, #<const> ; A1
   3846       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3847         EmitA32(0x03700000U | (cond.GetCondition() << 28) |
   3848                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   3849         return;
   3850       }
   3851     }
   3852   }
   3853   if (operand.IsImmediateShiftedRegister()) {
   3854     Register rm = operand.GetBaseRegister();
   3855     if (operand.IsPlainRegister()) {
   3856       if (IsUsingT32()) {
   3857         // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
   3858         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
   3859           EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
   3860           AdvanceIT();
   3861           return;
   3862         }
   3863       }
   3864     }
   3865     Shift shift = operand.GetShift();
   3866     uint32_t amount = operand.GetShiftAmount();
   3867     if (IsUsingT32()) {
   3868       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3869       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   3870           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3871         uint32_t amount_ = amount % 32;
   3872         EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
   3873                    (operand.GetTypeEncodingValue() << 4) |
   3874                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3875         AdvanceIT();
   3876         return;
   3877       }
   3878     } else {
   3879       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3880       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3881         uint32_t amount_ = amount % 32;
   3882         EmitA32(0x01700000U | (cond.GetCondition() << 28) |
   3883                 (rn.GetCode() << 16) | rm.GetCode() |
   3884                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3885         return;
   3886       }
   3887     }
   3888   }
   3889   if (operand.IsRegisterShiftedRegister()) {
   3890     Register rm = operand.GetBaseRegister();
   3891     Shift shift = operand.GetShift();
   3892     Register rs = operand.GetShiftRegister();
   3893     if (IsUsingA32()) {
   3894       // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   3895       if (cond.IsNotNever() &&
   3896           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   3897         EmitA32(0x01700010U | (cond.GetCondition() << 28) |
   3898                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   3899                 (rs.GetCode() << 8));
   3900         return;
   3901       }
   3902     }
   3903   }
   3904   Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
   3905 }
   3906 
   3907 void Assembler::cmp(Condition cond,
   3908                     EncodingSize size,
   3909                     Register rn,
   3910                     const Operand& operand) {
   3911   VIXL_ASSERT(AllowAssembler());
   3912   CheckIT(cond);
   3913   if (operand.IsImmediate()) {
   3914     uint32_t imm = operand.GetImmediate();
   3915     if (IsUsingT32()) {
   3916       ImmediateT32 immediate_t32(imm);
   3917       // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
   3918       if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
   3919         EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
   3920         AdvanceIT();
   3921         return;
   3922       }
   3923       // CMP{<c>}{<q>} <Rn>, #<const> ; T2
   3924       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   3925           (!rn.IsPC() || AllowUnpredictable())) {
   3926         EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
   3927                    (immediate_t32.GetEncodingValue() & 0xff) |
   3928                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3929                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3930         AdvanceIT();
   3931         return;
   3932       }
   3933     } else {
   3934       ImmediateA32 immediate_a32(imm);
   3935       // CMP{<c>}{<q>} <Rn>, #<const> ; A1
   3936       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3937         EmitA32(0x03500000U | (cond.GetCondition() << 28) |
   3938                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   3939         return;
   3940       }
   3941     }
   3942   }
   3943   if (operand.IsImmediateShiftedRegister()) {
   3944     Register rm = operand.GetBaseRegister();
   3945     if (operand.IsPlainRegister()) {
   3946       if (IsUsingT32()) {
   3947         // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
   3948         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
   3949           EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
   3950           AdvanceIT();
   3951           return;
   3952         }
   3953         // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
   3954         if (!size.IsWide() &&
   3955             ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3956           EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
   3957                      ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   3958           AdvanceIT();
   3959           return;
   3960         }
   3961       }
   3962     }
   3963     Shift shift = operand.GetShift();
   3964     uint32_t amount = operand.GetShiftAmount();
   3965     if (IsUsingT32()) {
   3966       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
   3967       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   3968           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3969         uint32_t amount_ = amount % 32;
   3970         EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
   3971                    (operand.GetTypeEncodingValue() << 4) |
   3972                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3973         AdvanceIT();
   3974         return;
   3975       }
   3976     } else {
   3977       // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3978       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3979         uint32_t amount_ = amount % 32;
   3980         EmitA32(0x01500000U | (cond.GetCondition() << 28) |
   3981                 (rn.GetCode() << 16) | rm.GetCode() |
   3982                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3983         return;
   3984       }
   3985     }
   3986   }
   3987   if (operand.IsRegisterShiftedRegister()) {
   3988     Register rm = operand.GetBaseRegister();
   3989     Shift shift = operand.GetShift();
   3990     Register rs = operand.GetShiftRegister();
   3991     if (IsUsingA32()) {
   3992       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   3993       if (cond.IsNotNever() &&
   3994           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   3995         EmitA32(0x01500010U | (cond.GetCondition() << 28) |
   3996                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   3997                 (rs.GetCode() << 8));
   3998         return;
   3999       }
   4000     }
   4001   }
   4002   Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
   4003 }
   4004 
   4005 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
   4006   VIXL_ASSERT(AllowAssembler());
   4007   CheckIT(cond);
   4008   if (IsUsingT32()) {
   4009     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
   4010     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4011          AllowUnpredictable())) {
   4012       EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4013                  rm.GetCode());
   4014       AdvanceIT();
   4015       return;
   4016     }
   4017   } else {
   4018     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
   4019     if ((cond.Is(al) || AllowUnpredictable()) &&
   4020         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4021       EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4022               (rn.GetCode() << 16) | rm.GetCode());
   4023       return;
   4024     }
   4025   }
   4026   Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
   4027 }
   4028 
   4029 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
   4030   VIXL_ASSERT(AllowAssembler());
   4031   CheckIT(cond);
   4032   if (IsUsingT32()) {
   4033     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
   4034     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4035          AllowUnpredictable())) {
   4036       EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4037                  rm.GetCode());
   4038       AdvanceIT();
   4039       return;
   4040     }
   4041   } else {
   4042     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
   4043     if ((cond.Is(al) || AllowUnpredictable()) &&
   4044         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4045       EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4046               (rn.GetCode() << 16) | rm.GetCode());
   4047       return;
   4048     }
   4049   }
   4050   Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
   4051 }
   4052 
   4053 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
   4054   VIXL_ASSERT(AllowAssembler());
   4055   CheckIT(cond);
   4056   if (IsUsingT32()) {
   4057     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
   4058     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4059          AllowUnpredictable())) {
   4060       EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4061                  rm.GetCode());
   4062       AdvanceIT();
   4063       return;
   4064     }
   4065   } else {
   4066     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
   4067     if ((cond.Is(al) || AllowUnpredictable()) &&
   4068         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4069       EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4070               (rn.GetCode() << 16) | rm.GetCode());
   4071       return;
   4072     }
   4073   }
   4074   Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
   4075 }
   4076 
   4077 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
   4078   VIXL_ASSERT(AllowAssembler());
   4079   CheckIT(cond);
   4080   if (IsUsingT32()) {
   4081     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
   4082     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4083          AllowUnpredictable())) {
   4084       EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4085                  rm.GetCode());
   4086       AdvanceIT();
   4087       return;
   4088     }
   4089   } else {
   4090     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
   4091     if ((cond.Is(al) || AllowUnpredictable()) &&
   4092         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4093       EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4094               (rn.GetCode() << 16) | rm.GetCode());
   4095       return;
   4096     }
   4097   }
   4098   Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
   4099 }
   4100 
   4101 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
   4102   VIXL_ASSERT(AllowAssembler());
   4103   CheckIT(cond);
   4104   if (IsUsingT32()) {
   4105     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
   4106     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4107          AllowUnpredictable())) {
   4108       EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4109                  rm.GetCode());
   4110       AdvanceIT();
   4111       return;
   4112     }
   4113   } else {
   4114     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
   4115     if ((cond.Is(al) || AllowUnpredictable()) &&
   4116         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4117       EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4118               (rn.GetCode() << 16) | rm.GetCode());
   4119       return;
   4120     }
   4121   }
   4122   Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
   4123 }
   4124 
   4125 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
   4126   VIXL_ASSERT(AllowAssembler());
   4127   CheckIT(cond);
   4128   if (IsUsingT32()) {
   4129     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
   4130     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4131          AllowUnpredictable())) {
   4132       EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4133                  rm.GetCode());
   4134       AdvanceIT();
   4135       return;
   4136     }
   4137   } else {
   4138     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
   4139     if ((cond.Is(al) || AllowUnpredictable()) &&
   4140         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4141       EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4142               (rn.GetCode() << 16) | rm.GetCode());
   4143       return;
   4144     }
   4145   }
   4146   Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
   4147 }
   4148 
   4149 void Assembler::dmb(Condition cond, MemoryBarrier option) {
   4150   VIXL_ASSERT(AllowAssembler());
   4151   CheckIT(cond);
   4152   if (IsUsingT32()) {
   4153     // DMB{<c>}{<q>} {<option>} ; T1
   4154     EmitT32_32(0xf3bf8f50U | option.GetType());
   4155     AdvanceIT();
   4156     return;
   4157   } else {
   4158     // DMB{<c>}{<q>} {<option>} ; A1
   4159     if (cond.Is(al)) {
   4160       EmitA32(0xf57ff050U | option.GetType());
   4161       return;
   4162     }
   4163   }
   4164   Delegate(kDmb, &Assembler::dmb, cond, option);
   4165 }
   4166 
   4167 void Assembler::dsb(Condition cond, MemoryBarrier option) {
   4168   VIXL_ASSERT(AllowAssembler());
   4169   CheckIT(cond);
   4170   if (IsUsingT32()) {
   4171     // DSB{<c>}{<q>} {<option>} ; T1
   4172     EmitT32_32(0xf3bf8f40U | option.GetType());
   4173     AdvanceIT();
   4174     return;
   4175   } else {
   4176     // DSB{<c>}{<q>} {<option>} ; A1
   4177     if (cond.Is(al)) {
   4178       EmitA32(0xf57ff040U | option.GetType());
   4179       return;
   4180     }
   4181   }
   4182   Delegate(kDsb, &Assembler::dsb, cond, option);
   4183 }
   4184 
   4185 void Assembler::eor(Condition cond,
   4186                     EncodingSize size,
   4187                     Register rd,
   4188                     Register rn,
   4189                     const Operand& operand) {
   4190   VIXL_ASSERT(AllowAssembler());
   4191   CheckIT(cond);
   4192   if (operand.IsImmediate()) {
   4193     uint32_t imm = operand.GetImmediate();
   4194     if (IsUsingT32()) {
   4195       ImmediateT32 immediate_t32(imm);
   4196       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   4197       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   4198           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4199         EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4200                    (immediate_t32.GetEncodingValue() & 0xff) |
   4201                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   4202                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   4203         AdvanceIT();
   4204         return;
   4205       }
   4206     } else {
   4207       ImmediateA32 immediate_a32(imm);
   4208       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   4209       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   4210         EmitA32(0x02200000U | (cond.GetCondition() << 28) |
   4211                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   4212                 immediate_a32.GetEncodingValue());
   4213         return;
   4214       }
   4215     }
   4216   }
   4217   if (operand.IsImmediateShiftedRegister()) {
   4218     Register rm = operand.GetBaseRegister();
   4219     if (operand.IsPlainRegister()) {
   4220       if (IsUsingT32()) {
   4221         // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   4222         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   4223             rm.IsLow()) {
   4224           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
   4225           AdvanceIT();
   4226           return;
   4227         }
   4228       }
   4229     }
   4230     Shift shift = operand.GetShift();
   4231     uint32_t amount = operand.GetShiftAmount();
   4232     if (IsUsingT32()) {
   4233       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   4234       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   4235           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4236         uint32_t amount_ = amount % 32;
   4237         EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4238                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   4239                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   4240         AdvanceIT();
   4241         return;
   4242       }
   4243     } else {
   4244       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   4245       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   4246         uint32_t amount_ = amount % 32;
   4247         EmitA32(0x00200000U | (cond.GetCondition() << 28) |
   4248                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4249                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   4250         return;
   4251       }
   4252     }
   4253   }
   4254   if (operand.IsRegisterShiftedRegister()) {
   4255     Register rm = operand.GetBaseRegister();
   4256     Shift shift = operand.GetShift();
   4257     Register rs = operand.GetShiftRegister();
   4258     if (IsUsingA32()) {
   4259       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   4260       if (cond.IsNotNever() &&
   4261           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   4262            AllowUnpredictable())) {
   4263         EmitA32(0x00200010U | (cond.GetCondition() << 28) |
   4264                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4265                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   4266         return;
   4267       }
   4268     }
   4269   }
   4270   Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
   4271 }
   4272 
   4273 void Assembler::eors(Condition cond,
   4274                      EncodingSize size,
   4275                      Register rd,
   4276                      Register rn,
   4277                      const Operand& operand) {
   4278   VIXL_ASSERT(AllowAssembler());
   4279   CheckIT(cond);
   4280   if (operand.IsImmediate()) {
   4281     uint32_t imm = operand.GetImmediate();
   4282     if (IsUsingT32()) {
   4283       ImmediateT32 immediate_t32(imm);
   4284       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   4285       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) &&
   4286           (!rn.IsPC() || AllowUnpredictable())) {
   4287         EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4288                    (immediate_t32.GetEncodingValue() & 0xff) |
   4289                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   4290                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   4291         AdvanceIT();
   4292         return;
   4293       }
   4294     } else {
   4295       ImmediateA32 immediate_a32(imm);
   4296       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   4297       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   4298         EmitA32(0x02300000U | (cond.GetCondition() << 28) |
   4299                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   4300                 immediate_a32.GetEncodingValue());
   4301         return;
   4302       }
   4303     }
   4304   }
   4305   if (operand.IsImmediateShiftedRegister()) {
   4306     Register rm = operand.GetBaseRegister();
   4307     if (operand.IsPlainRegister()) {
   4308       if (IsUsingT32()) {
   4309         // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   4310         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   4311             rm.IsLow()) {
   4312           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
   4313           AdvanceIT();
   4314           return;
   4315         }
   4316       }
   4317     }
   4318     Shift shift = operand.GetShift();
   4319     uint32_t amount = operand.GetShiftAmount();
   4320     if (IsUsingT32()) {
   4321       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   4322       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) &&
   4323           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4324         uint32_t amount_ = amount % 32;
   4325         EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4326                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   4327                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   4328         AdvanceIT();
   4329         return;
   4330       }
   4331     } else {
   4332       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   4333       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   4334         uint32_t amount_ = amount % 32;
   4335         EmitA32(0x00300000U | (cond.GetCondition() << 28) |
   4336                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4337                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   4338         return;
   4339       }
   4340     }
   4341   }
   4342   if (operand.IsRegisterShiftedRegister()) {
   4343     Register rm = operand.GetBaseRegister();
   4344     Shift shift = operand.GetShift();
   4345     Register rs = operand.GetShiftRegister();
   4346     if (IsUsingA32()) {
   4347       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   4348       if (cond.IsNotNever() &&
   4349           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   4350            AllowUnpredictable())) {
   4351         EmitA32(0x00300010U | (cond.GetCondition() << 28) |
   4352                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4353                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   4354         return;
   4355       }
   4356     }
   4357   }
   4358   Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
   4359 }
   4360 
   4361 void Assembler::fldmdbx(Condition cond,
   4362                         Register rn,
   4363                         WriteBack write_back,
   4364                         DRegisterList dreglist) {
   4365   VIXL_ASSERT(AllowAssembler());
   4366   CheckIT(cond);
   4367   if (IsUsingT32()) {
   4368     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
   4369     if (write_back.DoesWriteBack() &&
   4370         (((dreglist.GetLength() <= 16) &&
   4371           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4372          AllowUnpredictable())) {
   4373       const DRegister& dreg = dreglist.GetFirstDRegister();
   4374       unsigned len = dreglist.GetLength() * 2;
   4375       EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   4376                  (len & 0xff));
   4377       AdvanceIT();
   4378       return;
   4379     }
   4380   } else {
   4381     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
   4382     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   4383         (((dreglist.GetLength() <= 16) &&
   4384           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4385          AllowUnpredictable())) {
   4386       const DRegister& dreg = dreglist.GetFirstDRegister();
   4387       unsigned len = dreglist.GetLength() * 2;
   4388       EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4389               dreg.Encode(22, 12) | (len & 0xff));
   4390       return;
   4391     }
   4392   }
   4393   Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
   4394 }
   4395 
   4396 void Assembler::fldmiax(Condition cond,
   4397                         Register rn,
   4398                         WriteBack write_back,
   4399                         DRegisterList dreglist) {
   4400   VIXL_ASSERT(AllowAssembler());
   4401   CheckIT(cond);
   4402   if (IsUsingT32()) {
   4403     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
   4404     if ((((dreglist.GetLength() <= 16) &&
   4405           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4406          AllowUnpredictable())) {
   4407       const DRegister& dreg = dreglist.GetFirstDRegister();
   4408       unsigned len = dreglist.GetLength() * 2;
   4409       EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
   4410                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4411                  (len & 0xff));
   4412       AdvanceIT();
   4413       return;
   4414     }
   4415   } else {
   4416     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
   4417     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   4418                                (dreglist.GetLastDRegister().GetCode() < 16) &&
   4419                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
   4420                               AllowUnpredictable())) {
   4421       const DRegister& dreg = dreglist.GetFirstDRegister();
   4422       unsigned len = dreglist.GetLength() * 2;
   4423       EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4424               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4425               (len & 0xff));
   4426       return;
   4427     }
   4428   }
   4429   Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
   4430 }
   4431 
   4432 void Assembler::fstmdbx(Condition cond,
   4433                         Register rn,
   4434                         WriteBack write_back,
   4435                         DRegisterList dreglist) {
   4436   VIXL_ASSERT(AllowAssembler());
   4437   CheckIT(cond);
   4438   if (IsUsingT32()) {
   4439     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
   4440     if (write_back.DoesWriteBack() &&
   4441         (((dreglist.GetLength() <= 16) &&
   4442           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4443          AllowUnpredictable())) {
   4444       const DRegister& dreg = dreglist.GetFirstDRegister();
   4445       unsigned len = dreglist.GetLength() * 2;
   4446       EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   4447                  (len & 0xff));
   4448       AdvanceIT();
   4449       return;
   4450     }
   4451   } else {
   4452     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
   4453     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   4454         (((dreglist.GetLength() <= 16) &&
   4455           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4456          AllowUnpredictable())) {
   4457       const DRegister& dreg = dreglist.GetFirstDRegister();
   4458       unsigned len = dreglist.GetLength() * 2;
   4459       EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4460               dreg.Encode(22, 12) | (len & 0xff));
   4461       return;
   4462     }
   4463   }
   4464   Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
   4465 }
   4466 
   4467 void Assembler::fstmiax(Condition cond,
   4468                         Register rn,
   4469                         WriteBack write_back,
   4470                         DRegisterList dreglist) {
   4471   VIXL_ASSERT(AllowAssembler());
   4472   CheckIT(cond);
   4473   if (IsUsingT32()) {
   4474     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
   4475     if ((((dreglist.GetLength() <= 16) &&
   4476           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4477          AllowUnpredictable())) {
   4478       const DRegister& dreg = dreglist.GetFirstDRegister();
   4479       unsigned len = dreglist.GetLength() * 2;
   4480       EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
   4481                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4482                  (len & 0xff));
   4483       AdvanceIT();
   4484       return;
   4485     }
   4486   } else {
   4487     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
   4488     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   4489                                (dreglist.GetLastDRegister().GetCode() < 16) &&
   4490                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
   4491                               AllowUnpredictable())) {
   4492       const DRegister& dreg = dreglist.GetFirstDRegister();
   4493       unsigned len = dreglist.GetLength() * 2;
   4494       EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4495               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4496               (len & 0xff));
   4497       return;
   4498     }
   4499   }
   4500   Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
   4501 }
   4502 
   4503 void Assembler::hlt(Condition cond, uint32_t imm) {
   4504   VIXL_ASSERT(AllowAssembler());
   4505   CheckIT(cond);
   4506   if (IsUsingT32()) {
   4507     // HLT{<q>} {#}<imm> ; T1
   4508     if ((imm <= 63)) {
   4509       EmitT32_16(0xba80 | imm);
   4510       AdvanceIT();
   4511       return;
   4512     }
   4513   } else {
   4514     // HLT{<q>} {#}<imm> ; A1
   4515     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   4516       EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   4517               ((imm & 0xfff0) << 4));
   4518       return;
   4519     }
   4520   }
   4521   Delegate(kHlt, &Assembler::hlt, cond, imm);
   4522 }
   4523 
   4524 void Assembler::hvc(Condition cond, uint32_t imm) {
   4525   VIXL_ASSERT(AllowAssembler());
   4526   CheckIT(cond);
   4527   if (IsUsingT32()) {
   4528     // HVC{<q>} {#}<imm16> ; T1
   4529     if ((imm <= 65535) && (OutsideITBlock() || AllowUnpredictable())) {
   4530       EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
   4531       AdvanceIT();
   4532       return;
   4533     }
   4534   } else {
   4535     // HVC{<q>} {#}<imm16> ; A1
   4536     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   4537       EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   4538               ((imm & 0xfff0) << 4));
   4539       return;
   4540     }
   4541   }
   4542   Delegate(kHvc, &Assembler::hvc, cond, imm);
   4543 }
   4544 
   4545 void Assembler::isb(Condition cond, MemoryBarrier option) {
   4546   VIXL_ASSERT(AllowAssembler());
   4547   CheckIT(cond);
   4548   if (IsUsingT32()) {
   4549     // ISB{<c>}{<q>} {<option>} ; T1
   4550     EmitT32_32(0xf3bf8f60U | option.GetType());
   4551     AdvanceIT();
   4552     return;
   4553   } else {
   4554     // ISB{<c>}{<q>} {<option>} ; A1
   4555     if (cond.Is(al)) {
   4556       EmitA32(0xf57ff060U | option.GetType());
   4557       return;
   4558     }
   4559   }
   4560   Delegate(kIsb, &Assembler::isb, cond, option);
   4561 }
   4562 
   4563 void Assembler::it(Condition cond, uint16_t mask) {
   4564   VIXL_ASSERT(AllowAssembler());
   4565   CheckNotIT();
   4566   if (mask != 0) {
   4567     if ((cond.GetCondition() & 0x1) != 0) {
   4568       if ((mask & 0x1) != 0) {
   4569         mask ^= 0xE;
   4570       } else if ((mask & 0x2) != 0) {
   4571         mask ^= 0xC;
   4572       } else if ((mask & 0x4) != 0) {
   4573         mask ^= 0x8;
   4574       }
   4575     }
   4576     if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
   4577     SetIT(cond, mask);
   4578     return;
   4579   }
   4580   DelegateIt(cond, mask);
   4581 }
   4582 
   4583 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
   4584   VIXL_ASSERT(AllowAssembler());
   4585   CheckIT(cond);
   4586   if (operand.IsImmediateZero()) {
   4587     Register rn = operand.GetBaseRegister();
   4588     if (IsUsingT32()) {
   4589       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4590       if (operand.IsOffset() &&
   4591           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4592         EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4593         AdvanceIT();
   4594         return;
   4595       }
   4596     } else {
   4597       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4598       if (operand.IsOffset() && cond.IsNotNever() &&
   4599           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4600         EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
   4601                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4602         return;
   4603       }
   4604     }
   4605   }
   4606   Delegate(kLda, &Assembler::lda, cond, rt, operand);
   4607 }
   4608 
   4609 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
   4610   VIXL_ASSERT(AllowAssembler());
   4611   CheckIT(cond);
   4612   if (operand.IsImmediateZero()) {
   4613     Register rn = operand.GetBaseRegister();
   4614     if (IsUsingT32()) {
   4615       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4616       if (operand.IsOffset() &&
   4617           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4618         EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4619         AdvanceIT();
   4620         return;
   4621       }
   4622     } else {
   4623       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4624       if (operand.IsOffset() && cond.IsNotNever() &&
   4625           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4626         EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
   4627                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4628         return;
   4629       }
   4630     }
   4631   }
   4632   Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
   4633 }
   4634 
   4635 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
   4636   VIXL_ASSERT(AllowAssembler());
   4637   CheckIT(cond);
   4638   if (operand.IsImmediateZero()) {
   4639     Register rn = operand.GetBaseRegister();
   4640     if (IsUsingT32()) {
   4641       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4642       if (operand.IsOffset() &&
   4643           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4644         EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4645         AdvanceIT();
   4646         return;
   4647       }
   4648     } else {
   4649       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4650       if (operand.IsOffset() && cond.IsNotNever() &&
   4651           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4652         EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
   4653                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4654         return;
   4655       }
   4656     }
   4657   }
   4658   Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
   4659 }
   4660 
   4661 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
   4662   VIXL_ASSERT(AllowAssembler());
   4663   CheckIT(cond);
   4664   if (operand.IsImmediateZero()) {
   4665     Register rn = operand.GetBaseRegister();
   4666     if (IsUsingT32()) {
   4667       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4668       if (operand.IsOffset() &&
   4669           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4670         EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4671         AdvanceIT();
   4672         return;
   4673       }
   4674     } else {
   4675       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4676       if (operand.IsOffset() && cond.IsNotNever() &&
   4677           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4678         EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
   4679                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4680         return;
   4681       }
   4682     }
   4683   }
   4684   Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
   4685 }
   4686 
   4687 void Assembler::ldaexd(Condition cond,
   4688                        Register rt,
   4689                        Register rt2,
   4690                        const MemOperand& operand) {
   4691   VIXL_ASSERT(AllowAssembler());
   4692   CheckIT(cond);
   4693   if (operand.IsImmediateZero()) {
   4694     Register rn = operand.GetBaseRegister();
   4695     if (IsUsingT32()) {
   4696       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
   4697       if (operand.IsOffset() &&
   4698           ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4699         EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   4700                    (rn.GetCode() << 16));
   4701         AdvanceIT();
   4702         return;
   4703       }
   4704     } else {
   4705       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
   4706       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   4707           operand.IsOffset() && cond.IsNotNever() &&
   4708           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) ||
   4709            AllowUnpredictable())) {
   4710         EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
   4711                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4712         return;
   4713       }
   4714     }
   4715   }
   4716   Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
   4717 }
   4718 
   4719 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
   4720   VIXL_ASSERT(AllowAssembler());
   4721   CheckIT(cond);
   4722   if (operand.IsImmediateZero()) {
   4723     Register rn = operand.GetBaseRegister();
   4724     if (IsUsingT32()) {
   4725       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4726       if (operand.IsOffset() &&
   4727           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4728         EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4729         AdvanceIT();
   4730         return;
   4731       }
   4732     } else {
   4733       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4734       if (operand.IsOffset() && cond.IsNotNever() &&
   4735           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4736         EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
   4737                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4738         return;
   4739       }
   4740     }
   4741   }
   4742   Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
   4743 }
   4744 
   4745 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
   4746   VIXL_ASSERT(AllowAssembler());
   4747   CheckIT(cond);
   4748   if (operand.IsImmediateZero()) {
   4749     Register rn = operand.GetBaseRegister();
   4750     if (IsUsingT32()) {
   4751       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4752       if (operand.IsOffset() &&
   4753           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4754         EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4755         AdvanceIT();
   4756         return;
   4757       }
   4758     } else {
   4759       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4760       if (operand.IsOffset() && cond.IsNotNever() &&
   4761           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4762         EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
   4763                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4764         return;
   4765       }
   4766     }
   4767   }
   4768   Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
   4769 }
   4770 
   4771 void Assembler::ldm(Condition cond,
   4772                     EncodingSize size,
   4773                     Register rn,
   4774                     WriteBack write_back,
   4775                     RegisterList registers) {
   4776   VIXL_ASSERT(AllowAssembler());
   4777   CheckIT(cond);
   4778   if (IsUsingT32()) {
   4779     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4780     if (!size.IsWide() && rn.IsLow() &&
   4781         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
   4782          write_back.DoesWriteBack()) &&
   4783         ((registers.GetList() & ~0xff) == 0)) {
   4784       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
   4785                  GetRegisterListEncoding(registers, 0, 8));
   4786       AdvanceIT();
   4787       return;
   4788     }
   4789     // LDM{<c>}{<q>} SP!, <registers> ; T1
   4790     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
   4791         registers.IsR0toR7orPC()) {
   4792       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
   4793                  GetRegisterListEncoding(registers, 0, 8));
   4794       AdvanceIT();
   4795       return;
   4796     }
   4797     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
   4798     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) &&
   4799         (!rn.IsPC() || AllowUnpredictable())) {
   4800       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
   4801                  (write_back.GetWriteBackUint32() << 21) |
   4802                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4803                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4804                  GetRegisterListEncoding(registers, 0, 13));
   4805       AdvanceIT();
   4806       return;
   4807     }
   4808   } else {
   4809     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4810     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4811       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4812               (write_back.GetWriteBackUint32() << 21) |
   4813               GetRegisterListEncoding(registers, 0, 16));
   4814       return;
   4815     }
   4816   }
   4817   Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
   4818 }
   4819 
   4820 void Assembler::ldmda(Condition cond,
   4821                       Register rn,
   4822                       WriteBack write_back,
   4823                       RegisterList registers) {
   4824   VIXL_ASSERT(AllowAssembler());
   4825   CheckIT(cond);
   4826   if (IsUsingA32()) {
   4827     // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4828     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4829       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4830               (write_back.GetWriteBackUint32() << 21) |
   4831               GetRegisterListEncoding(registers, 0, 16));
   4832       return;
   4833     }
   4834   }
   4835   Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
   4836 }
   4837 
   4838 void Assembler::ldmdb(Condition cond,
   4839                       Register rn,
   4840                       WriteBack write_back,
   4841                       RegisterList registers) {
   4842   VIXL_ASSERT(AllowAssembler());
   4843   CheckIT(cond);
   4844   if (IsUsingT32()) {
   4845     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4846     if (((registers.GetList() & ~0xdfff) == 0) &&
   4847         (!rn.IsPC() || AllowUnpredictable())) {
   4848       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
   4849                  (write_back.GetWriteBackUint32() << 21) |
   4850                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4851                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4852                  GetRegisterListEncoding(registers, 0, 13));
   4853       AdvanceIT();
   4854       return;
   4855     }
   4856   } else {
   4857     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4858     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4859       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4860               (write_back.GetWriteBackUint32() << 21) |
   4861               GetRegisterListEncoding(registers, 0, 16));
   4862       return;
   4863     }
   4864   }
   4865   Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
   4866 }
   4867 
   4868 void Assembler::ldmea(Condition cond,
   4869                       Register rn,
   4870                       WriteBack write_back,
   4871                       RegisterList registers) {
   4872   VIXL_ASSERT(AllowAssembler());
   4873   CheckIT(cond);
   4874   if (IsUsingT32()) {
   4875     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4876     if (((registers.GetList() & ~0xdfff) == 0) &&
   4877         (!rn.IsPC() || AllowUnpredictable())) {
   4878       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
   4879                  (write_back.GetWriteBackUint32() << 21) |
   4880                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4881                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4882                  GetRegisterListEncoding(registers, 0, 13));
   4883       AdvanceIT();
   4884       return;
   4885     }
   4886   } else {
   4887     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4888     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4889       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4890               (write_back.GetWriteBackUint32() << 21) |
   4891               GetRegisterListEncoding(registers, 0, 16));
   4892       return;
   4893     }
   4894   }
   4895   Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
   4896 }
   4897 
   4898 void Assembler::ldmed(Condition cond,
   4899                       Register rn,
   4900                       WriteBack write_back,
   4901                       RegisterList registers) {
   4902   VIXL_ASSERT(AllowAssembler());
   4903   CheckIT(cond);
   4904   if (IsUsingA32()) {
   4905     // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4906     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4907       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4908               (write_back.GetWriteBackUint32() << 21) |
   4909               GetRegisterListEncoding(registers, 0, 16));
   4910       return;
   4911     }
   4912   }
   4913   Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
   4914 }
   4915 
   4916 void Assembler::ldmfa(Condition cond,
   4917                       Register rn,
   4918                       WriteBack write_back,
   4919                       RegisterList registers) {
   4920   VIXL_ASSERT(AllowAssembler());
   4921   CheckIT(cond);
   4922   if (IsUsingA32()) {
   4923     // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4924     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4925       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4926               (write_back.GetWriteBackUint32() << 21) |
   4927               GetRegisterListEncoding(registers, 0, 16));
   4928       return;
   4929     }
   4930   }
   4931   Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
   4932 }
   4933 
   4934 void Assembler::ldmfd(Condition cond,
   4935                       EncodingSize size,
   4936                       Register rn,
   4937                       WriteBack write_back,
   4938                       RegisterList registers) {
   4939   VIXL_ASSERT(AllowAssembler());
   4940   CheckIT(cond);
   4941   if (IsUsingT32()) {
   4942     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4943     if (!size.IsWide() && rn.IsLow() &&
   4944         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
   4945          write_back.DoesWriteBack()) &&
   4946         ((registers.GetList() & ~0xff) == 0)) {
   4947       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
   4948                  GetRegisterListEncoding(registers, 0, 8));
   4949       AdvanceIT();
   4950       return;
   4951     }
   4952     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
   4953     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) &&
   4954         (!rn.IsPC() || AllowUnpredictable())) {
   4955       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
   4956                  (write_back.GetWriteBackUint32() << 21) |
   4957                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4958                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4959                  GetRegisterListEncoding(registers, 0, 13));
   4960       AdvanceIT();
   4961       return;
   4962     }
   4963   } else {
   4964     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4965     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4966       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4967               (write_back.GetWriteBackUint32() << 21) |
   4968               GetRegisterListEncoding(registers, 0, 16));
   4969       return;
   4970     }
   4971   }
   4972   Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
   4973 }
   4974 
   4975 void Assembler::ldmib(Condition cond,
   4976                       Register rn,
   4977                       WriteBack write_back,
   4978                       RegisterList registers) {
   4979   VIXL_ASSERT(AllowAssembler());
   4980   CheckIT(cond);
   4981   if (IsUsingA32()) {
   4982     // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4983     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4984       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4985               (write_back.GetWriteBackUint32() << 21) |
   4986               GetRegisterListEncoding(registers, 0, 16));
   4987       return;
   4988     }
   4989   }
   4990   Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
   4991 }
   4992 
   4993 void Assembler::ldr(Condition cond,
   4994                     EncodingSize size,
   4995                     Register rt,
   4996                     const MemOperand& operand) {
   4997   VIXL_ASSERT(AllowAssembler());
   4998   CheckIT(cond);
   4999   if (operand.IsImmediate()) {
   5000     Register rn = operand.GetBaseRegister();
   5001     int32_t offset = operand.GetOffsetImmediate();
   5002     if (IsUsingT32()) {
   5003       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   5004       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   5005           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
   5006         int32_t offset_ = offset >> 2;
   5007         EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
   5008                    ((offset_ & 0x1f) << 6));
   5009         AdvanceIT();
   5010         return;
   5011       }
   5012       // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
   5013       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
   5014           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
   5015         int32_t offset_ = offset >> 2;
   5016         EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
   5017         AdvanceIT();
   5018         return;
   5019       }
   5020       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
   5021       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5022           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   5023           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5024            AllowUnpredictable())) {
   5025         EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5026                    (offset & 0xfff));
   5027         AdvanceIT();
   5028         return;
   5029       }
   5030       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
   5031       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5032           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   5033           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5034            AllowUnpredictable())) {
   5035         EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5036                    (-offset & 0xff));
   5037         AdvanceIT();
   5038         return;
   5039       }
   5040       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
   5041       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5042           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   5043           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5044            AllowUnpredictable())) {
   5045         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5046         uint32_t offset_ = abs(offset);
   5047         EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5048                    offset_ | (sign << 9));
   5049         AdvanceIT();
   5050         return;
   5051       }
   5052       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
   5053       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5054           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   5055           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5056            AllowUnpredictable())) {
   5057         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5058         uint32_t offset_ = abs(offset);
   5059         EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5060                    offset_ | (sign << 9));
   5061         AdvanceIT();
   5062         return;
   5063       }
   5064       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
   5065       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   5066           rn.Is(pc) && operand.IsOffset() &&
   5067           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5068            AllowUnpredictable())) {
   5069         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5070         uint32_t offset_ = abs(offset);
   5071         EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   5072         AdvanceIT();
   5073         return;
   5074       }
   5075     } else {
   5076       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   5077       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   5078           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5079         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5080         uint32_t offset_ = abs(offset);
   5081         EmitA32(0x05100000U | (cond.GetCondition() << 28) |
   5082                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5083                 (sign << 23));
   5084         return;
   5085       }
   5086       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   5087       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   5088           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5089         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5090         uint32_t offset_ = abs(offset);
   5091         EmitA32(0x04100000U | (cond.GetCondition() << 28) |
   5092                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5093                 (sign << 23));
   5094         return;
   5095       }
   5096       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   5097       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   5098           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5099         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5100         uint32_t offset_ = abs(offset);
   5101         EmitA32(0x05300000U | (cond.GetCondition() << 28) |
   5102                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5103                 (sign << 23));
   5104         return;
   5105       }
   5106       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   5107       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   5108           operand.IsOffset() && cond.IsNotNever()) {
   5109         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5110         uint32_t offset_ = abs(offset);
   5111         EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
   5112                 (rt.GetCode() << 12) | offset_ | (sign << 23));
   5113         return;
   5114       }
   5115     }
   5116   }
   5117   if (operand.IsPlainRegister()) {
   5118     Register rn = operand.GetBaseRegister();
   5119     Sign sign = operand.GetSign();
   5120     Register rm = operand.GetOffsetRegister();
   5121     if (IsUsingT32()) {
   5122       // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   5123       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   5124           sign.IsPlus() && operand.IsOffset()) {
   5125         EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
   5126                    (rm.GetCode() << 6));
   5127         AdvanceIT();
   5128         return;
   5129       }
   5130     }
   5131   }
   5132   if (operand.IsShiftedRegister()) {
   5133     Register rn = operand.GetBaseRegister();
   5134     Sign sign = operand.GetSign();
   5135     Register rm = operand.GetOffsetRegister();
   5136     Shift shift = operand.GetShift();
   5137     uint32_t amount = operand.GetShiftAmount();
   5138     if (IsUsingT32()) {
   5139       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   5140       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   5141           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   5142           ((!rm.IsPC() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) ||
   5143            AllowUnpredictable())) {
   5144         EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5145                    rm.GetCode() | (amount << 4));
   5146         AdvanceIT();
   5147         return;
   5148       }
   5149     } else {
   5150       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   5151       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
   5152           (!rm.IsPC() || AllowUnpredictable())) {
   5153         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5154         uint32_t shift_ = TypeEncodingValue(shift);
   5155         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5156         EmitA32(0x07100000U | (cond.GetCondition() << 28) |
   5157                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5158                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5159         return;
   5160       }
   5161       // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   5162       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   5163           cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
   5164         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5165         uint32_t shift_ = TypeEncodingValue(shift);
   5166         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5167         EmitA32(0x06100000U | (cond.GetCondition() << 28) |
   5168                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5169                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5170         return;
   5171       }
   5172       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   5173       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
   5174           (!rm.IsPC() || AllowUnpredictable())) {
   5175         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5176         uint32_t shift_ = TypeEncodingValue(shift);
   5177         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5178         EmitA32(0x07300000U | (cond.GetCondition() << 28) |
   5179                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5180                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5181         return;
   5182       }
   5183     }
   5184   }
   5185   Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
   5186 }
   5187 
   5188 void Assembler::ldr(Condition cond,
   5189                     EncodingSize size,
   5190                     Register rt,
   5191                     Location* location) {
   5192   VIXL_ASSERT(AllowAssembler());
   5193   CheckIT(cond);
   5194   Location::Offset offset =
   5195       location->IsBound()
   5196           ? location->GetLocation() -
   5197                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5198           : 0;
   5199   if (IsUsingT32()) {
   5200     // LDR{<c>}{<q>} <Rt>, <label> ; T1
   5201     if (!size.IsWide() && rt.IsLow() &&
   5202         ((location->IsBound() && (offset >= 0) && (offset <= 1020) &&
   5203           ((offset & 0x3) == 0)) ||
   5204          (!location->IsBound() && size.IsNarrow()))) {
   5205       static class EmitOp : public Location::EmitOperator {
   5206        public:
   5207         EmitOp() : Location::EmitOperator(T32) {}
   5208         virtual uint32_t Encode(uint32_t instr,
   5209                                 Location::Offset program_counter,
   5210                                 const Location* loc) const VIXL_OVERRIDE {
   5211           program_counter += kT32PcDelta;
   5212           Location::Offset off =
   5213               loc->GetLocation() - AlignDown(program_counter, 4);
   5214           VIXL_ASSERT((off >= 0) && (off <= 1020) && ((off & 0x3) == 0));
   5215           const int32_t target = off >> 2;
   5216           return instr | (target & 0xff);
   5217         }
   5218       } immop;
   5219       EmitT32_16(
   5220           Link(0x4800 | (rt.GetCode() << 8), location, immop, &kT16DataInfo));
   5221       AdvanceIT();
   5222       return;
   5223     }
   5224     // LDR{<c>}{<q>} <Rt>, <label> ; T2
   5225     if (!size.IsNarrow() &&
   5226         ((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5227          !location->IsBound()) &&
   5228         ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5229          AllowUnpredictable())) {
   5230       static class EmitOp : public Location::EmitOperator {
   5231        public:
   5232         EmitOp() : Location::EmitOperator(T32) {}
   5233         virtual uint32_t Encode(uint32_t instr,
   5234                                 Location::Offset program_counter,
   5235                                 const Location* loc) const VIXL_OVERRIDE {
   5236           program_counter += kT32PcDelta;
   5237           Location::Offset off =
   5238               loc->GetLocation() - AlignDown(program_counter, 4);
   5239           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   5240           uint32_t U = (off >= 0);
   5241           int32_t target = abs(off) | (U << 12);
   5242           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5243         }
   5244       } immop;
   5245       EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12),
   5246                       location,
   5247                       immop,
   5248                       &kT32FarDataInfo));
   5249       AdvanceIT();
   5250       return;
   5251     }
   5252   } else {
   5253     // LDR{<c>}{<q>} <Rt>, <label> ; A1
   5254     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5255          !location->IsBound()) &&
   5256         cond.IsNotNever()) {
   5257       static class EmitOp : public Location::EmitOperator {
   5258        public:
   5259         EmitOp() : Location::EmitOperator(A32) {}
   5260         virtual uint32_t Encode(uint32_t instr,
   5261                                 Location::Offset program_counter,
   5262                                 const Location* loc) const VIXL_OVERRIDE {
   5263           program_counter += kA32PcDelta;
   5264           Location::Offset off =
   5265               loc->GetLocation() - AlignDown(program_counter, 4);
   5266           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   5267           uint32_t U = (off >= 0);
   5268           int32_t target = abs(off) | (U << 12);
   5269           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5270         }
   5271       } immop;
   5272       EmitA32(
   5273           Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5274                location,
   5275                immop,
   5276                &kA32FarDataInfo));
   5277       return;
   5278     }
   5279   }
   5280   Delegate(kLdr, &Assembler::ldr, cond, size, rt, location);
   5281 }
   5282 
   5283 bool Assembler::ldr_info(Condition cond,
   5284                          EncodingSize size,
   5285                          Register rt,
   5286                          Location* location,
   5287                          const struct ReferenceInfo** info) {
   5288   VIXL_ASSERT(!location->IsBound());
   5289   USE(location);
   5290   if (IsUsingT32()) {
   5291     // LDR{<c>}{<q>} <Rt>, <label> ; T1
   5292     if (!size.IsWide() && rt.IsLow() && size.IsNarrow()) {
   5293       *info = &kT16DataInfo;
   5294       return true;
   5295     }
   5296     // LDR{<c>}{<q>} <Rt>, <label> ; T2
   5297     if (!size.IsNarrow()) {
   5298       *info = &kT32FarDataInfo;
   5299       return true;
   5300     }
   5301   } else {
   5302     // LDR{<c>}{<q>} <Rt>, <label> ; A1
   5303     if (cond.IsNotNever()) {
   5304       *info = &kA32FarDataInfo;
   5305       return true;
   5306     }
   5307   }
   5308   return false;
   5309 }
   5310 
   5311 void Assembler::ldrb(Condition cond,
   5312                      EncodingSize size,
   5313                      Register rt,
   5314                      const MemOperand& operand) {
   5315   VIXL_ASSERT(AllowAssembler());
   5316   CheckIT(cond);
   5317   if (operand.IsImmediate()) {
   5318     Register rn = operand.GetBaseRegister();
   5319     int32_t offset = operand.GetOffsetImmediate();
   5320     if (IsUsingT32()) {
   5321       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   5322       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   5323           (offset <= 31) && operand.IsOffset()) {
   5324         EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
   5325                    ((offset & 0x1f) << 6));
   5326         AdvanceIT();
   5327         return;
   5328       }
   5329       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   5330       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5331           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5332         EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5333                    (offset & 0xfff));
   5334         AdvanceIT();
   5335         return;
   5336       }
   5337       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   5338       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5339           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5340         EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5341                    (-offset & 0xff));
   5342         AdvanceIT();
   5343         return;
   5344       }
   5345       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   5346       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5347           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5348         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5349         uint32_t offset_ = abs(offset);
   5350         EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5351                    offset_ | (sign << 9));
   5352         AdvanceIT();
   5353         return;
   5354       }
   5355       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   5356       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5357           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5358         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5359         uint32_t offset_ = abs(offset);
   5360         EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5361                    offset_ | (sign << 9));
   5362         AdvanceIT();
   5363         return;
   5364       }
   5365       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   5366       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   5367           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   5368         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5369         uint32_t offset_ = abs(offset);
   5370         EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   5371         AdvanceIT();
   5372         return;
   5373       }
   5374     } else {
   5375       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   5376       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   5377           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5378           (!rt.IsPC() || AllowUnpredictable())) {
   5379         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5380         uint32_t offset_ = abs(offset);
   5381         EmitA32(0x05500000U | (cond.GetCondition() << 28) |
   5382                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5383                 (sign << 23));
   5384         return;
   5385       }
   5386       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   5387       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   5388           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5389           (!rt.IsPC() || AllowUnpredictable())) {
   5390         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5391         uint32_t offset_ = abs(offset);
   5392         EmitA32(0x04500000U | (cond.GetCondition() << 28) |
   5393                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5394                 (sign << 23));
   5395         return;
   5396       }
   5397       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   5398       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   5399           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5400           (!rt.IsPC() || AllowUnpredictable())) {
   5401         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5402         uint32_t offset_ = abs(offset);
   5403         EmitA32(0x05700000U | (cond.GetCondition() << 28) |
   5404                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5405                 (sign << 23));
   5406         return;
   5407       }
   5408       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   5409       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   5410           operand.IsOffset() && cond.IsNotNever() &&
   5411           (!rt.IsPC() || AllowUnpredictable())) {
   5412         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5413         uint32_t offset_ = abs(offset);
   5414         EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
   5415                 (rt.GetCode() << 12) | offset_ | (sign << 23));
   5416         return;
   5417       }
   5418     }
   5419   }
   5420   if (operand.IsPlainRegister()) {
   5421     Register rn = operand.GetBaseRegister();
   5422     Sign sign = operand.GetSign();
   5423     Register rm = operand.GetOffsetRegister();
   5424     if (IsUsingT32()) {
   5425       // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   5426       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   5427           sign.IsPlus() && operand.IsOffset()) {
   5428         EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
   5429                    (rm.GetCode() << 6));
   5430         AdvanceIT();
   5431         return;
   5432       }
   5433     }
   5434   }
   5435   if (operand.IsShiftedRegister()) {
   5436     Register rn = operand.GetBaseRegister();
   5437     Sign sign = operand.GetSign();
   5438     Register rm = operand.GetOffsetRegister();
   5439     Shift shift = operand.GetShift();
   5440     uint32_t amount = operand.GetShiftAmount();
   5441     if (IsUsingT32()) {
   5442       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   5443       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   5444           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
   5445           (!rm.IsPC() || AllowUnpredictable())) {
   5446         EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5447                    rm.GetCode() | (amount << 4));
   5448         AdvanceIT();
   5449         return;
   5450       }
   5451     } else {
   5452       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   5453       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
   5454           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   5455         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5456         uint32_t shift_ = TypeEncodingValue(shift);
   5457         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5458         EmitA32(0x07500000U | (cond.GetCondition() << 28) |
   5459                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5460                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5461         return;
   5462       }
   5463       // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   5464       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   5465           cond.IsNotNever() &&
   5466           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   5467         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5468         uint32_t shift_ = TypeEncodingValue(shift);
   5469         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5470         EmitA32(0x06500000U | (cond.GetCondition() << 28) |
   5471                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5472                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5473         return;
   5474       }
   5475       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   5476       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
   5477           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   5478         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5479         uint32_t shift_ = TypeEncodingValue(shift);
   5480         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5481         EmitA32(0x07700000U | (cond.GetCondition() << 28) |
   5482                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5483                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5484         return;
   5485       }
   5486     }
   5487   }
   5488   Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
   5489 }
   5490 
   5491 void Assembler::ldrb(Condition cond, Register rt, Location* location) {
   5492   VIXL_ASSERT(AllowAssembler());
   5493   CheckIT(cond);
   5494   Location::Offset offset =
   5495       location->IsBound()
   5496           ? location->GetLocation() -
   5497                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5498           : 0;
   5499   if (IsUsingT32()) {
   5500     // LDRB{<c>}{<q>} <Rt>, <label> ; T1
   5501     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5502          !location->IsBound()) &&
   5503         !rt.Is(pc)) {
   5504       static class EmitOp : public Location::EmitOperator {
   5505        public:
   5506         EmitOp() : Location::EmitOperator(T32) {}
   5507         virtual uint32_t Encode(uint32_t instr,
   5508                                 Location::Offset program_counter,
   5509                                 const Location* loc) const VIXL_OVERRIDE {
   5510           program_counter += kT32PcDelta;
   5511           Location::Offset off =
   5512               loc->GetLocation() - AlignDown(program_counter, 4);
   5513           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   5514           uint32_t U = (off >= 0);
   5515           int32_t target = abs(off) | (U << 12);
   5516           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5517         }
   5518       } immop;
   5519       EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12),
   5520                       location,
   5521                       immop,
   5522                       &kT32FarDataInfo));
   5523       AdvanceIT();
   5524       return;
   5525     }
   5526   } else {
   5527     // LDRB{<c>}{<q>} <Rt>, <label> ; A1
   5528     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5529          !location->IsBound()) &&
   5530         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   5531       static class EmitOp : public Location::EmitOperator {
   5532        public:
   5533         EmitOp() : Location::EmitOperator(A32) {}
   5534         virtual uint32_t Encode(uint32_t instr,
   5535                                 Location::Offset program_counter,
   5536                                 const Location* loc) const VIXL_OVERRIDE {
   5537           program_counter += kA32PcDelta;
   5538           Location::Offset off =
   5539               loc->GetLocation() - AlignDown(program_counter, 4);
   5540           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   5541           uint32_t U = (off >= 0);
   5542           int32_t target = abs(off) | (U << 12);
   5543           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5544         }
   5545       } immop;
   5546       EmitA32(
   5547           Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5548                location,
   5549                immop,
   5550                &kA32FarDataInfo));
   5551       return;
   5552     }
   5553   }
   5554   Delegate(kLdrb, &Assembler::ldrb, cond, rt, location);
   5555 }
   5556 
   5557 bool Assembler::ldrb_info(Condition cond,
   5558                           Register rt,
   5559                           Location* location,
   5560                           const struct ReferenceInfo** info) {
   5561   VIXL_ASSERT(!location->IsBound());
   5562   USE(location);
   5563   if (IsUsingT32()) {
   5564     // LDRB{<c>}{<q>} <Rt>, <label> ; T1
   5565     if (!rt.Is(pc)) {
   5566       *info = &kT32FarDataInfo;
   5567       return true;
   5568     }
   5569   } else {
   5570     // LDRB{<c>}{<q>} <Rt>, <label> ; A1
   5571     if (cond.IsNotNever()) {
   5572       *info = &kA32FarDataInfo;
   5573       return true;
   5574     }
   5575   }
   5576   return false;
   5577 }
   5578 
   5579 void Assembler::ldrd(Condition cond,
   5580                      Register rt,
   5581                      Register rt2,
   5582                      const MemOperand& operand) {
   5583   VIXL_ASSERT(AllowAssembler());
   5584   CheckIT(cond);
   5585   if (operand.IsImmediate()) {
   5586     Register rn = operand.GetBaseRegister();
   5587     int32_t offset = operand.GetOffsetImmediate();
   5588     if (IsUsingT32()) {
   5589       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
   5590       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5591           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   5592           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5593         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5594         uint32_t offset_ = abs(offset) >> 2;
   5595         EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5596                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5597         AdvanceIT();
   5598         return;
   5599       }
   5600       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
   5601       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5602           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   5603           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5604         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5605         uint32_t offset_ = abs(offset) >> 2;
   5606         EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5607                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5608         AdvanceIT();
   5609         return;
   5610       }
   5611       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
   5612       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5613           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   5614           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5615         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5616         uint32_t offset_ = abs(offset) >> 2;
   5617         EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5618                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5619         AdvanceIT();
   5620         return;
   5621       }
   5622       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
   5623       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5624           operand.IsOffset() &&
   5625           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5626         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5627         uint32_t offset_ = abs(offset);
   5628         EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5629                    offset_ | (sign << 23));
   5630         AdvanceIT();
   5631         return;
   5632       }
   5633     } else {
   5634       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
   5635       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5636           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   5637           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5638           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   5639            AllowUnpredictable())) {
   5640         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5641         uint32_t offset_ = abs(offset);
   5642         EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
   5643                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5644                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5645         return;
   5646       }
   5647       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
   5648       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5649           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   5650           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5651           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   5652            AllowUnpredictable())) {
   5653         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5654         uint32_t offset_ = abs(offset);
   5655         EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
   5656                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5657                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5658         return;
   5659       }
   5660       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
   5661       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5662           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   5663           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5664           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   5665            AllowUnpredictable())) {
   5666         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5667         uint32_t offset_ = abs(offset);
   5668         EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
   5669                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5670                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5671         return;
   5672       }
   5673       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
   5674       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5675           (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5676           operand.IsOffset() && cond.IsNotNever() &&
   5677           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   5678            AllowUnpredictable())) {
   5679         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5680         uint32_t offset_ = abs(offset);
   5681         EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
   5682                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   5683                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5684         return;
   5685       }
   5686     }
   5687   }
   5688   if (operand.IsPlainRegister()) {
   5689     Register rn = operand.GetBaseRegister();
   5690     Sign sign = operand.GetSign();
   5691     Register rm = operand.GetOffsetRegister();
   5692     if (IsUsingA32()) {
   5693       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
   5694       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5695           operand.IsOffset() && cond.IsNotNever() &&
   5696           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   5697            AllowUnpredictable())) {
   5698         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5699         EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
   5700                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5701                 (sign_ << 23));
   5702         return;
   5703       }
   5704       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
   5705       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5706           operand.IsPostIndex() && cond.IsNotNever() &&
   5707           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   5708            AllowUnpredictable())) {
   5709         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5710         EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
   5711                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5712                 (sign_ << 23));
   5713         return;
   5714       }
   5715       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
   5716       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5717           operand.IsPreIndex() && cond.IsNotNever() &&
   5718           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   5719            AllowUnpredictable())) {
   5720         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5721         EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
   5722                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5723                 (sign_ << 23));
   5724         return;
   5725       }
   5726     }
   5727   }
   5728   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
   5729 }
   5730 
   5731 void Assembler::ldrd(Condition cond,
   5732                      Register rt,
   5733                      Register rt2,
   5734                      Location* location) {
   5735   VIXL_ASSERT(AllowAssembler());
   5736   CheckIT(cond);
   5737   Location::Offset offset =
   5738       location->IsBound()
   5739           ? location->GetLocation() -
   5740                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5741           : 0;
   5742   if (IsUsingT32()) {
   5743     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
   5744     if (((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   5745           ((offset & 0x3) == 0)) ||
   5746          !location->IsBound()) &&
   5747         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5748       static class EmitOp : public Location::EmitOperator {
   5749        public:
   5750         EmitOp() : Location::EmitOperator(T32) {}
   5751         virtual uint32_t Encode(uint32_t instr,
   5752                                 Location::Offset program_counter,
   5753                                 const Location* loc) const VIXL_OVERRIDE {
   5754           program_counter += kT32PcDelta;
   5755           Location::Offset off =
   5756               loc->GetLocation() - AlignDown(program_counter, 4);
   5757           VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
   5758           int32_t target = off >> 2;
   5759           uint32_t U = (target >= 0);
   5760           target = abs(target) | (U << 8);
   5761           return instr | (target & 0xff) | ((target & 0x100) << 15);
   5762         }
   5763       } immop;
   5764       EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
   5765                       location,
   5766                       immop,
   5767                       &kT32DataInfo));
   5768       AdvanceIT();
   5769       return;
   5770     }
   5771   } else {
   5772     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
   5773     if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5774         ((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
   5775          !location->IsBound()) &&
   5776         cond.IsNotNever() &&
   5777         ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || AllowUnpredictable())) {
   5778       static class EmitOp : public Location::EmitOperator {
   5779        public:
   5780         EmitOp() : Location::EmitOperator(A32) {}
   5781         virtual uint32_t Encode(uint32_t instr,
   5782                                 Location::Offset program_counter,
   5783                                 const Location* loc) const VIXL_OVERRIDE {
   5784           program_counter += kA32PcDelta;
   5785           Location::Offset off =
   5786               loc->GetLocation() - AlignDown(program_counter, 4);
   5787           VIXL_ASSERT((off >= -255) && (off <= 255));
   5788           uint32_t U = (off >= 0);
   5789           int32_t target = abs(off) | (U << 8);
   5790           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   5791                  ((target & 0x100) << 15);
   5792         }
   5793       } immop;
   5794       EmitA32(
   5795           Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5796                location,
   5797                immop,
   5798                &kA32VeryNearDataInfo));
   5799       return;
   5800     }
   5801   }
   5802   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, location);
   5803 }
   5804 
   5805 bool Assembler::ldrd_info(Condition cond,
   5806                           Register rt,
   5807                           Register rt2,
   5808                           Location* location,
   5809                           const struct ReferenceInfo** info) {
   5810   VIXL_ASSERT(!location->IsBound());
   5811   USE(location);
   5812   if (IsUsingT32()) {
   5813     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
   5814     if (true) {
   5815       *info = &kT32DataInfo;
   5816       return true;
   5817     }
   5818   } else {
   5819     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
   5820     if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5821         cond.IsNotNever()) {
   5822       *info = &kA32VeryNearDataInfo;
   5823       return true;
   5824     }
   5825   }
   5826   return false;
   5827 }
   5828 
   5829 void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) {
   5830   VIXL_ASSERT(AllowAssembler());
   5831   CheckIT(cond);
   5832   if (operand.IsImmediate()) {
   5833     Register rn = operand.GetBaseRegister();
   5834     int32_t offset = operand.GetOffsetImmediate();
   5835     if (IsUsingT32()) {
   5836       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
   5837       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
   5838           operand.IsOffset() &&
   5839           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5840         int32_t offset_ = offset >> 2;
   5841         EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5842                    (offset_ & 0xff));
   5843         AdvanceIT();
   5844         return;
   5845       }
   5846     } else {
   5847       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
   5848       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() &&
   5849           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5850         EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
   5851                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5852         return;
   5853       }
   5854     }
   5855   }
   5856   Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
   5857 }
   5858 
   5859 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
   5860   VIXL_ASSERT(AllowAssembler());
   5861   CheckIT(cond);
   5862   if (operand.IsImmediateZero()) {
   5863     Register rn = operand.GetBaseRegister();
   5864     if (IsUsingT32()) {
   5865       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   5866       if (operand.IsOffset() &&
   5867           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5868         EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5869         AdvanceIT();
   5870         return;
   5871       }
   5872     } else {
   5873       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   5874       if (operand.IsOffset() && cond.IsNotNever() &&
   5875           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5876         EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
   5877                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5878         return;
   5879       }
   5880     }
   5881   }
   5882   Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
   5883 }
   5884 
   5885 void Assembler::ldrexd(Condition cond,
   5886                        Register rt,
   5887                        Register rt2,
   5888                        const MemOperand& operand) {
   5889   VIXL_ASSERT(AllowAssembler());
   5890   CheckIT(cond);
   5891   if (operand.IsImmediateZero()) {
   5892     Register rn = operand.GetBaseRegister();
   5893     if (IsUsingT32()) {
   5894       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
   5895       if (operand.IsOffset() &&
   5896           ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5897         EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5898                    (rn.GetCode() << 16));
   5899         AdvanceIT();
   5900         return;
   5901       }
   5902     } else {
   5903       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
   5904       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5905           operand.IsOffset() && cond.IsNotNever() &&
   5906           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) ||
   5907            AllowUnpredictable())) {
   5908         EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
   5909                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5910         return;
   5911       }
   5912     }
   5913   }
   5914   Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
   5915 }
   5916 
   5917 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
   5918   VIXL_ASSERT(AllowAssembler());
   5919   CheckIT(cond);
   5920   if (operand.IsImmediateZero()) {
   5921     Register rn = operand.GetBaseRegister();
   5922     if (IsUsingT32()) {
   5923       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   5924       if (operand.IsOffset() &&
   5925           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5926         EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5927         AdvanceIT();
   5928         return;
   5929       }
   5930     } else {
   5931       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   5932       if (operand.IsOffset() && cond.IsNotNever() &&
   5933           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5934         EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
   5935                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5936         return;
   5937       }
   5938     }
   5939   }
   5940   Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
   5941 }
   5942 
   5943 void Assembler::ldrh(Condition cond,
   5944                      EncodingSize size,
   5945                      Register rt,
   5946                      const MemOperand& operand) {
   5947   VIXL_ASSERT(AllowAssembler());
   5948   CheckIT(cond);
   5949   if (operand.IsImmediate()) {
   5950     Register rn = operand.GetBaseRegister();
   5951     int32_t offset = operand.GetOffsetImmediate();
   5952     if (IsUsingT32()) {
   5953       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   5954       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   5955           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
   5956         int32_t offset_ = offset >> 1;
   5957         EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
   5958                    ((offset_ & 0x1f) << 6));
   5959         AdvanceIT();
   5960         return;
   5961       }
   5962       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   5963       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5964           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5965         EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5966                    (offset & 0xfff));
   5967         AdvanceIT();
   5968         return;
   5969       }
   5970       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   5971       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5972           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5973         EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5974                    (-offset & 0xff));
   5975         AdvanceIT();
   5976         return;
   5977       }
   5978       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   5979       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5980           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5981         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5982         uint32_t offset_ = abs(offset);
   5983         EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5984                    offset_ | (sign << 9));
   5985         AdvanceIT();
   5986         return;
   5987       }
   5988       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   5989       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5990           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5991         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5992         uint32_t offset_ = abs(offset);
   5993         EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5994                    offset_ | (sign << 9));
   5995         AdvanceIT();
   5996         return;
   5997       }
   5998       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   5999       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   6000           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   6001         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6002         uint32_t offset_ = abs(offset);
   6003         EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   6004         AdvanceIT();
   6005         return;
   6006       }
   6007     } else {
   6008       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   6009       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   6010           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6011           (!rt.IsPC() || AllowUnpredictable())) {
   6012         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6013         uint32_t offset_ = abs(offset);
   6014         EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
   6015                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6016                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6017         return;
   6018       }
   6019       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   6020       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   6021           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6022           (!rt.IsPC() || AllowUnpredictable())) {
   6023         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6024         uint32_t offset_ = abs(offset);
   6025         EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
   6026                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6027                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6028         return;
   6029       }
   6030       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   6031       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   6032           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6033           (!rt.IsPC() || AllowUnpredictable())) {
   6034         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6035         uint32_t offset_ = abs(offset);
   6036         EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
   6037                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6038                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6039         return;
   6040       }
   6041       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   6042       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   6043           operand.IsOffset() && cond.IsNotNever() &&
   6044           (!rt.IsPC() || AllowUnpredictable())) {
   6045         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6046         uint32_t offset_ = abs(offset);
   6047         EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
   6048                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   6049                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6050         return;
   6051       }
   6052     }
   6053   }
   6054   if (operand.IsPlainRegister()) {
   6055     Register rn = operand.GetBaseRegister();
   6056     Sign sign = operand.GetSign();
   6057     Register rm = operand.GetOffsetRegister();
   6058     if (IsUsingT32()) {
   6059       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   6060       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   6061           sign.IsPlus() && operand.IsOffset()) {
   6062         EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
   6063                    (rm.GetCode() << 6));
   6064         AdvanceIT();
   6065         return;
   6066       }
   6067     } else {
   6068       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   6069       if (operand.IsOffset() && cond.IsNotNever() &&
   6070           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6071         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6072         EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
   6073                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6074                 (sign_ << 23));
   6075         return;
   6076       }
   6077       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   6078       if (operand.IsPostIndex() && cond.IsNotNever() &&
   6079           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6080         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6081         EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
   6082                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6083                 (sign_ << 23));
   6084         return;
   6085       }
   6086       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   6087       if (operand.IsPreIndex() && cond.IsNotNever() &&
   6088           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6089         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6090         EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
   6091                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6092                 (sign_ << 23));
   6093         return;
   6094       }
   6095     }
   6096   }
   6097   if (operand.IsShiftedRegister()) {
   6098     Register rn = operand.GetBaseRegister();
   6099     Sign sign = operand.GetSign();
   6100     Register rm = operand.GetOffsetRegister();
   6101     Shift shift = operand.GetShift();
   6102     uint32_t amount = operand.GetShiftAmount();
   6103     if (IsUsingT32()) {
   6104       // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   6105       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   6106           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
   6107           (!rm.IsPC() || AllowUnpredictable())) {
   6108         EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6109                    rm.GetCode() | (amount << 4));
   6110         AdvanceIT();
   6111         return;
   6112       }
   6113     }
   6114   }
   6115   Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
   6116 }
   6117 
   6118 void Assembler::ldrh(Condition cond, Register rt, Location* location) {
   6119   VIXL_ASSERT(AllowAssembler());
   6120   CheckIT(cond);
   6121   Location::Offset offset =
   6122       location->IsBound()
   6123           ? location->GetLocation() -
   6124                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   6125           : 0;
   6126   if (IsUsingT32()) {
   6127     // LDRH{<c>}{<q>} <Rt>, <label> ; T1
   6128     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   6129          !location->IsBound()) &&
   6130         !rt.Is(pc)) {
   6131       static class EmitOp : public Location::EmitOperator {
   6132        public:
   6133         EmitOp() : Location::EmitOperator(T32) {}
   6134         virtual uint32_t Encode(uint32_t instr,
   6135                                 Location::Offset program_counter,
   6136                                 const Location* loc) const VIXL_OVERRIDE {
   6137           program_counter += kT32PcDelta;
   6138           Location::Offset off =
   6139               loc->GetLocation() - AlignDown(program_counter, 4);
   6140           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   6141           uint32_t U = (off >= 0);
   6142           int32_t target = abs(off) | (U << 12);
   6143           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   6144         }
   6145       } immop;
   6146       EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12),
   6147                       location,
   6148                       immop,
   6149                       &kT32FarDataInfo));
   6150       AdvanceIT();
   6151       return;
   6152     }
   6153   } else {
   6154     // LDRH{<c>}{<q>} <Rt>, <label> ; A1
   6155     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
   6156          !location->IsBound()) &&
   6157         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   6158       static class EmitOp : public Location::EmitOperator {
   6159        public:
   6160         EmitOp() : Location::EmitOperator(A32) {}
   6161         virtual uint32_t Encode(uint32_t instr,
   6162                                 Location::Offset program_counter,
   6163                                 const Location* loc) const VIXL_OVERRIDE {
   6164           program_counter += kA32PcDelta;
   6165           Location::Offset off =
   6166               loc->GetLocation() - AlignDown(program_counter, 4);
   6167           VIXL_ASSERT((off >= -255) && (off <= 255));
   6168           uint32_t U = (off >= 0);
   6169           int32_t target = abs(off) | (U << 8);
   6170           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   6171                  ((target & 0x100) << 15);
   6172         }
   6173       } immop;
   6174       EmitA32(
   6175           Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   6176                location,
   6177                immop,
   6178                &kA32VeryNearDataInfo));
   6179       return;
   6180     }
   6181   }
   6182   Delegate(kLdrh, &Assembler::ldrh, cond, rt, location);
   6183 }
   6184 
   6185 bool Assembler::ldrh_info(Condition cond,
   6186                           Register rt,
   6187                           Location* location,
   6188                           const struct ReferenceInfo** info) {
   6189   VIXL_ASSERT(!location->IsBound());
   6190   USE(location);
   6191   if (IsUsingT32()) {
   6192     // LDRH{<c>}{<q>} <Rt>, <label> ; T1
   6193     if (!rt.Is(pc)) {
   6194       *info = &kT32FarDataInfo;
   6195       return true;
   6196     }
   6197   } else {
   6198     // LDRH{<c>}{<q>} <Rt>, <label> ; A1
   6199     if (cond.IsNotNever()) {
   6200       *info = &kA32VeryNearDataInfo;
   6201       return true;
   6202     }
   6203   }
   6204   return false;
   6205 }
   6206 
   6207 void Assembler::ldrsb(Condition cond,
   6208                       EncodingSize size,
   6209                       Register rt,
   6210                       const MemOperand& operand) {
   6211   VIXL_ASSERT(AllowAssembler());
   6212   CheckIT(cond);
   6213   if (operand.IsImmediate()) {
   6214     Register rn = operand.GetBaseRegister();
   6215     int32_t offset = operand.GetOffsetImmediate();
   6216     if (IsUsingT32()) {
   6217       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   6218       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   6219           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6220         EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6221                    (offset & 0xfff));
   6222         AdvanceIT();
   6223         return;
   6224       }
   6225       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
   6226       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   6227           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6228         EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6229                    (-offset & 0xff));
   6230         AdvanceIT();
   6231         return;
   6232       }
   6233       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
   6234       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   6235           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   6236         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6237         uint32_t offset_ = abs(offset);
   6238         EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6239                    offset_ | (sign << 9));
   6240         AdvanceIT();
   6241         return;
   6242       }
   6243       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
   6244       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   6245           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   6246         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6247         uint32_t offset_ = abs(offset);
   6248         EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6249                    offset_ | (sign << 9));
   6250         AdvanceIT();
   6251         return;
   6252       }
   6253       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   6254       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   6255           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   6256         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6257         uint32_t offset_ = abs(offset);
   6258         EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   6259         AdvanceIT();
   6260         return;
   6261       }
   6262     } else {
   6263       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
   6264       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   6265           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6266           (!rt.IsPC() || AllowUnpredictable())) {
   6267         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6268         uint32_t offset_ = abs(offset);
   6269         EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
   6270                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6271                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6272         return;
   6273       }
   6274       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
   6275       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   6276           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6277           (!rt.IsPC() || AllowUnpredictable())) {
   6278         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6279         uint32_t offset_ = abs(offset);
   6280         EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
   6281                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6282                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6283         return;
   6284       }
   6285       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
   6286       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   6287           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6288           (!rt.IsPC() || AllowUnpredictable())) {
   6289         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6290         uint32_t offset_ = abs(offset);
   6291         EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
   6292                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6293                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6294         return;
   6295       }
   6296       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   6297       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   6298           operand.IsOffset() && cond.IsNotNever() &&
   6299           (!rt.IsPC() || AllowUnpredictable())) {
   6300         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6301         uint32_t offset_ = abs(offset);
   6302         EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
   6303                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   6304                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6305         return;
   6306       }
   6307     }
   6308   }
   6309   if (operand.IsPlainRegister()) {
   6310     Register rn = operand.GetBaseRegister();
   6311     Sign sign = operand.GetSign();
   6312     Register rm = operand.GetOffsetRegister();
   6313     if (IsUsingT32()) {
   6314       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   6315       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   6316           sign.IsPlus() && operand.IsOffset()) {
   6317         EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
   6318                    (rm.GetCode() << 6));
   6319         AdvanceIT();
   6320         return;
   6321       }
   6322     } else {
   6323       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   6324       if (operand.IsOffset() && cond.IsNotNever() &&
   6325           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6326         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6327         EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
   6328                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6329                 (sign_ << 23));
   6330         return;
   6331       }
   6332       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   6333       if (operand.IsPostIndex() && cond.IsNotNever() &&
   6334           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6335         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6336         EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
   6337                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6338                 (sign_ << 23));
   6339         return;
   6340       }
   6341       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   6342       if (operand.IsPreIndex() && cond.IsNotNever() &&
   6343           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6344         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6345         EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
   6346                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6347                 (sign_ << 23));
   6348         return;
   6349       }
   6350     }
   6351   }
   6352   if (operand.IsShiftedRegister()) {
   6353     Register rn = operand.GetBaseRegister();
   6354     Sign sign = operand.GetSign();
   6355     Register rm = operand.GetOffsetRegister();
   6356     Shift shift = operand.GetShift();
   6357     uint32_t amount = operand.GetShiftAmount();
   6358     if (IsUsingT32()) {
   6359       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   6360       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   6361           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
   6362           (!rm.IsPC() || AllowUnpredictable())) {
   6363         EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6364                    rm.GetCode() | (amount << 4));
   6365         AdvanceIT();
   6366         return;
   6367       }
   6368     }
   6369   }
   6370   Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
   6371 }
   6372 
   6373 void Assembler::ldrsb(Condition cond, Register rt, Location* location) {
   6374   VIXL_ASSERT(AllowAssembler());
   6375   CheckIT(cond);
   6376   Location::Offset offset =
   6377       location->IsBound()
   6378           ? location->GetLocation() -
   6379                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   6380           : 0;
   6381   if (IsUsingT32()) {
   6382     // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
   6383     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   6384          !location->IsBound()) &&
   6385         !rt.Is(pc)) {
   6386       static class EmitOp : public Location::EmitOperator {
   6387        public:
   6388         EmitOp() : Location::EmitOperator(T32) {}
   6389         virtual uint32_t Encode(uint32_t instr,
   6390                                 Location::Offset program_counter,
   6391                                 const Location* loc) const VIXL_OVERRIDE {
   6392           program_counter += kT32PcDelta;
   6393           Location::Offset off =
   6394               loc->GetLocation() - AlignDown(program_counter, 4);
   6395           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   6396           uint32_t U = (off >= 0);
   6397           int32_t target = abs(off) | (U << 12);
   6398           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   6399         }
   6400       } immop;
   6401       EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12),
   6402                       location,
   6403                       immop,
   6404                       &kT32FarDataInfo));
   6405       AdvanceIT();
   6406       return;
   6407     }
   6408   } else {
   6409     // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
   6410     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
   6411          !location->IsBound()) &&
   6412         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   6413       static class EmitOp : public Location::EmitOperator {
   6414        public:
   6415         EmitOp() : Location::EmitOperator(A32) {}
   6416         virtual uint32_t Encode(uint32_t instr,
   6417                                 Location::Offset program_counter,
   6418                                 const Location* loc) const VIXL_OVERRIDE {
   6419           program_counter += kA32PcDelta;
   6420           Location::Offset off =
   6421               loc->GetLocation() - AlignDown(program_counter, 4);
   6422           VIXL_ASSERT((off >= -255) && (off <= 255));
   6423           uint32_t U = (off >= 0);
   6424           int32_t target = abs(off) | (U << 8);
   6425           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   6426                  ((target & 0x100) << 15);
   6427         }
   6428       } immop;
   6429       EmitA32(
   6430           Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   6431                location,
   6432                immop,
   6433                &kA32VeryNearDataInfo));
   6434       return;
   6435     }
   6436   }
   6437   Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, location);
   6438 }
   6439 
   6440 bool Assembler::ldrsb_info(Condition cond,
   6441                            Register rt,
   6442                            Location* location,
   6443                            const struct ReferenceInfo** info) {
   6444   VIXL_ASSERT(!location->IsBound());
   6445   USE(location);
   6446   if (IsUsingT32()) {
   6447     // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
   6448     if (!rt.Is(pc)) {
   6449       *info = &kT32FarDataInfo;
   6450       return true;
   6451     }
   6452   } else {
   6453     // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
   6454     if (cond.IsNotNever()) {
   6455       *info = &kA32VeryNearDataInfo;
   6456       return true;
   6457     }
   6458   }
   6459   return false;
   6460 }
   6461 
   6462 void Assembler::ldrsh(Condition cond,
   6463                       EncodingSize size,
   6464                       Register rt,
   6465                       const MemOperand& operand) {
   6466   VIXL_ASSERT(AllowAssembler());
   6467   CheckIT(cond);
   6468   if (operand.IsImmediate()) {
   6469     Register rn = operand.GetBaseRegister();
   6470     int32_t offset = operand.GetOffsetImmediate();
   6471     if (IsUsingT32()) {
   6472       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   6473       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   6474           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6475         EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6476                    (offset & 0xfff));
   6477         AdvanceIT();
   6478         return;
   6479       }
   6480       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
   6481       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   6482           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6483         EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6484                    (-offset & 0xff));
   6485         AdvanceIT();
   6486         return;
   6487       }
   6488       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
   6489       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   6490           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   6491         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6492         uint32_t offset_ = abs(offset);
   6493         EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6494                    offset_ | (sign << 9));
   6495         AdvanceIT();
   6496         return;
   6497       }
   6498       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
   6499       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   6500           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   6501         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6502         uint32_t offset_ = abs(offset);
   6503         EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6504                    offset_ | (sign << 9));
   6505         AdvanceIT();
   6506         return;
   6507       }
   6508       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   6509       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   6510           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   6511         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6512         uint32_t offset_ = abs(offset);
   6513         EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   6514         AdvanceIT();
   6515         return;
   6516       }
   6517     } else {
   6518       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
   6519       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   6520           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6521           (!rt.IsPC() || AllowUnpredictable())) {
   6522         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6523         uint32_t offset_ = abs(offset);
   6524         EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
   6525                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6526                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6527         return;
   6528       }
   6529       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
   6530       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   6531           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6532           (!rt.IsPC() || AllowUnpredictable())) {
   6533         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6534         uint32_t offset_ = abs(offset);
   6535         EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
   6536                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6537                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6538         return;
   6539       }
   6540       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
   6541       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   6542           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6543           (!rt.IsPC() || AllowUnpredictable())) {
   6544         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6545         uint32_t offset_ = abs(offset);
   6546         EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
   6547                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6548                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6549         return;
   6550       }
   6551       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   6552       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   6553           operand.IsOffset() && cond.IsNotNever() &&
   6554           (!rt.IsPC() || AllowUnpredictable())) {
   6555         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6556         uint32_t offset_ = abs(offset);
   6557         EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
   6558                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   6559                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6560         return;
   6561       }
   6562     }
   6563   }
   6564   if (operand.IsPlainRegister()) {
   6565     Register rn = operand.GetBaseRegister();
   6566     Sign sign = operand.GetSign();
   6567     Register rm = operand.GetOffsetRegister();
   6568     if (IsUsingT32()) {
   6569       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   6570       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   6571           sign.IsPlus() && operand.IsOffset()) {
   6572         EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
   6573                    (rm.GetCode() << 6));
   6574         AdvanceIT();
   6575         return;
   6576       }
   6577     } else {
   6578       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   6579       if (operand.IsOffset() && cond.IsNotNever() &&
   6580           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6581         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6582         EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
   6583                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6584                 (sign_ << 23));
   6585         return;
   6586       }
   6587       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   6588       if (operand.IsPostIndex() && cond.IsNotNever() &&
   6589           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6590         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6591         EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
   6592                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6593                 (sign_ << 23));
   6594         return;
   6595       }
   6596       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   6597       if (operand.IsPreIndex() && cond.IsNotNever() &&
   6598           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6599         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6600         EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
   6601                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6602                 (sign_ << 23));
   6603         return;
   6604       }
   6605     }
   6606   }
   6607   if (operand.IsShiftedRegister()) {
   6608     Register rn = operand.GetBaseRegister();
   6609     Sign sign = operand.GetSign();
   6610     Register rm = operand.GetOffsetRegister();
   6611     Shift shift = operand.GetShift();
   6612     uint32_t amount = operand.GetShiftAmount();
   6613     if (IsUsingT32()) {
   6614       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   6615       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   6616           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
   6617           (!rm.IsPC() || AllowUnpredictable())) {
   6618         EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6619                    rm.GetCode() | (amount << 4));
   6620         AdvanceIT();
   6621         return;
   6622       }
   6623     }
   6624   }
   6625   Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
   6626 }
   6627 
   6628 void Assembler::ldrsh(Condition cond, Register rt, Location* location) {
   6629   VIXL_ASSERT(AllowAssembler());
   6630   CheckIT(cond);
   6631   Location::Offset offset =
   6632       location->IsBound()
   6633           ? location->GetLocation() -
   6634                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   6635           : 0;
   6636   if (IsUsingT32()) {
   6637     // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
   6638     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   6639          !location->IsBound()) &&
   6640         !rt.Is(pc)) {
   6641       static class EmitOp : public Location::EmitOperator {
   6642        public:
   6643         EmitOp() : Location::EmitOperator(T32) {}
   6644         virtual uint32_t Encode(uint32_t instr,
   6645                                 Location::Offset program_counter,
   6646                                 const Location* loc) const VIXL_OVERRIDE {
   6647           program_counter += kT32PcDelta;
   6648           Location::Offset off =
   6649               loc->GetLocation() - AlignDown(program_counter, 4);
   6650           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   6651           uint32_t U = (off >= 0);
   6652           int32_t target = abs(off) | (U << 12);
   6653           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   6654         }
   6655       } immop;
   6656       EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12),
   6657                       location,
   6658                       immop,
   6659                       &kT32FarDataInfo));
   6660       AdvanceIT();
   6661       return;
   6662     }
   6663   } else {
   6664     // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
   6665     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
   6666          !location->IsBound()) &&
   6667         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   6668       static class EmitOp : public Location::EmitOperator {
   6669        public:
   6670         EmitOp() : Location::EmitOperator(A32) {}
   6671         virtual uint32_t Encode(uint32_t instr,
   6672                                 Location::Offset program_counter,
   6673                                 const Location* loc) const VIXL_OVERRIDE {
   6674           program_counter += kA32PcDelta;
   6675           Location::Offset off =
   6676               loc->GetLocation() - AlignDown(program_counter, 4);
   6677           VIXL_ASSERT((off >= -255) && (off <= 255));
   6678           uint32_t U = (off >= 0);
   6679           int32_t target = abs(off) | (U << 8);
   6680           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   6681                  ((target & 0x100) << 15);
   6682         }
   6683       } immop;
   6684       EmitA32(
   6685           Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   6686                location,
   6687                immop,
   6688                &kA32VeryNearDataInfo));
   6689       return;
   6690     }
   6691   }
   6692   Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, location);
   6693 }
   6694 
   6695 bool Assembler::ldrsh_info(Condition cond,
   6696                            Register rt,
   6697                            Location* location,
   6698                            const struct ReferenceInfo** info) {
   6699   VIXL_ASSERT(!location->IsBound());
   6700   USE(location);
   6701   if (IsUsingT32()) {
   6702     // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
   6703     if (!rt.Is(pc)) {
   6704       *info = &kT32FarDataInfo;
   6705       return true;
   6706     }
   6707   } else {
   6708     // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
   6709     if (cond.IsNotNever()) {
   6710       *info = &kA32VeryNearDataInfo;
   6711       return true;
   6712     }
   6713   }
   6714   return false;
   6715 }
   6716 
   6717 void Assembler::lsl(Condition cond,
   6718                     EncodingSize size,
   6719                     Register rd,
   6720                     Register rm,
   6721                     const Operand& operand) {
   6722   VIXL_ASSERT(AllowAssembler());
   6723   CheckIT(cond);
   6724   if (operand.IsImmediate()) {
   6725     uint32_t imm = operand.GetImmediate();
   6726     if (IsUsingT32()) {
   6727       // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6728       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6729           (imm >= 1) && (imm <= 31)) {
   6730         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
   6731         AdvanceIT();
   6732         return;
   6733       }
   6734       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6735       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
   6736           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6737         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6738                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   6739         AdvanceIT();
   6740         return;
   6741       }
   6742     } else {
   6743       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6744       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   6745         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
   6746                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   6747         return;
   6748       }
   6749     }
   6750   }
   6751   if (operand.IsPlainRegister()) {
   6752     Register rs = operand.GetBaseRegister();
   6753     if (IsUsingT32()) {
   6754       // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6755       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6756           rs.IsLow()) {
   6757         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   6758         AdvanceIT();
   6759         return;
   6760       }
   6761       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6762       if (!size.IsNarrow() &&
   6763           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6764         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6765                    rs.GetCode());
   6766         AdvanceIT();
   6767         return;
   6768       }
   6769     } else {
   6770       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6771       if (cond.IsNotNever() &&
   6772           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6773         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
   6774                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6775         return;
   6776       }
   6777     }
   6778   }
   6779   Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
   6780 }
   6781 
   6782 void Assembler::lsls(Condition cond,
   6783                      EncodingSize size,
   6784                      Register rd,
   6785                      Register rm,
   6786                      const Operand& operand) {
   6787   VIXL_ASSERT(AllowAssembler());
   6788   CheckIT(cond);
   6789   if (operand.IsImmediate()) {
   6790     uint32_t imm = operand.GetImmediate();
   6791     if (IsUsingT32()) {
   6792       // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6793       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6794           (imm >= 1) && (imm <= 31)) {
   6795         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
   6796         AdvanceIT();
   6797         return;
   6798       }
   6799       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6800       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
   6801           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6802         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6803                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   6804         AdvanceIT();
   6805         return;
   6806       }
   6807     } else {
   6808       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6809       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   6810         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
   6811                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   6812         return;
   6813       }
   6814     }
   6815   }
   6816   if (operand.IsPlainRegister()) {
   6817     Register rs = operand.GetBaseRegister();
   6818     if (IsUsingT32()) {
   6819       // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6820       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6821           rs.IsLow()) {
   6822         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   6823         AdvanceIT();
   6824         return;
   6825       }
   6826       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6827       if (!size.IsNarrow() &&
   6828           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6829         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6830                    rs.GetCode());
   6831         AdvanceIT();
   6832         return;
   6833       }
   6834     } else {
   6835       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6836       if (cond.IsNotNever() &&
   6837           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6838         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
   6839                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6840         return;
   6841       }
   6842     }
   6843   }
   6844   Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
   6845 }
   6846 
   6847 void Assembler::lsr(Condition cond,
   6848                     EncodingSize size,
   6849                     Register rd,
   6850                     Register rm,
   6851                     const Operand& operand) {
   6852   VIXL_ASSERT(AllowAssembler());
   6853   CheckIT(cond);
   6854   if (operand.IsImmediate()) {
   6855     uint32_t imm = operand.GetImmediate();
   6856     if (IsUsingT32()) {
   6857       // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6858       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6859           (imm >= 1) && (imm <= 32)) {
   6860         uint32_t amount_ = imm % 32;
   6861         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
   6862                    (amount_ << 6));
   6863         AdvanceIT();
   6864         return;
   6865       }
   6866       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6867       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
   6868           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6869         uint32_t amount_ = imm % 32;
   6870         EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
   6871                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6872         AdvanceIT();
   6873         return;
   6874       }
   6875     } else {
   6876       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6877       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   6878         uint32_t amount_ = imm % 32;
   6879         EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
   6880                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   6881         return;
   6882       }
   6883     }
   6884   }
   6885   if (operand.IsPlainRegister()) {
   6886     Register rs = operand.GetBaseRegister();
   6887     if (IsUsingT32()) {
   6888       // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6889       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6890           rs.IsLow()) {
   6891         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   6892         AdvanceIT();
   6893         return;
   6894       }
   6895       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6896       if (!size.IsNarrow() &&
   6897           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6898         EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6899                    rs.GetCode());
   6900         AdvanceIT();
   6901         return;
   6902       }
   6903     } else {
   6904       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6905       if (cond.IsNotNever() &&
   6906           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6907         EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
   6908                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6909         return;
   6910       }
   6911     }
   6912   }
   6913   Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
   6914 }
   6915 
   6916 void Assembler::lsrs(Condition cond,
   6917                      EncodingSize size,
   6918                      Register rd,
   6919                      Register rm,
   6920                      const Operand& operand) {
   6921   VIXL_ASSERT(AllowAssembler());
   6922   CheckIT(cond);
   6923   if (operand.IsImmediate()) {
   6924     uint32_t imm = operand.GetImmediate();
   6925     if (IsUsingT32()) {
   6926       // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6927       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6928           (imm >= 1) && (imm <= 32)) {
   6929         uint32_t amount_ = imm % 32;
   6930         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
   6931                    (amount_ << 6));
   6932         AdvanceIT();
   6933         return;
   6934       }
   6935       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6936       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
   6937           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6938         uint32_t amount_ = imm % 32;
   6939         EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
   6940                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6941         AdvanceIT();
   6942         return;
   6943       }
   6944     } else {
   6945       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6946       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   6947         uint32_t amount_ = imm % 32;
   6948         EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
   6949                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   6950         return;
   6951       }
   6952     }
   6953   }
   6954   if (operand.IsPlainRegister()) {
   6955     Register rs = operand.GetBaseRegister();
   6956     if (IsUsingT32()) {
   6957       // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6958       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6959           rs.IsLow()) {
   6960         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   6961         AdvanceIT();
   6962         return;
   6963       }
   6964       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6965       if (!size.IsNarrow() &&
   6966           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6967         EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6968                    rs.GetCode());
   6969         AdvanceIT();
   6970         return;
   6971       }
   6972     } else {
   6973       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6974       if (cond.IsNotNever() &&
   6975           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6976         EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
   6977                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6978         return;
   6979       }
   6980     }
   6981   }
   6982   Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
   6983 }
   6984 
   6985 void Assembler::mla(
   6986     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   6987   VIXL_ASSERT(AllowAssembler());
   6988   CheckIT(cond);
   6989   if (IsUsingT32()) {
   6990     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   6991     if (!ra.Is(pc) &&
   6992         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6993       EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   6994                  rm.GetCode() | (ra.GetCode() << 12));
   6995       AdvanceIT();
   6996       return;
   6997     }
   6998   } else {
   6999     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   7000     if (cond.IsNotNever() &&
   7001         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   7002          AllowUnpredictable())) {
   7003       EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   7004               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   7005       return;
   7006     }
   7007   }
   7008   Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
   7009 }
   7010 
   7011 void Assembler::mlas(
   7012     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   7013   VIXL_ASSERT(AllowAssembler());
   7014   CheckIT(cond);
   7015   if (IsUsingA32()) {
   7016     // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   7017     if (cond.IsNotNever() &&
   7018         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   7019          AllowUnpredictable())) {
   7020       EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   7021               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   7022       return;
   7023     }
   7024   }
   7025   Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
   7026 }
   7027 
   7028 void Assembler::mls(
   7029     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   7030   VIXL_ASSERT(AllowAssembler());
   7031   CheckIT(cond);
   7032   if (IsUsingT32()) {
   7033     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   7034     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   7035          AllowUnpredictable())) {
   7036       EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7037                  rm.GetCode() | (ra.GetCode() << 12));
   7038       AdvanceIT();
   7039       return;
   7040     }
   7041   } else {
   7042     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   7043     if (cond.IsNotNever() &&
   7044         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   7045          AllowUnpredictable())) {
   7046       EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   7047               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   7048       return;
   7049     }
   7050   }
   7051   Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
   7052 }
   7053 
   7054 void Assembler::mov(Condition cond,
   7055                     EncodingSize size,
   7056                     Register rd,
   7057                     const Operand& operand) {
   7058   VIXL_ASSERT(AllowAssembler());
   7059   CheckIT(cond);
   7060   if (operand.IsImmediateShiftedRegister()) {
   7061     Register rm = operand.GetBaseRegister();
   7062     if (operand.IsPlainRegister()) {
   7063       if (IsUsingT32()) {
   7064         // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
   7065         if (!size.IsWide() &&
   7066             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   7067              AllowUnpredictable())) {
   7068           EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
   7069                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   7070           AdvanceIT();
   7071           return;
   7072         }
   7073       }
   7074     }
   7075     Shift shift = operand.GetShift();
   7076     uint32_t amount = operand.GetShiftAmount();
   7077     if (IsUsingT32()) {
   7078       // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   7079       if (InITBlock() && !size.IsWide() && rd.IsLow() &&
   7080           shift.IsValidAmount(amount) && rm.IsLow() &&
   7081           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) &&
   7082           ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) {
   7083         uint32_t amount_ = amount % 32;
   7084         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
   7085                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
   7086         AdvanceIT();
   7087         return;
   7088       }
   7089       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
   7090       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   7091           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7092         uint32_t amount_ = amount % 32;
   7093         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   7094                    (operand.GetTypeEncodingValue() << 4) |
   7095                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7096         AdvanceIT();
   7097         return;
   7098       }
   7099     } else {
   7100       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   7101       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7102         uint32_t amount_ = amount % 32;
   7103         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
   7104                 (rd.GetCode() << 12) | rm.GetCode() |
   7105                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7106         return;
   7107       }
   7108     }
   7109   }
   7110   if (operand.IsRegisterShiftedRegister()) {
   7111     Register rm = operand.GetBaseRegister();
   7112     Shift shift = operand.GetShift();
   7113     Register rs = operand.GetShiftRegister();
   7114     if (IsUsingT32()) {
   7115       // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
   7116       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7117           shift.IsASR() && rs.IsLow()) {
   7118         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   7119         AdvanceIT();
   7120         return;
   7121       }
   7122       // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
   7123       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7124           shift.IsLSL() && rs.IsLow()) {
   7125         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   7126         AdvanceIT();
   7127         return;
   7128       }
   7129       // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
   7130       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7131           shift.IsLSR() && rs.IsLow()) {
   7132         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   7133         AdvanceIT();
   7134         return;
   7135       }
   7136       // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
   7137       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7138           shift.IsROR() && rs.IsLow()) {
   7139         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   7140         AdvanceIT();
   7141         return;
   7142       }
   7143       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
   7144       if (!size.IsNarrow() &&
   7145           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7146         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   7147                    (shift.GetType() << 21) | rs.GetCode());
   7148         AdvanceIT();
   7149         return;
   7150       }
   7151     } else {
   7152       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7153       if (cond.IsNotNever() &&
   7154           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7155         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
   7156                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7157                 (rs.GetCode() << 8));
   7158         return;
   7159       }
   7160     }
   7161   }
   7162   if (operand.IsImmediate()) {
   7163     uint32_t imm = operand.GetImmediate();
   7164     if (IsUsingT32()) {
   7165       ImmediateT32 immediate_t32(imm);
   7166       // MOV<c>{<q>} <Rd>, #<imm8> ; T1
   7167       if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
   7168         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
   7169         AdvanceIT();
   7170         return;
   7171       }
   7172       // MOV{<c>}{<q>} <Rd>, #<const> ; T2
   7173       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   7174           (!rd.IsPC() || AllowUnpredictable())) {
   7175         EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
   7176                    (immediate_t32.GetEncodingValue() & 0xff) |
   7177                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7178                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7179         AdvanceIT();
   7180         return;
   7181       }
   7182       // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
   7183       if (!size.IsNarrow() && (imm <= 65535) &&
   7184           (!rd.IsPC() || AllowUnpredictable())) {
   7185         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
   7186                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   7187                    ((imm & 0xf000) << 4));
   7188         AdvanceIT();
   7189         return;
   7190       }
   7191     } else {
   7192       ImmediateA32 immediate_a32(imm);
   7193       // MOV{<c>}{<q>} <Rd>, #<const> ; A1
   7194       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7195         EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
   7196                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   7197         return;
   7198       }
   7199       // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
   7200       if ((imm <= 65535) && cond.IsNotNever() &&
   7201           (!rd.IsPC() || AllowUnpredictable())) {
   7202         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
   7203                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   7204         return;
   7205       }
   7206     }
   7207   }
   7208   Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
   7209 }
   7210 
   7211 void Assembler::movs(Condition cond,
   7212                      EncodingSize size,
   7213                      Register rd,
   7214                      const Operand& operand) {
   7215   VIXL_ASSERT(AllowAssembler());
   7216   CheckIT(cond);
   7217   if (operand.IsImmediateShiftedRegister()) {
   7218     Register rm = operand.GetBaseRegister();
   7219     Shift shift = operand.GetShift();
   7220     uint32_t amount = operand.GetShiftAmount();
   7221     if (IsUsingT32()) {
   7222       // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   7223       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
   7224           shift.IsValidAmount(amount) && rm.IsLow() &&
   7225           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
   7226         uint32_t amount_ = amount % 32;
   7227         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
   7228                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
   7229         AdvanceIT();
   7230         return;
   7231       }
   7232       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
   7233       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   7234           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7235         uint32_t amount_ = amount % 32;
   7236         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   7237                    (operand.GetTypeEncodingValue() << 4) |
   7238                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7239         AdvanceIT();
   7240         return;
   7241       }
   7242     } else {
   7243       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   7244       if (shift.IsValidAmount(amount) && cond.IsNotNever() &&
   7245           (!rd.IsPC() || AllowUnpredictable())) {
   7246         uint32_t amount_ = amount % 32;
   7247         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
   7248                 (rd.GetCode() << 12) | rm.GetCode() |
   7249                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7250         return;
   7251       }
   7252     }
   7253   }
   7254   if (operand.IsRegisterShiftedRegister()) {
   7255     Register rm = operand.GetBaseRegister();
   7256     Shift shift = operand.GetShift();
   7257     Register rs = operand.GetShiftRegister();
   7258     if (IsUsingT32()) {
   7259       // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
   7260       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7261           shift.IsASR() && rs.IsLow()) {
   7262         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   7263         AdvanceIT();
   7264         return;
   7265       }
   7266       // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
   7267       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7268           shift.IsLSL() && rs.IsLow()) {
   7269         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   7270         AdvanceIT();
   7271         return;
   7272       }
   7273       // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
   7274       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7275           shift.IsLSR() && rs.IsLow()) {
   7276         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   7277         AdvanceIT();
   7278         return;
   7279       }
   7280       // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
   7281       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7282           shift.IsROR() && rs.IsLow()) {
   7283         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   7284         AdvanceIT();
   7285         return;
   7286       }
   7287       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
   7288       if (!size.IsNarrow() &&
   7289           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7290         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   7291                    (shift.GetType() << 21) | rs.GetCode());
   7292         AdvanceIT();
   7293         return;
   7294       }
   7295     } else {
   7296       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7297       if (cond.IsNotNever() &&
   7298           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7299         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
   7300                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7301                 (rs.GetCode() << 8));
   7302         return;
   7303       }
   7304     }
   7305   }
   7306   if (operand.IsImmediate()) {
   7307     uint32_t imm = operand.GetImmediate();
   7308     if (IsUsingT32()) {
   7309       ImmediateT32 immediate_t32(imm);
   7310       // MOVS{<q>} <Rd>, #<imm8> ; T1
   7311       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
   7312         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
   7313         AdvanceIT();
   7314         return;
   7315       }
   7316       // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
   7317       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   7318           (!rd.IsPC() || AllowUnpredictable())) {
   7319         EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
   7320                    (immediate_t32.GetEncodingValue() & 0xff) |
   7321                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7322                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7323         AdvanceIT();
   7324         return;
   7325       }
   7326     } else {
   7327       ImmediateA32 immediate_a32(imm);
   7328       // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
   7329       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7330         EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
   7331                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   7332         return;
   7333       }
   7334     }
   7335   }
   7336   Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
   7337 }
   7338 
   7339 void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
   7340   VIXL_ASSERT(AllowAssembler());
   7341   CheckIT(cond);
   7342   if (operand.IsImmediate()) {
   7343     uint32_t imm = operand.GetImmediate();
   7344     if (IsUsingT32()) {
   7345       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
   7346       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
   7347         EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
   7348                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   7349                    ((imm & 0xf000) << 4));
   7350         AdvanceIT();
   7351         return;
   7352       }
   7353     } else {
   7354       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
   7355       if ((imm <= 65535) && cond.IsNotNever() &&
   7356           (!rd.IsPC() || AllowUnpredictable())) {
   7357         EmitA32(0x03400000U | (cond.GetCondition() << 28) |
   7358                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   7359         return;
   7360       }
   7361     }
   7362   }
   7363   Delegate(kMovt, &Assembler::movt, cond, rd, operand);
   7364 }
   7365 
   7366 void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
   7367   VIXL_ASSERT(AllowAssembler());
   7368   CheckIT(cond);
   7369   if (operand.IsImmediate()) {
   7370     uint32_t imm = operand.GetImmediate();
   7371     if (IsUsingT32()) {
   7372       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
   7373       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
   7374         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
   7375                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   7376                    ((imm & 0xf000) << 4));
   7377         AdvanceIT();
   7378         return;
   7379       }
   7380     } else {
   7381       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
   7382       if ((imm <= 65535) && cond.IsNotNever() &&
   7383           (!rd.IsPC() || AllowUnpredictable())) {
   7384         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
   7385                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   7386         return;
   7387       }
   7388     }
   7389   }
   7390   Delegate(kMovw, &Assembler::movw, cond, rd, operand);
   7391 }
   7392 
   7393 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
   7394   VIXL_ASSERT(AllowAssembler());
   7395   CheckIT(cond);
   7396   if (IsUsingT32()) {
   7397     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
   7398     if ((!rd.IsPC() || AllowUnpredictable())) {
   7399       EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
   7400       AdvanceIT();
   7401       return;
   7402     }
   7403   } else {
   7404     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
   7405     if (cond.IsNotNever() && (!rd.IsPC() || AllowUnpredictable())) {
   7406       EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7407               (spec_reg.GetReg() << 22));
   7408       return;
   7409     }
   7410   }
   7411   Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
   7412 }
   7413 
   7414 void Assembler::msr(Condition cond,
   7415                     MaskedSpecialRegister spec_reg,
   7416                     const Operand& operand) {
   7417   VIXL_ASSERT(AllowAssembler());
   7418   CheckIT(cond);
   7419   if (operand.IsImmediate()) {
   7420     uint32_t imm = operand.GetImmediate();
   7421     if (IsUsingA32()) {
   7422       ImmediateA32 immediate_a32(imm);
   7423       // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
   7424       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7425         EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
   7426                 ((spec_reg.GetReg() & 0xf) << 16) |
   7427                 ((spec_reg.GetReg() & 0x10) << 18) |
   7428                 immediate_a32.GetEncodingValue());
   7429         return;
   7430       }
   7431     }
   7432   }
   7433   if (operand.IsPlainRegister()) {
   7434     Register rn = operand.GetBaseRegister();
   7435     if (IsUsingT32()) {
   7436       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
   7437       if ((!rn.IsPC() || AllowUnpredictable())) {
   7438         EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
   7439                    ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
   7440         AdvanceIT();
   7441         return;
   7442       }
   7443     } else {
   7444       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
   7445       if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   7446         EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
   7447                 ((spec_reg.GetReg() & 0xf) << 16) |
   7448                 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
   7449         return;
   7450       }
   7451     }
   7452   }
   7453   Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
   7454 }
   7455 
   7456 void Assembler::mul(
   7457     Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
   7458   VIXL_ASSERT(AllowAssembler());
   7459   CheckIT(cond);
   7460   if (IsUsingT32()) {
   7461     // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
   7462     if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
   7463         rm.IsLow()) {
   7464       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
   7465       AdvanceIT();
   7466       return;
   7467     }
   7468     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
   7469     if (!size.IsNarrow() &&
   7470         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7471       EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7472                  rm.GetCode());
   7473       AdvanceIT();
   7474       return;
   7475     }
   7476   } else {
   7477     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
   7478     if (cond.IsNotNever() &&
   7479         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7480       EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   7481               rn.GetCode() | (rm.GetCode() << 8));
   7482       return;
   7483     }
   7484   }
   7485   Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
   7486 }
   7487 
   7488 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
   7489   VIXL_ASSERT(AllowAssembler());
   7490   CheckIT(cond);
   7491   if (IsUsingT32()) {
   7492     // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
   7493     if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
   7494       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
   7495       AdvanceIT();
   7496       return;
   7497     }
   7498   } else {
   7499     // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
   7500     if (cond.IsNotNever() &&
   7501         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7502       EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   7503               rn.GetCode() | (rm.GetCode() << 8));
   7504       return;
   7505     }
   7506   }
   7507   Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
   7508 }
   7509 
   7510 void Assembler::mvn(Condition cond,
   7511                     EncodingSize size,
   7512                     Register rd,
   7513                     const Operand& operand) {
   7514   VIXL_ASSERT(AllowAssembler());
   7515   CheckIT(cond);
   7516   if (operand.IsImmediate()) {
   7517     uint32_t imm = operand.GetImmediate();
   7518     if (IsUsingT32()) {
   7519       ImmediateT32 immediate_t32(imm);
   7520       // MVN{<c>}{<q>} <Rd>, #<const> ; T1
   7521       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   7522           (!rd.IsPC() || AllowUnpredictable())) {
   7523         EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
   7524                    (immediate_t32.GetEncodingValue() & 0xff) |
   7525                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7526                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7527         AdvanceIT();
   7528         return;
   7529       }
   7530     } else {
   7531       ImmediateA32 immediate_a32(imm);
   7532       // MVN{<c>}{<q>} <Rd>, #<const> ; A1
   7533       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7534         EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
   7535                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   7536         return;
   7537       }
   7538     }
   7539   }
   7540   if (operand.IsImmediateShiftedRegister()) {
   7541     Register rm = operand.GetBaseRegister();
   7542     if (operand.IsPlainRegister()) {
   7543       if (IsUsingT32()) {
   7544         // MVN<c>{<q>} <Rd>, <Rm> ; T1
   7545         if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
   7546           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
   7547           AdvanceIT();
   7548           return;
   7549         }
   7550       }
   7551     }
   7552     Shift shift = operand.GetShift();
   7553     uint32_t amount = operand.GetShiftAmount();
   7554     if (IsUsingT32()) {
   7555       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   7556       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   7557           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7558         uint32_t amount_ = amount % 32;
   7559         EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   7560                    (operand.GetTypeEncodingValue() << 4) |
   7561                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7562         AdvanceIT();
   7563         return;
   7564       }
   7565     } else {
   7566       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   7567       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7568         uint32_t amount_ = amount % 32;
   7569         EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
   7570                 (rd.GetCode() << 12) | rm.GetCode() |
   7571                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7572         return;
   7573       }
   7574     }
   7575   }
   7576   if (operand.IsRegisterShiftedRegister()) {
   7577     Register rm = operand.GetBaseRegister();
   7578     Shift shift = operand.GetShift();
   7579     Register rs = operand.GetShiftRegister();
   7580     if (IsUsingA32()) {
   7581       // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7582       if (cond.IsNotNever() &&
   7583           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7584         EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
   7585                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7586                 (rs.GetCode() << 8));
   7587         return;
   7588       }
   7589     }
   7590   }
   7591   Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
   7592 }
   7593 
   7594 void Assembler::mvns(Condition cond,
   7595                      EncodingSize size,
   7596                      Register rd,
   7597                      const Operand& operand) {
   7598   VIXL_ASSERT(AllowAssembler());
   7599   CheckIT(cond);
   7600   if (operand.IsImmediate()) {
   7601     uint32_t imm = operand.GetImmediate();
   7602     if (IsUsingT32()) {
   7603       ImmediateT32 immediate_t32(imm);
   7604       // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
   7605       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   7606           (!rd.IsPC() || AllowUnpredictable())) {
   7607         EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
   7608                    (immediate_t32.GetEncodingValue() & 0xff) |
   7609                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7610                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7611         AdvanceIT();
   7612         return;
   7613       }
   7614     } else {
   7615       ImmediateA32 immediate_a32(imm);
   7616       // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
   7617       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7618         EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
   7619                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   7620         return;
   7621       }
   7622     }
   7623   }
   7624   if (operand.IsImmediateShiftedRegister()) {
   7625     Register rm = operand.GetBaseRegister();
   7626     if (operand.IsPlainRegister()) {
   7627       if (IsUsingT32()) {
   7628         // MVNS{<q>} <Rd>, <Rm> ; T1
   7629         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
   7630           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
   7631           AdvanceIT();
   7632           return;
   7633         }
   7634       }
   7635     }
   7636     Shift shift = operand.GetShift();
   7637     uint32_t amount = operand.GetShiftAmount();
   7638     if (IsUsingT32()) {
   7639       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   7640       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   7641           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7642         uint32_t amount_ = amount % 32;
   7643         EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   7644                    (operand.GetTypeEncodingValue() << 4) |
   7645                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7646         AdvanceIT();
   7647         return;
   7648       }
   7649     } else {
   7650       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   7651       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7652         uint32_t amount_ = amount % 32;
   7653         EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
   7654                 (rd.GetCode() << 12) | rm.GetCode() |
   7655                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7656         return;
   7657       }
   7658     }
   7659   }
   7660   if (operand.IsRegisterShiftedRegister()) {
   7661     Register rm = operand.GetBaseRegister();
   7662     Shift shift = operand.GetShift();
   7663     Register rs = operand.GetShiftRegister();
   7664     if (IsUsingA32()) {
   7665       // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7666       if (cond.IsNotNever() &&
   7667           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7668         EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
   7669                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7670                 (rs.GetCode() << 8));
   7671         return;
   7672       }
   7673     }
   7674   }
   7675   Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
   7676 }
   7677 
   7678 void Assembler::nop(Condition cond, EncodingSize size) {
   7679   VIXL_ASSERT(AllowAssembler());
   7680   CheckIT(cond);
   7681   if (IsUsingT32()) {
   7682     // NOP{<c>}{<q>} ; T1
   7683     if (!size.IsWide()) {
   7684       EmitT32_16(0xbf00);
   7685       AdvanceIT();
   7686       return;
   7687     }
   7688     // NOP{<c>}.W ; T2
   7689     if (!size.IsNarrow()) {
   7690       EmitT32_32(0xf3af8000U);
   7691       AdvanceIT();
   7692       return;
   7693     }
   7694   } else {
   7695     // NOP{<c>}{<q>} ; A1
   7696     if (cond.IsNotNever()) {
   7697       EmitA32(0x0320f000U | (cond.GetCondition() << 28));
   7698       return;
   7699     }
   7700   }
   7701   Delegate(kNop, &Assembler::nop, cond, size);
   7702 }
   7703 
   7704 void Assembler::orn(Condition cond,
   7705                     Register rd,
   7706                     Register rn,
   7707                     const Operand& operand) {
   7708   VIXL_ASSERT(AllowAssembler());
   7709   CheckIT(cond);
   7710   if (operand.IsImmediate()) {
   7711     uint32_t imm = operand.GetImmediate();
   7712     if (IsUsingT32()) {
   7713       ImmediateT32 immediate_t32(imm);
   7714       // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7715       if (immediate_t32.IsValid() && !rn.Is(pc) &&
   7716           (!rd.IsPC() || AllowUnpredictable())) {
   7717         EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7718                    (immediate_t32.GetEncodingValue() & 0xff) |
   7719                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7720                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7721         AdvanceIT();
   7722         return;
   7723       }
   7724     }
   7725   }
   7726   if (operand.IsImmediateShiftedRegister()) {
   7727     Register rm = operand.GetBaseRegister();
   7728     Shift shift = operand.GetShift();
   7729     uint32_t amount = operand.GetShiftAmount();
   7730     if (IsUsingT32()) {
   7731       // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   7732       if (shift.IsValidAmount(amount) && !rn.Is(pc) &&
   7733           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7734         uint32_t amount_ = amount % 32;
   7735         EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7736                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7737                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7738         AdvanceIT();
   7739         return;
   7740       }
   7741     }
   7742   }
   7743   Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
   7744 }
   7745 
   7746 void Assembler::orns(Condition cond,
   7747                      Register rd,
   7748                      Register rn,
   7749                      const Operand& operand) {
   7750   VIXL_ASSERT(AllowAssembler());
   7751   CheckIT(cond);
   7752   if (operand.IsImmediate()) {
   7753     uint32_t imm = operand.GetImmediate();
   7754     if (IsUsingT32()) {
   7755       ImmediateT32 immediate_t32(imm);
   7756       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7757       if (immediate_t32.IsValid() && !rn.Is(pc) &&
   7758           (!rd.IsPC() || AllowUnpredictable())) {
   7759         EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7760                    (immediate_t32.GetEncodingValue() & 0xff) |
   7761                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7762                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7763         AdvanceIT();
   7764         return;
   7765       }
   7766     }
   7767   }
   7768   if (operand.IsImmediateShiftedRegister()) {
   7769     Register rm = operand.GetBaseRegister();
   7770     Shift shift = operand.GetShift();
   7771     uint32_t amount = operand.GetShiftAmount();
   7772     if (IsUsingT32()) {
   7773       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   7774       if (shift.IsValidAmount(amount) && !rn.Is(pc) &&
   7775           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7776         uint32_t amount_ = amount % 32;
   7777         EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7778                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7779                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7780         AdvanceIT();
   7781         return;
   7782       }
   7783     }
   7784   }
   7785   Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
   7786 }
   7787 
   7788 void Assembler::orr(Condition cond,
   7789                     EncodingSize size,
   7790                     Register rd,
   7791                     Register rn,
   7792                     const Operand& operand) {
   7793   VIXL_ASSERT(AllowAssembler());
   7794   CheckIT(cond);
   7795   if (operand.IsImmediate()) {
   7796     uint32_t imm = operand.GetImmediate();
   7797     if (IsUsingT32()) {
   7798       ImmediateT32 immediate_t32(imm);
   7799       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7800       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) &&
   7801           (!rd.IsPC() || AllowUnpredictable())) {
   7802         EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7803                    (immediate_t32.GetEncodingValue() & 0xff) |
   7804                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7805                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7806         AdvanceIT();
   7807         return;
   7808       }
   7809     } else {
   7810       ImmediateA32 immediate_a32(imm);
   7811       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   7812       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7813         EmitA32(0x03800000U | (cond.GetCondition() << 28) |
   7814                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   7815                 immediate_a32.GetEncodingValue());
   7816         return;
   7817       }
   7818     }
   7819   }
   7820   if (operand.IsImmediateShiftedRegister()) {
   7821     Register rm = operand.GetBaseRegister();
   7822     if (operand.IsPlainRegister()) {
   7823       if (IsUsingT32()) {
   7824         // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   7825         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   7826             rm.IsLow()) {
   7827           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
   7828           AdvanceIT();
   7829           return;
   7830         }
   7831       }
   7832     }
   7833     Shift shift = operand.GetShift();
   7834     uint32_t amount = operand.GetShiftAmount();
   7835     if (IsUsingT32()) {
   7836       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   7837       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) &&
   7838           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7839         uint32_t amount_ = amount % 32;
   7840         EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7841                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7842                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7843         AdvanceIT();
   7844         return;
   7845       }
   7846     } else {
   7847       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   7848       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7849         uint32_t amount_ = amount % 32;
   7850         EmitA32(0x01800000U | (cond.GetCondition() << 28) |
   7851                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7852                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7853         return;
   7854       }
   7855     }
   7856   }
   7857   if (operand.IsRegisterShiftedRegister()) {
   7858     Register rm = operand.GetBaseRegister();
   7859     Shift shift = operand.GetShift();
   7860     Register rs = operand.GetShiftRegister();
   7861     if (IsUsingA32()) {
   7862       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   7863       if (cond.IsNotNever() &&
   7864           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   7865            AllowUnpredictable())) {
   7866         EmitA32(0x01800010U | (cond.GetCondition() << 28) |
   7867                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7868                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   7869         return;
   7870       }
   7871     }
   7872   }
   7873   Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
   7874 }
   7875 
   7876 void Assembler::orrs(Condition cond,
   7877                      EncodingSize size,
   7878                      Register rd,
   7879                      Register rn,
   7880                      const Operand& operand) {
   7881   VIXL_ASSERT(AllowAssembler());
   7882   CheckIT(cond);
   7883   if (operand.IsImmediate()) {
   7884     uint32_t imm = operand.GetImmediate();
   7885     if (IsUsingT32()) {
   7886       ImmediateT32 immediate_t32(imm);
   7887       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7888       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) &&
   7889           (!rd.IsPC() || AllowUnpredictable())) {
   7890         EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7891                    (immediate_t32.GetEncodingValue() & 0xff) |
   7892                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7893                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7894         AdvanceIT();
   7895         return;
   7896       }
   7897     } else {
   7898       ImmediateA32 immediate_a32(imm);
   7899       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   7900       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7901         EmitA32(0x03900000U | (cond.GetCondition() << 28) |
   7902                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   7903                 immediate_a32.GetEncodingValue());
   7904         return;
   7905       }
   7906     }
   7907   }
   7908   if (operand.IsImmediateShiftedRegister()) {
   7909     Register rm = operand.GetBaseRegister();
   7910     if (operand.IsPlainRegister()) {
   7911       if (IsUsingT32()) {
   7912         // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   7913         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   7914             rm.IsLow()) {
   7915           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
   7916           AdvanceIT();
   7917           return;
   7918         }
   7919       }
   7920     }
   7921     Shift shift = operand.GetShift();
   7922     uint32_t amount = operand.GetShiftAmount();
   7923     if (IsUsingT32()) {
   7924       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   7925       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) &&
   7926           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7927         uint32_t amount_ = amount % 32;
   7928         EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7929                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7930                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7931         AdvanceIT();
   7932         return;
   7933       }
   7934     } else {
   7935       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   7936       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7937         uint32_t amount_ = amount % 32;
   7938         EmitA32(0x01900000U | (cond.GetCondition() << 28) |
   7939                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7940                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7941         return;
   7942       }
   7943     }
   7944   }
   7945   if (operand.IsRegisterShiftedRegister()) {
   7946     Register rm = operand.GetBaseRegister();
   7947     Shift shift = operand.GetShift();
   7948     Register rs = operand.GetShiftRegister();
   7949     if (IsUsingA32()) {
   7950       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   7951       if (cond.IsNotNever() &&
   7952           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   7953            AllowUnpredictable())) {
   7954         EmitA32(0x01900010U | (cond.GetCondition() << 28) |
   7955                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7956                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   7957         return;
   7958       }
   7959     }
   7960   }
   7961   Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
   7962 }
   7963 
   7964 void Assembler::pkhbt(Condition cond,
   7965                       Register rd,
   7966                       Register rn,
   7967                       const Operand& operand) {
   7968   VIXL_ASSERT(AllowAssembler());
   7969   CheckIT(cond);
   7970   if (operand.IsImmediateShiftedRegister()) {
   7971     Register rm = operand.GetBaseRegister();
   7972     Shift shift = operand.GetShift();
   7973     uint32_t amount = operand.GetShiftAmount();
   7974     if (IsUsingT32()) {
   7975       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
   7976       if (shift.IsLSL() && shift.IsValidAmount(amount) &&
   7977           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7978         EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7979                    rm.GetCode() | ((amount & 0x3) << 6) |
   7980                    ((amount & 0x1c) << 10));
   7981         AdvanceIT();
   7982         return;
   7983       }
   7984     } else {
   7985       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
   7986       if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever() &&
   7987           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7988         EmitA32(0x06800010U | (cond.GetCondition() << 28) |
   7989                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7990                 (amount << 7));
   7991         return;
   7992       }
   7993     }
   7994   }
   7995   Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
   7996 }
   7997 
   7998 void Assembler::pkhtb(Condition cond,
   7999                       Register rd,
   8000                       Register rn,
   8001                       const Operand& operand) {
   8002   VIXL_ASSERT(AllowAssembler());
   8003   CheckIT(cond);
   8004   if (operand.IsImmediateShiftedRegister()) {
   8005     Register rm = operand.GetBaseRegister();
   8006     Shift shift = operand.GetShift();
   8007     uint32_t amount = operand.GetShiftAmount();
   8008     if (IsUsingT32()) {
   8009       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
   8010       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
   8011           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8012         uint32_t amount_ = amount % 32;
   8013         EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8014                    rm.GetCode() | ((amount_ & 0x3) << 6) |
   8015                    ((amount_ & 0x1c) << 10));
   8016         AdvanceIT();
   8017         return;
   8018       }
   8019     } else {
   8020       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
   8021       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
   8022           cond.IsNotNever() &&
   8023           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8024         uint32_t amount_ = amount % 32;
   8025         EmitA32(0x06800050U | (cond.GetCondition() << 28) |
   8026                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8027                 (amount_ << 7));
   8028         return;
   8029       }
   8030     }
   8031   }
   8032   Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
   8033 }
   8034 
   8035 void Assembler::pld(Condition cond, Location* location) {
   8036   VIXL_ASSERT(AllowAssembler());
   8037   CheckIT(cond);
   8038   Location::Offset offset =
   8039       location->IsBound()
   8040           ? location->GetLocation() -
   8041                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   8042           : 0;
   8043   if (IsUsingT32()) {
   8044     // PLD{<c>}{<q>} <label> ; T1
   8045     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   8046          !location->IsBound())) {
   8047       static class EmitOp : public Location::EmitOperator {
   8048        public:
   8049         EmitOp() : Location::EmitOperator(T32) {}
   8050         virtual uint32_t Encode(uint32_t instr,
   8051                                 Location::Offset program_counter,
   8052                                 const Location* loc) const VIXL_OVERRIDE {
   8053           program_counter += kT32PcDelta;
   8054           Location::Offset off =
   8055               loc->GetLocation() - AlignDown(program_counter, 4);
   8056           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   8057           uint32_t U = (off >= 0);
   8058           int32_t target = abs(off) | (U << 12);
   8059           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   8060         }
   8061       } immop;
   8062       EmitT32_32(Link(0xf81ff000U, location, immop, &kT32FarDataInfo));
   8063       AdvanceIT();
   8064       return;
   8065     }
   8066   } else {
   8067     // PLD{<c>}{<q>} <label> ; A1
   8068     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   8069          !location->IsBound())) {
   8070       if (cond.Is(al)) {
   8071         static class EmitOp : public Location::EmitOperator {
   8072          public:
   8073           EmitOp() : Location::EmitOperator(A32) {}
   8074           virtual uint32_t Encode(uint32_t instr,
   8075                                   Location::Offset program_counter,
   8076                                   const Location* loc) const VIXL_OVERRIDE {
   8077             program_counter += kA32PcDelta;
   8078             Location::Offset off =
   8079                 loc->GetLocation() - AlignDown(program_counter, 4);
   8080             VIXL_ASSERT((off >= -4095) && (off <= 4095));
   8081             uint32_t U = (off >= 0);
   8082             int32_t target = abs(off) | (U << 12);
   8083             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   8084           }
   8085         } immop;
   8086         EmitA32(Link(0xf55ff000U, location, immop, &kA32FarDataInfo));
   8087         return;
   8088       }
   8089     }
   8090   }
   8091   Delegate(kPld, &Assembler::pld, cond, location);
   8092 }
   8093 
   8094 bool Assembler::pld_info(Condition cond,
   8095                          Location* location,
   8096                          const struct ReferenceInfo** info) {
   8097   VIXL_ASSERT(!location->IsBound());
   8098   USE(location);
   8099   USE(cond);
   8100   if (IsUsingT32()) {
   8101     // PLD{<c>}{<q>} <label> ; T1
   8102     if (true) {
   8103       *info = &kT32FarDataInfo;
   8104       return true;
   8105     }
   8106   } else {
   8107     // PLD{<c>}{<q>} <label> ; A1
   8108     if (true) {
   8109       *info = &kA32FarDataInfo;
   8110       return true;
   8111     }
   8112   }
   8113   return false;
   8114 }
   8115 
   8116 void Assembler::pld(Condition cond, const MemOperand& operand) {
   8117   VIXL_ASSERT(AllowAssembler());
   8118   CheckIT(cond);
   8119   if (operand.IsImmediate()) {
   8120     Register rn = operand.GetBaseRegister();
   8121     int32_t offset = operand.GetOffsetImmediate();
   8122     if (IsUsingT32()) {
   8123       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
   8124       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   8125           operand.IsOffset()) {
   8126         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8127         uint32_t offset_ = abs(offset);
   8128         EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
   8129         AdvanceIT();
   8130         return;
   8131       }
   8132     } else {
   8133       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
   8134       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   8135           operand.IsOffset()) {
   8136         if (cond.Is(al)) {
   8137           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8138           uint32_t offset_ = abs(offset);
   8139           EmitA32(0xf55ff000U | offset_ | (sign << 23));
   8140           return;
   8141         }
   8142       }
   8143     }
   8144   }
   8145   if (operand.IsImmediate()) {
   8146     Register rn = operand.GetBaseRegister();
   8147     int32_t offset = operand.GetOffsetImmediate();
   8148     if (IsUsingT32()) {
   8149       // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   8150       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   8151           ((rn.GetCode() & 0xf) != 0xf)) {
   8152         EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   8153         AdvanceIT();
   8154         return;
   8155       }
   8156       // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   8157       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   8158           ((rn.GetCode() & 0xf) != 0xf)) {
   8159         EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   8160         AdvanceIT();
   8161         return;
   8162       }
   8163     } else {
   8164       // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
   8165       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   8166           ((rn.GetCode() & 0xf) != 0xf)) {
   8167         if (cond.Is(al)) {
   8168           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8169           uint32_t offset_ = abs(offset);
   8170           EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   8171           return;
   8172         }
   8173       }
   8174     }
   8175   }
   8176   if (operand.IsShiftedRegister()) {
   8177     Register rn = operand.GetBaseRegister();
   8178     Sign sign = operand.GetSign();
   8179     Register rm = operand.GetOffsetRegister();
   8180     Shift shift = operand.GetShift();
   8181     uint32_t amount = operand.GetShiftAmount();
   8182     if (IsUsingT32()) {
   8183       // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   8184       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   8185           ((rn.GetCode() & 0xf) != 0xf) &&
   8186           (!rm.IsPC() || AllowUnpredictable())) {
   8187         EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8188                    (amount << 4));
   8189         AdvanceIT();
   8190         return;
   8191       }
   8192     } else {
   8193       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   8194       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
   8195           (!rm.IsPC() || AllowUnpredictable())) {
   8196         if (cond.Is(al)) {
   8197           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8198           uint32_t amount_ = amount % 32;
   8199           EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8200                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   8201           return;
   8202         }
   8203       }
   8204       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   8205       if (shift.IsRRX() && operand.IsOffset() &&
   8206           (!rm.IsPC() || AllowUnpredictable())) {
   8207         if (cond.Is(al)) {
   8208           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8209           EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
   8210                   (sign_ << 23));
   8211           return;
   8212         }
   8213       }
   8214     }
   8215   }
   8216   Delegate(kPld, &Assembler::pld, cond, operand);
   8217 }
   8218 
   8219 void Assembler::pldw(Condition cond, const MemOperand& operand) {
   8220   VIXL_ASSERT(AllowAssembler());
   8221   CheckIT(cond);
   8222   if (operand.IsImmediate()) {
   8223     Register rn = operand.GetBaseRegister();
   8224     int32_t offset = operand.GetOffsetImmediate();
   8225     if (IsUsingT32()) {
   8226       // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   8227       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   8228           ((rn.GetCode() & 0xf) != 0xf)) {
   8229         EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   8230         AdvanceIT();
   8231         return;
   8232       }
   8233       // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   8234       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   8235           ((rn.GetCode() & 0xf) != 0xf)) {
   8236         EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   8237         AdvanceIT();
   8238         return;
   8239       }
   8240     } else {
   8241       // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
   8242       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   8243           ((rn.GetCode() & 0xf) != 0xf)) {
   8244         if (cond.Is(al)) {
   8245           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8246           uint32_t offset_ = abs(offset);
   8247           EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   8248           return;
   8249         }
   8250       }
   8251     }
   8252   }
   8253   if (operand.IsShiftedRegister()) {
   8254     Register rn = operand.GetBaseRegister();
   8255     Sign sign = operand.GetSign();
   8256     Register rm = operand.GetOffsetRegister();
   8257     Shift shift = operand.GetShift();
   8258     uint32_t amount = operand.GetShiftAmount();
   8259     if (IsUsingT32()) {
   8260       // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   8261       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   8262           ((rn.GetCode() & 0xf) != 0xf) &&
   8263           (!rm.IsPC() || AllowUnpredictable())) {
   8264         EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8265                    (amount << 4));
   8266         AdvanceIT();
   8267         return;
   8268       }
   8269     } else {
   8270       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   8271       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
   8272           (!rm.IsPC() || AllowUnpredictable())) {
   8273         if (cond.Is(al)) {
   8274           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8275           uint32_t amount_ = amount % 32;
   8276           EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8277                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   8278           return;
   8279         }
   8280       }
   8281       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   8282       if (shift.IsRRX() && operand.IsOffset() &&
   8283           (!rm.IsPC() || AllowUnpredictable())) {
   8284         if (cond.Is(al)) {
   8285           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8286           EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
   8287                   (sign_ << 23));
   8288           return;
   8289         }
   8290       }
   8291     }
   8292   }
   8293   Delegate(kPldw, &Assembler::pldw, cond, operand);
   8294 }
   8295 
   8296 void Assembler::pli(Condition cond, const MemOperand& operand) {
   8297   VIXL_ASSERT(AllowAssembler());
   8298   CheckIT(cond);
   8299   if (operand.IsImmediate()) {
   8300     Register rn = operand.GetBaseRegister();
   8301     int32_t offset = operand.GetOffsetImmediate();
   8302     if (IsUsingT32()) {
   8303       // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   8304       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   8305           ((rn.GetCode() & 0xf) != 0xf)) {
   8306         EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   8307         AdvanceIT();
   8308         return;
   8309       }
   8310       // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   8311       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   8312           ((rn.GetCode() & 0xf) != 0xf)) {
   8313         EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   8314         AdvanceIT();
   8315         return;
   8316       }
   8317     } else {
   8318       // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
   8319       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   8320           ((rn.GetCode() & 0xf) != 0xf)) {
   8321         if (cond.Is(al)) {
   8322           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8323           uint32_t offset_ = abs(offset);
   8324           EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   8325           return;
   8326         }
   8327       }
   8328     }
   8329   }
   8330   if (operand.IsImmediate()) {
   8331     Register rn = operand.GetBaseRegister();
   8332     int32_t offset = operand.GetOffsetImmediate();
   8333     if (IsUsingT32()) {
   8334       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
   8335       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   8336           operand.IsOffset()) {
   8337         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8338         uint32_t offset_ = abs(offset);
   8339         EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
   8340         AdvanceIT();
   8341         return;
   8342       }
   8343     } else {
   8344       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
   8345       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   8346           operand.IsOffset()) {
   8347         if (cond.Is(al)) {
   8348           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8349           uint32_t offset_ = abs(offset);
   8350           EmitA32(0xf45ff000U | offset_ | (sign << 23));
   8351           return;
   8352         }
   8353       }
   8354     }
   8355   }
   8356   if (operand.IsShiftedRegister()) {
   8357     Register rn = operand.GetBaseRegister();
   8358     Sign sign = operand.GetSign();
   8359     Register rm = operand.GetOffsetRegister();
   8360     Shift shift = operand.GetShift();
   8361     uint32_t amount = operand.GetShiftAmount();
   8362     if (IsUsingT32()) {
   8363       // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   8364       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   8365           ((rn.GetCode() & 0xf) != 0xf) &&
   8366           (!rm.IsPC() || AllowUnpredictable())) {
   8367         EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8368                    (amount << 4));
   8369         AdvanceIT();
   8370         return;
   8371       }
   8372     } else {
   8373       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   8374       if (shift.IsRRX() && operand.IsOffset() &&
   8375           (!rm.IsPC() || AllowUnpredictable())) {
   8376         if (cond.Is(al)) {
   8377           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8378           EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
   8379                   (sign_ << 23));
   8380           return;
   8381         }
   8382       }
   8383       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   8384       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
   8385           (!rm.IsPC() || AllowUnpredictable())) {
   8386         if (cond.Is(al)) {
   8387           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8388           uint32_t amount_ = amount % 32;
   8389           EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8390                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   8391           return;
   8392         }
   8393       }
   8394     }
   8395   }
   8396   Delegate(kPli, &Assembler::pli, cond, operand);
   8397 }
   8398 
   8399 void Assembler::pli(Condition cond, Location* location) {
   8400   VIXL_ASSERT(AllowAssembler());
   8401   CheckIT(cond);
   8402   Location::Offset offset =
   8403       location->IsBound()
   8404           ? location->GetLocation() -
   8405                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   8406           : 0;
   8407   if (IsUsingT32()) {
   8408     // PLI{<c>}{<q>} <label> ; T3
   8409     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   8410          !location->IsBound())) {
   8411       static class EmitOp : public Location::EmitOperator {
   8412        public:
   8413         EmitOp() : Location::EmitOperator(T32) {}
   8414         virtual uint32_t Encode(uint32_t instr,
   8415                                 Location::Offset program_counter,
   8416                                 const Location* loc) const VIXL_OVERRIDE {
   8417           program_counter += kT32PcDelta;
   8418           Location::Offset off =
   8419               loc->GetLocation() - AlignDown(program_counter, 4);
   8420           VIXL_ASSERT((off >= -4095) && (off <= 4095));
   8421           uint32_t U = (off >= 0);
   8422           int32_t target = abs(off) | (U << 12);
   8423           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   8424         }
   8425       } immop;
   8426       EmitT32_32(Link(0xf91ff000U, location, immop, &kT32FarDataInfo));
   8427       AdvanceIT();
   8428       return;
   8429     }
   8430   } else {
   8431     // PLI{<c>}{<q>} <label> ; A1
   8432     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   8433          !location->IsBound())) {
   8434       if (cond.Is(al)) {
   8435         static class EmitOp : public Location::EmitOperator {
   8436          public:
   8437           EmitOp() : Location::EmitOperator(A32) {}
   8438           virtual uint32_t Encode(uint32_t instr,
   8439                                   Location::Offset program_counter,
   8440                                   const Location* loc) const VIXL_OVERRIDE {
   8441             program_counter += kA32PcDelta;
   8442             Location::Offset off =
   8443                 loc->GetLocation() - AlignDown(program_counter, 4);
   8444             VIXL_ASSERT((off >= -4095) && (off <= 4095));
   8445             uint32_t U = (off >= 0);
   8446             int32_t target = abs(off) | (U << 12);
   8447             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   8448           }
   8449         } immop;
   8450         EmitA32(Link(0xf45ff000U, location, immop, &kA32FarDataInfo));
   8451         return;
   8452       }
   8453     }
   8454   }
   8455   Delegate(kPli, &Assembler::pli, cond, location);
   8456 }
   8457 
   8458 bool Assembler::pli_info(Condition cond,
   8459                          Location* location,
   8460                          const struct ReferenceInfo** info) {
   8461   VIXL_ASSERT(!location->IsBound());
   8462   USE(location);
   8463   USE(cond);
   8464   if (IsUsingT32()) {
   8465     // PLI{<c>}{<q>} <label> ; T3
   8466     if (true) {
   8467       *info = &kT32FarDataInfo;
   8468       return true;
   8469     }
   8470   } else {
   8471     // PLI{<c>}{<q>} <label> ; A1
   8472     if (true) {
   8473       *info = &kA32FarDataInfo;
   8474       return true;
   8475     }
   8476   }
   8477   return false;
   8478 }
   8479 
   8480 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
   8481   VIXL_ASSERT(AllowAssembler());
   8482   CheckIT(cond);
   8483   if (!registers.IsEmpty() || AllowUnpredictable()) {
   8484     if (IsUsingT32()) {
   8485       // A branch out of an IT block should be the last instruction in the
   8486       // block.
   8487       if (!registers.Includes(pc) || OutsideITBlockAndAlOrLast(cond) ||
   8488           AllowUnpredictable()) {
   8489         // POP{<c>}{<q>} <registers> ; T1
   8490         if (!size.IsWide() && registers.IsR0toR7orPC()) {
   8491           EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
   8492                      GetRegisterListEncoding(registers, 0, 8));
   8493           AdvanceIT();
   8494           return;
   8495         }
   8496         // POP{<c>}{<q>} <registers> ; T2
   8497         // Alias of: LDM{<c>}{<q>} SP!, <registers> ; T2
   8498         if (!size.IsNarrow() &&
   8499             ((!registers.Includes(sp) && (registers.GetCount() > 1) &&
   8500               !(registers.Includes(pc) && registers.Includes(lr))) ||
   8501              AllowUnpredictable())) {
   8502           EmitT32_32(0xe8bd0000U | GetRegisterListEncoding(registers, 0, 16));
   8503           AdvanceIT();
   8504           return;
   8505         }
   8506       }
   8507     } else {
   8508       // POP{<c>}{<q>} <registers> ; A1
   8509       // Alias of: LDM{<c>}{<q>} SP!, <registers> ; A1
   8510       if (cond.IsNotNever() &&
   8511           (!registers.Includes(sp) || AllowUnpredictable())) {
   8512         EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
   8513                 GetRegisterListEncoding(registers, 0, 16));
   8514         return;
   8515       }
   8516     }
   8517   }
   8518   Delegate(kPop, &Assembler::pop, cond, size, registers);
   8519 }
   8520 
   8521 void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
   8522   VIXL_ASSERT(AllowAssembler());
   8523   CheckIT(cond);
   8524   if (!rt.IsSP() || AllowUnpredictable()) {
   8525     if (IsUsingT32()) {
   8526       // POP{<c>}{<q>} <single_register_list> ; T4
   8527       // Alias of: LDR{<c>}{<q>} <Rt>, [SP], #4 ; T4
   8528       if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond) ||
   8529                                AllowUnpredictable())) {
   8530         EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
   8531         AdvanceIT();
   8532         return;
   8533       }
   8534     } else {
   8535       // POP{<c>}{<q>} <single_register_list> ; A1
   8536       // Alias of: LDR{<c>}{<q>} <Rt>, [SP], #4 ; T1
   8537       if (cond.IsNotNever()) {
   8538         EmitA32(0x049d0004U | (cond.GetCondition() << 28) |
   8539                 (rt.GetCode() << 12));
   8540         return;
   8541       }
   8542     }
   8543   }
   8544   Delegate(kPop, &Assembler::pop, cond, size, rt);
   8545 }
   8546 
   8547 void Assembler::push(Condition cond,
   8548                      EncodingSize size,
   8549                      RegisterList registers) {
   8550   VIXL_ASSERT(AllowAssembler());
   8551   CheckIT(cond);
   8552   if (!registers.IsEmpty() || AllowUnpredictable()) {
   8553     if (IsUsingT32()) {
   8554       // PUSH{<c>}{<q>} <registers> ; T1
   8555       if (!size.IsWide() && registers.IsR0toR7orLR()) {
   8556         EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
   8557                    GetRegisterListEncoding(registers, 0, 8));
   8558         AdvanceIT();
   8559         return;
   8560       }
   8561       // PUSH{<c>}{<q>} <registers> ; T1
   8562       // Alias of: STMDB SP!, <registers> ; T1
   8563       if (!size.IsNarrow() && !registers.Includes(pc) &&
   8564           ((!registers.Includes(sp) && (registers.GetCount() > 1)) ||
   8565            AllowUnpredictable())) {
   8566         EmitT32_32(0xe92d0000U | GetRegisterListEncoding(registers, 0, 15));
   8567         AdvanceIT();
   8568         return;
   8569       }
   8570     } else {
   8571       // PUSH{<c>}{<q>} <registers> ; A1
   8572       // Alias of: STMDB SP!, <registers> ; A1
   8573       if (cond.IsNotNever() &&
   8574           // For A32, sp can appear in the list, but stores an UNKNOWN value if
   8575           // it is not the lowest-valued register.
   8576           (!registers.Includes(sp) ||
   8577            registers.GetFirstAvailableRegister().IsSP() ||
   8578            AllowUnpredictable())) {
   8579         EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
   8580                 GetRegisterListEncoding(registers, 0, 16));
   8581         return;
   8582       }
   8583     }
   8584   }
   8585   Delegate(kPush, &Assembler::push, cond, size, registers);
   8586 }
   8587 
   8588 void Assembler::push(Condition cond, EncodingSize size, Register rt) {
   8589   VIXL_ASSERT(AllowAssembler());
   8590   CheckIT(cond);
   8591   if (IsUsingT32()) {
   8592     // PUSH{<c>}{<q>} <single_register_list> ; T4
   8593     // Alias of: STR{<c>}{<q>} <Rt>, [SP, #4]! ; T4
   8594     if (!size.IsNarrow() &&
   8595         ((!rt.IsPC() && !rt.IsSP()) || AllowUnpredictable())) {
   8596       EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
   8597       AdvanceIT();
   8598       return;
   8599     }
   8600   } else {
   8601     // PUSH{<c>}{<q>} <single_register_list> ; A1
   8602     // Alias of: STR{<c>}{<q>} <Rt>, [SP, #4]! ; A1
   8603     if (cond.IsNotNever() && (!rt.IsSP() || AllowUnpredictable())) {
   8604       EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
   8605       return;
   8606     }
   8607   }
   8608   Delegate(kPush, &Assembler::push, cond, size, rt);
   8609 }
   8610 
   8611 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
   8612   VIXL_ASSERT(AllowAssembler());
   8613   CheckIT(cond);
   8614   if (IsUsingT32()) {
   8615     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   8616     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8617       EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
   8618                  (rn.GetCode() << 16));
   8619       AdvanceIT();
   8620       return;
   8621     }
   8622   } else {
   8623     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   8624     if (cond.IsNotNever() &&
   8625         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8626       EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8627               rm.GetCode() | (rn.GetCode() << 16));
   8628       return;
   8629     }
   8630   }
   8631   Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
   8632 }
   8633 
   8634 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
   8635   VIXL_ASSERT(AllowAssembler());
   8636   CheckIT(cond);
   8637   if (IsUsingT32()) {
   8638     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8639     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8640       EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8641                  rm.GetCode());
   8642       AdvanceIT();
   8643       return;
   8644     }
   8645   } else {
   8646     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8647     if (cond.IsNotNever() &&
   8648         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8649       EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8650               (rn.GetCode() << 16) | rm.GetCode());
   8651       return;
   8652     }
   8653   }
   8654   Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
   8655 }
   8656 
   8657 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
   8658   VIXL_ASSERT(AllowAssembler());
   8659   CheckIT(cond);
   8660   if (IsUsingT32()) {
   8661     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8662     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8663       EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8664                  rm.GetCode());
   8665       AdvanceIT();
   8666       return;
   8667     }
   8668   } else {
   8669     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8670     if (cond.IsNotNever() &&
   8671         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8672       EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8673               (rn.GetCode() << 16) | rm.GetCode());
   8674       return;
   8675     }
   8676   }
   8677   Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
   8678 }
   8679 
   8680 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
   8681   VIXL_ASSERT(AllowAssembler());
   8682   CheckIT(cond);
   8683   if (IsUsingT32()) {
   8684     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8685     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8686       EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8687                  rm.GetCode());
   8688       AdvanceIT();
   8689       return;
   8690     }
   8691   } else {
   8692     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8693     if (cond.IsNotNever() &&
   8694         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8695       EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8696               (rn.GetCode() << 16) | rm.GetCode());
   8697       return;
   8698     }
   8699   }
   8700   Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
   8701 }
   8702 
   8703 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
   8704   VIXL_ASSERT(AllowAssembler());
   8705   CheckIT(cond);
   8706   if (IsUsingT32()) {
   8707     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   8708     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8709       EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
   8710                  (rn.GetCode() << 16));
   8711       AdvanceIT();
   8712       return;
   8713     }
   8714   } else {
   8715     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   8716     if (cond.IsNotNever() &&
   8717         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8718       EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8719               rm.GetCode() | (rn.GetCode() << 16));
   8720       return;
   8721     }
   8722   }
   8723   Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
   8724 }
   8725 
   8726 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
   8727   VIXL_ASSERT(AllowAssembler());
   8728   CheckIT(cond);
   8729   if (IsUsingT32()) {
   8730     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   8731     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8732       EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
   8733                  (rn.GetCode() << 16));
   8734       AdvanceIT();
   8735       return;
   8736     }
   8737   } else {
   8738     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   8739     if (cond.IsNotNever() &&
   8740         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8741       EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8742               rm.GetCode() | (rn.GetCode() << 16));
   8743       return;
   8744     }
   8745   }
   8746   Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
   8747 }
   8748 
   8749 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
   8750   VIXL_ASSERT(AllowAssembler());
   8751   CheckIT(cond);
   8752   if (IsUsingT32()) {
   8753     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8754     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8755       EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8756                  rm.GetCode());
   8757       AdvanceIT();
   8758       return;
   8759     }
   8760   } else {
   8761     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8762     if (cond.IsNotNever() &&
   8763         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8764       EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8765               (rn.GetCode() << 16) | rm.GetCode());
   8766       return;
   8767     }
   8768   }
   8769   Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
   8770 }
   8771 
   8772 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
   8773   VIXL_ASSERT(AllowAssembler());
   8774   CheckIT(cond);
   8775   if (IsUsingT32()) {
   8776     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   8777     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8778       EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
   8779                  (rn.GetCode() << 16));
   8780       AdvanceIT();
   8781       return;
   8782     }
   8783   } else {
   8784     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   8785     if (cond.IsNotNever() &&
   8786         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8787       EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8788               rm.GetCode() | (rn.GetCode() << 16));
   8789       return;
   8790     }
   8791   }
   8792   Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
   8793 }
   8794 
   8795 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
   8796   VIXL_ASSERT(AllowAssembler());
   8797   CheckIT(cond);
   8798   if (IsUsingT32()) {
   8799     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8800     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8801       EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8802                  rm.GetCode());
   8803       AdvanceIT();
   8804       return;
   8805     }
   8806   } else {
   8807     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8808     if (cond.IsNotNever() &&
   8809         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8810       EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8811               (rn.GetCode() << 16) | rm.GetCode());
   8812       return;
   8813     }
   8814   }
   8815   Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
   8816 }
   8817 
   8818 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
   8819   VIXL_ASSERT(AllowAssembler());
   8820   CheckIT(cond);
   8821   if (IsUsingT32()) {
   8822     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8823     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8824       EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8825                  rm.GetCode());
   8826       AdvanceIT();
   8827       return;
   8828     }
   8829   } else {
   8830     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8831     if (cond.IsNotNever() &&
   8832         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8833       EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8834               (rn.GetCode() << 16) | rm.GetCode());
   8835       return;
   8836     }
   8837   }
   8838   Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
   8839 }
   8840 
   8841 void Assembler::rbit(Condition cond, Register rd, Register rm) {
   8842   VIXL_ASSERT(AllowAssembler());
   8843   CheckIT(cond);
   8844   if (IsUsingT32()) {
   8845     // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
   8846     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8847       EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
   8848                  (rm.GetCode() << 16));
   8849       AdvanceIT();
   8850       return;
   8851     }
   8852   } else {
   8853     // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
   8854     if (cond.IsNotNever() &&
   8855         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8856       EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8857               rm.GetCode());
   8858       return;
   8859     }
   8860   }
   8861   Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
   8862 }
   8863 
   8864 void Assembler::rev(Condition cond,
   8865                     EncodingSize size,
   8866                     Register rd,
   8867                     Register rm) {
   8868   VIXL_ASSERT(AllowAssembler());
   8869   CheckIT(cond);
   8870   if (IsUsingT32()) {
   8871     // REV{<c>}{<q>} <Rd>, <Rm> ; T1
   8872     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8873       EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
   8874       AdvanceIT();
   8875       return;
   8876     }
   8877     // REV{<c>}{<q>} <Rd>, <Rm> ; T2
   8878     if (!size.IsNarrow() &&
   8879         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8880       EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
   8881                  (rm.GetCode() << 16));
   8882       AdvanceIT();
   8883       return;
   8884     }
   8885   } else {
   8886     // REV{<c>}{<q>} <Rd>, <Rm> ; A1
   8887     if (cond.IsNotNever() &&
   8888         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8889       EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8890               rm.GetCode());
   8891       return;
   8892     }
   8893   }
   8894   Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
   8895 }
   8896 
   8897 void Assembler::rev16(Condition cond,
   8898                       EncodingSize size,
   8899                       Register rd,
   8900                       Register rm) {
   8901   VIXL_ASSERT(AllowAssembler());
   8902   CheckIT(cond);
   8903   if (IsUsingT32()) {
   8904     // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
   8905     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8906       EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
   8907       AdvanceIT();
   8908       return;
   8909     }
   8910     // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
   8911     if (!size.IsNarrow() &&
   8912         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8913       EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
   8914                  (rm.GetCode() << 16));
   8915       AdvanceIT();
   8916       return;
   8917     }
   8918   } else {
   8919     // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
   8920     if (cond.IsNotNever() &&
   8921         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8922       EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8923               rm.GetCode());
   8924       return;
   8925     }
   8926   }
   8927   Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
   8928 }
   8929 
   8930 void Assembler::revsh(Condition cond,
   8931                       EncodingSize size,
   8932                       Register rd,
   8933                       Register rm) {
   8934   VIXL_ASSERT(AllowAssembler());
   8935   CheckIT(cond);
   8936   if (IsUsingT32()) {
   8937     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
   8938     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8939       EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
   8940       AdvanceIT();
   8941       return;
   8942     }
   8943     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
   8944     if (!size.IsNarrow() &&
   8945         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8946       EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
   8947                  (rm.GetCode() << 16));
   8948       AdvanceIT();
   8949       return;
   8950     }
   8951   } else {
   8952     // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
   8953     if (cond.IsNotNever() &&
   8954         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8955       EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8956               rm.GetCode());
   8957       return;
   8958     }
   8959   }
   8960   Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
   8961 }
   8962 
   8963 void Assembler::ror(Condition cond,
   8964                     EncodingSize size,
   8965                     Register rd,
   8966                     Register rm,
   8967                     const Operand& operand) {
   8968   VIXL_ASSERT(AllowAssembler());
   8969   CheckIT(cond);
   8970   if (operand.IsImmediate()) {
   8971     uint32_t imm = operand.GetImmediate();
   8972     if (IsUsingT32()) {
   8973       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   8974       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
   8975           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8976         EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
   8977                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   8978         AdvanceIT();
   8979         return;
   8980       }
   8981     } else {
   8982       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   8983       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   8984         EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
   8985                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   8986         return;
   8987       }
   8988     }
   8989   }
   8990   if (operand.IsPlainRegister()) {
   8991     Register rs = operand.GetBaseRegister();
   8992     if (IsUsingT32()) {
   8993       // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   8994       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   8995           rs.IsLow()) {
   8996         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   8997         AdvanceIT();
   8998         return;
   8999       }
   9000       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   9001       if (!size.IsNarrow() &&
   9002           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   9003         EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   9004                    rs.GetCode());
   9005         AdvanceIT();
   9006         return;
   9007       }
   9008     } else {
   9009       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   9010       if (cond.IsNotNever() &&
   9011           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   9012         EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
   9013                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   9014         return;
   9015       }
   9016     }
   9017   }
   9018   Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
   9019 }
   9020 
   9021 void Assembler::rors(Condition cond,
   9022                      EncodingSize size,
   9023                      Register rd,
   9024                      Register rm,
   9025                      const Operand& operand) {
   9026   VIXL_ASSERT(AllowAssembler());
   9027   CheckIT(cond);
   9028   if (operand.IsImmediate()) {
   9029     uint32_t imm = operand.GetImmediate();
   9030     if (IsUsingT32()) {
   9031       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   9032       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
   9033           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9034         EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
   9035                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   9036         AdvanceIT();
   9037         return;
   9038       }
   9039     } else {
   9040       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   9041       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   9042         EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
   9043                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   9044         return;
   9045       }
   9046     }
   9047   }
   9048   if (operand.IsPlainRegister()) {
   9049     Register rs = operand.GetBaseRegister();
   9050     if (IsUsingT32()) {
   9051       // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   9052       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   9053           rs.IsLow()) {
   9054         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   9055         AdvanceIT();
   9056         return;
   9057       }
   9058       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   9059       if (!size.IsNarrow() &&
   9060           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   9061         EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   9062                    rs.GetCode());
   9063         AdvanceIT();
   9064         return;
   9065       }
   9066     } else {
   9067       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   9068       if (cond.IsNotNever() &&
   9069           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   9070         EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
   9071                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   9072         return;
   9073       }
   9074     }
   9075   }
   9076   Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
   9077 }
   9078 
   9079 void Assembler::rrx(Condition cond, Register rd, Register rm) {
   9080   VIXL_ASSERT(AllowAssembler());
   9081   CheckIT(cond);
   9082   if (IsUsingT32()) {
   9083     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
   9084     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9085       EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
   9086       AdvanceIT();
   9087       return;
   9088     }
   9089   } else {
   9090     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
   9091     if (cond.IsNotNever()) {
   9092       EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9093               rm.GetCode());
   9094       return;
   9095     }
   9096   }
   9097   Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
   9098 }
   9099 
   9100 void Assembler::rrxs(Condition cond, Register rd, Register rm) {
   9101   VIXL_ASSERT(AllowAssembler());
   9102   CheckIT(cond);
   9103   if (IsUsingT32()) {
   9104     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
   9105     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9106       EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
   9107       AdvanceIT();
   9108       return;
   9109     }
   9110   } else {
   9111     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
   9112     if (cond.IsNotNever()) {
   9113       EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9114               rm.GetCode());
   9115       return;
   9116     }
   9117   }
   9118   Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
   9119 }
   9120 
   9121 void Assembler::rsb(Condition cond,
   9122                     EncodingSize size,
   9123                     Register rd,
   9124                     Register rn,
   9125                     const Operand& operand) {
   9126   VIXL_ASSERT(AllowAssembler());
   9127   CheckIT(cond);
   9128   if (operand.IsImmediate()) {
   9129     uint32_t imm = operand.GetImmediate();
   9130     if (IsUsingT32()) {
   9131       ImmediateT32 immediate_t32(imm);
   9132       // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
   9133       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   9134           (imm == 0)) {
   9135         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
   9136         AdvanceIT();
   9137         return;
   9138       }
   9139       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
   9140       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   9141           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   9142         EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9143                    (immediate_t32.GetEncodingValue() & 0xff) |
   9144                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   9145                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   9146         AdvanceIT();
   9147         return;
   9148       }
   9149     } else {
   9150       ImmediateA32 immediate_a32(imm);
   9151       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9152       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9153         EmitA32(0x02600000U | (cond.GetCondition() << 28) |
   9154                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9155                 immediate_a32.GetEncodingValue());
   9156         return;
   9157       }
   9158     }
   9159   }
   9160   if (operand.IsImmediateShiftedRegister()) {
   9161     Register rm = operand.GetBaseRegister();
   9162     Shift shift = operand.GetShift();
   9163     uint32_t amount = operand.GetShiftAmount();
   9164     if (IsUsingT32()) {
   9165       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   9166       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   9167           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9168         uint32_t amount_ = amount % 32;
   9169         EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9170                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   9171                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   9172         AdvanceIT();
   9173         return;
   9174       }
   9175     } else {
   9176       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9177       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9178         uint32_t amount_ = amount % 32;
   9179         EmitA32(0x00600000U | (cond.GetCondition() << 28) |
   9180                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9181                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9182         return;
   9183       }
   9184     }
   9185   }
   9186   if (operand.IsRegisterShiftedRegister()) {
   9187     Register rm = operand.GetBaseRegister();
   9188     Shift shift = operand.GetShift();
   9189     Register rs = operand.GetShiftRegister();
   9190     if (IsUsingA32()) {
   9191       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9192       if (cond.IsNotNever() &&
   9193           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9194            AllowUnpredictable())) {
   9195         EmitA32(0x00600010U | (cond.GetCondition() << 28) |
   9196                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9197                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9198         return;
   9199       }
   9200     }
   9201   }
   9202   Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
   9203 }
   9204 
   9205 void Assembler::rsbs(Condition cond,
   9206                      EncodingSize size,
   9207                      Register rd,
   9208                      Register rn,
   9209                      const Operand& operand) {
   9210   VIXL_ASSERT(AllowAssembler());
   9211   CheckIT(cond);
   9212   if (operand.IsImmediate()) {
   9213     uint32_t imm = operand.GetImmediate();
   9214     if (IsUsingT32()) {
   9215       ImmediateT32 immediate_t32(imm);
   9216       // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
   9217       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   9218           (imm == 0)) {
   9219         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
   9220         AdvanceIT();
   9221         return;
   9222       }
   9223       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
   9224       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   9225           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   9226         EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9227                    (immediate_t32.GetEncodingValue() & 0xff) |
   9228                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   9229                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   9230         AdvanceIT();
   9231         return;
   9232       }
   9233     } else {
   9234       ImmediateA32 immediate_a32(imm);
   9235       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9236       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9237         EmitA32(0x02700000U | (cond.GetCondition() << 28) |
   9238                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9239                 immediate_a32.GetEncodingValue());
   9240         return;
   9241       }
   9242     }
   9243   }
   9244   if (operand.IsImmediateShiftedRegister()) {
   9245     Register rm = operand.GetBaseRegister();
   9246     Shift shift = operand.GetShift();
   9247     uint32_t amount = operand.GetShiftAmount();
   9248     if (IsUsingT32()) {
   9249       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   9250       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   9251           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9252         uint32_t amount_ = amount % 32;
   9253         EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9254                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   9255                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   9256         AdvanceIT();
   9257         return;
   9258       }
   9259     } else {
   9260       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9261       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9262         uint32_t amount_ = amount % 32;
   9263         EmitA32(0x00700000U | (cond.GetCondition() << 28) |
   9264                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9265                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9266         return;
   9267       }
   9268     }
   9269   }
   9270   if (operand.IsRegisterShiftedRegister()) {
   9271     Register rm = operand.GetBaseRegister();
   9272     Shift shift = operand.GetShift();
   9273     Register rs = operand.GetShiftRegister();
   9274     if (IsUsingA32()) {
   9275       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9276       if (cond.IsNotNever() &&
   9277           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9278            AllowUnpredictable())) {
   9279         EmitA32(0x00700010U | (cond.GetCondition() << 28) |
   9280                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9281                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9282         return;
   9283       }
   9284     }
   9285   }
   9286   Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
   9287 }
   9288 
   9289 void Assembler::rsc(Condition cond,
   9290                     Register rd,
   9291                     Register rn,
   9292                     const Operand& operand) {
   9293   VIXL_ASSERT(AllowAssembler());
   9294   CheckIT(cond);
   9295   if (operand.IsImmediate()) {
   9296     uint32_t imm = operand.GetImmediate();
   9297     if (IsUsingA32()) {
   9298       ImmediateA32 immediate_a32(imm);
   9299       // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9300       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9301         EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
   9302                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9303                 immediate_a32.GetEncodingValue());
   9304         return;
   9305       }
   9306     }
   9307   }
   9308   if (operand.IsImmediateShiftedRegister()) {
   9309     Register rm = operand.GetBaseRegister();
   9310     Shift shift = operand.GetShift();
   9311     uint32_t amount = operand.GetShiftAmount();
   9312     if (IsUsingA32()) {
   9313       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9314       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9315         uint32_t amount_ = amount % 32;
   9316         EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
   9317                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9318                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9319         return;
   9320       }
   9321     }
   9322   }
   9323   if (operand.IsRegisterShiftedRegister()) {
   9324     Register rm = operand.GetBaseRegister();
   9325     Shift shift = operand.GetShift();
   9326     Register rs = operand.GetShiftRegister();
   9327     if (IsUsingA32()) {
   9328       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9329       if (cond.IsNotNever() &&
   9330           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9331            AllowUnpredictable())) {
   9332         EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
   9333                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9334                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9335         return;
   9336       }
   9337     }
   9338   }
   9339   Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
   9340 }
   9341 
   9342 void Assembler::rscs(Condition cond,
   9343                      Register rd,
   9344                      Register rn,
   9345                      const Operand& operand) {
   9346   VIXL_ASSERT(AllowAssembler());
   9347   CheckIT(cond);
   9348   if (operand.IsImmediate()) {
   9349     uint32_t imm = operand.GetImmediate();
   9350     if (IsUsingA32()) {
   9351       ImmediateA32 immediate_a32(imm);
   9352       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9353       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9354         EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
   9355                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9356                 immediate_a32.GetEncodingValue());
   9357         return;
   9358       }
   9359     }
   9360   }
   9361   if (operand.IsImmediateShiftedRegister()) {
   9362     Register rm = operand.GetBaseRegister();
   9363     Shift shift = operand.GetShift();
   9364     uint32_t amount = operand.GetShiftAmount();
   9365     if (IsUsingA32()) {
   9366       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9367       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9368         uint32_t amount_ = amount % 32;
   9369         EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
   9370                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9371                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9372         return;
   9373       }
   9374     }
   9375   }
   9376   if (operand.IsRegisterShiftedRegister()) {
   9377     Register rm = operand.GetBaseRegister();
   9378     Shift shift = operand.GetShift();
   9379     Register rs = operand.GetShiftRegister();
   9380     if (IsUsingA32()) {
   9381       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9382       if (cond.IsNotNever() &&
   9383           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9384            AllowUnpredictable())) {
   9385         EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
   9386                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9387                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9388         return;
   9389       }
   9390     }
   9391   }
   9392   Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
   9393 }
   9394 
   9395 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
   9396   VIXL_ASSERT(AllowAssembler());
   9397   CheckIT(cond);
   9398   if (IsUsingT32()) {
   9399     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9400     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9401       EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9402                  rm.GetCode());
   9403       AdvanceIT();
   9404       return;
   9405     }
   9406   } else {
   9407     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9408     if (cond.IsNotNever() &&
   9409         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9410       EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9411               (rn.GetCode() << 16) | rm.GetCode());
   9412       return;
   9413     }
   9414   }
   9415   Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
   9416 }
   9417 
   9418 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
   9419   VIXL_ASSERT(AllowAssembler());
   9420   CheckIT(cond);
   9421   if (IsUsingT32()) {
   9422     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9423     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9424       EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9425                  rm.GetCode());
   9426       AdvanceIT();
   9427       return;
   9428     }
   9429   } else {
   9430     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9431     if (cond.IsNotNever() &&
   9432         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9433       EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9434               (rn.GetCode() << 16) | rm.GetCode());
   9435       return;
   9436     }
   9437   }
   9438   Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
   9439 }
   9440 
   9441 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
   9442   VIXL_ASSERT(AllowAssembler());
   9443   CheckIT(cond);
   9444   if (IsUsingT32()) {
   9445     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9446     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9447       EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9448                  rm.GetCode());
   9449       AdvanceIT();
   9450       return;
   9451     }
   9452   } else {
   9453     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9454     if (cond.IsNotNever() &&
   9455         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9456       EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9457               (rn.GetCode() << 16) | rm.GetCode());
   9458       return;
   9459     }
   9460   }
   9461   Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
   9462 }
   9463 
   9464 void Assembler::sbc(Condition cond,
   9465                     EncodingSize size,
   9466                     Register rd,
   9467                     Register rn,
   9468                     const Operand& operand) {
   9469   VIXL_ASSERT(AllowAssembler());
   9470   CheckIT(cond);
   9471   if (operand.IsImmediate()) {
   9472     uint32_t imm = operand.GetImmediate();
   9473     if (IsUsingT32()) {
   9474       ImmediateT32 immediate_t32(imm);
   9475       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   9476       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   9477           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   9478         EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9479                    (immediate_t32.GetEncodingValue() & 0xff) |
   9480                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   9481                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   9482         AdvanceIT();
   9483         return;
   9484       }
   9485     } else {
   9486       ImmediateA32 immediate_a32(imm);
   9487       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9488       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9489         EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
   9490                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9491                 immediate_a32.GetEncodingValue());
   9492         return;
   9493       }
   9494     }
   9495   }
   9496   if (operand.IsImmediateShiftedRegister()) {
   9497     Register rm = operand.GetBaseRegister();
   9498     if (operand.IsPlainRegister()) {
   9499       if (IsUsingT32()) {
   9500         // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   9501         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   9502             rm.IsLow()) {
   9503           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
   9504           AdvanceIT();
   9505           return;
   9506         }
   9507       }
   9508     }
   9509     Shift shift = operand.GetShift();
   9510     uint32_t amount = operand.GetShiftAmount();
   9511     if (IsUsingT32()) {
   9512       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   9513       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   9514           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9515         uint32_t amount_ = amount % 32;
   9516         EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9517                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   9518                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   9519         AdvanceIT();
   9520         return;
   9521       }
   9522     } else {
   9523       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9524       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9525         uint32_t amount_ = amount % 32;
   9526         EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
   9527                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9528                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9529         return;
   9530       }
   9531     }
   9532   }
   9533   if (operand.IsRegisterShiftedRegister()) {
   9534     Register rm = operand.GetBaseRegister();
   9535     Shift shift = operand.GetShift();
   9536     Register rs = operand.GetShiftRegister();
   9537     if (IsUsingA32()) {
   9538       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9539       if (cond.IsNotNever() &&
   9540           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9541            AllowUnpredictable())) {
   9542         EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
   9543                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9544                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9545         return;
   9546       }
   9547     }
   9548   }
   9549   Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
   9550 }
   9551 
   9552 void Assembler::sbcs(Condition cond,
   9553                      EncodingSize size,
   9554                      Register rd,
   9555                      Register rn,
   9556                      const Operand& operand) {
   9557   VIXL_ASSERT(AllowAssembler());
   9558   CheckIT(cond);
   9559   if (operand.IsImmediate()) {
   9560     uint32_t imm = operand.GetImmediate();
   9561     if (IsUsingT32()) {
   9562       ImmediateT32 immediate_t32(imm);
   9563       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   9564       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   9565           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   9566         EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9567                    (immediate_t32.GetEncodingValue() & 0xff) |
   9568                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   9569                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   9570         AdvanceIT();
   9571         return;
   9572       }
   9573     } else {
   9574       ImmediateA32 immediate_a32(imm);
   9575       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9576       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9577         EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
   9578                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9579                 immediate_a32.GetEncodingValue());
   9580         return;
   9581       }
   9582     }
   9583   }
   9584   if (operand.IsImmediateShiftedRegister()) {
   9585     Register rm = operand.GetBaseRegister();
   9586     if (operand.IsPlainRegister()) {
   9587       if (IsUsingT32()) {
   9588         // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   9589         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   9590             rm.IsLow()) {
   9591           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
   9592           AdvanceIT();
   9593           return;
   9594         }
   9595       }
   9596     }
   9597     Shift shift = operand.GetShift();
   9598     uint32_t amount = operand.GetShiftAmount();
   9599     if (IsUsingT32()) {
   9600       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   9601       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   9602           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9603         uint32_t amount_ = amount % 32;
   9604         EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9605                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   9606                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   9607         AdvanceIT();
   9608         return;
   9609       }
   9610     } else {
   9611       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9612       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9613         uint32_t amount_ = amount % 32;
   9614         EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
   9615                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9616                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9617         return;
   9618       }
   9619     }
   9620   }
   9621   if (operand.IsRegisterShiftedRegister()) {
   9622     Register rm = operand.GetBaseRegister();
   9623     Shift shift = operand.GetShift();
   9624     Register rs = operand.GetShiftRegister();
   9625     if (IsUsingA32()) {
   9626       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9627       if (cond.IsNotNever() &&
   9628           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9629            AllowUnpredictable())) {
   9630         EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
   9631                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9632                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9633         return;
   9634       }
   9635     }
   9636   }
   9637   Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
   9638 }
   9639 
   9640 void Assembler::sbfx(
   9641     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
   9642   VIXL_ASSERT(AllowAssembler());
   9643   CheckIT(cond);
   9644   if (IsUsingT32()) {
   9645     // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
   9646     if ((lsb <= 31) &&
   9647         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
   9648          AllowUnpredictable())) {
   9649       uint32_t widthm1 = width - 1;
   9650       EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9651                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
   9652       AdvanceIT();
   9653       return;
   9654     }
   9655   } else {
   9656     // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
   9657     if ((lsb <= 31) && cond.IsNotNever() &&
   9658         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
   9659          AllowUnpredictable())) {
   9660       uint32_t widthm1 = width - 1;
   9661       EmitA32(0x07a00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9662               rn.GetCode() | (lsb << 7) | (widthm1 << 16));
   9663       return;
   9664     }
   9665   }
   9666   Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, width);
   9667 }
   9668 
   9669 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
   9670   VIXL_ASSERT(AllowAssembler());
   9671   CheckIT(cond);
   9672   if (IsUsingT32()) {
   9673     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9674     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9675       EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9676                  rm.GetCode());
   9677       AdvanceIT();
   9678       return;
   9679     }
   9680   } else {
   9681     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9682     if (cond.IsNotNever() &&
   9683         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9684       EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9685               rn.GetCode() | (rm.GetCode() << 8));
   9686       return;
   9687     }
   9688   }
   9689   Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
   9690 }
   9691 
   9692 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
   9693   VIXL_ASSERT(AllowAssembler());
   9694   CheckIT(cond);
   9695   if (IsUsingT32()) {
   9696     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9697     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9698       EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9699                  rm.GetCode());
   9700       AdvanceIT();
   9701       return;
   9702     }
   9703   } else {
   9704     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9705     if (cond.IsNotNever() &&
   9706         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9707       EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9708               (rn.GetCode() << 16) | rm.GetCode());
   9709       return;
   9710     }
   9711   }
   9712   Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
   9713 }
   9714 
   9715 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
   9716   VIXL_ASSERT(AllowAssembler());
   9717   CheckIT(cond);
   9718   if (IsUsingT32()) {
   9719     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9720     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9721       EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9722                  rm.GetCode());
   9723       AdvanceIT();
   9724       return;
   9725     }
   9726   } else {
   9727     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9728     if (cond.IsNotNever() &&
   9729         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9730       EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9731               (rn.GetCode() << 16) | rm.GetCode());
   9732       return;
   9733     }
   9734   }
   9735   Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
   9736 }
   9737 
   9738 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
   9739   VIXL_ASSERT(AllowAssembler());
   9740   CheckIT(cond);
   9741   if (IsUsingT32()) {
   9742     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9743     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9744       EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9745                  rm.GetCode());
   9746       AdvanceIT();
   9747       return;
   9748     }
   9749   } else {
   9750     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9751     if (cond.IsNotNever() &&
   9752         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9753       EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9754               (rn.GetCode() << 16) | rm.GetCode());
   9755       return;
   9756     }
   9757   }
   9758   Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
   9759 }
   9760 
   9761 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
   9762   VIXL_ASSERT(AllowAssembler());
   9763   CheckIT(cond);
   9764   if (IsUsingT32()) {
   9765     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9766     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9767       EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9768                  rm.GetCode());
   9769       AdvanceIT();
   9770       return;
   9771     }
   9772   } else {
   9773     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9774     if (cond.IsNotNever() &&
   9775         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9776       EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9777               (rn.GetCode() << 16) | rm.GetCode());
   9778       return;
   9779     }
   9780   }
   9781   Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
   9782 }
   9783 
   9784 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
   9785   VIXL_ASSERT(AllowAssembler());
   9786   CheckIT(cond);
   9787   if (IsUsingT32()) {
   9788     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9789     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9790       EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9791                  rm.GetCode());
   9792       AdvanceIT();
   9793       return;
   9794     }
   9795   } else {
   9796     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9797     if (cond.IsNotNever() &&
   9798         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9799       EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9800               (rn.GetCode() << 16) | rm.GetCode());
   9801       return;
   9802     }
   9803   }
   9804   Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
   9805 }
   9806 
   9807 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
   9808   VIXL_ASSERT(AllowAssembler());
   9809   CheckIT(cond);
   9810   if (IsUsingT32()) {
   9811     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9812     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9813       EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9814                  rm.GetCode());
   9815       AdvanceIT();
   9816       return;
   9817     }
   9818   } else {
   9819     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9820     if (cond.IsNotNever() &&
   9821         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9822       EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9823               (rn.GetCode() << 16) | rm.GetCode());
   9824       return;
   9825     }
   9826   }
   9827   Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
   9828 }
   9829 
   9830 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
   9831   VIXL_ASSERT(AllowAssembler());
   9832   CheckIT(cond);
   9833   if (IsUsingT32()) {
   9834     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9835     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9836       EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9837                  rm.GetCode());
   9838       AdvanceIT();
   9839       return;
   9840     }
   9841   } else {
   9842     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9843     if (cond.IsNotNever() &&
   9844         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9845       EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9846               (rn.GetCode() << 16) | rm.GetCode());
   9847       return;
   9848     }
   9849   }
   9850   Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
   9851 }
   9852 
   9853 void Assembler::smlabb(
   9854     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9855   VIXL_ASSERT(AllowAssembler());
   9856   CheckIT(cond);
   9857   if (IsUsingT32()) {
   9858     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9859     if (!ra.Is(pc) &&
   9860         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9861       EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9862                  rm.GetCode() | (ra.GetCode() << 12));
   9863       AdvanceIT();
   9864       return;
   9865     }
   9866   } else {
   9867     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9868     if (cond.IsNotNever() &&
   9869         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   9870          AllowUnpredictable())) {
   9871       EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9872               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9873       return;
   9874     }
   9875   }
   9876   Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
   9877 }
   9878 
   9879 void Assembler::smlabt(
   9880     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9881   VIXL_ASSERT(AllowAssembler());
   9882   CheckIT(cond);
   9883   if (IsUsingT32()) {
   9884     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9885     if (!ra.Is(pc) &&
   9886         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9887       EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9888                  rm.GetCode() | (ra.GetCode() << 12));
   9889       AdvanceIT();
   9890       return;
   9891     }
   9892   } else {
   9893     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9894     if (cond.IsNotNever() &&
   9895         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   9896          AllowUnpredictable())) {
   9897       EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9898               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9899       return;
   9900     }
   9901   }
   9902   Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
   9903 }
   9904 
   9905 void Assembler::smlad(
   9906     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9907   VIXL_ASSERT(AllowAssembler());
   9908   CheckIT(cond);
   9909   if (IsUsingT32()) {
   9910     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9911     if (!ra.Is(pc) &&
   9912         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9913       EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9914                  rm.GetCode() | (ra.GetCode() << 12));
   9915       AdvanceIT();
   9916       return;
   9917     }
   9918   } else {
   9919     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9920     if (cond.IsNotNever() && !ra.Is(pc) &&
   9921         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9922       EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9923               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9924       return;
   9925     }
   9926   }
   9927   Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
   9928 }
   9929 
   9930 void Assembler::smladx(
   9931     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9932   VIXL_ASSERT(AllowAssembler());
   9933   CheckIT(cond);
   9934   if (IsUsingT32()) {
   9935     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9936     if (!ra.Is(pc) &&
   9937         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9938       EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9939                  rm.GetCode() | (ra.GetCode() << 12));
   9940       AdvanceIT();
   9941       return;
   9942     }
   9943   } else {
   9944     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9945     if (cond.IsNotNever() && !ra.Is(pc) &&
   9946         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9947       EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9948               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9949       return;
   9950     }
   9951   }
   9952   Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
   9953 }
   9954 
   9955 void Assembler::smlal(
   9956     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9957   VIXL_ASSERT(AllowAssembler());
   9958   CheckIT(cond);
   9959   if (IsUsingT32()) {
   9960     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9961     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9962          AllowUnpredictable())) {
   9963       EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9964                  (rn.GetCode() << 16) | rm.GetCode());
   9965       AdvanceIT();
   9966       return;
   9967     }
   9968   } else {
   9969     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9970     if (cond.IsNotNever() &&
   9971         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9972          AllowUnpredictable())) {
   9973       EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
   9974               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9975               (rm.GetCode() << 8));
   9976       return;
   9977     }
   9978   }
   9979   Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
   9980 }
   9981 
   9982 void Assembler::smlalbb(
   9983     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9984   VIXL_ASSERT(AllowAssembler());
   9985   CheckIT(cond);
   9986   if (IsUsingT32()) {
   9987     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9988     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9989          AllowUnpredictable())) {
   9990       EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9991                  (rn.GetCode() << 16) | rm.GetCode());
   9992       AdvanceIT();
   9993       return;
   9994     }
   9995   } else {
   9996     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9997     if (cond.IsNotNever() &&
   9998         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9999          AllowUnpredictable())) {
  10000       EmitA32(0x01400080U | (cond.GetCondition() << 28) |
  10001               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10002               (rm.GetCode() << 8));
  10003       return;
  10004     }
  10005   }
  10006   Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
  10007 }
  10008 
  10009 void Assembler::smlalbt(
  10010     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10011   VIXL_ASSERT(AllowAssembler());
  10012   CheckIT(cond);
  10013   if (IsUsingT32()) {
  10014     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  10015     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10016          AllowUnpredictable())) {
  10017       EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  10018                  (rn.GetCode() << 16) | rm.GetCode());
  10019       AdvanceIT();
  10020       return;
  10021     }
  10022   } else {
  10023     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10024     if (cond.IsNotNever() &&
  10025         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10026          AllowUnpredictable())) {
  10027       EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
  10028               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10029               (rm.GetCode() << 8));
  10030       return;
  10031     }
  10032   }
  10033   Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
  10034 }
  10035 
  10036 void Assembler::smlald(
  10037     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10038   VIXL_ASSERT(AllowAssembler());
  10039   CheckIT(cond);
  10040   if (IsUsingT32()) {
  10041     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  10042     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10043          AllowUnpredictable())) {
  10044       EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  10045                  (rn.GetCode() << 16) | rm.GetCode());
  10046       AdvanceIT();
  10047       return;
  10048     }
  10049   } else {
  10050     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10051     if (cond.IsNotNever() &&
  10052         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10053          AllowUnpredictable())) {
  10054       EmitA32(0x07400010U | (cond.GetCondition() << 28) |
  10055               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10056               (rm.GetCode() << 8));
  10057       return;
  10058     }
  10059   }
  10060   Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
  10061 }
  10062 
  10063 void Assembler::smlaldx(
  10064     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10065   VIXL_ASSERT(AllowAssembler());
  10066   CheckIT(cond);
  10067   if (IsUsingT32()) {
  10068     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  10069     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10070          AllowUnpredictable())) {
  10071       EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  10072                  (rn.GetCode() << 16) | rm.GetCode());
  10073       AdvanceIT();
  10074       return;
  10075     }
  10076   } else {
  10077     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10078     if (cond.IsNotNever() &&
  10079         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10080          AllowUnpredictable())) {
  10081       EmitA32(0x07400030U | (cond.GetCondition() << 28) |
  10082               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10083               (rm.GetCode() << 8));
  10084       return;
  10085     }
  10086   }
  10087   Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
  10088 }
  10089 
  10090 void Assembler::smlals(
  10091     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10092   VIXL_ASSERT(AllowAssembler());
  10093   CheckIT(cond);
  10094   if (IsUsingA32()) {
  10095     // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10096     if (cond.IsNotNever() &&
  10097         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10098          AllowUnpredictable())) {
  10099       EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
  10100               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10101               (rm.GetCode() << 8));
  10102       return;
  10103     }
  10104   }
  10105   Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
  10106 }
  10107 
  10108 void Assembler::smlaltb(
  10109     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10110   VIXL_ASSERT(AllowAssembler());
  10111   CheckIT(cond);
  10112   if (IsUsingT32()) {
  10113     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  10114     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10115          AllowUnpredictable())) {
  10116       EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  10117                  (rn.GetCode() << 16) | rm.GetCode());
  10118       AdvanceIT();
  10119       return;
  10120     }
  10121   } else {
  10122     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10123     if (cond.IsNotNever() &&
  10124         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10125          AllowUnpredictable())) {
  10126       EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
  10127               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10128               (rm.GetCode() << 8));
  10129       return;
  10130     }
  10131   }
  10132   Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
  10133 }
  10134 
  10135 void Assembler::smlaltt(
  10136     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10137   VIXL_ASSERT(AllowAssembler());
  10138   CheckIT(cond);
  10139   if (IsUsingT32()) {
  10140     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  10141     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10142          AllowUnpredictable())) {
  10143       EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  10144                  (rn.GetCode() << 16) | rm.GetCode());
  10145       AdvanceIT();
  10146       return;
  10147     }
  10148   } else {
  10149     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10150     if (cond.IsNotNever() &&
  10151         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10152          AllowUnpredictable())) {
  10153       EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
  10154               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10155               (rm.GetCode() << 8));
  10156       return;
  10157     }
  10158   }
  10159   Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
  10160 }
  10161 
  10162 void Assembler::smlatb(
  10163     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10164   VIXL_ASSERT(AllowAssembler());
  10165   CheckIT(cond);
  10166   if (IsUsingT32()) {
  10167     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10168     if (!ra.Is(pc) &&
  10169         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10170       EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10171                  rm.GetCode() | (ra.GetCode() << 12));
  10172       AdvanceIT();
  10173       return;
  10174     }
  10175   } else {
  10176     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10177     if (cond.IsNotNever() &&
  10178         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
  10179          AllowUnpredictable())) {
  10180       EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10181               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10182       return;
  10183     }
  10184   }
  10185   Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
  10186 }
  10187 
  10188 void Assembler::smlatt(
  10189     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10190   VIXL_ASSERT(AllowAssembler());
  10191   CheckIT(cond);
  10192   if (IsUsingT32()) {
  10193     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10194     if (!ra.Is(pc) &&
  10195         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10196       EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10197                  rm.GetCode() | (ra.GetCode() << 12));
  10198       AdvanceIT();
  10199       return;
  10200     }
  10201   } else {
  10202     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10203     if (cond.IsNotNever() &&
  10204         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
  10205          AllowUnpredictable())) {
  10206       EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10207               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10208       return;
  10209     }
  10210   }
  10211   Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
  10212 }
  10213 
  10214 void Assembler::smlawb(
  10215     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10216   VIXL_ASSERT(AllowAssembler());
  10217   CheckIT(cond);
  10218   if (IsUsingT32()) {
  10219     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10220     if (!ra.Is(pc) &&
  10221         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10222       EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10223                  rm.GetCode() | (ra.GetCode() << 12));
  10224       AdvanceIT();
  10225       return;
  10226     }
  10227   } else {
  10228     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10229     if (cond.IsNotNever() &&
  10230         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
  10231          AllowUnpredictable())) {
  10232       EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10233               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10234       return;
  10235     }
  10236   }
  10237   Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
  10238 }
  10239 
  10240 void Assembler::smlawt(
  10241     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10242   VIXL_ASSERT(AllowAssembler());
  10243   CheckIT(cond);
  10244   if (IsUsingT32()) {
  10245     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10246     if (!ra.Is(pc) &&
  10247         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10248       EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10249                  rm.GetCode() | (ra.GetCode() << 12));
  10250       AdvanceIT();
  10251       return;
  10252     }
  10253   } else {
  10254     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10255     if (cond.IsNotNever() &&
  10256         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
  10257          AllowUnpredictable())) {
  10258       EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10259               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10260       return;
  10261     }
  10262   }
  10263   Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
  10264 }
  10265 
  10266 void Assembler::smlsd(
  10267     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10268   VIXL_ASSERT(AllowAssembler());
  10269   CheckIT(cond);
  10270   if (IsUsingT32()) {
  10271     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10272     if (!ra.Is(pc) &&
  10273         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10274       EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10275                  rm.GetCode() | (ra.GetCode() << 12));
  10276       AdvanceIT();
  10277       return;
  10278     }
  10279   } else {
  10280     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10281     if (cond.IsNotNever() && !ra.Is(pc) &&
  10282         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10283       EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10284               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10285       return;
  10286     }
  10287   }
  10288   Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
  10289 }
  10290 
  10291 void Assembler::smlsdx(
  10292     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10293   VIXL_ASSERT(AllowAssembler());
  10294   CheckIT(cond);
  10295   if (IsUsingT32()) {
  10296     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10297     if (!ra.Is(pc) &&
  10298         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10299       EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10300                  rm.GetCode() | (ra.GetCode() << 12));
  10301       AdvanceIT();
  10302       return;
  10303     }
  10304   } else {
  10305     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10306     if (cond.IsNotNever() && !ra.Is(pc) &&
  10307         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10308       EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10309               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10310       return;
  10311     }
  10312   }
  10313   Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
  10314 }
  10315 
  10316 void Assembler::smlsld(
  10317     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10318   VIXL_ASSERT(AllowAssembler());
  10319   CheckIT(cond);
  10320   if (IsUsingT32()) {
  10321     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  10322     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10323          AllowUnpredictable())) {
  10324       EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  10325                  (rn.GetCode() << 16) | rm.GetCode());
  10326       AdvanceIT();
  10327       return;
  10328     }
  10329   } else {
  10330     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10331     if (cond.IsNotNever() &&
  10332         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10333          AllowUnpredictable())) {
  10334       EmitA32(0x07400050U | (cond.GetCondition() << 28) |
  10335               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10336               (rm.GetCode() << 8));
  10337       return;
  10338     }
  10339   }
  10340   Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
  10341 }
  10342 
  10343 void Assembler::smlsldx(
  10344     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10345   VIXL_ASSERT(AllowAssembler());
  10346   CheckIT(cond);
  10347   if (IsUsingT32()) {
  10348     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  10349     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10350          AllowUnpredictable())) {
  10351       EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  10352                  (rn.GetCode() << 16) | rm.GetCode());
  10353       AdvanceIT();
  10354       return;
  10355     }
  10356   } else {
  10357     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10358     if (cond.IsNotNever() &&
  10359         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10360          AllowUnpredictable())) {
  10361       EmitA32(0x07400070U | (cond.GetCondition() << 28) |
  10362               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10363               (rm.GetCode() << 8));
  10364       return;
  10365     }
  10366   }
  10367   Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
  10368 }
  10369 
  10370 void Assembler::smmla(
  10371     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10372   VIXL_ASSERT(AllowAssembler());
  10373   CheckIT(cond);
  10374   if (IsUsingT32()) {
  10375     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10376     if (!ra.Is(pc) &&
  10377         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10378       EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10379                  rm.GetCode() | (ra.GetCode() << 12));
  10380       AdvanceIT();
  10381       return;
  10382     }
  10383   } else {
  10384     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10385     if (cond.IsNotNever() && !ra.Is(pc) &&
  10386         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10387       EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10388               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10389       return;
  10390     }
  10391   }
  10392   Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
  10393 }
  10394 
  10395 void Assembler::smmlar(
  10396     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10397   VIXL_ASSERT(AllowAssembler());
  10398   CheckIT(cond);
  10399   if (IsUsingT32()) {
  10400     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10401     if (!ra.Is(pc) &&
  10402         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10403       EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10404                  rm.GetCode() | (ra.GetCode() << 12));
  10405       AdvanceIT();
  10406       return;
  10407     }
  10408   } else {
  10409     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10410     if (cond.IsNotNever() && !ra.Is(pc) &&
  10411         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10412       EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10413               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10414       return;
  10415     }
  10416   }
  10417   Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
  10418 }
  10419 
  10420 void Assembler::smmls(
  10421     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10422   VIXL_ASSERT(AllowAssembler());
  10423   CheckIT(cond);
  10424   if (IsUsingT32()) {
  10425     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10426     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
  10427          AllowUnpredictable())) {
  10428       EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10429                  rm.GetCode() | (ra.GetCode() << 12));
  10430       AdvanceIT();
  10431       return;
  10432     }
  10433   } else {
  10434     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10435     if (cond.IsNotNever() &&
  10436         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
  10437          AllowUnpredictable())) {
  10438       EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10439               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10440       return;
  10441     }
  10442   }
  10443   Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
  10444 }
  10445 
  10446 void Assembler::smmlsr(
  10447     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  10448   VIXL_ASSERT(AllowAssembler());
  10449   CheckIT(cond);
  10450   if (IsUsingT32()) {
  10451     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  10452     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
  10453          AllowUnpredictable())) {
  10454       EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10455                  rm.GetCode() | (ra.GetCode() << 12));
  10456       AdvanceIT();
  10457       return;
  10458     }
  10459   } else {
  10460     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  10461     if (cond.IsNotNever() &&
  10462         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
  10463          AllowUnpredictable())) {
  10464       EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10465               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  10466       return;
  10467     }
  10468   }
  10469   Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
  10470 }
  10471 
  10472 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
  10473   VIXL_ASSERT(AllowAssembler());
  10474   CheckIT(cond);
  10475   if (IsUsingT32()) {
  10476     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10477     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10478       EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10479                  rm.GetCode());
  10480       AdvanceIT();
  10481       return;
  10482     }
  10483   } else {
  10484     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10485     if (cond.IsNotNever() &&
  10486         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10487       EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10488               rn.GetCode() | (rm.GetCode() << 8));
  10489       return;
  10490     }
  10491   }
  10492   Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
  10493 }
  10494 
  10495 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
  10496   VIXL_ASSERT(AllowAssembler());
  10497   CheckIT(cond);
  10498   if (IsUsingT32()) {
  10499     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10500     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10501       EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10502                  rm.GetCode());
  10503       AdvanceIT();
  10504       return;
  10505     }
  10506   } else {
  10507     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10508     if (cond.IsNotNever() &&
  10509         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10510       EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10511               rn.GetCode() | (rm.GetCode() << 8));
  10512       return;
  10513     }
  10514   }
  10515   Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
  10516 }
  10517 
  10518 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
  10519   VIXL_ASSERT(AllowAssembler());
  10520   CheckIT(cond);
  10521   if (IsUsingT32()) {
  10522     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10523     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10524       EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10525                  rm.GetCode());
  10526       AdvanceIT();
  10527       return;
  10528     }
  10529   } else {
  10530     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10531     if (cond.IsNotNever() &&
  10532         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10533       EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10534               rn.GetCode() | (rm.GetCode() << 8));
  10535       return;
  10536     }
  10537   }
  10538   Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
  10539 }
  10540 
  10541 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
  10542   VIXL_ASSERT(AllowAssembler());
  10543   CheckIT(cond);
  10544   if (IsUsingT32()) {
  10545     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10546     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10547       EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10548                  rm.GetCode());
  10549       AdvanceIT();
  10550       return;
  10551     }
  10552   } else {
  10553     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10554     if (cond.IsNotNever() &&
  10555         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10556       EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10557               rn.GetCode() | (rm.GetCode() << 8));
  10558       return;
  10559     }
  10560   }
  10561   Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
  10562 }
  10563 
  10564 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
  10565   VIXL_ASSERT(AllowAssembler());
  10566   CheckIT(cond);
  10567   if (IsUsingT32()) {
  10568     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10569     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10570       EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10571                  rm.GetCode());
  10572       AdvanceIT();
  10573       return;
  10574     }
  10575   } else {
  10576     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10577     if (cond.IsNotNever() &&
  10578         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10579       EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10580               rn.GetCode() | (rm.GetCode() << 8));
  10581       return;
  10582     }
  10583   }
  10584   Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
  10585 }
  10586 
  10587 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
  10588   VIXL_ASSERT(AllowAssembler());
  10589   CheckIT(cond);
  10590   if (IsUsingT32()) {
  10591     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10592     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10593       EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10594                  rm.GetCode());
  10595       AdvanceIT();
  10596       return;
  10597     }
  10598   } else {
  10599     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10600     if (cond.IsNotNever() &&
  10601         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10602       EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10603               rn.GetCode() | (rm.GetCode() << 8));
  10604       return;
  10605     }
  10606   }
  10607   Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
  10608 }
  10609 
  10610 void Assembler::smull(
  10611     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10612   VIXL_ASSERT(AllowAssembler());
  10613   CheckIT(cond);
  10614   if (IsUsingT32()) {
  10615     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  10616     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10617          AllowUnpredictable())) {
  10618       EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  10619                  (rn.GetCode() << 16) | rm.GetCode());
  10620       AdvanceIT();
  10621       return;
  10622     }
  10623   } else {
  10624     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10625     if (cond.IsNotNever() &&
  10626         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10627          AllowUnpredictable())) {
  10628       EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
  10629               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10630               (rm.GetCode() << 8));
  10631       return;
  10632     }
  10633   }
  10634   Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
  10635 }
  10636 
  10637 void Assembler::smulls(
  10638     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  10639   VIXL_ASSERT(AllowAssembler());
  10640   CheckIT(cond);
  10641   if (IsUsingA32()) {
  10642     // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  10643     if (cond.IsNotNever() &&
  10644         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  10645          AllowUnpredictable())) {
  10646       EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
  10647               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  10648               (rm.GetCode() << 8));
  10649       return;
  10650     }
  10651   }
  10652   Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
  10653 }
  10654 
  10655 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
  10656   VIXL_ASSERT(AllowAssembler());
  10657   CheckIT(cond);
  10658   if (IsUsingT32()) {
  10659     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10660     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10661       EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10662                  rm.GetCode());
  10663       AdvanceIT();
  10664       return;
  10665     }
  10666   } else {
  10667     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10668     if (cond.IsNotNever() &&
  10669         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10670       EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10671               rn.GetCode() | (rm.GetCode() << 8));
  10672       return;
  10673     }
  10674   }
  10675   Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
  10676 }
  10677 
  10678 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
  10679   VIXL_ASSERT(AllowAssembler());
  10680   CheckIT(cond);
  10681   if (IsUsingT32()) {
  10682     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10683     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10684       EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10685                  rm.GetCode());
  10686       AdvanceIT();
  10687       return;
  10688     }
  10689   } else {
  10690     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10691     if (cond.IsNotNever() &&
  10692         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10693       EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10694               rn.GetCode() | (rm.GetCode() << 8));
  10695       return;
  10696     }
  10697   }
  10698   Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
  10699 }
  10700 
  10701 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
  10702   VIXL_ASSERT(AllowAssembler());
  10703   CheckIT(cond);
  10704   if (IsUsingT32()) {
  10705     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10706     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10707       EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10708                  rm.GetCode());
  10709       AdvanceIT();
  10710       return;
  10711     }
  10712   } else {
  10713     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10714     if (cond.IsNotNever() &&
  10715         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10716       EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10717               rn.GetCode() | (rm.GetCode() << 8));
  10718       return;
  10719     }
  10720   }
  10721   Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
  10722 }
  10723 
  10724 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
  10725   VIXL_ASSERT(AllowAssembler());
  10726   CheckIT(cond);
  10727   if (IsUsingT32()) {
  10728     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10729     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10730       EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10731                  rm.GetCode());
  10732       AdvanceIT();
  10733       return;
  10734     }
  10735   } else {
  10736     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10737     if (cond.IsNotNever() &&
  10738         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10739       EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10740               rn.GetCode() | (rm.GetCode() << 8));
  10741       return;
  10742     }
  10743   }
  10744   Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
  10745 }
  10746 
  10747 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
  10748   VIXL_ASSERT(AllowAssembler());
  10749   CheckIT(cond);
  10750   if (IsUsingT32()) {
  10751     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10752     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10753       EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10754                  rm.GetCode());
  10755       AdvanceIT();
  10756       return;
  10757     }
  10758   } else {
  10759     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10760     if (cond.IsNotNever() &&
  10761         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10762       EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10763               rn.GetCode() | (rm.GetCode() << 8));
  10764       return;
  10765     }
  10766   }
  10767   Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
  10768 }
  10769 
  10770 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
  10771   VIXL_ASSERT(AllowAssembler());
  10772   CheckIT(cond);
  10773   if (IsUsingT32()) {
  10774     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10775     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10776       EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10777                  rm.GetCode());
  10778       AdvanceIT();
  10779       return;
  10780     }
  10781   } else {
  10782     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10783     if (cond.IsNotNever() &&
  10784         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10785       EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  10786               rn.GetCode() | (rm.GetCode() << 8));
  10787       return;
  10788     }
  10789   }
  10790   Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
  10791 }
  10792 
  10793 void Assembler::ssat(Condition cond,
  10794                      Register rd,
  10795                      uint32_t imm,
  10796                      const Operand& operand) {
  10797   VIXL_ASSERT(AllowAssembler());
  10798   CheckIT(cond);
  10799   if (operand.IsImmediateShiftedRegister()) {
  10800     Register rn = operand.GetBaseRegister();
  10801     Shift shift = operand.GetShift();
  10802     uint32_t amount = operand.GetShiftAmount();
  10803     if (IsUsingT32()) {
  10804       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
  10805       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
  10806           (amount <= 31) &&
  10807           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10808         uint32_t imm_ = imm - 1;
  10809         EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
  10810                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
  10811                    ((amount & 0x1c) << 10));
  10812         AdvanceIT();
  10813         return;
  10814       }
  10815       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
  10816       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
  10817           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10818         uint32_t imm_ = imm - 1;
  10819         EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
  10820                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
  10821                    ((amount & 0x1c) << 10));
  10822         AdvanceIT();
  10823         return;
  10824       }
  10825     } else {
  10826       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
  10827       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
  10828           (amount <= 32) && cond.IsNotNever() &&
  10829           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10830         uint32_t imm_ = imm - 1;
  10831         uint32_t amount_ = amount % 32;
  10832         EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
  10833                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
  10834                 (amount_ << 7));
  10835         return;
  10836       }
  10837       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
  10838       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
  10839           cond.IsNotNever() &&
  10840           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10841         uint32_t imm_ = imm - 1;
  10842         EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
  10843                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
  10844                 (amount << 7));
  10845         return;
  10846       }
  10847     }
  10848   }
  10849   Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
  10850 }
  10851 
  10852 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
  10853   VIXL_ASSERT(AllowAssembler());
  10854   CheckIT(cond);
  10855   if (IsUsingT32()) {
  10856     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
  10857     if ((imm >= 1) && (imm <= 16) &&
  10858         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10859       uint32_t imm_ = imm - 1;
  10860       EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
  10861                  (rn.GetCode() << 16));
  10862       AdvanceIT();
  10863       return;
  10864     }
  10865   } else {
  10866     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
  10867     if ((imm >= 1) && (imm <= 16) && cond.IsNotNever() &&
  10868         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10869       uint32_t imm_ = imm - 1;
  10870       EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  10871               (imm_ << 16) | rn.GetCode());
  10872       return;
  10873     }
  10874   }
  10875   Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
  10876 }
  10877 
  10878 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
  10879   VIXL_ASSERT(AllowAssembler());
  10880   CheckIT(cond);
  10881   if (IsUsingT32()) {
  10882     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10883     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10884       EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10885                  rm.GetCode());
  10886       AdvanceIT();
  10887       return;
  10888     }
  10889   } else {
  10890     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10891     if (cond.IsNotNever() &&
  10892         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10893       EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  10894               (rn.GetCode() << 16) | rm.GetCode());
  10895       return;
  10896     }
  10897   }
  10898   Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
  10899 }
  10900 
  10901 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
  10902   VIXL_ASSERT(AllowAssembler());
  10903   CheckIT(cond);
  10904   if (IsUsingT32()) {
  10905     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10906     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10907       EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10908                  rm.GetCode());
  10909       AdvanceIT();
  10910       return;
  10911     }
  10912   } else {
  10913     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10914     if (cond.IsNotNever() &&
  10915         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10916       EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  10917               (rn.GetCode() << 16) | rm.GetCode());
  10918       return;
  10919     }
  10920   }
  10921   Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
  10922 }
  10923 
  10924 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
  10925   VIXL_ASSERT(AllowAssembler());
  10926   CheckIT(cond);
  10927   if (IsUsingT32()) {
  10928     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  10929     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10930       EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  10931                  rm.GetCode());
  10932       AdvanceIT();
  10933       return;
  10934     }
  10935   } else {
  10936     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  10937     if (cond.IsNotNever() &&
  10938         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  10939       EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  10940               (rn.GetCode() << 16) | rm.GetCode());
  10941       return;
  10942     }
  10943   }
  10944   Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
  10945 }
  10946 
  10947 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
  10948   VIXL_ASSERT(AllowAssembler());
  10949   CheckIT(cond);
  10950   if (operand.IsImmediateZero()) {
  10951     Register rn = operand.GetBaseRegister();
  10952     if (IsUsingT32()) {
  10953       // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
  10954       if (operand.IsOffset() &&
  10955           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10956         EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
  10957         AdvanceIT();
  10958         return;
  10959       }
  10960     } else {
  10961       // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
  10962       if (operand.IsOffset() && cond.IsNotNever() &&
  10963           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10964         EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
  10965                 (rn.GetCode() << 16));
  10966         return;
  10967       }
  10968     }
  10969   }
  10970   Delegate(kStl, &Assembler::stl, cond, rt, operand);
  10971 }
  10972 
  10973 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
  10974   VIXL_ASSERT(AllowAssembler());
  10975   CheckIT(cond);
  10976   if (operand.IsImmediateZero()) {
  10977     Register rn = operand.GetBaseRegister();
  10978     if (IsUsingT32()) {
  10979       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
  10980       if (operand.IsOffset() &&
  10981           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10982         EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
  10983         AdvanceIT();
  10984         return;
  10985       }
  10986     } else {
  10987       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
  10988       if (operand.IsOffset() && cond.IsNotNever() &&
  10989           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  10990         EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
  10991                 (rn.GetCode() << 16));
  10992         return;
  10993       }
  10994     }
  10995   }
  10996   Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
  10997 }
  10998 
  10999 void Assembler::stlex(Condition cond,
  11000                       Register rd,
  11001                       Register rt,
  11002                       const MemOperand& operand) {
  11003   VIXL_ASSERT(AllowAssembler());
  11004   CheckIT(cond);
  11005   if (operand.IsImmediateZero()) {
  11006     Register rn = operand.GetBaseRegister();
  11007     if (IsUsingT32()) {
  11008       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
  11009       if (operand.IsOffset() &&
  11010           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11011         EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
  11012                    (rn.GetCode() << 16));
  11013         AdvanceIT();
  11014         return;
  11015       }
  11016     } else {
  11017       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
  11018       if (operand.IsOffset() && cond.IsNotNever() &&
  11019           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11020         EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
  11021                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
  11022         return;
  11023       }
  11024     }
  11025   }
  11026   Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
  11027 }
  11028 
  11029 void Assembler::stlexb(Condition cond,
  11030                        Register rd,
  11031                        Register rt,
  11032                        const MemOperand& operand) {
  11033   VIXL_ASSERT(AllowAssembler());
  11034   CheckIT(cond);
  11035   if (operand.IsImmediateZero()) {
  11036     Register rn = operand.GetBaseRegister();
  11037     if (IsUsingT32()) {
  11038       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
  11039       if (operand.IsOffset() &&
  11040           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11041         EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
  11042                    (rn.GetCode() << 16));
  11043         AdvanceIT();
  11044         return;
  11045       }
  11046     } else {
  11047       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
  11048       if (operand.IsOffset() && cond.IsNotNever() &&
  11049           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11050         EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
  11051                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
  11052         return;
  11053       }
  11054     }
  11055   }
  11056   Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
  11057 }
  11058 
  11059 void Assembler::stlexd(Condition cond,
  11060                        Register rd,
  11061                        Register rt,
  11062                        Register rt2,
  11063                        const MemOperand& operand) {
  11064   VIXL_ASSERT(AllowAssembler());
  11065   CheckIT(cond);
  11066   if (operand.IsImmediateZero()) {
  11067     Register rn = operand.GetBaseRegister();
  11068     if (IsUsingT32()) {
  11069       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
  11070       if (operand.IsOffset() &&
  11071           ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) ||
  11072            AllowUnpredictable())) {
  11073         EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
  11074                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
  11075         AdvanceIT();
  11076         return;
  11077       }
  11078     } else {
  11079       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
  11080       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
  11081           operand.IsOffset() && cond.IsNotNever() &&
  11082           ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() &&
  11083             !rn.IsPC()) ||
  11084            AllowUnpredictable())) {
  11085         EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
  11086                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
  11087         return;
  11088       }
  11089     }
  11090   }
  11091   Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
  11092 }
  11093 
  11094 void Assembler::stlexh(Condition cond,
  11095                        Register rd,
  11096                        Register rt,
  11097                        const MemOperand& operand) {
  11098   VIXL_ASSERT(AllowAssembler());
  11099   CheckIT(cond);
  11100   if (operand.IsImmediateZero()) {
  11101     Register rn = operand.GetBaseRegister();
  11102     if (IsUsingT32()) {
  11103       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
  11104       if (operand.IsOffset() &&
  11105           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11106         EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
  11107                    (rn.GetCode() << 16));
  11108         AdvanceIT();
  11109         return;
  11110       }
  11111     } else {
  11112       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
  11113       if (operand.IsOffset() && cond.IsNotNever() &&
  11114           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11115         EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
  11116                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
  11117         return;
  11118       }
  11119     }
  11120   }
  11121   Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
  11122 }
  11123 
  11124 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
  11125   VIXL_ASSERT(AllowAssembler());
  11126   CheckIT(cond);
  11127   if (operand.IsImmediateZero()) {
  11128     Register rn = operand.GetBaseRegister();
  11129     if (IsUsingT32()) {
  11130       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
  11131       if (operand.IsOffset() &&
  11132           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11133         EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
  11134         AdvanceIT();
  11135         return;
  11136       }
  11137     } else {
  11138       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
  11139       if (operand.IsOffset() && cond.IsNotNever() &&
  11140           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11141         EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
  11142                 (rn.GetCode() << 16));
  11143         return;
  11144       }
  11145     }
  11146   }
  11147   Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
  11148 }
  11149 
  11150 void Assembler::stm(Condition cond,
  11151                     EncodingSize size,
  11152                     Register rn,
  11153                     WriteBack write_back,
  11154                     RegisterList registers) {
  11155   VIXL_ASSERT(AllowAssembler());
  11156   CheckIT(cond);
  11157   if (IsUsingT32()) {
  11158     // STM{<c>}{<q>} <Rn>!, <registers> ; T1
  11159     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
  11160         ((registers.GetList() & ~0xff) == 0)) {
  11161       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
  11162                  GetRegisterListEncoding(registers, 0, 8));
  11163       AdvanceIT();
  11164       return;
  11165     }
  11166     // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
  11167     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
  11168         (!rn.IsPC() || AllowUnpredictable())) {
  11169       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
  11170                  (write_back.GetWriteBackUint32() << 21) |
  11171                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
  11172                  GetRegisterListEncoding(registers, 0, 13));
  11173       AdvanceIT();
  11174       return;
  11175     }
  11176   } else {
  11177     // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
  11178     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
  11179       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  11180               (write_back.GetWriteBackUint32() << 21) |
  11181               GetRegisterListEncoding(registers, 0, 16));
  11182       return;
  11183     }
  11184   }
  11185   Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
  11186 }
  11187 
  11188 void Assembler::stmda(Condition cond,
  11189                       Register rn,
  11190                       WriteBack write_back,
  11191                       RegisterList registers) {
  11192   VIXL_ASSERT(AllowAssembler());
  11193   CheckIT(cond);
  11194   if (IsUsingA32()) {
  11195     // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
  11196     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
  11197       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  11198               (write_back.GetWriteBackUint32() << 21) |
  11199               GetRegisterListEncoding(registers, 0, 16));
  11200       return;
  11201     }
  11202   }
  11203   Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
  11204 }
  11205 
  11206 void Assembler::stmdb(Condition cond,
  11207                       EncodingSize size,
  11208                       Register rn,
  11209                       WriteBack write_back,
  11210                       RegisterList registers) {
  11211   VIXL_ASSERT(AllowAssembler());
  11212   CheckIT(cond);
  11213   if (IsUsingT32()) {
  11214     // STMDB{<c>}{<q>} SP!, <registers> ; T1
  11215     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
  11216         registers.IsR0toR7orLR()) {
  11217       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
  11218                  GetRegisterListEncoding(registers, 0, 8));
  11219       AdvanceIT();
  11220       return;
  11221     }
  11222     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
  11223     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
  11224         (!rn.IsPC() || AllowUnpredictable())) {
  11225       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
  11226                  (write_back.GetWriteBackUint32() << 21) |
  11227                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
  11228                  GetRegisterListEncoding(registers, 0, 13));
  11229       AdvanceIT();
  11230       return;
  11231     }
  11232   } else {
  11233     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
  11234     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
  11235       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  11236               (write_back.GetWriteBackUint32() << 21) |
  11237               GetRegisterListEncoding(registers, 0, 16));
  11238       return;
  11239     }
  11240   }
  11241   Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
  11242 }
  11243 
  11244 void Assembler::stmea(Condition cond,
  11245                       EncodingSize size,
  11246                       Register rn,
  11247                       WriteBack write_back,
  11248                       RegisterList registers) {
  11249   VIXL_ASSERT(AllowAssembler());
  11250   CheckIT(cond);
  11251   if (IsUsingT32()) {
  11252     // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
  11253     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
  11254         ((registers.GetList() & ~0xff) == 0)) {
  11255       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
  11256                  GetRegisterListEncoding(registers, 0, 8));
  11257       AdvanceIT();
  11258       return;
  11259     }
  11260     // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
  11261     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
  11262         (!rn.IsPC() || AllowUnpredictable())) {
  11263       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
  11264                  (write_back.GetWriteBackUint32() << 21) |
  11265                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
  11266                  GetRegisterListEncoding(registers, 0, 13));
  11267       AdvanceIT();
  11268       return;
  11269     }
  11270     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
  11271     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
  11272         (!rn.IsPC() || AllowUnpredictable())) {
  11273       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
  11274                  (write_back.GetWriteBackUint32() << 21) |
  11275                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
  11276                  GetRegisterListEncoding(registers, 0, 13));
  11277       AdvanceIT();
  11278       return;
  11279     }
  11280   } else {
  11281     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
  11282     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
  11283       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  11284               (write_back.GetWriteBackUint32() << 21) |
  11285               GetRegisterListEncoding(registers, 0, 16));
  11286       return;
  11287     }
  11288   }
  11289   Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
  11290 }
  11291 
  11292 void Assembler::stmed(Condition cond,
  11293                       Register rn,
  11294                       WriteBack write_back,
  11295                       RegisterList registers) {
  11296   VIXL_ASSERT(AllowAssembler());
  11297   CheckIT(cond);
  11298   if (IsUsingA32()) {
  11299     // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
  11300     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
  11301       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  11302               (write_back.GetWriteBackUint32() << 21) |
  11303               GetRegisterListEncoding(registers, 0, 16));
  11304       return;
  11305     }
  11306   }
  11307   Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
  11308 }
  11309 
  11310 void Assembler::stmfa(Condition cond,
  11311                       Register rn,
  11312                       WriteBack write_back,
  11313                       RegisterList registers) {
  11314   VIXL_ASSERT(AllowAssembler());
  11315   CheckIT(cond);
  11316   if (IsUsingA32()) {
  11317     // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
  11318     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
  11319       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  11320               (write_back.GetWriteBackUint32() << 21) |
  11321               GetRegisterListEncoding(registers, 0, 16));
  11322       return;
  11323     }
  11324   }
  11325   Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
  11326 }
  11327 
  11328 void Assembler::stmfd(Condition cond,
  11329                       Register rn,
  11330                       WriteBack write_back,
  11331                       RegisterList registers) {
  11332   VIXL_ASSERT(AllowAssembler());
  11333   CheckIT(cond);
  11334   if (IsUsingT32()) {
  11335     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
  11336     if (((registers.GetList() & ~0x5fff) == 0) &&
  11337         (!rn.IsPC() || AllowUnpredictable())) {
  11338       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
  11339                  (write_back.GetWriteBackUint32() << 21) |
  11340                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
  11341                  GetRegisterListEncoding(registers, 0, 13));
  11342       AdvanceIT();
  11343       return;
  11344     }
  11345   } else {
  11346     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
  11347     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
  11348       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  11349               (write_back.GetWriteBackUint32() << 21) |
  11350               GetRegisterListEncoding(registers, 0, 16));
  11351       return;
  11352     }
  11353   }
  11354   Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
  11355 }
  11356 
  11357 void Assembler::stmib(Condition cond,
  11358                       Register rn,
  11359                       WriteBack write_back,
  11360                       RegisterList registers) {
  11361   VIXL_ASSERT(AllowAssembler());
  11362   CheckIT(cond);
  11363   if (IsUsingA32()) {
  11364     // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
  11365     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
  11366       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  11367               (write_back.GetWriteBackUint32() << 21) |
  11368               GetRegisterListEncoding(registers, 0, 16));
  11369       return;
  11370     }
  11371   }
  11372   Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
  11373 }
  11374 
  11375 void Assembler::str(Condition cond,
  11376                     EncodingSize size,
  11377                     Register rt,
  11378                     const MemOperand& operand) {
  11379   VIXL_ASSERT(AllowAssembler());
  11380   CheckIT(cond);
  11381   if (operand.IsImmediate()) {
  11382     Register rn = operand.GetBaseRegister();
  11383     int32_t offset = operand.GetOffsetImmediate();
  11384     if (IsUsingT32()) {
  11385       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
  11386       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
  11387           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
  11388         int32_t offset_ = offset >> 2;
  11389         EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
  11390                    ((offset_ & 0x1f) << 6));
  11391         AdvanceIT();
  11392         return;
  11393       }
  11394       // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
  11395       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
  11396           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
  11397         int32_t offset_ = offset >> 2;
  11398         EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
  11399         AdvanceIT();
  11400         return;
  11401       }
  11402       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
  11403       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
  11404           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11405           (!rt.IsPC() || AllowUnpredictable())) {
  11406         EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11407                    (offset & 0xfff));
  11408         AdvanceIT();
  11409         return;
  11410       }
  11411       // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
  11412       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
  11413           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11414           (!rt.IsPC() || AllowUnpredictable())) {
  11415         EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11416                    (-offset & 0xff));
  11417         AdvanceIT();
  11418         return;
  11419       }
  11420       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
  11421       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
  11422           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
  11423           (!rt.IsPC() || AllowUnpredictable())) {
  11424         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11425         uint32_t offset_ = abs(offset);
  11426         EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11427                    offset_ | (sign << 9));
  11428         AdvanceIT();
  11429         return;
  11430       }
  11431       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
  11432       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
  11433           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
  11434           (!rt.IsPC() || AllowUnpredictable())) {
  11435         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11436         uint32_t offset_ = abs(offset);
  11437         EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11438                    offset_ | (sign << 9));
  11439         AdvanceIT();
  11440         return;
  11441       }
  11442     } else {
  11443       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
  11444       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
  11445           cond.IsNotNever()) {
  11446         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11447         uint32_t offset_ = abs(offset);
  11448         EmitA32(0x05000000U | (cond.GetCondition() << 28) |
  11449                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
  11450                 (sign << 23));
  11451         return;
  11452       }
  11453       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
  11454       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
  11455           cond.IsNotNever()) {
  11456         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11457         uint32_t offset_ = abs(offset);
  11458         EmitA32(0x04000000U | (cond.GetCondition() << 28) |
  11459                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
  11460                 (sign << 23));
  11461         return;
  11462       }
  11463       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
  11464       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
  11465           cond.IsNotNever()) {
  11466         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11467         uint32_t offset_ = abs(offset);
  11468         EmitA32(0x05200000U | (cond.GetCondition() << 28) |
  11469                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
  11470                 (sign << 23));
  11471         return;
  11472       }
  11473     }
  11474   }
  11475   if (operand.IsPlainRegister()) {
  11476     Register rn = operand.GetBaseRegister();
  11477     Sign sign = operand.GetSign();
  11478     Register rm = operand.GetOffsetRegister();
  11479     if (IsUsingT32()) {
  11480       // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
  11481       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
  11482           sign.IsPlus() && operand.IsOffset()) {
  11483         EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
  11484                    (rm.GetCode() << 6));
  11485         AdvanceIT();
  11486         return;
  11487       }
  11488     }
  11489   }
  11490   if (operand.IsShiftedRegister()) {
  11491     Register rn = operand.GetBaseRegister();
  11492     Sign sign = operand.GetSign();
  11493     Register rm = operand.GetOffsetRegister();
  11494     Shift shift = operand.GetShift();
  11495     uint32_t amount = operand.GetShiftAmount();
  11496     if (IsUsingT32()) {
  11497       // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
  11498       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
  11499           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11500           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  11501         EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11502                    rm.GetCode() | (amount << 4));
  11503         AdvanceIT();
  11504         return;
  11505       }
  11506     } else {
  11507       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
  11508       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
  11509           (!rm.IsPC() || AllowUnpredictable())) {
  11510         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11511         uint32_t shift_ = TypeEncodingValue(shift);
  11512         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
  11513         EmitA32(0x07000000U | (cond.GetCondition() << 28) |
  11514                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11515                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
  11516         return;
  11517       }
  11518       // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
  11519       if (operand.IsShiftValid() && operand.IsPostIndex() &&
  11520           cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
  11521         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11522         uint32_t shift_ = TypeEncodingValue(shift);
  11523         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
  11524         EmitA32(0x06000000U | (cond.GetCondition() << 28) |
  11525                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11526                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
  11527         return;
  11528       }
  11529       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
  11530       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
  11531           (!rm.IsPC() || AllowUnpredictable())) {
  11532         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11533         uint32_t shift_ = TypeEncodingValue(shift);
  11534         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
  11535         EmitA32(0x07200000U | (cond.GetCondition() << 28) |
  11536                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11537                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
  11538         return;
  11539       }
  11540     }
  11541   }
  11542   Delegate(kStr, &Assembler::str, cond, size, rt, operand);
  11543 }
  11544 
  11545 void Assembler::strb(Condition cond,
  11546                      EncodingSize size,
  11547                      Register rt,
  11548                      const MemOperand& operand) {
  11549   VIXL_ASSERT(AllowAssembler());
  11550   CheckIT(cond);
  11551   if (operand.IsImmediate()) {
  11552     Register rn = operand.GetBaseRegister();
  11553     int32_t offset = operand.GetOffsetImmediate();
  11554     if (IsUsingT32()) {
  11555       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
  11556       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
  11557           (offset <= 31) && operand.IsOffset()) {
  11558         EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
  11559                    ((offset & 0x1f) << 6));
  11560         AdvanceIT();
  11561         return;
  11562       }
  11563       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
  11564       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
  11565           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11566           (!rt.IsPC() || AllowUnpredictable())) {
  11567         EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11568                    (offset & 0xfff));
  11569         AdvanceIT();
  11570         return;
  11571       }
  11572       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
  11573       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
  11574           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11575           (!rt.IsPC() || AllowUnpredictable())) {
  11576         EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11577                    (-offset & 0xff));
  11578         AdvanceIT();
  11579         return;
  11580       }
  11581       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
  11582       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
  11583           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
  11584           (!rt.IsPC() || AllowUnpredictable())) {
  11585         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11586         uint32_t offset_ = abs(offset);
  11587         EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11588                    offset_ | (sign << 9));
  11589         AdvanceIT();
  11590         return;
  11591       }
  11592       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
  11593       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
  11594           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
  11595           (!rt.IsPC() || AllowUnpredictable())) {
  11596         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11597         uint32_t offset_ = abs(offset);
  11598         EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11599                    offset_ | (sign << 9));
  11600         AdvanceIT();
  11601         return;
  11602       }
  11603     } else {
  11604       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
  11605       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
  11606           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  11607         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11608         uint32_t offset_ = abs(offset);
  11609         EmitA32(0x05400000U | (cond.GetCondition() << 28) |
  11610                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
  11611                 (sign << 23));
  11612         return;
  11613       }
  11614       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
  11615       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
  11616           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  11617         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11618         uint32_t offset_ = abs(offset);
  11619         EmitA32(0x04400000U | (cond.GetCondition() << 28) |
  11620                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
  11621                 (sign << 23));
  11622         return;
  11623       }
  11624       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
  11625       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
  11626           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  11627         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11628         uint32_t offset_ = abs(offset);
  11629         EmitA32(0x05600000U | (cond.GetCondition() << 28) |
  11630                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
  11631                 (sign << 23));
  11632         return;
  11633       }
  11634     }
  11635   }
  11636   if (operand.IsPlainRegister()) {
  11637     Register rn = operand.GetBaseRegister();
  11638     Sign sign = operand.GetSign();
  11639     Register rm = operand.GetOffsetRegister();
  11640     if (IsUsingT32()) {
  11641       // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
  11642       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
  11643           sign.IsPlus() && operand.IsOffset()) {
  11644         EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
  11645                    (rm.GetCode() << 6));
  11646         AdvanceIT();
  11647         return;
  11648       }
  11649     }
  11650   }
  11651   if (operand.IsShiftedRegister()) {
  11652     Register rn = operand.GetBaseRegister();
  11653     Sign sign = operand.GetSign();
  11654     Register rm = operand.GetOffsetRegister();
  11655     Shift shift = operand.GetShift();
  11656     uint32_t amount = operand.GetShiftAmount();
  11657     if (IsUsingT32()) {
  11658       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
  11659       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
  11660           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11661           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  11662         EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11663                    rm.GetCode() | (amount << 4));
  11664         AdvanceIT();
  11665         return;
  11666       }
  11667     } else {
  11668       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
  11669       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
  11670           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  11671         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11672         uint32_t shift_ = TypeEncodingValue(shift);
  11673         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
  11674         EmitA32(0x07400000U | (cond.GetCondition() << 28) |
  11675                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11676                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
  11677         return;
  11678       }
  11679       // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
  11680       if (operand.IsShiftValid() && operand.IsPostIndex() &&
  11681           cond.IsNotNever() &&
  11682           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  11683         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11684         uint32_t shift_ = TypeEncodingValue(shift);
  11685         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
  11686         EmitA32(0x06400000U | (cond.GetCondition() << 28) |
  11687                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11688                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
  11689         return;
  11690       }
  11691       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
  11692       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
  11693           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  11694         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11695         uint32_t shift_ = TypeEncodingValue(shift);
  11696         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
  11697         EmitA32(0x07600000U | (cond.GetCondition() << 28) |
  11698                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11699                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
  11700         return;
  11701       }
  11702     }
  11703   }
  11704   Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
  11705 }
  11706 
  11707 void Assembler::strd(Condition cond,
  11708                      Register rt,
  11709                      Register rt2,
  11710                      const MemOperand& operand) {
  11711   VIXL_ASSERT(AllowAssembler());
  11712   CheckIT(cond);
  11713   if (operand.IsImmediate()) {
  11714     Register rn = operand.GetBaseRegister();
  11715     int32_t offset = operand.GetOffsetImmediate();
  11716     if (IsUsingT32()) {
  11717       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
  11718       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
  11719           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11720           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  11721         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11722         uint32_t offset_ = abs(offset) >> 2;
  11723         EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
  11724                    (rn.GetCode() << 16) | offset_ | (sign << 23));
  11725         AdvanceIT();
  11726         return;
  11727       }
  11728       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
  11729       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
  11730           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
  11731           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  11732         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11733         uint32_t offset_ = abs(offset) >> 2;
  11734         EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
  11735                    (rn.GetCode() << 16) | offset_ | (sign << 23));
  11736         AdvanceIT();
  11737         return;
  11738       }
  11739       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
  11740       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
  11741           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
  11742           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  11743         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11744         uint32_t offset_ = abs(offset) >> 2;
  11745         EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
  11746                    (rn.GetCode() << 16) | offset_ | (sign << 23));
  11747         AdvanceIT();
  11748         return;
  11749       }
  11750     } else {
  11751       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
  11752       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
  11753           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
  11754           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
  11755                                 AllowUnpredictable())) {
  11756         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11757         uint32_t offset_ = abs(offset);
  11758         EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
  11759                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
  11760                 ((offset_ & 0xf0) << 4) | (sign << 23));
  11761         return;
  11762       }
  11763       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
  11764       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
  11765           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
  11766           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
  11767                                 AllowUnpredictable())) {
  11768         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11769         uint32_t offset_ = abs(offset);
  11770         EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
  11771                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
  11772                 ((offset_ & 0xf0) << 4) | (sign << 23));
  11773         return;
  11774       }
  11775       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
  11776       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
  11777           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
  11778           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
  11779                                 AllowUnpredictable())) {
  11780         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  11781         uint32_t offset_ = abs(offset);
  11782         EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
  11783                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
  11784                 ((offset_ & 0xf0) << 4) | (sign << 23));
  11785         return;
  11786       }
  11787     }
  11788   }
  11789   if (operand.IsPlainRegister()) {
  11790     Register rn = operand.GetBaseRegister();
  11791     Sign sign = operand.GetSign();
  11792     Register rm = operand.GetOffsetRegister();
  11793     if (IsUsingA32()) {
  11794       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
  11795       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
  11796           operand.IsOffset() && cond.IsNotNever() &&
  11797           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
  11798            AllowUnpredictable())) {
  11799         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11800         EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
  11801                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11802                 (sign_ << 23));
  11803         return;
  11804       }
  11805       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
  11806       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
  11807           operand.IsPostIndex() && cond.IsNotNever() &&
  11808           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
  11809            AllowUnpredictable())) {
  11810         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11811         EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
  11812                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11813                 (sign_ << 23));
  11814         return;
  11815       }
  11816       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
  11817       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
  11818           operand.IsPreIndex() && cond.IsNotNever() &&
  11819           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
  11820            AllowUnpredictable())) {
  11821         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  11822         EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
  11823                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  11824                 (sign_ << 23));
  11825         return;
  11826       }
  11827     }
  11828   }
  11829   Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
  11830 }
  11831 
  11832 void Assembler::strex(Condition cond,
  11833                       Register rd,
  11834                       Register rt,
  11835                       const MemOperand& operand) {
  11836   VIXL_ASSERT(AllowAssembler());
  11837   CheckIT(cond);
  11838   if (operand.IsImmediate()) {
  11839     Register rn = operand.GetBaseRegister();
  11840     int32_t offset = operand.GetOffsetImmediate();
  11841     if (IsUsingT32()) {
  11842       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
  11843       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
  11844           operand.IsOffset() &&
  11845           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11846         int32_t offset_ = offset >> 2;
  11847         EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
  11848                    (rn.GetCode() << 16) | (offset_ & 0xff));
  11849         AdvanceIT();
  11850         return;
  11851       }
  11852     } else {
  11853       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
  11854       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() &&
  11855           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11856         EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
  11857                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
  11858         return;
  11859       }
  11860     }
  11861   }
  11862   Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
  11863 }
  11864 
  11865 void Assembler::strexb(Condition cond,
  11866                        Register rd,
  11867                        Register rt,
  11868                        const MemOperand& operand) {
  11869   VIXL_ASSERT(AllowAssembler());
  11870   CheckIT(cond);
  11871   if (operand.IsImmediateZero()) {
  11872     Register rn = operand.GetBaseRegister();
  11873     if (IsUsingT32()) {
  11874       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
  11875       if (operand.IsOffset() &&
  11876           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11877         EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
  11878                    (rn.GetCode() << 16));
  11879         AdvanceIT();
  11880         return;
  11881       }
  11882     } else {
  11883       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
  11884       if (operand.IsOffset() && cond.IsNotNever() &&
  11885           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11886         EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
  11887                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
  11888         return;
  11889       }
  11890     }
  11891   }
  11892   Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
  11893 }
  11894 
  11895 void Assembler::strexd(Condition cond,
  11896                        Register rd,
  11897                        Register rt,
  11898                        Register rt2,
  11899                        const MemOperand& operand) {
  11900   VIXL_ASSERT(AllowAssembler());
  11901   CheckIT(cond);
  11902   if (operand.IsImmediateZero()) {
  11903     Register rn = operand.GetBaseRegister();
  11904     if (IsUsingT32()) {
  11905       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
  11906       if (operand.IsOffset() &&
  11907           ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) ||
  11908            AllowUnpredictable())) {
  11909         EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
  11910                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
  11911         AdvanceIT();
  11912         return;
  11913       }
  11914     } else {
  11915       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
  11916       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
  11917           operand.IsOffset() && cond.IsNotNever() &&
  11918           ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() &&
  11919             !rn.IsPC()) ||
  11920            AllowUnpredictable())) {
  11921         EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
  11922                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
  11923         return;
  11924       }
  11925     }
  11926   }
  11927   Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
  11928 }
  11929 
  11930 void Assembler::strexh(Condition cond,
  11931                        Register rd,
  11932                        Register rt,
  11933                        const MemOperand& operand) {
  11934   VIXL_ASSERT(AllowAssembler());
  11935   CheckIT(cond);
  11936   if (operand.IsImmediateZero()) {
  11937     Register rn = operand.GetBaseRegister();
  11938     if (IsUsingT32()) {
  11939       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
  11940       if (operand.IsOffset() &&
  11941           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11942         EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
  11943                    (rn.GetCode() << 16));
  11944         AdvanceIT();
  11945         return;
  11946       }
  11947     } else {
  11948       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
  11949       if (operand.IsOffset() && cond.IsNotNever() &&
  11950           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  11951         EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
  11952                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
  11953         return;
  11954       }
  11955     }
  11956   }
  11957   Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
  11958 }
  11959 
  11960 void Assembler::strh(Condition cond,
  11961                      EncodingSize size,
  11962                      Register rt,
  11963                      const MemOperand& operand) {
  11964   VIXL_ASSERT(AllowAssembler());
  11965   CheckIT(cond);
  11966   if (operand.IsImmediate()) {
  11967     Register rn = operand.GetBaseRegister();
  11968     int32_t offset = operand.GetOffsetImmediate();
  11969     if (IsUsingT32()) {
  11970       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
  11971       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
  11972           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
  11973         int32_t offset_ = offset >> 1;
  11974         EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
  11975                    ((offset_ & 0x1f) << 6));
  11976         AdvanceIT();
  11977         return;
  11978       }
  11979       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
  11980       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
  11981           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11982           (!rt.IsPC() || AllowUnpredictable())) {
  11983         EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11984                    (offset & 0xfff));
  11985         AdvanceIT();
  11986         return;
  11987       }
  11988       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
  11989       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
  11990           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  11991           (!rt.IsPC() || AllowUnpredictable())) {
  11992         EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  11993                    (-offset & 0xff));
  11994         AdvanceIT();
  11995         return;
  11996       }
  11997       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
  11998       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
  11999           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
  12000           (!rt.IsPC() || AllowUnpredictable())) {
  12001         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  12002         uint32_t offset_ = abs(offset);
  12003         EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  12004                    offset_ | (sign << 9));
  12005         AdvanceIT();
  12006         return;
  12007       }
  12008       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
  12009       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
  12010           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
  12011           (!rt.IsPC() || AllowUnpredictable())) {
  12012         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  12013         uint32_t offset_ = abs(offset);
  12014         EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  12015                    offset_ | (sign << 9));
  12016         AdvanceIT();
  12017         return;
  12018       }
  12019     } else {
  12020       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
  12021       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
  12022           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  12023         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  12024         uint32_t offset_ = abs(offset);
  12025         EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
  12026                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
  12027                 ((offset_ & 0xf0) << 4) | (sign << 23));
  12028         return;
  12029       }
  12030       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
  12031       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
  12032           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  12033         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  12034         uint32_t offset_ = abs(offset);
  12035         EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
  12036                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
  12037                 ((offset_ & 0xf0) << 4) | (sign << 23));
  12038         return;
  12039       }
  12040       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
  12041       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
  12042           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  12043         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  12044         uint32_t offset_ = abs(offset);
  12045         EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
  12046                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
  12047                 ((offset_ & 0xf0) << 4) | (sign << 23));
  12048         return;
  12049       }
  12050     }
  12051   }
  12052   if (operand.IsPlainRegister()) {
  12053     Register rn = operand.GetBaseRegister();
  12054     Sign sign = operand.GetSign();
  12055     Register rm = operand.GetOffsetRegister();
  12056     if (IsUsingT32()) {
  12057       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
  12058       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
  12059           sign.IsPlus() && operand.IsOffset()) {
  12060         EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
  12061                    (rm.GetCode() << 6));
  12062         AdvanceIT();
  12063         return;
  12064       }
  12065     } else {
  12066       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
  12067       if (operand.IsOffset() && cond.IsNotNever() &&
  12068           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12069         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  12070         EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
  12071                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12072                 (sign_ << 23));
  12073         return;
  12074       }
  12075       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
  12076       if (operand.IsPostIndex() && cond.IsNotNever() &&
  12077           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12078         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  12079         EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
  12080                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12081                 (sign_ << 23));
  12082         return;
  12083       }
  12084       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
  12085       if (operand.IsPreIndex() && cond.IsNotNever() &&
  12086           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12087         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
  12088         EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
  12089                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12090                 (sign_ << 23));
  12091         return;
  12092       }
  12093     }
  12094   }
  12095   if (operand.IsShiftedRegister()) {
  12096     Register rn = operand.GetBaseRegister();
  12097     Sign sign = operand.GetSign();
  12098     Register rm = operand.GetOffsetRegister();
  12099     Shift shift = operand.GetShift();
  12100     uint32_t amount = operand.GetShiftAmount();
  12101     if (IsUsingT32()) {
  12102       // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
  12103       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
  12104           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
  12105           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12106         EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
  12107                    rm.GetCode() | (amount << 4));
  12108         AdvanceIT();
  12109         return;
  12110       }
  12111     }
  12112   }
  12113   Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
  12114 }
  12115 
  12116 void Assembler::sub(Condition cond,
  12117                     EncodingSize size,
  12118                     Register rd,
  12119                     Register rn,
  12120                     const Operand& operand) {
  12121   VIXL_ASSERT(AllowAssembler());
  12122   CheckIT(cond);
  12123   if (operand.IsImmediate()) {
  12124     uint32_t imm = operand.GetImmediate();
  12125     if (IsUsingT32()) {
  12126       ImmediateT32 immediate_t32(imm);
  12127       // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
  12128       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
  12129           (imm <= 7)) {
  12130         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
  12131         AdvanceIT();
  12132         return;
  12133       }
  12134       // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
  12135       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
  12136           (imm <= 255)) {
  12137         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
  12138         AdvanceIT();
  12139         return;
  12140       }
  12141       // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
  12142       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
  12143           ((imm % 4) == 0)) {
  12144         uint32_t imm_ = imm >> 2;
  12145         EmitT32_16(0xb080 | imm_);
  12146         AdvanceIT();
  12147         return;
  12148       }
  12149       // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
  12150       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
  12151           (!rd.IsPC() || AllowUnpredictable())) {
  12152         EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
  12153                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
  12154         AdvanceIT();
  12155         return;
  12156       }
  12157       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
  12158       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
  12159           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  12160         EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12161                    (immediate_t32.GetEncodingValue() & 0xff) |
  12162                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
  12163                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
  12164         AdvanceIT();
  12165         return;
  12166       }
  12167       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
  12168       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
  12169           (!rd.IsPC() || AllowUnpredictable())) {
  12170         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12171                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
  12172         AdvanceIT();
  12173         return;
  12174       }
  12175       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
  12176       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
  12177           (!rd.IsPC() || AllowUnpredictable())) {
  12178         EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
  12179                    (immediate_t32.GetEncodingValue() & 0xff) |
  12180                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
  12181                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
  12182         AdvanceIT();
  12183         return;
  12184       }
  12185       // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
  12186       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
  12187           (!rd.IsPC() || AllowUnpredictable())) {
  12188         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
  12189                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
  12190         AdvanceIT();
  12191         return;
  12192       }
  12193     } else {
  12194       ImmediateA32 immediate_a32(imm);
  12195       // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
  12196       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
  12197         EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
  12198                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
  12199         return;
  12200       }
  12201       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
  12202       if (immediate_a32.IsValid() && cond.IsNotNever() &&
  12203           ((rn.GetCode() & 0xd) != 0xd)) {
  12204         EmitA32(0x02400000U | (cond.GetCondition() << 28) |
  12205                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
  12206                 immediate_a32.GetEncodingValue());
  12207         return;
  12208       }
  12209       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
  12210       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
  12211         EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
  12212                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
  12213         return;
  12214       }
  12215     }
  12216   }
  12217   if (operand.IsImmediateShiftedRegister()) {
  12218     Register rm = operand.GetBaseRegister();
  12219     if (operand.IsPlainRegister()) {
  12220       if (IsUsingT32()) {
  12221         // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
  12222         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
  12223             rm.IsLow()) {
  12224           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
  12225                      (rm.GetCode() << 6));
  12226           AdvanceIT();
  12227           return;
  12228         }
  12229         // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
  12230         if (rn.Is(sp) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12231           EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
  12232           AdvanceIT();
  12233           return;
  12234         }
  12235       }
  12236     }
  12237     Shift shift = operand.GetShift();
  12238     uint32_t amount = operand.GetShiftAmount();
  12239     if (IsUsingT32()) {
  12240       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
  12241       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
  12242           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12243         uint32_t amount_ = amount % 32;
  12244         EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12245                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
  12246                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
  12247         AdvanceIT();
  12248         return;
  12249       }
  12250       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
  12251       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
  12252           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12253         uint32_t amount_ = amount % 32;
  12254         EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
  12255                    (operand.GetTypeEncodingValue() << 4) |
  12256                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
  12257         AdvanceIT();
  12258         return;
  12259       }
  12260     } else {
  12261       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
  12262       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
  12263         uint32_t amount_ = amount % 32;
  12264         EmitA32(0x00400000U | (cond.GetCondition() << 28) |
  12265                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12266                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
  12267         return;
  12268       }
  12269       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
  12270       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
  12271         uint32_t amount_ = amount % 32;
  12272         EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
  12273                 (rd.GetCode() << 12) | rm.GetCode() |
  12274                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
  12275         return;
  12276       }
  12277     }
  12278   }
  12279   if (operand.IsRegisterShiftedRegister()) {
  12280     Register rm = operand.GetBaseRegister();
  12281     Shift shift = operand.GetShift();
  12282     Register rs = operand.GetShiftRegister();
  12283     if (IsUsingA32()) {
  12284       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
  12285       if (cond.IsNotNever() &&
  12286           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
  12287            AllowUnpredictable())) {
  12288         EmitA32(0x00400010U | (cond.GetCondition() << 28) |
  12289                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12290                 (shift.GetType() << 5) | (rs.GetCode() << 8));
  12291         return;
  12292       }
  12293     }
  12294   }
  12295   Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
  12296 }
  12297 
  12298 void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
  12299   VIXL_ASSERT(AllowAssembler());
  12300   CheckIT(cond);
  12301   if (operand.IsImmediate()) {
  12302     uint32_t imm = operand.GetImmediate();
  12303     if (IsUsingT32()) {
  12304       // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
  12305       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
  12306         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
  12307         AdvanceIT();
  12308         return;
  12309       }
  12310     }
  12311   }
  12312   Delegate(kSub, &Assembler::sub, cond, rd, operand);
  12313 }
  12314 
  12315 void Assembler::subs(Condition cond,
  12316                      EncodingSize size,
  12317                      Register rd,
  12318                      Register rn,
  12319                      const Operand& operand) {
  12320   VIXL_ASSERT(AllowAssembler());
  12321   CheckIT(cond);
  12322   if (operand.IsImmediate()) {
  12323     uint32_t imm = operand.GetImmediate();
  12324     if (IsUsingT32()) {
  12325       ImmediateT32 immediate_t32(imm);
  12326       // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
  12327       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
  12328           (imm <= 7)) {
  12329         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
  12330         AdvanceIT();
  12331         return;
  12332       }
  12333       // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
  12334       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
  12335           (imm <= 255)) {
  12336         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
  12337         AdvanceIT();
  12338         return;
  12339       }
  12340       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
  12341       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
  12342           !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
  12343         EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12344                    (immediate_t32.GetEncodingValue() & 0xff) |
  12345                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
  12346                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
  12347         AdvanceIT();
  12348         return;
  12349       }
  12350       // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
  12351       if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255) &&
  12352           (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
  12353         EmitT32_32(0xf3de8f00U | imm);
  12354         AdvanceIT();
  12355         return;
  12356       }
  12357       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
  12358       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
  12359           !rd.Is(pc)) {
  12360         EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
  12361                    (immediate_t32.GetEncodingValue() & 0xff) |
  12362                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
  12363                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
  12364         AdvanceIT();
  12365         return;
  12366       }
  12367     } else {
  12368       ImmediateA32 immediate_a32(imm);
  12369       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
  12370       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
  12371         EmitA32(0x02500000U | (cond.GetCondition() << 28) |
  12372                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
  12373                 immediate_a32.GetEncodingValue());
  12374         return;
  12375       }
  12376       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
  12377       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
  12378         EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
  12379                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
  12380         return;
  12381       }
  12382     }
  12383   }
  12384   if (operand.IsImmediateShiftedRegister()) {
  12385     Register rm = operand.GetBaseRegister();
  12386     if (operand.IsPlainRegister()) {
  12387       if (IsUsingT32()) {
  12388         // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  12389         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
  12390             rm.IsLow()) {
  12391           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
  12392                      (rm.GetCode() << 6));
  12393           AdvanceIT();
  12394           return;
  12395         }
  12396       }
  12397     }
  12398     Shift shift = operand.GetShift();
  12399     uint32_t amount = operand.GetShiftAmount();
  12400     if (IsUsingT32()) {
  12401       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
  12402       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
  12403           !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12404         uint32_t amount_ = amount % 32;
  12405         EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12406                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
  12407                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
  12408         AdvanceIT();
  12409         return;
  12410       }
  12411       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
  12412       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
  12413           !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
  12414         uint32_t amount_ = amount % 32;
  12415         EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
  12416                    (operand.GetTypeEncodingValue() << 4) |
  12417                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
  12418         AdvanceIT();
  12419         return;
  12420       }
  12421     } else {
  12422       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
  12423       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
  12424         uint32_t amount_ = amount % 32;
  12425         EmitA32(0x00500000U | (cond.GetCondition() << 28) |
  12426                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12427                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
  12428         return;
  12429       }
  12430       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
  12431       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
  12432         uint32_t amount_ = amount % 32;
  12433         EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
  12434                 (rd.GetCode() << 12) | rm.GetCode() |
  12435                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
  12436         return;
  12437       }
  12438     }
  12439   }
  12440   if (operand.IsRegisterShiftedRegister()) {
  12441     Register rm = operand.GetBaseRegister();
  12442     Shift shift = operand.GetShift();
  12443     Register rs = operand.GetShiftRegister();
  12444     if (IsUsingA32()) {
  12445       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
  12446       if (cond.IsNotNever() &&
  12447           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
  12448            AllowUnpredictable())) {
  12449         EmitA32(0x00500010U | (cond.GetCondition() << 28) |
  12450                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12451                 (shift.GetType() << 5) | (rs.GetCode() << 8));
  12452         return;
  12453       }
  12454     }
  12455   }
  12456   Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
  12457 }
  12458 
  12459 void Assembler::subs(Register rd, const Operand& operand) {
  12460   VIXL_ASSERT(AllowAssembler());
  12461   CheckIT(al);
  12462   if (operand.IsImmediate()) {
  12463     uint32_t imm = operand.GetImmediate();
  12464     if (IsUsingT32()) {
  12465       // SUBS{<q>} <Rdn>, #<imm8> ; T2
  12466       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
  12467         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
  12468         AdvanceIT();
  12469         return;
  12470       }
  12471     }
  12472   }
  12473   Delegate(kSubs, &Assembler::subs, rd, operand);
  12474 }
  12475 
  12476 void Assembler::subw(Condition cond,
  12477                      Register rd,
  12478                      Register rn,
  12479                      const Operand& operand) {
  12480   VIXL_ASSERT(AllowAssembler());
  12481   CheckIT(cond);
  12482   if (operand.IsImmediate()) {
  12483     uint32_t imm = operand.GetImmediate();
  12484     if (IsUsingT32()) {
  12485       // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
  12486       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
  12487           (!rd.IsPC() || AllowUnpredictable())) {
  12488         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12489                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
  12490         AdvanceIT();
  12491         return;
  12492       }
  12493       // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
  12494       if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
  12495         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
  12496                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
  12497         AdvanceIT();
  12498         return;
  12499       }
  12500     }
  12501   }
  12502   Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
  12503 }
  12504 
  12505 void Assembler::svc(Condition cond, uint32_t imm) {
  12506   VIXL_ASSERT(AllowAssembler());
  12507   CheckIT(cond);
  12508   if (IsUsingT32()) {
  12509     // SVC{<c>}{<q>} {#}<imm> ; T1
  12510     if ((imm <= 255)) {
  12511       EmitT32_16(0xdf00 | imm);
  12512       AdvanceIT();
  12513       return;
  12514     }
  12515   } else {
  12516     // SVC{<c>}{<q>} {#}<imm> ; A1
  12517     if ((imm <= 16777215) && cond.IsNotNever()) {
  12518       EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
  12519       return;
  12520     }
  12521   }
  12522   Delegate(kSvc, &Assembler::svc, cond, imm);
  12523 }
  12524 
  12525 void Assembler::sxtab(Condition cond,
  12526                       Register rd,
  12527                       Register rn,
  12528                       const Operand& operand) {
  12529   VIXL_ASSERT(AllowAssembler());
  12530   CheckIT(cond);
  12531   if (operand.IsImmediateShiftedRegister()) {
  12532     Register rm = operand.GetBaseRegister();
  12533     Shift shift = operand.GetShift();
  12534     uint32_t amount = operand.GetShiftAmount();
  12535     if (IsUsingT32()) {
  12536       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
  12537       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12538           ((amount % 8) == 0) && !rn.Is(pc) &&
  12539           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12540         uint32_t amount_ = amount / 8;
  12541         EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12542                    rm.GetCode() | (amount_ << 4));
  12543         AdvanceIT();
  12544         return;
  12545       }
  12546     } else {
  12547       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
  12548       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12549           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
  12550           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12551         uint32_t amount_ = amount / 8;
  12552         EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
  12553                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12554                 (amount_ << 10));
  12555         return;
  12556       }
  12557     }
  12558   }
  12559   Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
  12560 }
  12561 
  12562 void Assembler::sxtab16(Condition cond,
  12563                         Register rd,
  12564                         Register rn,
  12565                         const Operand& operand) {
  12566   VIXL_ASSERT(AllowAssembler());
  12567   CheckIT(cond);
  12568   if (operand.IsImmediateShiftedRegister()) {
  12569     Register rm = operand.GetBaseRegister();
  12570     Shift shift = operand.GetShift();
  12571     uint32_t amount = operand.GetShiftAmount();
  12572     if (IsUsingT32()) {
  12573       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
  12574       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12575           ((amount % 8) == 0) && !rn.Is(pc) &&
  12576           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12577         uint32_t amount_ = amount / 8;
  12578         EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12579                    rm.GetCode() | (amount_ << 4));
  12580         AdvanceIT();
  12581         return;
  12582       }
  12583     } else {
  12584       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
  12585       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12586           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
  12587           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12588         uint32_t amount_ = amount / 8;
  12589         EmitA32(0x06800070U | (cond.GetCondition() << 28) |
  12590                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12591                 (amount_ << 10));
  12592         return;
  12593       }
  12594     }
  12595   }
  12596   Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
  12597 }
  12598 
  12599 void Assembler::sxtah(Condition cond,
  12600                       Register rd,
  12601                       Register rn,
  12602                       const Operand& operand) {
  12603   VIXL_ASSERT(AllowAssembler());
  12604   CheckIT(cond);
  12605   if (operand.IsImmediateShiftedRegister()) {
  12606     Register rm = operand.GetBaseRegister();
  12607     Shift shift = operand.GetShift();
  12608     uint32_t amount = operand.GetShiftAmount();
  12609     if (IsUsingT32()) {
  12610       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
  12611       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12612           ((amount % 8) == 0) && !rn.Is(pc) &&
  12613           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12614         uint32_t amount_ = amount / 8;
  12615         EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12616                    rm.GetCode() | (amount_ << 4));
  12617         AdvanceIT();
  12618         return;
  12619       }
  12620     } else {
  12621       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
  12622       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12623           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
  12624           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12625         uint32_t amount_ = amount / 8;
  12626         EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
  12627                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  12628                 (amount_ << 10));
  12629         return;
  12630       }
  12631     }
  12632   }
  12633   Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
  12634 }
  12635 
  12636 void Assembler::sxtb(Condition cond,
  12637                      EncodingSize size,
  12638                      Register rd,
  12639                      const Operand& operand) {
  12640   VIXL_ASSERT(AllowAssembler());
  12641   CheckIT(cond);
  12642   if (operand.IsImmediateShiftedRegister()) {
  12643     Register rm = operand.GetBaseRegister();
  12644     if (operand.IsPlainRegister()) {
  12645       if (IsUsingT32()) {
  12646         // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
  12647         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
  12648           EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
  12649           AdvanceIT();
  12650           return;
  12651         }
  12652       }
  12653     }
  12654     Shift shift = operand.GetShift();
  12655     uint32_t amount = operand.GetShiftAmount();
  12656     if (IsUsingT32()) {
  12657       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
  12658       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
  12659           (amount <= 24) && ((amount % 8) == 0) &&
  12660           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12661         uint32_t amount_ = amount / 8;
  12662         EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
  12663                    (amount_ << 4));
  12664         AdvanceIT();
  12665         return;
  12666       }
  12667     } else {
  12668       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
  12669       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12670           ((amount % 8) == 0) && cond.IsNotNever() &&
  12671           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12672         uint32_t amount_ = amount / 8;
  12673         EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
  12674                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
  12675         return;
  12676       }
  12677     }
  12678   }
  12679   Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
  12680 }
  12681 
  12682 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
  12683   VIXL_ASSERT(AllowAssembler());
  12684   CheckIT(cond);
  12685   if (operand.IsImmediateShiftedRegister()) {
  12686     Register rm = operand.GetBaseRegister();
  12687     Shift shift = operand.GetShift();
  12688     uint32_t amount = operand.GetShiftAmount();
  12689     if (IsUsingT32()) {
  12690       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
  12691       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12692           ((amount % 8) == 0) &&
  12693           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12694         uint32_t amount_ = amount / 8;
  12695         EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
  12696                    (amount_ << 4));
  12697         AdvanceIT();
  12698         return;
  12699       }
  12700     } else {
  12701       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
  12702       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12703           ((amount % 8) == 0) && cond.IsNotNever() &&
  12704           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12705         uint32_t amount_ = amount / 8;
  12706         EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
  12707                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
  12708         return;
  12709       }
  12710     }
  12711   }
  12712   Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
  12713 }
  12714 
  12715 void Assembler::sxth(Condition cond,
  12716                      EncodingSize size,
  12717                      Register rd,
  12718                      const Operand& operand) {
  12719   VIXL_ASSERT(AllowAssembler());
  12720   CheckIT(cond);
  12721   if (operand.IsImmediateShiftedRegister()) {
  12722     Register rm = operand.GetBaseRegister();
  12723     if (operand.IsPlainRegister()) {
  12724       if (IsUsingT32()) {
  12725         // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
  12726         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
  12727           EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
  12728           AdvanceIT();
  12729           return;
  12730         }
  12731       }
  12732     }
  12733     Shift shift = operand.GetShift();
  12734     uint32_t amount = operand.GetShiftAmount();
  12735     if (IsUsingT32()) {
  12736       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
  12737       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
  12738           (amount <= 24) && ((amount % 8) == 0) &&
  12739           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12740         uint32_t amount_ = amount / 8;
  12741         EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
  12742                    (amount_ << 4));
  12743         AdvanceIT();
  12744         return;
  12745       }
  12746     } else {
  12747       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
  12748       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  12749           ((amount % 8) == 0) && cond.IsNotNever() &&
  12750           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12751         uint32_t amount_ = amount / 8;
  12752         EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
  12753                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
  12754         return;
  12755       }
  12756     }
  12757   }
  12758   Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
  12759 }
  12760 
  12761 void Assembler::tbb(Condition cond, Register rn, Register rm) {
  12762   VIXL_ASSERT(AllowAssembler());
  12763   CheckIT(cond);
  12764   if (IsUsingT32()) {
  12765     // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
  12766     if (OutsideITBlockAndAlOrLast(cond) &&
  12767         (!rm.IsPC() || AllowUnpredictable())) {
  12768       EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
  12769       AdvanceIT();
  12770       return;
  12771     }
  12772   }
  12773   Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
  12774 }
  12775 
  12776 void Assembler::tbh(Condition cond, Register rn, Register rm) {
  12777   VIXL_ASSERT(AllowAssembler());
  12778   CheckIT(cond);
  12779   if (IsUsingT32()) {
  12780     // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
  12781     if (OutsideITBlockAndAlOrLast(cond) &&
  12782         (!rm.IsPC() || AllowUnpredictable())) {
  12783       EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
  12784       AdvanceIT();
  12785       return;
  12786     }
  12787   }
  12788   Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
  12789 }
  12790 
  12791 void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
  12792   VIXL_ASSERT(AllowAssembler());
  12793   CheckIT(cond);
  12794   if (operand.IsImmediate()) {
  12795     uint32_t imm = operand.GetImmediate();
  12796     if (IsUsingT32()) {
  12797       ImmediateT32 immediate_t32(imm);
  12798       // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
  12799       if (immediate_t32.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  12800         EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
  12801                    (immediate_t32.GetEncodingValue() & 0xff) |
  12802                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
  12803                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
  12804         AdvanceIT();
  12805         return;
  12806       }
  12807     } else {
  12808       ImmediateA32 immediate_a32(imm);
  12809       // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
  12810       if (immediate_a32.IsValid() && cond.IsNotNever()) {
  12811         EmitA32(0x03300000U | (cond.GetCondition() << 28) |
  12812                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
  12813         return;
  12814       }
  12815     }
  12816   }
  12817   if (operand.IsImmediateShiftedRegister()) {
  12818     Register rm = operand.GetBaseRegister();
  12819     Shift shift = operand.GetShift();
  12820     uint32_t amount = operand.GetShiftAmount();
  12821     if (IsUsingT32()) {
  12822       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
  12823       if (shift.IsValidAmount(amount) &&
  12824           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12825         uint32_t amount_ = amount % 32;
  12826         EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
  12827                    (operand.GetTypeEncodingValue() << 4) |
  12828                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
  12829         AdvanceIT();
  12830         return;
  12831       }
  12832     } else {
  12833       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
  12834       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
  12835         uint32_t amount_ = amount % 32;
  12836         EmitA32(0x01300000U | (cond.GetCondition() << 28) |
  12837                 (rn.GetCode() << 16) | rm.GetCode() |
  12838                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
  12839         return;
  12840       }
  12841     }
  12842   }
  12843   if (operand.IsRegisterShiftedRegister()) {
  12844     Register rm = operand.GetBaseRegister();
  12845     Shift shift = operand.GetShift();
  12846     Register rs = operand.GetShiftRegister();
  12847     if (IsUsingA32()) {
  12848       // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
  12849       if (cond.IsNotNever() &&
  12850           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
  12851         EmitA32(0x01300010U | (cond.GetCondition() << 28) |
  12852                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
  12853                 (rs.GetCode() << 8));
  12854         return;
  12855       }
  12856     }
  12857   }
  12858   Delegate(kTeq, &Assembler::teq, cond, rn, operand);
  12859 }
  12860 
  12861 void Assembler::tst(Condition cond,
  12862                     EncodingSize size,
  12863                     Register rn,
  12864                     const Operand& operand) {
  12865   VIXL_ASSERT(AllowAssembler());
  12866   CheckIT(cond);
  12867   if (operand.IsImmediate()) {
  12868     uint32_t imm = operand.GetImmediate();
  12869     if (IsUsingT32()) {
  12870       ImmediateT32 immediate_t32(imm);
  12871       // TST{<c>}{<q>} <Rn>, #<const> ; T1
  12872       if (!size.IsNarrow() && immediate_t32.IsValid() &&
  12873           (!rn.IsPC() || AllowUnpredictable())) {
  12874         EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
  12875                    (immediate_t32.GetEncodingValue() & 0xff) |
  12876                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
  12877                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
  12878         AdvanceIT();
  12879         return;
  12880       }
  12881     } else {
  12882       ImmediateA32 immediate_a32(imm);
  12883       // TST{<c>}{<q>} <Rn>, #<const> ; A1
  12884       if (immediate_a32.IsValid() && cond.IsNotNever()) {
  12885         EmitA32(0x03100000U | (cond.GetCondition() << 28) |
  12886                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
  12887         return;
  12888       }
  12889     }
  12890   }
  12891   if (operand.IsImmediateShiftedRegister()) {
  12892     Register rm = operand.GetBaseRegister();
  12893     if (operand.IsPlainRegister()) {
  12894       if (IsUsingT32()) {
  12895         // TST{<c>}{<q>} <Rn>, <Rm> ; T1
  12896         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
  12897           EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
  12898           AdvanceIT();
  12899           return;
  12900         }
  12901       }
  12902     }
  12903     Shift shift = operand.GetShift();
  12904     uint32_t amount = operand.GetShiftAmount();
  12905     if (IsUsingT32()) {
  12906       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
  12907       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
  12908           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12909         uint32_t amount_ = amount % 32;
  12910         EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
  12911                    (operand.GetTypeEncodingValue() << 4) |
  12912                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
  12913         AdvanceIT();
  12914         return;
  12915       }
  12916     } else {
  12917       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
  12918       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
  12919         uint32_t amount_ = amount % 32;
  12920         EmitA32(0x01100000U | (cond.GetCondition() << 28) |
  12921                 (rn.GetCode() << 16) | rm.GetCode() |
  12922                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
  12923         return;
  12924       }
  12925     }
  12926   }
  12927   if (operand.IsRegisterShiftedRegister()) {
  12928     Register rm = operand.GetBaseRegister();
  12929     Shift shift = operand.GetShift();
  12930     Register rs = operand.GetShiftRegister();
  12931     if (IsUsingA32()) {
  12932       // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
  12933       if (cond.IsNotNever() &&
  12934           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
  12935         EmitA32(0x01100010U | (cond.GetCondition() << 28) |
  12936                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
  12937                 (rs.GetCode() << 8));
  12938         return;
  12939       }
  12940     }
  12941   }
  12942   Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
  12943 }
  12944 
  12945 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
  12946   VIXL_ASSERT(AllowAssembler());
  12947   CheckIT(cond);
  12948   if (IsUsingT32()) {
  12949     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  12950     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12951       EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12952                  rm.GetCode());
  12953       AdvanceIT();
  12954       return;
  12955     }
  12956   } else {
  12957     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  12958     if (cond.IsNotNever() &&
  12959         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12960       EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  12961               (rn.GetCode() << 16) | rm.GetCode());
  12962       return;
  12963     }
  12964   }
  12965   Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
  12966 }
  12967 
  12968 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
  12969   VIXL_ASSERT(AllowAssembler());
  12970   CheckIT(cond);
  12971   if (IsUsingT32()) {
  12972     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  12973     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12974       EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12975                  rm.GetCode());
  12976       AdvanceIT();
  12977       return;
  12978     }
  12979   } else {
  12980     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  12981     if (cond.IsNotNever() &&
  12982         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12983       EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  12984               (rn.GetCode() << 16) | rm.GetCode());
  12985       return;
  12986     }
  12987   }
  12988   Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
  12989 }
  12990 
  12991 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
  12992   VIXL_ASSERT(AllowAssembler());
  12993   CheckIT(cond);
  12994   if (IsUsingT32()) {
  12995     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  12996     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  12997       EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  12998                  rm.GetCode());
  12999       AdvanceIT();
  13000       return;
  13001     }
  13002   } else {
  13003     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13004     if (cond.IsNotNever() &&
  13005         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13006       EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13007               (rn.GetCode() << 16) | rm.GetCode());
  13008       return;
  13009     }
  13010   }
  13011   Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
  13012 }
  13013 
  13014 void Assembler::ubfx(
  13015     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
  13016   VIXL_ASSERT(AllowAssembler());
  13017   CheckIT(cond);
  13018   if (IsUsingT32()) {
  13019     // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
  13020     if ((lsb <= 31) &&
  13021         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
  13022          AllowUnpredictable())) {
  13023       uint32_t widthm1 = width - 1;
  13024       EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13025                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
  13026       AdvanceIT();
  13027       return;
  13028     }
  13029   } else {
  13030     // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
  13031     if ((lsb <= 31) && cond.IsNotNever() &&
  13032         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
  13033          AllowUnpredictable())) {
  13034       uint32_t widthm1 = width - 1;
  13035       EmitA32(0x07e00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13036               rn.GetCode() | (lsb << 7) | (widthm1 << 16));
  13037       return;
  13038     }
  13039   }
  13040   Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, width);
  13041 }
  13042 
  13043 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
  13044   VIXL_ASSERT(AllowAssembler());
  13045   CheckIT(cond);
  13046   if (IsUsingT32()) {
  13047     // UDF{<c>}{<q>} {#}<imm> ; T1
  13048     if (!size.IsWide() && (imm <= 255)) {
  13049       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  13050         EmitT32_16(0xde00 | imm);
  13051         AdvanceIT();
  13052         return;
  13053       }
  13054     }
  13055     // UDF{<c>}{<q>} {#}<imm> ; T2
  13056     if (!size.IsNarrow() && (imm <= 65535)) {
  13057       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  13058         EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
  13059         AdvanceIT();
  13060         return;
  13061       }
  13062     }
  13063   } else {
  13064     // UDF{<c>}{<q>} {#}<imm> ; A1
  13065     if ((imm <= 65535)) {
  13066       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  13067         EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
  13068         return;
  13069       }
  13070     }
  13071   }
  13072   Delegate(kUdf, &Assembler::udf, cond, size, imm);
  13073 }
  13074 
  13075 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
  13076   VIXL_ASSERT(AllowAssembler());
  13077   CheckIT(cond);
  13078   if (IsUsingT32()) {
  13079     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13080     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13081       EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13082                  rm.GetCode());
  13083       AdvanceIT();
  13084       return;
  13085     }
  13086   } else {
  13087     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13088     if (cond.IsNotNever() &&
  13089         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13090       EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  13091               rn.GetCode() | (rm.GetCode() << 8));
  13092       return;
  13093     }
  13094   }
  13095   Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
  13096 }
  13097 
  13098 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
  13099   VIXL_ASSERT(AllowAssembler());
  13100   CheckIT(cond);
  13101   if (IsUsingT32()) {
  13102     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13103     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13104       EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13105                  rm.GetCode());
  13106       AdvanceIT();
  13107       return;
  13108     }
  13109   } else {
  13110     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13111     if (cond.IsNotNever() &&
  13112         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13113       EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13114               (rn.GetCode() << 16) | rm.GetCode());
  13115       return;
  13116     }
  13117   }
  13118   Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
  13119 }
  13120 
  13121 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
  13122   VIXL_ASSERT(AllowAssembler());
  13123   CheckIT(cond);
  13124   if (IsUsingT32()) {
  13125     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13126     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13127       EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13128                  rm.GetCode());
  13129       AdvanceIT();
  13130       return;
  13131     }
  13132   } else {
  13133     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13134     if (cond.IsNotNever() &&
  13135         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13136       EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13137               (rn.GetCode() << 16) | rm.GetCode());
  13138       return;
  13139     }
  13140   }
  13141   Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
  13142 }
  13143 
  13144 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
  13145   VIXL_ASSERT(AllowAssembler());
  13146   CheckIT(cond);
  13147   if (IsUsingT32()) {
  13148     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13149     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13150       EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13151                  rm.GetCode());
  13152       AdvanceIT();
  13153       return;
  13154     }
  13155   } else {
  13156     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13157     if (cond.IsNotNever() &&
  13158         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13159       EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13160               (rn.GetCode() << 16) | rm.GetCode());
  13161       return;
  13162     }
  13163   }
  13164   Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
  13165 }
  13166 
  13167 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
  13168   VIXL_ASSERT(AllowAssembler());
  13169   CheckIT(cond);
  13170   if (IsUsingT32()) {
  13171     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13172     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13173       EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13174                  rm.GetCode());
  13175       AdvanceIT();
  13176       return;
  13177     }
  13178   } else {
  13179     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13180     if (cond.IsNotNever() &&
  13181         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13182       EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13183               (rn.GetCode() << 16) | rm.GetCode());
  13184       return;
  13185     }
  13186   }
  13187   Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
  13188 }
  13189 
  13190 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
  13191   VIXL_ASSERT(AllowAssembler());
  13192   CheckIT(cond);
  13193   if (IsUsingT32()) {
  13194     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13195     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13196       EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13197                  rm.GetCode());
  13198       AdvanceIT();
  13199       return;
  13200     }
  13201   } else {
  13202     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13203     if (cond.IsNotNever() &&
  13204         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13205       EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13206               (rn.GetCode() << 16) | rm.GetCode());
  13207       return;
  13208     }
  13209   }
  13210   Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
  13211 }
  13212 
  13213 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
  13214   VIXL_ASSERT(AllowAssembler());
  13215   CheckIT(cond);
  13216   if (IsUsingT32()) {
  13217     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13218     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13219       EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13220                  rm.GetCode());
  13221       AdvanceIT();
  13222       return;
  13223     }
  13224   } else {
  13225     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13226     if (cond.IsNotNever() &&
  13227         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13228       EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13229               (rn.GetCode() << 16) | rm.GetCode());
  13230       return;
  13231     }
  13232   }
  13233   Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
  13234 }
  13235 
  13236 void Assembler::umaal(
  13237     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  13238   VIXL_ASSERT(AllowAssembler());
  13239   CheckIT(cond);
  13240   if (IsUsingT32()) {
  13241     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  13242     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  13243          AllowUnpredictable())) {
  13244       EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  13245                  (rn.GetCode() << 16) | rm.GetCode());
  13246       AdvanceIT();
  13247       return;
  13248     }
  13249   } else {
  13250     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  13251     if (cond.IsNotNever() &&
  13252         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  13253          AllowUnpredictable())) {
  13254       EmitA32(0x00400090U | (cond.GetCondition() << 28) |
  13255               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  13256               (rm.GetCode() << 8));
  13257       return;
  13258     }
  13259   }
  13260   Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
  13261 }
  13262 
  13263 void Assembler::umlal(
  13264     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  13265   VIXL_ASSERT(AllowAssembler());
  13266   CheckIT(cond);
  13267   if (IsUsingT32()) {
  13268     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  13269     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  13270          AllowUnpredictable())) {
  13271       EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  13272                  (rn.GetCode() << 16) | rm.GetCode());
  13273       AdvanceIT();
  13274       return;
  13275     }
  13276   } else {
  13277     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  13278     if (cond.IsNotNever() &&
  13279         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  13280          AllowUnpredictable())) {
  13281       EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
  13282               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  13283               (rm.GetCode() << 8));
  13284       return;
  13285     }
  13286   }
  13287   Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
  13288 }
  13289 
  13290 void Assembler::umlals(
  13291     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  13292   VIXL_ASSERT(AllowAssembler());
  13293   CheckIT(cond);
  13294   if (IsUsingA32()) {
  13295     // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  13296     if (cond.IsNotNever() &&
  13297         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  13298          AllowUnpredictable())) {
  13299       EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
  13300               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  13301               (rm.GetCode() << 8));
  13302       return;
  13303     }
  13304   }
  13305   Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
  13306 }
  13307 
  13308 void Assembler::umull(
  13309     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  13310   VIXL_ASSERT(AllowAssembler());
  13311   CheckIT(cond);
  13312   if (IsUsingT32()) {
  13313     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
  13314     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  13315          AllowUnpredictable())) {
  13316       EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
  13317                  (rn.GetCode() << 16) | rm.GetCode());
  13318       AdvanceIT();
  13319       return;
  13320     }
  13321   } else {
  13322     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  13323     if (cond.IsNotNever() &&
  13324         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  13325          AllowUnpredictable())) {
  13326       EmitA32(0x00800090U | (cond.GetCondition() << 28) |
  13327               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  13328               (rm.GetCode() << 8));
  13329       return;
  13330     }
  13331   }
  13332   Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
  13333 }
  13334 
  13335 void Assembler::umulls(
  13336     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
  13337   VIXL_ASSERT(AllowAssembler());
  13338   CheckIT(cond);
  13339   if (IsUsingA32()) {
  13340     // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
  13341     if (cond.IsNotNever() &&
  13342         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
  13343          AllowUnpredictable())) {
  13344       EmitA32(0x00900090U | (cond.GetCondition() << 28) |
  13345               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
  13346               (rm.GetCode() << 8));
  13347       return;
  13348     }
  13349   }
  13350   Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
  13351 }
  13352 
  13353 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
  13354   VIXL_ASSERT(AllowAssembler());
  13355   CheckIT(cond);
  13356   if (IsUsingT32()) {
  13357     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13358     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13359       EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13360                  rm.GetCode());
  13361       AdvanceIT();
  13362       return;
  13363     }
  13364   } else {
  13365     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13366     if (cond.IsNotNever() &&
  13367         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13368       EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13369               (rn.GetCode() << 16) | rm.GetCode());
  13370       return;
  13371     }
  13372   }
  13373   Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
  13374 }
  13375 
  13376 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
  13377   VIXL_ASSERT(AllowAssembler());
  13378   CheckIT(cond);
  13379   if (IsUsingT32()) {
  13380     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13381     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13382       EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13383                  rm.GetCode());
  13384       AdvanceIT();
  13385       return;
  13386     }
  13387   } else {
  13388     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13389     if (cond.IsNotNever() &&
  13390         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13391       EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13392               (rn.GetCode() << 16) | rm.GetCode());
  13393       return;
  13394     }
  13395   }
  13396   Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
  13397 }
  13398 
  13399 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
  13400   VIXL_ASSERT(AllowAssembler());
  13401   CheckIT(cond);
  13402   if (IsUsingT32()) {
  13403     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13404     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13405       EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13406                  rm.GetCode());
  13407       AdvanceIT();
  13408       return;
  13409     }
  13410   } else {
  13411     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13412     if (cond.IsNotNever() &&
  13413         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13414       EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13415               (rn.GetCode() << 16) | rm.GetCode());
  13416       return;
  13417     }
  13418   }
  13419   Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
  13420 }
  13421 
  13422 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
  13423   VIXL_ASSERT(AllowAssembler());
  13424   CheckIT(cond);
  13425   if (IsUsingT32()) {
  13426     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13427     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13428       EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13429                  rm.GetCode());
  13430       AdvanceIT();
  13431       return;
  13432     }
  13433   } else {
  13434     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13435     if (cond.IsNotNever() &&
  13436         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13437       EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13438               (rn.GetCode() << 16) | rm.GetCode());
  13439       return;
  13440     }
  13441   }
  13442   Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
  13443 }
  13444 
  13445 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
  13446   VIXL_ASSERT(AllowAssembler());
  13447   CheckIT(cond);
  13448   if (IsUsingT32()) {
  13449     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13450     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13451       EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13452                  rm.GetCode());
  13453       AdvanceIT();
  13454       return;
  13455     }
  13456   } else {
  13457     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13458     if (cond.IsNotNever() &&
  13459         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13460       EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13461               (rn.GetCode() << 16) | rm.GetCode());
  13462       return;
  13463     }
  13464   }
  13465   Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
  13466 }
  13467 
  13468 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
  13469   VIXL_ASSERT(AllowAssembler());
  13470   CheckIT(cond);
  13471   if (IsUsingT32()) {
  13472     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13473     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13474       EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13475                  rm.GetCode());
  13476       AdvanceIT();
  13477       return;
  13478     }
  13479   } else {
  13480     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13481     if (cond.IsNotNever() &&
  13482         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13483       EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13484               (rn.GetCode() << 16) | rm.GetCode());
  13485       return;
  13486     }
  13487   }
  13488   Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
  13489 }
  13490 
  13491 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
  13492   VIXL_ASSERT(AllowAssembler());
  13493   CheckIT(cond);
  13494   if (IsUsingT32()) {
  13495     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13496     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13497       EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13498                  rm.GetCode());
  13499       AdvanceIT();
  13500       return;
  13501     }
  13502   } else {
  13503     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13504     if (cond.IsNotNever() &&
  13505         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13506       EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  13507               rn.GetCode() | (rm.GetCode() << 8));
  13508       return;
  13509     }
  13510   }
  13511   Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
  13512 }
  13513 
  13514 void Assembler::usada8(
  13515     Condition cond, Register rd, Register rn, Register rm, Register ra) {
  13516   VIXL_ASSERT(AllowAssembler());
  13517   CheckIT(cond);
  13518   if (IsUsingT32()) {
  13519     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
  13520     if (!ra.Is(pc) &&
  13521         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13522       EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13523                  rm.GetCode() | (ra.GetCode() << 12));
  13524       AdvanceIT();
  13525       return;
  13526     }
  13527   } else {
  13528     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
  13529     if (cond.IsNotNever() && !ra.Is(pc) &&
  13530         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13531       EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
  13532               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
  13533       return;
  13534     }
  13535   }
  13536   Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
  13537 }
  13538 
  13539 void Assembler::usat(Condition cond,
  13540                      Register rd,
  13541                      uint32_t imm,
  13542                      const Operand& operand) {
  13543   VIXL_ASSERT(AllowAssembler());
  13544   CheckIT(cond);
  13545   if (operand.IsImmediateShiftedRegister()) {
  13546     Register rn = operand.GetBaseRegister();
  13547     Shift shift = operand.GetShift();
  13548     uint32_t amount = operand.GetShiftAmount();
  13549     if (IsUsingT32()) {
  13550       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
  13551       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31) &&
  13552           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  13553         EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
  13554                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
  13555                    ((amount & 0x1c) << 10));
  13556         AdvanceIT();
  13557         return;
  13558       }
  13559       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
  13560       if ((imm <= 31) && shift.IsLSL() && (amount <= 31) &&
  13561           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  13562         EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
  13563                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
  13564                    ((amount & 0x1c) << 10));
  13565         AdvanceIT();
  13566         return;
  13567       }
  13568     } else {
  13569       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
  13570       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
  13571           cond.IsNotNever() &&
  13572           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  13573         uint32_t amount_ = amount % 32;
  13574         EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
  13575                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
  13576                 (amount_ << 7));
  13577         return;
  13578       }
  13579       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
  13580       if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever() &&
  13581           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  13582         EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
  13583                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
  13584                 (amount << 7));
  13585         return;
  13586       }
  13587     }
  13588   }
  13589   Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
  13590 }
  13591 
  13592 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
  13593   VIXL_ASSERT(AllowAssembler());
  13594   CheckIT(cond);
  13595   if (IsUsingT32()) {
  13596     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
  13597     if ((imm <= 15) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  13598       EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
  13599                  (rn.GetCode() << 16));
  13600       AdvanceIT();
  13601       return;
  13602     }
  13603   } else {
  13604     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
  13605     if ((imm <= 15) && cond.IsNotNever() &&
  13606         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
  13607       EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13608               (imm << 16) | rn.GetCode());
  13609       return;
  13610     }
  13611   }
  13612   Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
  13613 }
  13614 
  13615 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
  13616   VIXL_ASSERT(AllowAssembler());
  13617   CheckIT(cond);
  13618   if (IsUsingT32()) {
  13619     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13620     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13621       EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13622                  rm.GetCode());
  13623       AdvanceIT();
  13624       return;
  13625     }
  13626   } else {
  13627     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13628     if (cond.IsNotNever() &&
  13629         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13630       EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13631               (rn.GetCode() << 16) | rm.GetCode());
  13632       return;
  13633     }
  13634   }
  13635   Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
  13636 }
  13637 
  13638 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
  13639   VIXL_ASSERT(AllowAssembler());
  13640   CheckIT(cond);
  13641   if (IsUsingT32()) {
  13642     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13643     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13644       EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13645                  rm.GetCode());
  13646       AdvanceIT();
  13647       return;
  13648     }
  13649   } else {
  13650     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13651     if (cond.IsNotNever() &&
  13652         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13653       EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13654               (rn.GetCode() << 16) | rm.GetCode());
  13655       return;
  13656     }
  13657   }
  13658   Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
  13659 }
  13660 
  13661 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
  13662   VIXL_ASSERT(AllowAssembler());
  13663   CheckIT(cond);
  13664   if (IsUsingT32()) {
  13665     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
  13666     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13667       EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13668                  rm.GetCode());
  13669       AdvanceIT();
  13670       return;
  13671     }
  13672   } else {
  13673     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
  13674     if (cond.IsNotNever() &&
  13675         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13676       EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
  13677               (rn.GetCode() << 16) | rm.GetCode());
  13678       return;
  13679     }
  13680   }
  13681   Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
  13682 }
  13683 
  13684 void Assembler::uxtab(Condition cond,
  13685                       Register rd,
  13686                       Register rn,
  13687                       const Operand& operand) {
  13688   VIXL_ASSERT(AllowAssembler());
  13689   CheckIT(cond);
  13690   if (operand.IsImmediateShiftedRegister()) {
  13691     Register rm = operand.GetBaseRegister();
  13692     Shift shift = operand.GetShift();
  13693     uint32_t amount = operand.GetShiftAmount();
  13694     if (IsUsingT32()) {
  13695       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
  13696       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13697           ((amount % 8) == 0) && !rn.Is(pc) &&
  13698           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13699         uint32_t amount_ = amount / 8;
  13700         EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13701                    rm.GetCode() | (amount_ << 4));
  13702         AdvanceIT();
  13703         return;
  13704       }
  13705     } else {
  13706       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
  13707       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13708           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
  13709           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13710         uint32_t amount_ = amount / 8;
  13711         EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
  13712                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  13713                 (amount_ << 10));
  13714         return;
  13715       }
  13716     }
  13717   }
  13718   Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
  13719 }
  13720 
  13721 void Assembler::uxtab16(Condition cond,
  13722                         Register rd,
  13723                         Register rn,
  13724                         const Operand& operand) {
  13725   VIXL_ASSERT(AllowAssembler());
  13726   CheckIT(cond);
  13727   if (operand.IsImmediateShiftedRegister()) {
  13728     Register rm = operand.GetBaseRegister();
  13729     Shift shift = operand.GetShift();
  13730     uint32_t amount = operand.GetShiftAmount();
  13731     if (IsUsingT32()) {
  13732       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
  13733       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13734           ((amount % 8) == 0) && !rn.Is(pc) &&
  13735           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13736         uint32_t amount_ = amount / 8;
  13737         EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13738                    rm.GetCode() | (amount_ << 4));
  13739         AdvanceIT();
  13740         return;
  13741       }
  13742     } else {
  13743       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
  13744       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13745           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
  13746           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13747         uint32_t amount_ = amount / 8;
  13748         EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
  13749                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  13750                 (amount_ << 10));
  13751         return;
  13752       }
  13753     }
  13754   }
  13755   Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
  13756 }
  13757 
  13758 void Assembler::uxtah(Condition cond,
  13759                       Register rd,
  13760                       Register rn,
  13761                       const Operand& operand) {
  13762   VIXL_ASSERT(AllowAssembler());
  13763   CheckIT(cond);
  13764   if (operand.IsImmediateShiftedRegister()) {
  13765     Register rm = operand.GetBaseRegister();
  13766     Shift shift = operand.GetShift();
  13767     uint32_t amount = operand.GetShiftAmount();
  13768     if (IsUsingT32()) {
  13769       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
  13770       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13771           ((amount % 8) == 0) && !rn.Is(pc) &&
  13772           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13773         uint32_t amount_ = amount / 8;
  13774         EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
  13775                    rm.GetCode() | (amount_ << 4));
  13776         AdvanceIT();
  13777         return;
  13778       }
  13779     } else {
  13780       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
  13781       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13782           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
  13783           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13784         uint32_t amount_ = amount / 8;
  13785         EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
  13786                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
  13787                 (amount_ << 10));
  13788         return;
  13789       }
  13790     }
  13791   }
  13792   Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
  13793 }
  13794 
  13795 void Assembler::uxtb(Condition cond,
  13796                      EncodingSize size,
  13797                      Register rd,
  13798                      const Operand& operand) {
  13799   VIXL_ASSERT(AllowAssembler());
  13800   CheckIT(cond);
  13801   if (operand.IsImmediateShiftedRegister()) {
  13802     Register rm = operand.GetBaseRegister();
  13803     if (operand.IsPlainRegister()) {
  13804       if (IsUsingT32()) {
  13805         // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
  13806         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
  13807           EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
  13808           AdvanceIT();
  13809           return;
  13810         }
  13811       }
  13812     }
  13813     Shift shift = operand.GetShift();
  13814     uint32_t amount = operand.GetShiftAmount();
  13815     if (IsUsingT32()) {
  13816       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
  13817       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
  13818           (amount <= 24) && ((amount % 8) == 0) &&
  13819           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13820         uint32_t amount_ = amount / 8;
  13821         EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
  13822                    (amount_ << 4));
  13823         AdvanceIT();
  13824         return;
  13825       }
  13826     } else {
  13827       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
  13828       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13829           ((amount % 8) == 0) && cond.IsNotNever() &&
  13830           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13831         uint32_t amount_ = amount / 8;
  13832         EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
  13833                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
  13834         return;
  13835       }
  13836     }
  13837   }
  13838   Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
  13839 }
  13840 
  13841 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
  13842   VIXL_ASSERT(AllowAssembler());
  13843   CheckIT(cond);
  13844   if (operand.IsImmediateShiftedRegister()) {
  13845     Register rm = operand.GetBaseRegister();
  13846     Shift shift = operand.GetShift();
  13847     uint32_t amount = operand.GetShiftAmount();
  13848     if (IsUsingT32()) {
  13849       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
  13850       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13851           ((amount % 8) == 0) &&
  13852           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13853         uint32_t amount_ = amount / 8;
  13854         EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
  13855                    (amount_ << 4));
  13856         AdvanceIT();
  13857         return;
  13858       }
  13859     } else {
  13860       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
  13861       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13862           ((amount % 8) == 0) && cond.IsNotNever() &&
  13863           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13864         uint32_t amount_ = amount / 8;
  13865         EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
  13866                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
  13867         return;
  13868       }
  13869     }
  13870   }
  13871   Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
  13872 }
  13873 
  13874 void Assembler::uxth(Condition cond,
  13875                      EncodingSize size,
  13876                      Register rd,
  13877                      const Operand& operand) {
  13878   VIXL_ASSERT(AllowAssembler());
  13879   CheckIT(cond);
  13880   if (operand.IsImmediateShiftedRegister()) {
  13881     Register rm = operand.GetBaseRegister();
  13882     if (operand.IsPlainRegister()) {
  13883       if (IsUsingT32()) {
  13884         // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
  13885         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
  13886           EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
  13887           AdvanceIT();
  13888           return;
  13889         }
  13890       }
  13891     }
  13892     Shift shift = operand.GetShift();
  13893     uint32_t amount = operand.GetShiftAmount();
  13894     if (IsUsingT32()) {
  13895       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
  13896       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
  13897           (amount <= 24) && ((amount % 8) == 0) &&
  13898           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13899         uint32_t amount_ = amount / 8;
  13900         EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
  13901                    (amount_ << 4));
  13902         AdvanceIT();
  13903         return;
  13904       }
  13905     } else {
  13906       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
  13907       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
  13908           ((amount % 8) == 0) && cond.IsNotNever() &&
  13909           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
  13910         uint32_t amount_ = amount / 8;
  13911         EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
  13912                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
  13913         return;
  13914       }
  13915     }
  13916   }
  13917   Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
  13918 }
  13919 
  13920 void Assembler::vaba(
  13921     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  13922   VIXL_ASSERT(AllowAssembler());
  13923   CheckIT(cond);
  13924   Dt_U_size_1 encoded_dt(dt);
  13925   if (IsUsingT32()) {
  13926     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
  13927     if (encoded_dt.IsValid()) {
  13928       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  13929         EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  13930                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  13931                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  13932         AdvanceIT();
  13933         return;
  13934       }
  13935     }
  13936   } else {
  13937     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
  13938     if (encoded_dt.IsValid()) {
  13939       if (cond.Is(al)) {
  13940         EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  13941                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  13942                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  13943         return;
  13944       }
  13945     }
  13946   }
  13947   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
  13948 }
  13949 
  13950 void Assembler::vaba(
  13951     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  13952   VIXL_ASSERT(AllowAssembler());
  13953   CheckIT(cond);
  13954   Dt_U_size_1 encoded_dt(dt);
  13955   if (IsUsingT32()) {
  13956     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
  13957     if (encoded_dt.IsValid()) {
  13958       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  13959         EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  13960                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  13961                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  13962         AdvanceIT();
  13963         return;
  13964       }
  13965     }
  13966   } else {
  13967     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
  13968     if (encoded_dt.IsValid()) {
  13969       if (cond.Is(al)) {
  13970         EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  13971                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  13972                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  13973         return;
  13974       }
  13975     }
  13976   }
  13977   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
  13978 }
  13979 
  13980 void Assembler::vabal(
  13981     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  13982   VIXL_ASSERT(AllowAssembler());
  13983   CheckIT(cond);
  13984   Dt_U_size_1 encoded_dt(dt);
  13985   if (IsUsingT32()) {
  13986     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
  13987     if (encoded_dt.IsValid()) {
  13988       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  13989         EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  13990                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  13991                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  13992         AdvanceIT();
  13993         return;
  13994       }
  13995     }
  13996   } else {
  13997     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
  13998     if (encoded_dt.IsValid()) {
  13999       if (cond.Is(al)) {
  14000         EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14001                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  14002                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14003         return;
  14004       }
  14005     }
  14006   }
  14007   Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
  14008 }
  14009 
  14010 void Assembler::vabd(
  14011     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14012   VIXL_ASSERT(AllowAssembler());
  14013   CheckIT(cond);
  14014   Dt_U_size_1 encoded_dt(dt);
  14015   if (IsUsingT32()) {
  14016     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  14017     if (dt.Is(F32)) {
  14018       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14019         EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14020                    rm.Encode(5, 0));
  14021         AdvanceIT();
  14022         return;
  14023       }
  14024     }
  14025     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  14026     if (encoded_dt.IsValid()) {
  14027       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14028         EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14029                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  14030                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14031         AdvanceIT();
  14032         return;
  14033       }
  14034     }
  14035   } else {
  14036     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  14037     if (dt.Is(F32)) {
  14038       if (cond.Is(al)) {
  14039         EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14040                 rm.Encode(5, 0));
  14041         return;
  14042       }
  14043     }
  14044     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  14045     if (encoded_dt.IsValid()) {
  14046       if (cond.Is(al)) {
  14047         EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14048                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  14049                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14050         return;
  14051       }
  14052     }
  14053   }
  14054   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
  14055 }
  14056 
  14057 void Assembler::vabd(
  14058     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  14059   VIXL_ASSERT(AllowAssembler());
  14060   CheckIT(cond);
  14061   Dt_U_size_1 encoded_dt(dt);
  14062   if (IsUsingT32()) {
  14063     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  14064     if (dt.Is(F32)) {
  14065       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14066         EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14067                    rm.Encode(5, 0));
  14068         AdvanceIT();
  14069         return;
  14070       }
  14071     }
  14072     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  14073     if (encoded_dt.IsValid()) {
  14074       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14075         EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14076                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  14077                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14078         AdvanceIT();
  14079         return;
  14080       }
  14081     }
  14082   } else {
  14083     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  14084     if (dt.Is(F32)) {
  14085       if (cond.Is(al)) {
  14086         EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14087                 rm.Encode(5, 0));
  14088         return;
  14089       }
  14090     }
  14091     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  14092     if (encoded_dt.IsValid()) {
  14093       if (cond.Is(al)) {
  14094         EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14095                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  14096                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14097         return;
  14098       }
  14099     }
  14100   }
  14101   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
  14102 }
  14103 
  14104 void Assembler::vabdl(
  14105     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  14106   VIXL_ASSERT(AllowAssembler());
  14107   CheckIT(cond);
  14108   Dt_U_size_1 encoded_dt(dt);
  14109   if (IsUsingT32()) {
  14110     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
  14111     if (encoded_dt.IsValid()) {
  14112       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14113         EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14114                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  14115                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14116         AdvanceIT();
  14117         return;
  14118       }
  14119     }
  14120   } else {
  14121     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
  14122     if (encoded_dt.IsValid()) {
  14123       if (cond.Is(al)) {
  14124         EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14125                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  14126                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14127         return;
  14128       }
  14129     }
  14130   }
  14131   Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
  14132 }
  14133 
  14134 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  14135   VIXL_ASSERT(AllowAssembler());
  14136   CheckIT(cond);
  14137   Dt_F_size_1 encoded_dt(dt);
  14138   if (IsUsingT32()) {
  14139     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  14140     if (encoded_dt.IsValid()) {
  14141       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14142         EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  14143                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  14144                    rd.Encode(22, 12) | rm.Encode(5, 0));
  14145         AdvanceIT();
  14146         return;
  14147       }
  14148     }
  14149     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
  14150     if (dt.Is(F64)) {
  14151       EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  14152       AdvanceIT();
  14153       return;
  14154     }
  14155   } else {
  14156     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  14157     if (encoded_dt.IsValid()) {
  14158       if (cond.Is(al)) {
  14159         EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  14160                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  14161                 rd.Encode(22, 12) | rm.Encode(5, 0));
  14162         return;
  14163       }
  14164     }
  14165     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
  14166     if (dt.Is(F64) && cond.IsNotNever()) {
  14167       EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  14168               rm.Encode(5, 0));
  14169       return;
  14170     }
  14171   }
  14172   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
  14173 }
  14174 
  14175 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  14176   VIXL_ASSERT(AllowAssembler());
  14177   CheckIT(cond);
  14178   Dt_F_size_1 encoded_dt(dt);
  14179   if (IsUsingT32()) {
  14180     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  14181     if (encoded_dt.IsValid()) {
  14182       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14183         EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  14184                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  14185                    rd.Encode(22, 12) | rm.Encode(5, 0));
  14186         AdvanceIT();
  14187         return;
  14188       }
  14189     }
  14190   } else {
  14191     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  14192     if (encoded_dt.IsValid()) {
  14193       if (cond.Is(al)) {
  14194         EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  14195                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  14196                 rd.Encode(22, 12) | rm.Encode(5, 0));
  14197         return;
  14198       }
  14199     }
  14200   }
  14201   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
  14202 }
  14203 
  14204 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
  14205   VIXL_ASSERT(AllowAssembler());
  14206   CheckIT(cond);
  14207   if (IsUsingT32()) {
  14208     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
  14209     if (dt.Is(F32)) {
  14210       EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  14211       AdvanceIT();
  14212       return;
  14213     }
  14214   } else {
  14215     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
  14216     if (dt.Is(F32) && cond.IsNotNever()) {
  14217       EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  14218               rm.Encode(5, 0));
  14219       return;
  14220     }
  14221   }
  14222   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
  14223 }
  14224 
  14225 void Assembler::vacge(
  14226     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14227   VIXL_ASSERT(AllowAssembler());
  14228   CheckIT(cond);
  14229   if (IsUsingT32()) {
  14230     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  14231     if (dt.Is(F32)) {
  14232       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14233         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14234                    rm.Encode(5, 0));
  14235         AdvanceIT();
  14236         return;
  14237       }
  14238     }
  14239   } else {
  14240     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  14241     if (dt.Is(F32)) {
  14242       if (cond.Is(al)) {
  14243         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14244                 rm.Encode(5, 0));
  14245         return;
  14246       }
  14247     }
  14248   }
  14249   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
  14250 }
  14251 
  14252 void Assembler::vacge(
  14253     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  14254   VIXL_ASSERT(AllowAssembler());
  14255   CheckIT(cond);
  14256   if (IsUsingT32()) {
  14257     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  14258     if (dt.Is(F32)) {
  14259       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14260         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14261                    rm.Encode(5, 0));
  14262         AdvanceIT();
  14263         return;
  14264       }
  14265     }
  14266   } else {
  14267     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  14268     if (dt.Is(F32)) {
  14269       if (cond.Is(al)) {
  14270         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14271                 rm.Encode(5, 0));
  14272         return;
  14273       }
  14274     }
  14275   }
  14276   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
  14277 }
  14278 
  14279 void Assembler::vacgt(
  14280     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14281   VIXL_ASSERT(AllowAssembler());
  14282   CheckIT(cond);
  14283   if (IsUsingT32()) {
  14284     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  14285     if (dt.Is(F32)) {
  14286       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14287         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14288                    rm.Encode(5, 0));
  14289         AdvanceIT();
  14290         return;
  14291       }
  14292     }
  14293   } else {
  14294     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  14295     if (dt.Is(F32)) {
  14296       if (cond.Is(al)) {
  14297         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14298                 rm.Encode(5, 0));
  14299         return;
  14300       }
  14301     }
  14302   }
  14303   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
  14304 }
  14305 
  14306 void Assembler::vacgt(
  14307     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  14308   VIXL_ASSERT(AllowAssembler());
  14309   CheckIT(cond);
  14310   if (IsUsingT32()) {
  14311     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  14312     if (dt.Is(F32)) {
  14313       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14314         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14315                    rm.Encode(5, 0));
  14316         AdvanceIT();
  14317         return;
  14318       }
  14319     }
  14320   } else {
  14321     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  14322     if (dt.Is(F32)) {
  14323       if (cond.Is(al)) {
  14324         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14325                 rm.Encode(5, 0));
  14326         return;
  14327       }
  14328     }
  14329   }
  14330   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
  14331 }
  14332 
  14333 void Assembler::vacle(
  14334     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14335   VIXL_ASSERT(AllowAssembler());
  14336   CheckIT(cond);
  14337   if (IsUsingT32()) {
  14338     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  14339     if (dt.Is(F32)) {
  14340       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14341         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14342                    rm.Encode(5, 0));
  14343         AdvanceIT();
  14344         return;
  14345       }
  14346     }
  14347   } else {
  14348     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  14349     if (dt.Is(F32)) {
  14350       if (cond.Is(al)) {
  14351         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14352                 rm.Encode(5, 0));
  14353         return;
  14354       }
  14355     }
  14356   }
  14357   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
  14358 }
  14359 
  14360 void Assembler::vacle(
  14361     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  14362   VIXL_ASSERT(AllowAssembler());
  14363   CheckIT(cond);
  14364   if (IsUsingT32()) {
  14365     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  14366     if (dt.Is(F32)) {
  14367       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14368         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14369                    rm.Encode(5, 0));
  14370         AdvanceIT();
  14371         return;
  14372       }
  14373     }
  14374   } else {
  14375     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  14376     if (dt.Is(F32)) {
  14377       if (cond.Is(al)) {
  14378         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14379                 rm.Encode(5, 0));
  14380         return;
  14381       }
  14382     }
  14383   }
  14384   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
  14385 }
  14386 
  14387 void Assembler::vaclt(
  14388     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14389   VIXL_ASSERT(AllowAssembler());
  14390   CheckIT(cond);
  14391   if (IsUsingT32()) {
  14392     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  14393     if (dt.Is(F32)) {
  14394       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14395         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14396                    rm.Encode(5, 0));
  14397         AdvanceIT();
  14398         return;
  14399       }
  14400     }
  14401   } else {
  14402     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  14403     if (dt.Is(F32)) {
  14404       if (cond.Is(al)) {
  14405         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14406                 rm.Encode(5, 0));
  14407         return;
  14408       }
  14409     }
  14410   }
  14411   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
  14412 }
  14413 
  14414 void Assembler::vaclt(
  14415     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  14416   VIXL_ASSERT(AllowAssembler());
  14417   CheckIT(cond);
  14418   if (IsUsingT32()) {
  14419     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  14420     if (dt.Is(F32)) {
  14421       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14422         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14423                    rm.Encode(5, 0));
  14424         AdvanceIT();
  14425         return;
  14426       }
  14427     }
  14428   } else {
  14429     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  14430     if (dt.Is(F32)) {
  14431       if (cond.Is(al)) {
  14432         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14433                 rm.Encode(5, 0));
  14434         return;
  14435       }
  14436     }
  14437   }
  14438   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
  14439 }
  14440 
  14441 void Assembler::vadd(
  14442     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14443   VIXL_ASSERT(AllowAssembler());
  14444   CheckIT(cond);
  14445   Dt_size_2 encoded_dt(dt);
  14446   if (IsUsingT32()) {
  14447     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  14448     if (dt.Is(F32)) {
  14449       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14450         EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14451                    rm.Encode(5, 0));
  14452         AdvanceIT();
  14453         return;
  14454       }
  14455     }
  14456     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
  14457     if (dt.Is(F64)) {
  14458       EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14459                  rm.Encode(5, 0));
  14460       AdvanceIT();
  14461       return;
  14462     }
  14463     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  14464     if (encoded_dt.IsValid()) {
  14465       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14466         EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
  14467                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14468         AdvanceIT();
  14469         return;
  14470       }
  14471     }
  14472   } else {
  14473     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  14474     if (dt.Is(F32)) {
  14475       if (cond.Is(al)) {
  14476         EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14477                 rm.Encode(5, 0));
  14478         return;
  14479       }
  14480     }
  14481     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
  14482     if (dt.Is(F64) && cond.IsNotNever()) {
  14483       EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  14484               rn.Encode(7, 16) | rm.Encode(5, 0));
  14485       return;
  14486     }
  14487     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  14488     if (encoded_dt.IsValid()) {
  14489       if (cond.Is(al)) {
  14490         EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
  14491                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14492         return;
  14493       }
  14494     }
  14495   }
  14496   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
  14497 }
  14498 
  14499 void Assembler::vadd(
  14500     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  14501   VIXL_ASSERT(AllowAssembler());
  14502   CheckIT(cond);
  14503   Dt_size_2 encoded_dt(dt);
  14504   if (IsUsingT32()) {
  14505     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  14506     if (dt.Is(F32)) {
  14507       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14508         EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14509                    rm.Encode(5, 0));
  14510         AdvanceIT();
  14511         return;
  14512       }
  14513     }
  14514     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  14515     if (encoded_dt.IsValid()) {
  14516       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14517         EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
  14518                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14519         AdvanceIT();
  14520         return;
  14521       }
  14522     }
  14523   } else {
  14524     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  14525     if (dt.Is(F32)) {
  14526       if (cond.Is(al)) {
  14527         EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14528                 rm.Encode(5, 0));
  14529         return;
  14530       }
  14531     }
  14532     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  14533     if (encoded_dt.IsValid()) {
  14534       if (cond.Is(al)) {
  14535         EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
  14536                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14537         return;
  14538       }
  14539     }
  14540   }
  14541   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
  14542 }
  14543 
  14544 void Assembler::vadd(
  14545     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  14546   VIXL_ASSERT(AllowAssembler());
  14547   CheckIT(cond);
  14548   if (IsUsingT32()) {
  14549     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
  14550     if (dt.Is(F32)) {
  14551       EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14552                  rm.Encode(5, 0));
  14553       AdvanceIT();
  14554       return;
  14555     }
  14556   } else {
  14557     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
  14558     if (dt.Is(F32) && cond.IsNotNever()) {
  14559       EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  14560               rn.Encode(7, 16) | rm.Encode(5, 0));
  14561       return;
  14562     }
  14563   }
  14564   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
  14565 }
  14566 
  14567 void Assembler::vaddhn(
  14568     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
  14569   VIXL_ASSERT(AllowAssembler());
  14570   CheckIT(cond);
  14571   Dt_size_3 encoded_dt(dt);
  14572   if (IsUsingT32()) {
  14573     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
  14574     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
  14575       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14576         EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
  14577                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14578         AdvanceIT();
  14579         return;
  14580       }
  14581     }
  14582   } else {
  14583     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
  14584     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
  14585       if (cond.Is(al)) {
  14586         EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
  14587                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14588         return;
  14589       }
  14590     }
  14591   }
  14592   Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
  14593 }
  14594 
  14595 void Assembler::vaddl(
  14596     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  14597   VIXL_ASSERT(AllowAssembler());
  14598   CheckIT(cond);
  14599   Dt_U_size_1 encoded_dt(dt);
  14600   if (IsUsingT32()) {
  14601     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
  14602     if (encoded_dt.IsValid()) {
  14603       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14604         EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14605                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  14606                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14607         AdvanceIT();
  14608         return;
  14609       }
  14610     }
  14611   } else {
  14612     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
  14613     if (encoded_dt.IsValid()) {
  14614       if (cond.Is(al)) {
  14615         EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14616                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  14617                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14618         return;
  14619       }
  14620     }
  14621   }
  14622   Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
  14623 }
  14624 
  14625 void Assembler::vaddw(
  14626     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
  14627   VIXL_ASSERT(AllowAssembler());
  14628   CheckIT(cond);
  14629   Dt_U_size_1 encoded_dt(dt);
  14630   if (IsUsingT32()) {
  14631     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
  14632     if (encoded_dt.IsValid()) {
  14633       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14634         EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14635                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  14636                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14637         AdvanceIT();
  14638         return;
  14639       }
  14640     }
  14641   } else {
  14642     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
  14643     if (encoded_dt.IsValid()) {
  14644       if (cond.Is(al)) {
  14645         EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  14646                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  14647                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  14648         return;
  14649       }
  14650     }
  14651   }
  14652   Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
  14653 }
  14654 
  14655 void Assembler::vand(Condition cond,
  14656                      DataType dt,
  14657                      DRegister rd,
  14658                      DRegister rn,
  14659                      const DOperand& operand) {
  14660   VIXL_ASSERT(AllowAssembler());
  14661   CheckIT(cond);
  14662   if (operand.IsImmediate()) {
  14663     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
  14664     if (IsUsingT32()) {
  14665       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
  14666       if (encoded_dt.IsValid() && rd.Is(rn)) {
  14667         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14668           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
  14669                      rd.Encode(22, 12) |
  14670                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  14671                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  14672                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  14673           AdvanceIT();
  14674           return;
  14675         }
  14676       }
  14677     } else {
  14678       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
  14679       if (encoded_dt.IsValid() && rd.Is(rn)) {
  14680         if (cond.Is(al)) {
  14681           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
  14682                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  14683                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  14684                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  14685           return;
  14686         }
  14687       }
  14688     }
  14689   }
  14690   if (operand.IsRegister()) {
  14691     DRegister rm = operand.GetRegister();
  14692     USE(dt);
  14693     if (IsUsingT32()) {
  14694       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
  14695       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14696         EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14697                    rm.Encode(5, 0));
  14698         AdvanceIT();
  14699         return;
  14700       }
  14701     } else {
  14702       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
  14703       if (cond.Is(al)) {
  14704         EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14705                 rm.Encode(5, 0));
  14706         return;
  14707       }
  14708     }
  14709   }
  14710   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
  14711 }
  14712 
  14713 void Assembler::vand(Condition cond,
  14714                      DataType dt,
  14715                      QRegister rd,
  14716                      QRegister rn,
  14717                      const QOperand& operand) {
  14718   VIXL_ASSERT(AllowAssembler());
  14719   CheckIT(cond);
  14720   if (operand.IsImmediate()) {
  14721     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
  14722     if (IsUsingT32()) {
  14723       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
  14724       if (encoded_dt.IsValid() && rd.Is(rn)) {
  14725         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14726           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
  14727                      rd.Encode(22, 12) |
  14728                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  14729                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  14730                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  14731           AdvanceIT();
  14732           return;
  14733         }
  14734       }
  14735     } else {
  14736       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
  14737       if (encoded_dt.IsValid() && rd.Is(rn)) {
  14738         if (cond.Is(al)) {
  14739           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
  14740                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  14741                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  14742                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  14743           return;
  14744         }
  14745       }
  14746     }
  14747   }
  14748   if (operand.IsRegister()) {
  14749     QRegister rm = operand.GetRegister();
  14750     USE(dt);
  14751     if (IsUsingT32()) {
  14752       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
  14753       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14754         EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14755                    rm.Encode(5, 0));
  14756         AdvanceIT();
  14757         return;
  14758       }
  14759     } else {
  14760       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
  14761       if (cond.Is(al)) {
  14762         EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14763                 rm.Encode(5, 0));
  14764         return;
  14765       }
  14766     }
  14767   }
  14768   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
  14769 }
  14770 
  14771 void Assembler::vbic(Condition cond,
  14772                      DataType dt,
  14773                      DRegister rd,
  14774                      DRegister rn,
  14775                      const DOperand& operand) {
  14776   VIXL_ASSERT(AllowAssembler());
  14777   CheckIT(cond);
  14778   if (operand.IsImmediate()) {
  14779     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
  14780     if (IsUsingT32()) {
  14781       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
  14782       if (encoded_dt.IsValid() && rd.Is(rn)) {
  14783         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14784           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
  14785                      rd.Encode(22, 12) |
  14786                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  14787                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  14788                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  14789           AdvanceIT();
  14790           return;
  14791         }
  14792       }
  14793     } else {
  14794       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
  14795       if (encoded_dt.IsValid() && rd.Is(rn)) {
  14796         if (cond.Is(al)) {
  14797           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
  14798                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  14799                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  14800                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  14801           return;
  14802         }
  14803       }
  14804     }
  14805   }
  14806   if (operand.IsRegister()) {
  14807     DRegister rm = operand.GetRegister();
  14808     USE(dt);
  14809     if (IsUsingT32()) {
  14810       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
  14811       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14812         EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14813                    rm.Encode(5, 0));
  14814         AdvanceIT();
  14815         return;
  14816       }
  14817     } else {
  14818       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
  14819       if (cond.Is(al)) {
  14820         EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14821                 rm.Encode(5, 0));
  14822         return;
  14823       }
  14824     }
  14825   }
  14826   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
  14827 }
  14828 
  14829 void Assembler::vbic(Condition cond,
  14830                      DataType dt,
  14831                      QRegister rd,
  14832                      QRegister rn,
  14833                      const QOperand& operand) {
  14834   VIXL_ASSERT(AllowAssembler());
  14835   CheckIT(cond);
  14836   if (operand.IsImmediate()) {
  14837     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
  14838     if (IsUsingT32()) {
  14839       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
  14840       if (encoded_dt.IsValid() && rd.Is(rn)) {
  14841         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14842           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
  14843                      rd.Encode(22, 12) |
  14844                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  14845                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  14846                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  14847           AdvanceIT();
  14848           return;
  14849         }
  14850       }
  14851     } else {
  14852       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
  14853       if (encoded_dt.IsValid() && rd.Is(rn)) {
  14854         if (cond.Is(al)) {
  14855           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
  14856                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  14857                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  14858                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  14859           return;
  14860         }
  14861       }
  14862     }
  14863   }
  14864   if (operand.IsRegister()) {
  14865     QRegister rm = operand.GetRegister();
  14866     USE(dt);
  14867     if (IsUsingT32()) {
  14868       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
  14869       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14870         EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14871                    rm.Encode(5, 0));
  14872         AdvanceIT();
  14873         return;
  14874       }
  14875     } else {
  14876       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
  14877       if (cond.Is(al)) {
  14878         EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14879                 rm.Encode(5, 0));
  14880         return;
  14881       }
  14882     }
  14883   }
  14884   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
  14885 }
  14886 
  14887 void Assembler::vbif(
  14888     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14889   VIXL_ASSERT(AllowAssembler());
  14890   CheckIT(cond);
  14891   USE(dt);
  14892   if (IsUsingT32()) {
  14893     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
  14894     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14895       EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14896                  rm.Encode(5, 0));
  14897       AdvanceIT();
  14898       return;
  14899     }
  14900   } else {
  14901     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
  14902     if (cond.Is(al)) {
  14903       EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14904               rm.Encode(5, 0));
  14905       return;
  14906     }
  14907   }
  14908   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
  14909 }
  14910 
  14911 void Assembler::vbif(
  14912     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  14913   VIXL_ASSERT(AllowAssembler());
  14914   CheckIT(cond);
  14915   USE(dt);
  14916   if (IsUsingT32()) {
  14917     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
  14918     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14919       EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14920                  rm.Encode(5, 0));
  14921       AdvanceIT();
  14922       return;
  14923     }
  14924   } else {
  14925     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
  14926     if (cond.Is(al)) {
  14927       EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14928               rm.Encode(5, 0));
  14929       return;
  14930     }
  14931   }
  14932   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
  14933 }
  14934 
  14935 void Assembler::vbit(
  14936     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14937   VIXL_ASSERT(AllowAssembler());
  14938   CheckIT(cond);
  14939   USE(dt);
  14940   if (IsUsingT32()) {
  14941     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
  14942     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14943       EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14944                  rm.Encode(5, 0));
  14945       AdvanceIT();
  14946       return;
  14947     }
  14948   } else {
  14949     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
  14950     if (cond.Is(al)) {
  14951       EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14952               rm.Encode(5, 0));
  14953       return;
  14954     }
  14955   }
  14956   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
  14957 }
  14958 
  14959 void Assembler::vbit(
  14960     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  14961   VIXL_ASSERT(AllowAssembler());
  14962   CheckIT(cond);
  14963   USE(dt);
  14964   if (IsUsingT32()) {
  14965     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
  14966     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14967       EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14968                  rm.Encode(5, 0));
  14969       AdvanceIT();
  14970       return;
  14971     }
  14972   } else {
  14973     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
  14974     if (cond.Is(al)) {
  14975       EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14976               rm.Encode(5, 0));
  14977       return;
  14978     }
  14979   }
  14980   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
  14981 }
  14982 
  14983 void Assembler::vbsl(
  14984     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  14985   VIXL_ASSERT(AllowAssembler());
  14986   CheckIT(cond);
  14987   USE(dt);
  14988   if (IsUsingT32()) {
  14989     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
  14990     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  14991       EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  14992                  rm.Encode(5, 0));
  14993       AdvanceIT();
  14994       return;
  14995     }
  14996   } else {
  14997     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
  14998     if (cond.Is(al)) {
  14999       EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15000               rm.Encode(5, 0));
  15001       return;
  15002     }
  15003   }
  15004   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
  15005 }
  15006 
  15007 void Assembler::vbsl(
  15008     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  15009   VIXL_ASSERT(AllowAssembler());
  15010   CheckIT(cond);
  15011   USE(dt);
  15012   if (IsUsingT32()) {
  15013     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
  15014     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15015       EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15016                  rm.Encode(5, 0));
  15017       AdvanceIT();
  15018       return;
  15019     }
  15020   } else {
  15021     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
  15022     if (cond.Is(al)) {
  15023       EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15024               rm.Encode(5, 0));
  15025       return;
  15026     }
  15027   }
  15028   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
  15029 }
  15030 
  15031 void Assembler::vceq(Condition cond,
  15032                      DataType dt,
  15033                      DRegister rd,
  15034                      DRegister rm,
  15035                      const DOperand& operand) {
  15036   VIXL_ASSERT(AllowAssembler());
  15037   CheckIT(cond);
  15038   if (operand.IsImmediate()) {
  15039     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15040       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15041       Dt_F_size_2 encoded_dt(dt);
  15042       if (IsUsingT32()) {
  15043         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
  15044         if (encoded_dt.IsValid() && (imm == 0)) {
  15045           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15046             EmitT32_32(0xffb10100U |
  15047                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15048                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15049                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15050             AdvanceIT();
  15051             return;
  15052           }
  15053         }
  15054       } else {
  15055         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
  15056         if (encoded_dt.IsValid() && (imm == 0)) {
  15057           if (cond.Is(al)) {
  15058             EmitA32(0xf3b10100U |
  15059                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15060                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15061                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15062             return;
  15063           }
  15064         }
  15065       }
  15066     }
  15067   }
  15068   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
  15069 }
  15070 
  15071 void Assembler::vceq(Condition cond,
  15072                      DataType dt,
  15073                      QRegister rd,
  15074                      QRegister rm,
  15075                      const QOperand& operand) {
  15076   VIXL_ASSERT(AllowAssembler());
  15077   CheckIT(cond);
  15078   if (operand.IsImmediate()) {
  15079     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15080       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15081       Dt_F_size_2 encoded_dt(dt);
  15082       if (IsUsingT32()) {
  15083         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
  15084         if (encoded_dt.IsValid() && (imm == 0)) {
  15085           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15086             EmitT32_32(0xffb10140U |
  15087                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15088                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15089                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15090             AdvanceIT();
  15091             return;
  15092           }
  15093         }
  15094       } else {
  15095         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
  15096         if (encoded_dt.IsValid() && (imm == 0)) {
  15097           if (cond.Is(al)) {
  15098             EmitA32(0xf3b10140U |
  15099                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15100                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15101                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15102             return;
  15103           }
  15104         }
  15105       }
  15106     }
  15107   }
  15108   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
  15109 }
  15110 
  15111 void Assembler::vceq(
  15112     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  15113   VIXL_ASSERT(AllowAssembler());
  15114   CheckIT(cond);
  15115   Dt_size_4 encoded_dt(dt);
  15116   Dt_sz_1 encoded_dt_2(dt);
  15117   if (IsUsingT32()) {
  15118     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  15119     if (encoded_dt.IsValid()) {
  15120       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15121         EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
  15122                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15123         AdvanceIT();
  15124         return;
  15125       }
  15126     }
  15127     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
  15128     if (encoded_dt_2.IsValid()) {
  15129       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15130         EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
  15131                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15132         AdvanceIT();
  15133         return;
  15134       }
  15135     }
  15136   } else {
  15137     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  15138     if (encoded_dt.IsValid()) {
  15139       if (cond.Is(al)) {
  15140         EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
  15141                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15142         return;
  15143       }
  15144     }
  15145     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
  15146     if (encoded_dt_2.IsValid()) {
  15147       if (cond.Is(al)) {
  15148         EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
  15149                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15150         return;
  15151       }
  15152     }
  15153   }
  15154   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
  15155 }
  15156 
  15157 void Assembler::vceq(
  15158     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  15159   VIXL_ASSERT(AllowAssembler());
  15160   CheckIT(cond);
  15161   Dt_size_4 encoded_dt(dt);
  15162   Dt_sz_1 encoded_dt_2(dt);
  15163   if (IsUsingT32()) {
  15164     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  15165     if (encoded_dt.IsValid()) {
  15166       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15167         EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
  15168                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15169         AdvanceIT();
  15170         return;
  15171       }
  15172     }
  15173     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
  15174     if (encoded_dt_2.IsValid()) {
  15175       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15176         EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
  15177                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15178         AdvanceIT();
  15179         return;
  15180       }
  15181     }
  15182   } else {
  15183     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  15184     if (encoded_dt.IsValid()) {
  15185       if (cond.Is(al)) {
  15186         EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
  15187                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15188         return;
  15189       }
  15190     }
  15191     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
  15192     if (encoded_dt_2.IsValid()) {
  15193       if (cond.Is(al)) {
  15194         EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
  15195                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15196         return;
  15197       }
  15198     }
  15199   }
  15200   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
  15201 }
  15202 
  15203 void Assembler::vcge(Condition cond,
  15204                      DataType dt,
  15205                      DRegister rd,
  15206                      DRegister rm,
  15207                      const DOperand& operand) {
  15208   VIXL_ASSERT(AllowAssembler());
  15209   CheckIT(cond);
  15210   if (operand.IsImmediate()) {
  15211     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15212       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15213       Dt_F_size_1 encoded_dt(dt);
  15214       if (IsUsingT32()) {
  15215         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
  15216         if (encoded_dt.IsValid() && (imm == 0)) {
  15217           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15218             EmitT32_32(0xffb10080U |
  15219                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15220                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15221                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15222             AdvanceIT();
  15223             return;
  15224           }
  15225         }
  15226       } else {
  15227         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
  15228         if (encoded_dt.IsValid() && (imm == 0)) {
  15229           if (cond.Is(al)) {
  15230             EmitA32(0xf3b10080U |
  15231                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15232                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15233                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15234             return;
  15235           }
  15236         }
  15237       }
  15238     }
  15239   }
  15240   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
  15241 }
  15242 
  15243 void Assembler::vcge(Condition cond,
  15244                      DataType dt,
  15245                      QRegister rd,
  15246                      QRegister rm,
  15247                      const QOperand& operand) {
  15248   VIXL_ASSERT(AllowAssembler());
  15249   CheckIT(cond);
  15250   if (operand.IsImmediate()) {
  15251     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15252       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15253       Dt_F_size_1 encoded_dt(dt);
  15254       if (IsUsingT32()) {
  15255         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
  15256         if (encoded_dt.IsValid() && (imm == 0)) {
  15257           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15258             EmitT32_32(0xffb100c0U |
  15259                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15260                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15261                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15262             AdvanceIT();
  15263             return;
  15264           }
  15265         }
  15266       } else {
  15267         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
  15268         if (encoded_dt.IsValid() && (imm == 0)) {
  15269           if (cond.Is(al)) {
  15270             EmitA32(0xf3b100c0U |
  15271                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15272                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15273                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15274             return;
  15275           }
  15276         }
  15277       }
  15278     }
  15279   }
  15280   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
  15281 }
  15282 
  15283 void Assembler::vcge(
  15284     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  15285   VIXL_ASSERT(AllowAssembler());
  15286   CheckIT(cond);
  15287   Dt_U_size_1 encoded_dt(dt);
  15288   if (IsUsingT32()) {
  15289     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  15290     if (encoded_dt.IsValid()) {
  15291       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15292         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15293                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  15294                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15295         AdvanceIT();
  15296         return;
  15297       }
  15298     }
  15299     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
  15300     if (dt.Is(F32)) {
  15301       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15302         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15303                    rm.Encode(5, 0));
  15304         AdvanceIT();
  15305         return;
  15306       }
  15307     }
  15308   } else {
  15309     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  15310     if (encoded_dt.IsValid()) {
  15311       if (cond.Is(al)) {
  15312         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15313                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  15314                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15315         return;
  15316       }
  15317     }
  15318     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
  15319     if (dt.Is(F32)) {
  15320       if (cond.Is(al)) {
  15321         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15322                 rm.Encode(5, 0));
  15323         return;
  15324       }
  15325     }
  15326   }
  15327   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
  15328 }
  15329 
  15330 void Assembler::vcge(
  15331     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  15332   VIXL_ASSERT(AllowAssembler());
  15333   CheckIT(cond);
  15334   Dt_U_size_1 encoded_dt(dt);
  15335   if (IsUsingT32()) {
  15336     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  15337     if (encoded_dt.IsValid()) {
  15338       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15339         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15340                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  15341                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15342         AdvanceIT();
  15343         return;
  15344       }
  15345     }
  15346     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
  15347     if (dt.Is(F32)) {
  15348       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15349         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15350                    rm.Encode(5, 0));
  15351         AdvanceIT();
  15352         return;
  15353       }
  15354     }
  15355   } else {
  15356     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  15357     if (encoded_dt.IsValid()) {
  15358       if (cond.Is(al)) {
  15359         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15360                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  15361                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15362         return;
  15363       }
  15364     }
  15365     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
  15366     if (dt.Is(F32)) {
  15367       if (cond.Is(al)) {
  15368         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15369                 rm.Encode(5, 0));
  15370         return;
  15371       }
  15372     }
  15373   }
  15374   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
  15375 }
  15376 
  15377 void Assembler::vcgt(Condition cond,
  15378                      DataType dt,
  15379                      DRegister rd,
  15380                      DRegister rm,
  15381                      const DOperand& operand) {
  15382   VIXL_ASSERT(AllowAssembler());
  15383   CheckIT(cond);
  15384   if (operand.IsImmediate()) {
  15385     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15386       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15387       Dt_F_size_1 encoded_dt(dt);
  15388       if (IsUsingT32()) {
  15389         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
  15390         if (encoded_dt.IsValid() && (imm == 0)) {
  15391           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15392             EmitT32_32(0xffb10000U |
  15393                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15394                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15395                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15396             AdvanceIT();
  15397             return;
  15398           }
  15399         }
  15400       } else {
  15401         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
  15402         if (encoded_dt.IsValid() && (imm == 0)) {
  15403           if (cond.Is(al)) {
  15404             EmitA32(0xf3b10000U |
  15405                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15406                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15407                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15408             return;
  15409           }
  15410         }
  15411       }
  15412     }
  15413   }
  15414   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
  15415 }
  15416 
  15417 void Assembler::vcgt(Condition cond,
  15418                      DataType dt,
  15419                      QRegister rd,
  15420                      QRegister rm,
  15421                      const QOperand& operand) {
  15422   VIXL_ASSERT(AllowAssembler());
  15423   CheckIT(cond);
  15424   if (operand.IsImmediate()) {
  15425     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15426       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15427       Dt_F_size_1 encoded_dt(dt);
  15428       if (IsUsingT32()) {
  15429         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
  15430         if (encoded_dt.IsValid() && (imm == 0)) {
  15431           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15432             EmitT32_32(0xffb10040U |
  15433                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15434                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15435                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15436             AdvanceIT();
  15437             return;
  15438           }
  15439         }
  15440       } else {
  15441         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
  15442         if (encoded_dt.IsValid() && (imm == 0)) {
  15443           if (cond.Is(al)) {
  15444             EmitA32(0xf3b10040U |
  15445                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15446                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15447                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15448             return;
  15449           }
  15450         }
  15451       }
  15452     }
  15453   }
  15454   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
  15455 }
  15456 
  15457 void Assembler::vcgt(
  15458     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  15459   VIXL_ASSERT(AllowAssembler());
  15460   CheckIT(cond);
  15461   Dt_U_size_1 encoded_dt(dt);
  15462   if (IsUsingT32()) {
  15463     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  15464     if (encoded_dt.IsValid()) {
  15465       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15466         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15467                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  15468                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15469         AdvanceIT();
  15470         return;
  15471       }
  15472     }
  15473     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
  15474     if (dt.Is(F32)) {
  15475       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15476         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15477                    rm.Encode(5, 0));
  15478         AdvanceIT();
  15479         return;
  15480       }
  15481     }
  15482   } else {
  15483     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  15484     if (encoded_dt.IsValid()) {
  15485       if (cond.Is(al)) {
  15486         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15487                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  15488                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15489         return;
  15490       }
  15491     }
  15492     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
  15493     if (dt.Is(F32)) {
  15494       if (cond.Is(al)) {
  15495         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15496                 rm.Encode(5, 0));
  15497         return;
  15498       }
  15499     }
  15500   }
  15501   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
  15502 }
  15503 
  15504 void Assembler::vcgt(
  15505     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  15506   VIXL_ASSERT(AllowAssembler());
  15507   CheckIT(cond);
  15508   Dt_U_size_1 encoded_dt(dt);
  15509   if (IsUsingT32()) {
  15510     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  15511     if (encoded_dt.IsValid()) {
  15512       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15513         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15514                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  15515                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15516         AdvanceIT();
  15517         return;
  15518       }
  15519     }
  15520     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
  15521     if (dt.Is(F32)) {
  15522       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15523         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15524                    rm.Encode(5, 0));
  15525         AdvanceIT();
  15526         return;
  15527       }
  15528     }
  15529   } else {
  15530     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  15531     if (encoded_dt.IsValid()) {
  15532       if (cond.Is(al)) {
  15533         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15534                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  15535                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  15536         return;
  15537       }
  15538     }
  15539     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
  15540     if (dt.Is(F32)) {
  15541       if (cond.Is(al)) {
  15542         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  15543                 rm.Encode(5, 0));
  15544         return;
  15545       }
  15546     }
  15547   }
  15548   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
  15549 }
  15550 
  15551 void Assembler::vcle(Condition cond,
  15552                      DataType dt,
  15553                      DRegister rd,
  15554                      DRegister rm,
  15555                      const DOperand& operand) {
  15556   VIXL_ASSERT(AllowAssembler());
  15557   CheckIT(cond);
  15558   if (operand.IsImmediate()) {
  15559     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15560       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15561       Dt_F_size_1 encoded_dt(dt);
  15562       if (IsUsingT32()) {
  15563         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
  15564         if (encoded_dt.IsValid() && (imm == 0)) {
  15565           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15566             EmitT32_32(0xffb10180U |
  15567                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15568                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15569                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15570             AdvanceIT();
  15571             return;
  15572           }
  15573         }
  15574       } else {
  15575         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
  15576         if (encoded_dt.IsValid() && (imm == 0)) {
  15577           if (cond.Is(al)) {
  15578             EmitA32(0xf3b10180U |
  15579                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15580                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15581                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15582             return;
  15583           }
  15584         }
  15585       }
  15586     }
  15587   }
  15588   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
  15589 }
  15590 
  15591 void Assembler::vcle(Condition cond,
  15592                      DataType dt,
  15593                      QRegister rd,
  15594                      QRegister rm,
  15595                      const QOperand& operand) {
  15596   VIXL_ASSERT(AllowAssembler());
  15597   CheckIT(cond);
  15598   if (operand.IsImmediate()) {
  15599     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15600       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15601       Dt_F_size_1 encoded_dt(dt);
  15602       if (IsUsingT32()) {
  15603         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
  15604         if (encoded_dt.IsValid() && (imm == 0)) {
  15605           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15606             EmitT32_32(0xffb101c0U |
  15607                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15608                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15609                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15610             AdvanceIT();
  15611             return;
  15612           }
  15613         }
  15614       } else {
  15615         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
  15616         if (encoded_dt.IsValid() && (imm == 0)) {
  15617           if (cond.Is(al)) {
  15618             EmitA32(0xf3b101c0U |
  15619                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15620                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15621                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15622             return;
  15623           }
  15624         }
  15625       }
  15626     }
  15627   }
  15628   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
  15629 }
  15630 
  15631 void Assembler::vcle(
  15632     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  15633   VIXL_ASSERT(AllowAssembler());
  15634   CheckIT(cond);
  15635   Dt_U_size_1 encoded_dt(dt);
  15636   if (IsUsingT32()) {
  15637     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  15638     if (encoded_dt.IsValid()) {
  15639       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15640         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15641                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  15642                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
  15643         AdvanceIT();
  15644         return;
  15645       }
  15646     }
  15647     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
  15648     if (dt.Is(F32)) {
  15649       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15650         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
  15651                    rm.Encode(7, 16));
  15652         AdvanceIT();
  15653         return;
  15654       }
  15655     }
  15656   } else {
  15657     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  15658     if (encoded_dt.IsValid()) {
  15659       if (cond.Is(al)) {
  15660         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15661                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  15662                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
  15663         return;
  15664       }
  15665     }
  15666     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
  15667     if (dt.Is(F32)) {
  15668       if (cond.Is(al)) {
  15669         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
  15670                 rm.Encode(7, 16));
  15671         return;
  15672       }
  15673     }
  15674   }
  15675   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
  15676 }
  15677 
  15678 void Assembler::vcle(
  15679     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  15680   VIXL_ASSERT(AllowAssembler());
  15681   CheckIT(cond);
  15682   Dt_U_size_1 encoded_dt(dt);
  15683   if (IsUsingT32()) {
  15684     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  15685     if (encoded_dt.IsValid()) {
  15686       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15687         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15688                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  15689                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
  15690         AdvanceIT();
  15691         return;
  15692       }
  15693     }
  15694     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
  15695     if (dt.Is(F32)) {
  15696       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15697         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
  15698                    rm.Encode(7, 16));
  15699         AdvanceIT();
  15700         return;
  15701       }
  15702     }
  15703   } else {
  15704     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  15705     if (encoded_dt.IsValid()) {
  15706       if (cond.Is(al)) {
  15707         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15708                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  15709                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
  15710         return;
  15711       }
  15712     }
  15713     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
  15714     if (dt.Is(F32)) {
  15715       if (cond.Is(al)) {
  15716         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
  15717                 rm.Encode(7, 16));
  15718         return;
  15719       }
  15720     }
  15721   }
  15722   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
  15723 }
  15724 
  15725 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  15726   VIXL_ASSERT(AllowAssembler());
  15727   CheckIT(cond);
  15728   Dt_size_5 encoded_dt(dt);
  15729   if (IsUsingT32()) {
  15730     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  15731     if (encoded_dt.IsValid()) {
  15732       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15733         EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
  15734                    rd.Encode(22, 12) | rm.Encode(5, 0));
  15735         AdvanceIT();
  15736         return;
  15737       }
  15738     }
  15739   } else {
  15740     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  15741     if (encoded_dt.IsValid()) {
  15742       if (cond.Is(al)) {
  15743         EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
  15744                 rd.Encode(22, 12) | rm.Encode(5, 0));
  15745         return;
  15746       }
  15747     }
  15748   }
  15749   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
  15750 }
  15751 
  15752 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  15753   VIXL_ASSERT(AllowAssembler());
  15754   CheckIT(cond);
  15755   Dt_size_5 encoded_dt(dt);
  15756   if (IsUsingT32()) {
  15757     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  15758     if (encoded_dt.IsValid()) {
  15759       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15760         EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
  15761                    rd.Encode(22, 12) | rm.Encode(5, 0));
  15762         AdvanceIT();
  15763         return;
  15764       }
  15765     }
  15766   } else {
  15767     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  15768     if (encoded_dt.IsValid()) {
  15769       if (cond.Is(al)) {
  15770         EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
  15771                 rd.Encode(22, 12) | rm.Encode(5, 0));
  15772         return;
  15773       }
  15774     }
  15775   }
  15776   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
  15777 }
  15778 
  15779 void Assembler::vclt(Condition cond,
  15780                      DataType dt,
  15781                      DRegister rd,
  15782                      DRegister rm,
  15783                      const DOperand& operand) {
  15784   VIXL_ASSERT(AllowAssembler());
  15785   CheckIT(cond);
  15786   if (operand.IsImmediate()) {
  15787     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15788       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15789       Dt_F_size_1 encoded_dt(dt);
  15790       if (IsUsingT32()) {
  15791         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
  15792         if (encoded_dt.IsValid() && (imm == 0)) {
  15793           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15794             EmitT32_32(0xffb10200U |
  15795                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15796                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15797                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15798             AdvanceIT();
  15799             return;
  15800           }
  15801         }
  15802       } else {
  15803         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
  15804         if (encoded_dt.IsValid() && (imm == 0)) {
  15805           if (cond.Is(al)) {
  15806             EmitA32(0xf3b10200U |
  15807                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15808                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15809                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15810             return;
  15811           }
  15812         }
  15813       }
  15814     }
  15815   }
  15816   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
  15817 }
  15818 
  15819 void Assembler::vclt(Condition cond,
  15820                      DataType dt,
  15821                      QRegister rd,
  15822                      QRegister rm,
  15823                      const QOperand& operand) {
  15824   VIXL_ASSERT(AllowAssembler());
  15825   CheckIT(cond);
  15826   if (operand.IsImmediate()) {
  15827     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  15828       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  15829       Dt_F_size_1 encoded_dt(dt);
  15830       if (IsUsingT32()) {
  15831         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
  15832         if (encoded_dt.IsValid() && (imm == 0)) {
  15833           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15834             EmitT32_32(0xffb10240U |
  15835                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15836                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15837                        rd.Encode(22, 12) | rm.Encode(5, 0));
  15838             AdvanceIT();
  15839             return;
  15840           }
  15841         }
  15842       } else {
  15843         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
  15844         if (encoded_dt.IsValid() && (imm == 0)) {
  15845           if (cond.Is(al)) {
  15846             EmitA32(0xf3b10240U |
  15847                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  15848                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  15849                     rd.Encode(22, 12) | rm.Encode(5, 0));
  15850             return;
  15851           }
  15852         }
  15853       }
  15854     }
  15855   }
  15856   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
  15857 }
  15858 
  15859 void Assembler::vclt(
  15860     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  15861   VIXL_ASSERT(AllowAssembler());
  15862   CheckIT(cond);
  15863   Dt_U_size_1 encoded_dt(dt);
  15864   if (IsUsingT32()) {
  15865     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  15866     if (encoded_dt.IsValid()) {
  15867       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15868         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15869                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  15870                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
  15871         AdvanceIT();
  15872         return;
  15873       }
  15874     }
  15875     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
  15876     if (dt.Is(F32)) {
  15877       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15878         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
  15879                    rm.Encode(7, 16));
  15880         AdvanceIT();
  15881         return;
  15882       }
  15883     }
  15884   } else {
  15885     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  15886     if (encoded_dt.IsValid()) {
  15887       if (cond.Is(al)) {
  15888         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15889                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  15890                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
  15891         return;
  15892       }
  15893     }
  15894     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
  15895     if (dt.Is(F32)) {
  15896       if (cond.Is(al)) {
  15897         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
  15898                 rm.Encode(7, 16));
  15899         return;
  15900       }
  15901     }
  15902   }
  15903   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
  15904 }
  15905 
  15906 void Assembler::vclt(
  15907     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  15908   VIXL_ASSERT(AllowAssembler());
  15909   CheckIT(cond);
  15910   Dt_U_size_1 encoded_dt(dt);
  15911   if (IsUsingT32()) {
  15912     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  15913     if (encoded_dt.IsValid()) {
  15914       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15915         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15916                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  15917                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
  15918         AdvanceIT();
  15919         return;
  15920       }
  15921     }
  15922     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
  15923     if (dt.Is(F32)) {
  15924       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15925         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
  15926                    rm.Encode(7, 16));
  15927         AdvanceIT();
  15928         return;
  15929       }
  15930     }
  15931   } else {
  15932     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  15933     if (encoded_dt.IsValid()) {
  15934       if (cond.Is(al)) {
  15935         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  15936                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  15937                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
  15938         return;
  15939       }
  15940     }
  15941     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
  15942     if (dt.Is(F32)) {
  15943       if (cond.Is(al)) {
  15944         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
  15945                 rm.Encode(7, 16));
  15946         return;
  15947       }
  15948     }
  15949   }
  15950   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
  15951 }
  15952 
  15953 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  15954   VIXL_ASSERT(AllowAssembler());
  15955   CheckIT(cond);
  15956   Dt_size_4 encoded_dt(dt);
  15957   if (IsUsingT32()) {
  15958     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  15959     if (encoded_dt.IsValid()) {
  15960       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15961         EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
  15962                    rd.Encode(22, 12) | rm.Encode(5, 0));
  15963         AdvanceIT();
  15964         return;
  15965       }
  15966     }
  15967   } else {
  15968     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  15969     if (encoded_dt.IsValid()) {
  15970       if (cond.Is(al)) {
  15971         EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
  15972                 rd.Encode(22, 12) | rm.Encode(5, 0));
  15973         return;
  15974       }
  15975     }
  15976   }
  15977   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
  15978 }
  15979 
  15980 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  15981   VIXL_ASSERT(AllowAssembler());
  15982   CheckIT(cond);
  15983   Dt_size_4 encoded_dt(dt);
  15984   if (IsUsingT32()) {
  15985     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  15986     if (encoded_dt.IsValid()) {
  15987       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  15988         EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
  15989                    rd.Encode(22, 12) | rm.Encode(5, 0));
  15990         AdvanceIT();
  15991         return;
  15992       }
  15993     }
  15994   } else {
  15995     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  15996     if (encoded_dt.IsValid()) {
  15997       if (cond.Is(al)) {
  15998         EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
  15999                 rd.Encode(22, 12) | rm.Encode(5, 0));
  16000         return;
  16001       }
  16002     }
  16003   }
  16004   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
  16005 }
  16006 
  16007 void Assembler::vcmp(Condition cond,
  16008                      DataType dt,
  16009                      SRegister rd,
  16010                      const SOperand& operand) {
  16011   VIXL_ASSERT(AllowAssembler());
  16012   CheckIT(cond);
  16013   if (operand.IsRegister()) {
  16014     SRegister rm = operand.GetRegister();
  16015     if (IsUsingT32()) {
  16016       // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
  16017       if (dt.Is(F32)) {
  16018         EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16019         AdvanceIT();
  16020         return;
  16021       }
  16022     } else {
  16023       // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
  16024       if (dt.Is(F32) && cond.IsNotNever()) {
  16025         EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16026                 rm.Encode(5, 0));
  16027         return;
  16028       }
  16029     }
  16030   }
  16031   if (operand.IsImmediate()) {
  16032     if (IsUsingT32()) {
  16033       // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
  16034       if (dt.Is(F32) && (operand.IsFloatZero())) {
  16035         EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
  16036         AdvanceIT();
  16037         return;
  16038       }
  16039     } else {
  16040       // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
  16041       if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) {
  16042         EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
  16043         return;
  16044       }
  16045     }
  16046   }
  16047   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand);
  16048 }
  16049 
  16050 void Assembler::vcmp(Condition cond,
  16051                      DataType dt,
  16052                      DRegister rd,
  16053                      const DOperand& operand) {
  16054   VIXL_ASSERT(AllowAssembler());
  16055   CheckIT(cond);
  16056   if (operand.IsRegister()) {
  16057     DRegister rm = operand.GetRegister();
  16058     if (IsUsingT32()) {
  16059       // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
  16060       if (dt.Is(F64)) {
  16061         EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16062         AdvanceIT();
  16063         return;
  16064       }
  16065     } else {
  16066       // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
  16067       if (dt.Is(F64) && cond.IsNotNever()) {
  16068         EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16069                 rm.Encode(5, 0));
  16070         return;
  16071       }
  16072     }
  16073   }
  16074   if (operand.IsImmediate()) {
  16075     if (IsUsingT32()) {
  16076       // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
  16077       if (dt.Is(F64) && (operand.IsFloatZero())) {
  16078         EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
  16079         AdvanceIT();
  16080         return;
  16081       }
  16082     } else {
  16083       // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
  16084       if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) {
  16085         EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
  16086         return;
  16087       }
  16088     }
  16089   }
  16090   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand);
  16091 }
  16092 
  16093 void Assembler::vcmpe(Condition cond,
  16094                       DataType dt,
  16095                       SRegister rd,
  16096                       const SOperand& operand) {
  16097   VIXL_ASSERT(AllowAssembler());
  16098   CheckIT(cond);
  16099   if (operand.IsRegister()) {
  16100     SRegister rm = operand.GetRegister();
  16101     if (IsUsingT32()) {
  16102       // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
  16103       if (dt.Is(F32)) {
  16104         EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16105         AdvanceIT();
  16106         return;
  16107       }
  16108     } else {
  16109       // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
  16110       if (dt.Is(F32) && cond.IsNotNever()) {
  16111         EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16112                 rm.Encode(5, 0));
  16113         return;
  16114       }
  16115     }
  16116   }
  16117   if (operand.IsImmediate()) {
  16118     if (IsUsingT32()) {
  16119       // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
  16120       if (dt.Is(F32) && (operand.IsFloatZero())) {
  16121         EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
  16122         AdvanceIT();
  16123         return;
  16124       }
  16125     } else {
  16126       // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
  16127       if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) {
  16128         EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
  16129         return;
  16130       }
  16131     }
  16132   }
  16133   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand);
  16134 }
  16135 
  16136 void Assembler::vcmpe(Condition cond,
  16137                       DataType dt,
  16138                       DRegister rd,
  16139                       const DOperand& operand) {
  16140   VIXL_ASSERT(AllowAssembler());
  16141   CheckIT(cond);
  16142   if (operand.IsRegister()) {
  16143     DRegister rm = operand.GetRegister();
  16144     if (IsUsingT32()) {
  16145       // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
  16146       if (dt.Is(F64)) {
  16147         EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16148         AdvanceIT();
  16149         return;
  16150       }
  16151     } else {
  16152       // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
  16153       if (dt.Is(F64) && cond.IsNotNever()) {
  16154         EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16155                 rm.Encode(5, 0));
  16156         return;
  16157       }
  16158     }
  16159   }
  16160   if (operand.IsImmediate()) {
  16161     if (IsUsingT32()) {
  16162       // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
  16163       if (dt.Is(F64) && (operand.IsFloatZero())) {
  16164         EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
  16165         AdvanceIT();
  16166         return;
  16167       }
  16168     } else {
  16169       // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
  16170       if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) {
  16171         EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
  16172         return;
  16173       }
  16174     }
  16175   }
  16176   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand);
  16177 }
  16178 
  16179 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  16180   VIXL_ASSERT(AllowAssembler());
  16181   CheckIT(cond);
  16182   if (IsUsingT32()) {
  16183     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
  16184     if (dt.Is(Untyped8)) {
  16185       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  16186         EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16187         AdvanceIT();
  16188         return;
  16189       }
  16190     }
  16191   } else {
  16192     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
  16193     if (dt.Is(Untyped8)) {
  16194       if (cond.Is(al)) {
  16195         EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16196         return;
  16197       }
  16198     }
  16199   }
  16200   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
  16201 }
  16202 
  16203 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  16204   VIXL_ASSERT(AllowAssembler());
  16205   CheckIT(cond);
  16206   if (IsUsingT32()) {
  16207     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
  16208     if (dt.Is(Untyped8)) {
  16209       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  16210         EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16211         AdvanceIT();
  16212         return;
  16213       }
  16214     }
  16215   } else {
  16216     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
  16217     if (dt.Is(Untyped8)) {
  16218       if (cond.Is(al)) {
  16219         EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16220         return;
  16221       }
  16222     }
  16223   }
  16224   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
  16225 }
  16226 
  16227 void Assembler::vcvt(
  16228     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
  16229   VIXL_ASSERT(AllowAssembler());
  16230   CheckIT(cond);
  16231   Dt_op_2 encoded_dt(dt2);
  16232   if (IsUsingT32()) {
  16233     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
  16234     if (dt1.Is(F64) && dt2.Is(F32)) {
  16235       EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16236       AdvanceIT();
  16237       return;
  16238     }
  16239     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
  16240     if (dt1.Is(F64) && encoded_dt.IsValid()) {
  16241       EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
  16242                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16243       AdvanceIT();
  16244       return;
  16245     }
  16246   } else {
  16247     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
  16248     if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
  16249       EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16250               rm.Encode(5, 0));
  16251       return;
  16252     }
  16253     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
  16254     if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
  16255       EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
  16256               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
  16257               rm.Encode(5, 0));
  16258       return;
  16259     }
  16260   }
  16261   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
  16262 }
  16263 
  16264 void Assembler::vcvt(
  16265     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
  16266   VIXL_ASSERT(AllowAssembler());
  16267   CheckIT(cond);
  16268   if (IsUsingT32()) {
  16269     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
  16270     if (dt1.Is(F32) && dt2.Is(F64)) {
  16271       EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16272       AdvanceIT();
  16273       return;
  16274     }
  16275     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
  16276     if (dt1.Is(U32) && dt2.Is(F64)) {
  16277       EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16278       AdvanceIT();
  16279       return;
  16280     }
  16281     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
  16282     if (dt1.Is(S32) && dt2.Is(F64)) {
  16283       EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16284       AdvanceIT();
  16285       return;
  16286     }
  16287   } else {
  16288     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
  16289     if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
  16290       EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16291               rm.Encode(5, 0));
  16292       return;
  16293     }
  16294     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
  16295     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
  16296       EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16297               rm.Encode(5, 0));
  16298       return;
  16299     }
  16300     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
  16301     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
  16302       EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16303               rm.Encode(5, 0));
  16304       return;
  16305     }
  16306   }
  16307   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
  16308 }
  16309 
  16310 void Assembler::vcvt(Condition cond,
  16311                      DataType dt1,
  16312                      DataType dt2,
  16313                      DRegister rd,
  16314                      DRegister rm,
  16315                      int32_t fbits) {
  16316   VIXL_ASSERT(AllowAssembler());
  16317   CheckIT(cond);
  16318   Dt_op_U_1 encoded_dt(dt1, dt2);
  16319   Dt_U_sx_1 encoded_dt_2(dt2);
  16320   Dt_U_sx_1 encoded_dt_3(dt1);
  16321   if (IsUsingT32()) {
  16322     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
  16323     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
  16324       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  16325         uint32_t fbits_ = 64 - fbits;
  16326         EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
  16327                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
  16328                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
  16329         AdvanceIT();
  16330         return;
  16331       }
  16332     }
  16333     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
  16334     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
  16335         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
  16336          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
  16337       unsigned offset = 32;
  16338       if (dt2.Is(S16) || dt2.Is(U16)) {
  16339         offset = 16;
  16340       }
  16341       uint32_t fbits_ = offset - fbits;
  16342       EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
  16343                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
  16344                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
  16345                  ((fbits_ & 0x1e) >> 1));
  16346       AdvanceIT();
  16347       return;
  16348     }
  16349     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
  16350     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
  16351         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
  16352          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
  16353       unsigned offset = 32;
  16354       if (dt1.Is(S16) || dt1.Is(U16)) {
  16355         offset = 16;
  16356       }
  16357       uint32_t fbits_ = offset - fbits;
  16358       EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
  16359                  ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
  16360                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
  16361                  ((fbits_ & 0x1e) >> 1));
  16362       AdvanceIT();
  16363       return;
  16364     }
  16365   } else {
  16366     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
  16367     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
  16368       if (cond.Is(al)) {
  16369         uint32_t fbits_ = 64 - fbits;
  16370         EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
  16371                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
  16372                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
  16373         return;
  16374       }
  16375     }
  16376     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
  16377     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
  16378         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
  16379          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
  16380         cond.IsNotNever()) {
  16381       unsigned offset = 32;
  16382       if (dt2.Is(S16) || dt2.Is(U16)) {
  16383         offset = 16;
  16384       }
  16385       uint32_t fbits_ = offset - fbits;
  16386       EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
  16387               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
  16388               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
  16389               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
  16390               ((fbits_ & 0x1e) >> 1));
  16391       return;
  16392     }
  16393     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
  16394     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
  16395         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
  16396          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
  16397         cond.IsNotNever()) {
  16398       unsigned offset = 32;
  16399       if (dt1.Is(S16) || dt1.Is(U16)) {
  16400         offset = 16;
  16401       }
  16402       uint32_t fbits_ = offset - fbits;
  16403       EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
  16404               ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
  16405               ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
  16406               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
  16407               ((fbits_ & 0x1e) >> 1));
  16408       return;
  16409     }
  16410   }
  16411   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
  16412 }
  16413 
  16414 void Assembler::vcvt(Condition cond,
  16415                      DataType dt1,
  16416                      DataType dt2,
  16417                      QRegister rd,
  16418                      QRegister rm,
  16419                      int32_t fbits) {
  16420   VIXL_ASSERT(AllowAssembler());
  16421   CheckIT(cond);
  16422   Dt_op_U_1 encoded_dt(dt1, dt2);
  16423   if (IsUsingT32()) {
  16424     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
  16425     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
  16426       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  16427         uint32_t fbits_ = 64 - fbits;
  16428         EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
  16429                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
  16430                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
  16431         AdvanceIT();
  16432         return;
  16433       }
  16434     }
  16435   } else {
  16436     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
  16437     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
  16438       if (cond.Is(al)) {
  16439         uint32_t fbits_ = 64 - fbits;
  16440         EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
  16441                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
  16442                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
  16443         return;
  16444       }
  16445     }
  16446   }
  16447   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
  16448 }
  16449 
  16450 void Assembler::vcvt(Condition cond,
  16451                      DataType dt1,
  16452                      DataType dt2,
  16453                      SRegister rd,
  16454                      SRegister rm,
  16455                      int32_t fbits) {
  16456   VIXL_ASSERT(AllowAssembler());
  16457   CheckIT(cond);
  16458   Dt_U_sx_1 encoded_dt(dt2);
  16459   Dt_U_sx_1 encoded_dt_2(dt1);
  16460   if (IsUsingT32()) {
  16461     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
  16462     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
  16463         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
  16464          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
  16465       unsigned offset = 32;
  16466       if (dt2.Is(S16) || dt2.Is(U16)) {
  16467         offset = 16;
  16468       }
  16469       uint32_t fbits_ = offset - fbits;
  16470       EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
  16471                  ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
  16472                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
  16473                  ((fbits_ & 0x1e) >> 1));
  16474       AdvanceIT();
  16475       return;
  16476     }
  16477     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
  16478     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
  16479         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
  16480          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
  16481       unsigned offset = 32;
  16482       if (dt1.Is(S16) || dt1.Is(U16)) {
  16483         offset = 16;
  16484       }
  16485       uint32_t fbits_ = offset - fbits;
  16486       EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
  16487                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
  16488                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
  16489                  ((fbits_ & 0x1e) >> 1));
  16490       AdvanceIT();
  16491       return;
  16492     }
  16493   } else {
  16494     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
  16495     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
  16496         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
  16497          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
  16498         cond.IsNotNever()) {
  16499       unsigned offset = 32;
  16500       if (dt2.Is(S16) || dt2.Is(U16)) {
  16501         offset = 16;
  16502       }
  16503       uint32_t fbits_ = offset - fbits;
  16504       EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
  16505               ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
  16506               ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
  16507               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
  16508               ((fbits_ & 0x1e) >> 1));
  16509       return;
  16510     }
  16511     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
  16512     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
  16513         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
  16514          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
  16515         cond.IsNotNever()) {
  16516       unsigned offset = 32;
  16517       if (dt1.Is(S16) || dt1.Is(U16)) {
  16518         offset = 16;
  16519       }
  16520       uint32_t fbits_ = offset - fbits;
  16521       EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
  16522               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
  16523               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
  16524               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
  16525               ((fbits_ & 0x1e) >> 1));
  16526       return;
  16527     }
  16528   }
  16529   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
  16530 }
  16531 
  16532 void Assembler::vcvt(
  16533     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
  16534   VIXL_ASSERT(AllowAssembler());
  16535   CheckIT(cond);
  16536   Dt_op_1 encoded_dt(dt1, dt2);
  16537   if (IsUsingT32()) {
  16538     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
  16539     if (encoded_dt.IsValid()) {
  16540       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  16541         EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
  16542                    rd.Encode(22, 12) | rm.Encode(5, 0));
  16543         AdvanceIT();
  16544         return;
  16545       }
  16546     }
  16547   } else {
  16548     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
  16549     if (encoded_dt.IsValid()) {
  16550       if (cond.Is(al)) {
  16551         EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
  16552                 rd.Encode(22, 12) | rm.Encode(5, 0));
  16553         return;
  16554       }
  16555     }
  16556   }
  16557   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
  16558 }
  16559 
  16560 void Assembler::vcvt(
  16561     Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
  16562   VIXL_ASSERT(AllowAssembler());
  16563   CheckIT(cond);
  16564   Dt_op_1 encoded_dt(dt1, dt2);
  16565   if (IsUsingT32()) {
  16566     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
  16567     if (encoded_dt.IsValid()) {
  16568       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  16569         EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
  16570                    rd.Encode(22, 12) | rm.Encode(5, 0));
  16571         AdvanceIT();
  16572         return;
  16573       }
  16574     }
  16575   } else {
  16576     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
  16577     if (encoded_dt.IsValid()) {
  16578       if (cond.Is(al)) {
  16579         EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
  16580                 rd.Encode(22, 12) | rm.Encode(5, 0));
  16581         return;
  16582       }
  16583     }
  16584   }
  16585   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
  16586 }
  16587 
  16588 void Assembler::vcvt(
  16589     Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
  16590   VIXL_ASSERT(AllowAssembler());
  16591   CheckIT(cond);
  16592   if (IsUsingT32()) {
  16593     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
  16594     if (dt1.Is(F16) && dt2.Is(F32)) {
  16595       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  16596         EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16597         AdvanceIT();
  16598         return;
  16599       }
  16600     }
  16601   } else {
  16602     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
  16603     if (dt1.Is(F16) && dt2.Is(F32)) {
  16604       if (cond.Is(al)) {
  16605         EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16606         return;
  16607       }
  16608     }
  16609   }
  16610   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
  16611 }
  16612 
  16613 void Assembler::vcvt(
  16614     Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
  16615   VIXL_ASSERT(AllowAssembler());
  16616   CheckIT(cond);
  16617   if (IsUsingT32()) {
  16618     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
  16619     if (dt1.Is(F32) && dt2.Is(F16)) {
  16620       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  16621         EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16622         AdvanceIT();
  16623         return;
  16624       }
  16625     }
  16626   } else {
  16627     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
  16628     if (dt1.Is(F32) && dt2.Is(F16)) {
  16629       if (cond.Is(al)) {
  16630         EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16631         return;
  16632       }
  16633     }
  16634   }
  16635   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
  16636 }
  16637 
  16638 void Assembler::vcvt(
  16639     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
  16640   VIXL_ASSERT(AllowAssembler());
  16641   CheckIT(cond);
  16642   Dt_op_2 encoded_dt(dt2);
  16643   if (IsUsingT32()) {
  16644     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
  16645     if (dt1.Is(U32) && dt2.Is(F32)) {
  16646       EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16647       AdvanceIT();
  16648       return;
  16649     }
  16650     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
  16651     if (dt1.Is(S32) && dt2.Is(F32)) {
  16652       EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16653       AdvanceIT();
  16654       return;
  16655     }
  16656     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
  16657     if (dt1.Is(F32) && encoded_dt.IsValid()) {
  16658       EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
  16659                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16660       AdvanceIT();
  16661       return;
  16662     }
  16663   } else {
  16664     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
  16665     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
  16666       EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16667               rm.Encode(5, 0));
  16668       return;
  16669     }
  16670     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
  16671     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
  16672       EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16673               rm.Encode(5, 0));
  16674       return;
  16675     }
  16676     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
  16677     if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
  16678       EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
  16679               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
  16680               rm.Encode(5, 0));
  16681       return;
  16682     }
  16683   }
  16684   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
  16685 }
  16686 
  16687 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
  16688   VIXL_ASSERT(AllowAssembler());
  16689   CheckIT(al);
  16690   Dt_op_3 encoded_dt(dt1);
  16691   if (IsUsingT32()) {
  16692     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
  16693     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16694       EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
  16695                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16696       AdvanceIT();
  16697       return;
  16698     }
  16699   } else {
  16700     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
  16701     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16702       EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
  16703               rd.Encode(22, 12) | rm.Encode(5, 0));
  16704       return;
  16705     }
  16706   }
  16707   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
  16708 }
  16709 
  16710 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
  16711   VIXL_ASSERT(AllowAssembler());
  16712   CheckIT(al);
  16713   Dt_op_3 encoded_dt(dt1);
  16714   if (IsUsingT32()) {
  16715     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
  16716     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16717       EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
  16718                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16719       AdvanceIT();
  16720       return;
  16721     }
  16722   } else {
  16723     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
  16724     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16725       EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
  16726               rd.Encode(22, 12) | rm.Encode(5, 0));
  16727       return;
  16728     }
  16729   }
  16730   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
  16731 }
  16732 
  16733 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
  16734   VIXL_ASSERT(AllowAssembler());
  16735   CheckIT(al);
  16736   Dt_op_2 encoded_dt(dt1);
  16737   if (IsUsingT32()) {
  16738     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
  16739     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16740       EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
  16741                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16742       AdvanceIT();
  16743       return;
  16744     }
  16745   } else {
  16746     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
  16747     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16748       EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
  16749               rd.Encode(22, 12) | rm.Encode(5, 0));
  16750       return;
  16751     }
  16752   }
  16753   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
  16754 }
  16755 
  16756 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
  16757   VIXL_ASSERT(AllowAssembler());
  16758   CheckIT(al);
  16759   Dt_op_2 encoded_dt(dt1);
  16760   if (IsUsingT32()) {
  16761     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
  16762     if (encoded_dt.IsValid() && dt2.Is(F64)) {
  16763       EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
  16764                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16765       AdvanceIT();
  16766       return;
  16767     }
  16768   } else {
  16769     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
  16770     if (encoded_dt.IsValid() && dt2.Is(F64)) {
  16771       EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
  16772               rd.Encode(22, 12) | rm.Encode(5, 0));
  16773       return;
  16774     }
  16775   }
  16776   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
  16777 }
  16778 
  16779 void Assembler::vcvtb(
  16780     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
  16781   VIXL_ASSERT(AllowAssembler());
  16782   CheckIT(cond);
  16783   if (IsUsingT32()) {
  16784     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
  16785     if (dt1.Is(F32) && dt2.Is(F16)) {
  16786       EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16787       AdvanceIT();
  16788       return;
  16789     }
  16790     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
  16791     if (dt1.Is(F16) && dt2.Is(F32)) {
  16792       EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16793       AdvanceIT();
  16794       return;
  16795     }
  16796   } else {
  16797     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
  16798     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
  16799       EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16800               rm.Encode(5, 0));
  16801       return;
  16802     }
  16803     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
  16804     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
  16805       EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16806               rm.Encode(5, 0));
  16807       return;
  16808     }
  16809   }
  16810   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
  16811 }
  16812 
  16813 void Assembler::vcvtb(
  16814     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
  16815   VIXL_ASSERT(AllowAssembler());
  16816   CheckIT(cond);
  16817   if (IsUsingT32()) {
  16818     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
  16819     if (dt1.Is(F64) && dt2.Is(F16)) {
  16820       EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16821       AdvanceIT();
  16822       return;
  16823     }
  16824   } else {
  16825     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
  16826     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
  16827       EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16828               rm.Encode(5, 0));
  16829       return;
  16830     }
  16831   }
  16832   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
  16833 }
  16834 
  16835 void Assembler::vcvtb(
  16836     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
  16837   VIXL_ASSERT(AllowAssembler());
  16838   CheckIT(cond);
  16839   if (IsUsingT32()) {
  16840     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
  16841     if (dt1.Is(F16) && dt2.Is(F64)) {
  16842       EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  16843       AdvanceIT();
  16844       return;
  16845     }
  16846   } else {
  16847     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
  16848     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
  16849       EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  16850               rm.Encode(5, 0));
  16851       return;
  16852     }
  16853   }
  16854   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
  16855 }
  16856 
  16857 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
  16858   VIXL_ASSERT(AllowAssembler());
  16859   CheckIT(al);
  16860   Dt_op_3 encoded_dt(dt1);
  16861   if (IsUsingT32()) {
  16862     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
  16863     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16864       EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
  16865                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16866       AdvanceIT();
  16867       return;
  16868     }
  16869   } else {
  16870     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
  16871     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16872       EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
  16873               rd.Encode(22, 12) | rm.Encode(5, 0));
  16874       return;
  16875     }
  16876   }
  16877   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
  16878 }
  16879 
  16880 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
  16881   VIXL_ASSERT(AllowAssembler());
  16882   CheckIT(al);
  16883   Dt_op_3 encoded_dt(dt1);
  16884   if (IsUsingT32()) {
  16885     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
  16886     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16887       EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
  16888                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16889       AdvanceIT();
  16890       return;
  16891     }
  16892   } else {
  16893     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
  16894     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16895       EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
  16896               rd.Encode(22, 12) | rm.Encode(5, 0));
  16897       return;
  16898     }
  16899   }
  16900   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
  16901 }
  16902 
  16903 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
  16904   VIXL_ASSERT(AllowAssembler());
  16905   CheckIT(al);
  16906   Dt_op_2 encoded_dt(dt1);
  16907   if (IsUsingT32()) {
  16908     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
  16909     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16910       EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
  16911                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16912       AdvanceIT();
  16913       return;
  16914     }
  16915   } else {
  16916     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
  16917     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16918       EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
  16919               rd.Encode(22, 12) | rm.Encode(5, 0));
  16920       return;
  16921     }
  16922   }
  16923   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
  16924 }
  16925 
  16926 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
  16927   VIXL_ASSERT(AllowAssembler());
  16928   CheckIT(al);
  16929   Dt_op_2 encoded_dt(dt1);
  16930   if (IsUsingT32()) {
  16931     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
  16932     if (encoded_dt.IsValid() && dt2.Is(F64)) {
  16933       EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
  16934                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16935       AdvanceIT();
  16936       return;
  16937     }
  16938   } else {
  16939     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
  16940     if (encoded_dt.IsValid() && dt2.Is(F64)) {
  16941       EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
  16942               rd.Encode(22, 12) | rm.Encode(5, 0));
  16943       return;
  16944     }
  16945   }
  16946   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
  16947 }
  16948 
  16949 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
  16950   VIXL_ASSERT(AllowAssembler());
  16951   CheckIT(al);
  16952   Dt_op_3 encoded_dt(dt1);
  16953   if (IsUsingT32()) {
  16954     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
  16955     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16956       EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
  16957                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16958       AdvanceIT();
  16959       return;
  16960     }
  16961   } else {
  16962     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
  16963     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16964       EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
  16965               rd.Encode(22, 12) | rm.Encode(5, 0));
  16966       return;
  16967     }
  16968   }
  16969   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
  16970 }
  16971 
  16972 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
  16973   VIXL_ASSERT(AllowAssembler());
  16974   CheckIT(al);
  16975   Dt_op_3 encoded_dt(dt1);
  16976   if (IsUsingT32()) {
  16977     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
  16978     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16979       EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
  16980                  rd.Encode(22, 12) | rm.Encode(5, 0));
  16981       AdvanceIT();
  16982       return;
  16983     }
  16984   } else {
  16985     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
  16986     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  16987       EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
  16988               rd.Encode(22, 12) | rm.Encode(5, 0));
  16989       return;
  16990     }
  16991   }
  16992   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
  16993 }
  16994 
  16995 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
  16996   VIXL_ASSERT(AllowAssembler());
  16997   CheckIT(al);
  16998   Dt_op_2 encoded_dt(dt1);
  16999   if (IsUsingT32()) {
  17000     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
  17001     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  17002       EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
  17003                  rd.Encode(22, 12) | rm.Encode(5, 0));
  17004       AdvanceIT();
  17005       return;
  17006     }
  17007   } else {
  17008     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
  17009     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  17010       EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
  17011               rd.Encode(22, 12) | rm.Encode(5, 0));
  17012       return;
  17013     }
  17014   }
  17015   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
  17016 }
  17017 
  17018 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
  17019   VIXL_ASSERT(AllowAssembler());
  17020   CheckIT(al);
  17021   Dt_op_2 encoded_dt(dt1);
  17022   if (IsUsingT32()) {
  17023     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
  17024     if (encoded_dt.IsValid() && dt2.Is(F64)) {
  17025       EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
  17026                  rd.Encode(22, 12) | rm.Encode(5, 0));
  17027       AdvanceIT();
  17028       return;
  17029     }
  17030   } else {
  17031     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
  17032     if (encoded_dt.IsValid() && dt2.Is(F64)) {
  17033       EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
  17034               rd.Encode(22, 12) | rm.Encode(5, 0));
  17035       return;
  17036     }
  17037   }
  17038   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
  17039 }
  17040 
  17041 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
  17042   VIXL_ASSERT(AllowAssembler());
  17043   CheckIT(al);
  17044   Dt_op_3 encoded_dt(dt1);
  17045   if (IsUsingT32()) {
  17046     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
  17047     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  17048       EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
  17049                  rd.Encode(22, 12) | rm.Encode(5, 0));
  17050       AdvanceIT();
  17051       return;
  17052     }
  17053   } else {
  17054     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
  17055     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  17056       EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
  17057               rd.Encode(22, 12) | rm.Encode(5, 0));
  17058       return;
  17059     }
  17060   }
  17061   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
  17062 }
  17063 
  17064 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
  17065   VIXL_ASSERT(AllowAssembler());
  17066   CheckIT(al);
  17067   Dt_op_3 encoded_dt(dt1);
  17068   if (IsUsingT32()) {
  17069     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
  17070     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  17071       EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
  17072                  rd.Encode(22, 12) | rm.Encode(5, 0));
  17073       AdvanceIT();
  17074       return;
  17075     }
  17076   } else {
  17077     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
  17078     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  17079       EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
  17080               rd.Encode(22, 12) | rm.Encode(5, 0));
  17081       return;
  17082     }
  17083   }
  17084   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
  17085 }
  17086 
  17087 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
  17088   VIXL_ASSERT(AllowAssembler());
  17089   CheckIT(al);
  17090   Dt_op_2 encoded_dt(dt1);
  17091   if (IsUsingT32()) {
  17092     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
  17093     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  17094       EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
  17095                  rd.Encode(22, 12) | rm.Encode(5, 0));
  17096       AdvanceIT();
  17097       return;
  17098     }
  17099   } else {
  17100     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
  17101     if (encoded_dt.IsValid() && dt2.Is(F32)) {
  17102       EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
  17103               rd.Encode(22, 12) | rm.Encode(5, 0));
  17104       return;
  17105     }
  17106   }
  17107   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
  17108 }
  17109 
  17110 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
  17111   VIXL_ASSERT(AllowAssembler());
  17112   CheckIT(al);
  17113   Dt_op_2 encoded_dt(dt1);
  17114   if (IsUsingT32()) {
  17115     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
  17116     if (encoded_dt.IsValid() && dt2.Is(F64)) {
  17117       EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
  17118                  rd.Encode(22, 12) | rm.Encode(5, 0));
  17119       AdvanceIT();
  17120       return;
  17121     }
  17122   } else {
  17123     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
  17124     if (encoded_dt.IsValid() && dt2.Is(F64)) {
  17125       EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
  17126               rd.Encode(22, 12) | rm.Encode(5, 0));
  17127       return;
  17128     }
  17129   }
  17130   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
  17131 }
  17132 
  17133 void Assembler::vcvtr(
  17134     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
  17135   VIXL_ASSERT(AllowAssembler());
  17136   CheckIT(cond);
  17137   if (IsUsingT32()) {
  17138     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
  17139     if (dt1.Is(U32) && dt2.Is(F32)) {
  17140       EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  17141       AdvanceIT();
  17142       return;
  17143     }
  17144     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
  17145     if (dt1.Is(S32) && dt2.Is(F32)) {
  17146       EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  17147       AdvanceIT();
  17148       return;
  17149     }
  17150   } else {
  17151     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
  17152     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
  17153       EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17154               rm.Encode(5, 0));
  17155       return;
  17156     }
  17157     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
  17158     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
  17159       EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17160               rm.Encode(5, 0));
  17161       return;
  17162     }
  17163   }
  17164   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
  17165 }
  17166 
  17167 void Assembler::vcvtr(
  17168     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
  17169   VIXL_ASSERT(AllowAssembler());
  17170   CheckIT(cond);
  17171   if (IsUsingT32()) {
  17172     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
  17173     if (dt1.Is(U32) && dt2.Is(F64)) {
  17174       EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  17175       AdvanceIT();
  17176       return;
  17177     }
  17178     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
  17179     if (dt1.Is(S32) && dt2.Is(F64)) {
  17180       EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  17181       AdvanceIT();
  17182       return;
  17183     }
  17184   } else {
  17185     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
  17186     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
  17187       EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17188               rm.Encode(5, 0));
  17189       return;
  17190     }
  17191     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
  17192     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
  17193       EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17194               rm.Encode(5, 0));
  17195       return;
  17196     }
  17197   }
  17198   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
  17199 }
  17200 
  17201 void Assembler::vcvtt(
  17202     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
  17203   VIXL_ASSERT(AllowAssembler());
  17204   CheckIT(cond);
  17205   if (IsUsingT32()) {
  17206     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
  17207     if (dt1.Is(F32) && dt2.Is(F16)) {
  17208       EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  17209       AdvanceIT();
  17210       return;
  17211     }
  17212     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
  17213     if (dt1.Is(F16) && dt2.Is(F32)) {
  17214       EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  17215       AdvanceIT();
  17216       return;
  17217     }
  17218   } else {
  17219     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
  17220     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
  17221       EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17222               rm.Encode(5, 0));
  17223       return;
  17224     }
  17225     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
  17226     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
  17227       EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17228               rm.Encode(5, 0));
  17229       return;
  17230     }
  17231   }
  17232   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
  17233 }
  17234 
  17235 void Assembler::vcvtt(
  17236     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
  17237   VIXL_ASSERT(AllowAssembler());
  17238   CheckIT(cond);
  17239   if (IsUsingT32()) {
  17240     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
  17241     if (dt1.Is(F64) && dt2.Is(F16)) {
  17242       EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  17243       AdvanceIT();
  17244       return;
  17245     }
  17246   } else {
  17247     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
  17248     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
  17249       EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17250               rm.Encode(5, 0));
  17251       return;
  17252     }
  17253   }
  17254   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
  17255 }
  17256 
  17257 void Assembler::vcvtt(
  17258     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
  17259   VIXL_ASSERT(AllowAssembler());
  17260   CheckIT(cond);
  17261   if (IsUsingT32()) {
  17262     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
  17263     if (dt1.Is(F16) && dt2.Is(F64)) {
  17264       EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  17265       AdvanceIT();
  17266       return;
  17267     }
  17268   } else {
  17269     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
  17270     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
  17271       EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17272               rm.Encode(5, 0));
  17273       return;
  17274     }
  17275   }
  17276   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
  17277 }
  17278 
  17279 void Assembler::vdiv(
  17280     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  17281   VIXL_ASSERT(AllowAssembler());
  17282   CheckIT(cond);
  17283   if (IsUsingT32()) {
  17284     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
  17285     if (dt.Is(F32)) {
  17286       EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17287                  rm.Encode(5, 0));
  17288       AdvanceIT();
  17289       return;
  17290     }
  17291   } else {
  17292     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
  17293     if (dt.Is(F32) && cond.IsNotNever()) {
  17294       EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17295               rn.Encode(7, 16) | rm.Encode(5, 0));
  17296       return;
  17297     }
  17298   }
  17299   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
  17300 }
  17301 
  17302 void Assembler::vdiv(
  17303     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  17304   VIXL_ASSERT(AllowAssembler());
  17305   CheckIT(cond);
  17306   if (IsUsingT32()) {
  17307     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
  17308     if (dt.Is(F64)) {
  17309       EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17310                  rm.Encode(5, 0));
  17311       AdvanceIT();
  17312       return;
  17313     }
  17314   } else {
  17315     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
  17316     if (dt.Is(F64) && cond.IsNotNever()) {
  17317       EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17318               rn.Encode(7, 16) | rm.Encode(5, 0));
  17319       return;
  17320     }
  17321   }
  17322   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
  17323 }
  17324 
  17325 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
  17326   VIXL_ASSERT(AllowAssembler());
  17327   CheckIT(cond);
  17328   Dt_B_E_1 encoded_dt(dt);
  17329   if (IsUsingT32()) {
  17330     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
  17331     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
  17332       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17333         EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
  17334                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
  17335                    rd.Encode(7, 16) | (rt.GetCode() << 12));
  17336         AdvanceIT();
  17337         return;
  17338       }
  17339     }
  17340   } else {
  17341     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
  17342     if (encoded_dt.IsValid() && cond.IsNotNever() &&
  17343         (!rt.IsPC() || AllowUnpredictable())) {
  17344       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17345         EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
  17346                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
  17347                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
  17348                 rd.Encode(7, 16) | (rt.GetCode() << 12));
  17349         return;
  17350       }
  17351     }
  17352   }
  17353   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
  17354 }
  17355 
  17356 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
  17357   VIXL_ASSERT(AllowAssembler());
  17358   CheckIT(cond);
  17359   Dt_B_E_1 encoded_dt(dt);
  17360   if (IsUsingT32()) {
  17361     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
  17362     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
  17363       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17364         EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
  17365                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
  17366                    rd.Encode(7, 16) | (rt.GetCode() << 12));
  17367         AdvanceIT();
  17368         return;
  17369       }
  17370     }
  17371   } else {
  17372     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
  17373     if (encoded_dt.IsValid() && cond.IsNotNever() &&
  17374         (!rt.IsPC() || AllowUnpredictable())) {
  17375       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17376         EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
  17377                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
  17378                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
  17379                 rd.Encode(7, 16) | (rt.GetCode() << 12));
  17380         return;
  17381       }
  17382     }
  17383   }
  17384   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
  17385 }
  17386 
  17387 void Assembler::vdup(Condition cond,
  17388                      DataType dt,
  17389                      DRegister rd,
  17390                      DRegisterLane rm) {
  17391   VIXL_ASSERT(AllowAssembler());
  17392   CheckIT(cond);
  17393   Dt_imm4_1 encoded_dt(dt, rm);
  17394   if (IsUsingT32()) {
  17395     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
  17396     if (encoded_dt.IsValid()) {
  17397       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17398         EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
  17399                    rd.Encode(22, 12) | rm.Encode(5, 0));
  17400         AdvanceIT();
  17401         return;
  17402       }
  17403     }
  17404   } else {
  17405     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
  17406     if (encoded_dt.IsValid()) {
  17407       if (cond.Is(al)) {
  17408         EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
  17409                 rd.Encode(22, 12) | rm.Encode(5, 0));
  17410         return;
  17411       }
  17412     }
  17413   }
  17414   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
  17415 }
  17416 
  17417 void Assembler::vdup(Condition cond,
  17418                      DataType dt,
  17419                      QRegister rd,
  17420                      DRegisterLane rm) {
  17421   VIXL_ASSERT(AllowAssembler());
  17422   CheckIT(cond);
  17423   Dt_imm4_1 encoded_dt(dt, rm);
  17424   if (IsUsingT32()) {
  17425     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
  17426     if (encoded_dt.IsValid()) {
  17427       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17428         EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
  17429                    rd.Encode(22, 12) | rm.Encode(5, 0));
  17430         AdvanceIT();
  17431         return;
  17432       }
  17433     }
  17434   } else {
  17435     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
  17436     if (encoded_dt.IsValid()) {
  17437       if (cond.Is(al)) {
  17438         EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
  17439                 rd.Encode(22, 12) | rm.Encode(5, 0));
  17440         return;
  17441       }
  17442     }
  17443   }
  17444   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
  17445 }
  17446 
  17447 void Assembler::veor(
  17448     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  17449   VIXL_ASSERT(AllowAssembler());
  17450   CheckIT(cond);
  17451   USE(dt);
  17452   if (IsUsingT32()) {
  17453     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
  17454     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17455       EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17456                  rm.Encode(5, 0));
  17457       AdvanceIT();
  17458       return;
  17459     }
  17460   } else {
  17461     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
  17462     if (cond.Is(al)) {
  17463       EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17464               rm.Encode(5, 0));
  17465       return;
  17466     }
  17467   }
  17468   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
  17469 }
  17470 
  17471 void Assembler::veor(
  17472     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  17473   VIXL_ASSERT(AllowAssembler());
  17474   CheckIT(cond);
  17475   USE(dt);
  17476   if (IsUsingT32()) {
  17477     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
  17478     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17479       EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17480                  rm.Encode(5, 0));
  17481       AdvanceIT();
  17482       return;
  17483     }
  17484   } else {
  17485     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
  17486     if (cond.Is(al)) {
  17487       EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17488               rm.Encode(5, 0));
  17489       return;
  17490     }
  17491   }
  17492   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
  17493 }
  17494 
  17495 void Assembler::vext(Condition cond,
  17496                      DataType dt,
  17497                      DRegister rd,
  17498                      DRegister rn,
  17499                      DRegister rm,
  17500                      const DOperand& operand) {
  17501   VIXL_ASSERT(AllowAssembler());
  17502   CheckIT(cond);
  17503   if (operand.IsImmediate()) {
  17504     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  17505       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  17506       if (IsUsingT32()) {
  17507         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
  17508         if (dt.Is(Untyped8) && (imm <= 7)) {
  17509           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17510             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17511                        rm.Encode(5, 0) | (imm << 8));
  17512             AdvanceIT();
  17513             return;
  17514           }
  17515         }
  17516         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
  17517         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
  17518             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
  17519           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17520             uint32_t imm4 = imm / dt.GetSize();
  17521             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17522                        rm.Encode(5, 0) | (imm4 << 8));
  17523             AdvanceIT();
  17524             return;
  17525           }
  17526         }
  17527       } else {
  17528         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
  17529         if (dt.Is(Untyped8) && (imm <= 7)) {
  17530           if (cond.Is(al)) {
  17531             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17532                     rm.Encode(5, 0) | (imm << 8));
  17533             return;
  17534           }
  17535         }
  17536         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
  17537         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
  17538             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
  17539           if (cond.Is(al)) {
  17540             uint32_t imm4 = imm / dt.GetSize();
  17541             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17542                     rm.Encode(5, 0) | (imm4 << 8));
  17543             return;
  17544           }
  17545         }
  17546       }
  17547     }
  17548   }
  17549   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
  17550 }
  17551 
  17552 void Assembler::vext(Condition cond,
  17553                      DataType dt,
  17554                      QRegister rd,
  17555                      QRegister rn,
  17556                      QRegister rm,
  17557                      const QOperand& operand) {
  17558   VIXL_ASSERT(AllowAssembler());
  17559   CheckIT(cond);
  17560   if (operand.IsImmediate()) {
  17561     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  17562       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  17563       if (IsUsingT32()) {
  17564         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
  17565         if (dt.Is(Untyped8) && (imm <= 15)) {
  17566           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17567             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17568                        rm.Encode(5, 0) | (imm << 8));
  17569             AdvanceIT();
  17570             return;
  17571           }
  17572         }
  17573         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
  17574         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
  17575             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
  17576           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17577             uint32_t imm4 = imm / dt.GetSize();
  17578             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17579                        rm.Encode(5, 0) | (imm4 << 8));
  17580             AdvanceIT();
  17581             return;
  17582           }
  17583         }
  17584       } else {
  17585         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
  17586         if (dt.Is(Untyped8) && (imm <= 15)) {
  17587           if (cond.Is(al)) {
  17588             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17589                     rm.Encode(5, 0) | (imm << 8));
  17590             return;
  17591           }
  17592         }
  17593         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
  17594         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
  17595             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
  17596           if (cond.Is(al)) {
  17597             uint32_t imm4 = imm / dt.GetSize();
  17598             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17599                     rm.Encode(5, 0) | (imm4 << 8));
  17600             return;
  17601           }
  17602         }
  17603       }
  17604     }
  17605   }
  17606   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
  17607 }
  17608 
  17609 void Assembler::vfma(
  17610     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  17611   VIXL_ASSERT(AllowAssembler());
  17612   CheckIT(cond);
  17613   if (IsUsingT32()) {
  17614     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
  17615     if (dt.Is(F32)) {
  17616       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17617         EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17618                    rm.Encode(5, 0));
  17619         AdvanceIT();
  17620         return;
  17621       }
  17622     }
  17623     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
  17624     if (dt.Is(F64)) {
  17625       EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17626                  rm.Encode(5, 0));
  17627       AdvanceIT();
  17628       return;
  17629     }
  17630   } else {
  17631     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
  17632     if (dt.Is(F32)) {
  17633       if (cond.Is(al)) {
  17634         EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17635                 rm.Encode(5, 0));
  17636         return;
  17637       }
  17638     }
  17639     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
  17640     if (dt.Is(F64) && cond.IsNotNever()) {
  17641       EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17642               rn.Encode(7, 16) | rm.Encode(5, 0));
  17643       return;
  17644     }
  17645   }
  17646   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
  17647 }
  17648 
  17649 void Assembler::vfma(
  17650     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  17651   VIXL_ASSERT(AllowAssembler());
  17652   CheckIT(cond);
  17653   if (IsUsingT32()) {
  17654     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
  17655     if (dt.Is(F32)) {
  17656       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17657         EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17658                    rm.Encode(5, 0));
  17659         AdvanceIT();
  17660         return;
  17661       }
  17662     }
  17663   } else {
  17664     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
  17665     if (dt.Is(F32)) {
  17666       if (cond.Is(al)) {
  17667         EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17668                 rm.Encode(5, 0));
  17669         return;
  17670       }
  17671     }
  17672   }
  17673   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
  17674 }
  17675 
  17676 void Assembler::vfma(
  17677     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  17678   VIXL_ASSERT(AllowAssembler());
  17679   CheckIT(cond);
  17680   if (IsUsingT32()) {
  17681     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
  17682     if (dt.Is(F32)) {
  17683       EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17684                  rm.Encode(5, 0));
  17685       AdvanceIT();
  17686       return;
  17687     }
  17688   } else {
  17689     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
  17690     if (dt.Is(F32) && cond.IsNotNever()) {
  17691       EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17692               rn.Encode(7, 16) | rm.Encode(5, 0));
  17693       return;
  17694     }
  17695   }
  17696   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
  17697 }
  17698 
  17699 void Assembler::vfms(
  17700     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  17701   VIXL_ASSERT(AllowAssembler());
  17702   CheckIT(cond);
  17703   if (IsUsingT32()) {
  17704     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
  17705     if (dt.Is(F32)) {
  17706       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17707         EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17708                    rm.Encode(5, 0));
  17709         AdvanceIT();
  17710         return;
  17711       }
  17712     }
  17713     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
  17714     if (dt.Is(F64)) {
  17715       EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17716                  rm.Encode(5, 0));
  17717       AdvanceIT();
  17718       return;
  17719     }
  17720   } else {
  17721     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
  17722     if (dt.Is(F32)) {
  17723       if (cond.Is(al)) {
  17724         EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17725                 rm.Encode(5, 0));
  17726         return;
  17727       }
  17728     }
  17729     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
  17730     if (dt.Is(F64) && cond.IsNotNever()) {
  17731       EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17732               rn.Encode(7, 16) | rm.Encode(5, 0));
  17733       return;
  17734     }
  17735   }
  17736   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
  17737 }
  17738 
  17739 void Assembler::vfms(
  17740     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  17741   VIXL_ASSERT(AllowAssembler());
  17742   CheckIT(cond);
  17743   if (IsUsingT32()) {
  17744     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
  17745     if (dt.Is(F32)) {
  17746       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17747         EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17748                    rm.Encode(5, 0));
  17749         AdvanceIT();
  17750         return;
  17751       }
  17752     }
  17753   } else {
  17754     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
  17755     if (dt.Is(F32)) {
  17756       if (cond.Is(al)) {
  17757         EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17758                 rm.Encode(5, 0));
  17759         return;
  17760       }
  17761     }
  17762   }
  17763   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
  17764 }
  17765 
  17766 void Assembler::vfms(
  17767     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  17768   VIXL_ASSERT(AllowAssembler());
  17769   CheckIT(cond);
  17770   if (IsUsingT32()) {
  17771     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
  17772     if (dt.Is(F32)) {
  17773       EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17774                  rm.Encode(5, 0));
  17775       AdvanceIT();
  17776       return;
  17777     }
  17778   } else {
  17779     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
  17780     if (dt.Is(F32) && cond.IsNotNever()) {
  17781       EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17782               rn.Encode(7, 16) | rm.Encode(5, 0));
  17783       return;
  17784     }
  17785   }
  17786   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
  17787 }
  17788 
  17789 void Assembler::vfnma(
  17790     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  17791   VIXL_ASSERT(AllowAssembler());
  17792   CheckIT(cond);
  17793   if (IsUsingT32()) {
  17794     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
  17795     if (dt.Is(F32)) {
  17796       EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17797                  rm.Encode(5, 0));
  17798       AdvanceIT();
  17799       return;
  17800     }
  17801   } else {
  17802     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
  17803     if (dt.Is(F32) && cond.IsNotNever()) {
  17804       EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17805               rn.Encode(7, 16) | rm.Encode(5, 0));
  17806       return;
  17807     }
  17808   }
  17809   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
  17810 }
  17811 
  17812 void Assembler::vfnma(
  17813     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  17814   VIXL_ASSERT(AllowAssembler());
  17815   CheckIT(cond);
  17816   if (IsUsingT32()) {
  17817     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
  17818     if (dt.Is(F64)) {
  17819       EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17820                  rm.Encode(5, 0));
  17821       AdvanceIT();
  17822       return;
  17823     }
  17824   } else {
  17825     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
  17826     if (dt.Is(F64) && cond.IsNotNever()) {
  17827       EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17828               rn.Encode(7, 16) | rm.Encode(5, 0));
  17829       return;
  17830     }
  17831   }
  17832   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
  17833 }
  17834 
  17835 void Assembler::vfnms(
  17836     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  17837   VIXL_ASSERT(AllowAssembler());
  17838   CheckIT(cond);
  17839   if (IsUsingT32()) {
  17840     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
  17841     if (dt.Is(F32)) {
  17842       EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17843                  rm.Encode(5, 0));
  17844       AdvanceIT();
  17845       return;
  17846     }
  17847   } else {
  17848     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
  17849     if (dt.Is(F32) && cond.IsNotNever()) {
  17850       EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17851               rn.Encode(7, 16) | rm.Encode(5, 0));
  17852       return;
  17853     }
  17854   }
  17855   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
  17856 }
  17857 
  17858 void Assembler::vfnms(
  17859     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  17860   VIXL_ASSERT(AllowAssembler());
  17861   CheckIT(cond);
  17862   if (IsUsingT32()) {
  17863     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
  17864     if (dt.Is(F64)) {
  17865       EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  17866                  rm.Encode(5, 0));
  17867       AdvanceIT();
  17868       return;
  17869     }
  17870   } else {
  17871     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
  17872     if (dt.Is(F64) && cond.IsNotNever()) {
  17873       EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  17874               rn.Encode(7, 16) | rm.Encode(5, 0));
  17875       return;
  17876     }
  17877   }
  17878   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
  17879 }
  17880 
  17881 void Assembler::vhadd(
  17882     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  17883   VIXL_ASSERT(AllowAssembler());
  17884   CheckIT(cond);
  17885   Dt_U_size_1 encoded_dt(dt);
  17886   if (IsUsingT32()) {
  17887     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  17888     if (encoded_dt.IsValid()) {
  17889       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17890         EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  17891                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  17892                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  17893         AdvanceIT();
  17894         return;
  17895       }
  17896     }
  17897   } else {
  17898     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  17899     if (encoded_dt.IsValid()) {
  17900       if (cond.Is(al)) {
  17901         EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  17902                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  17903                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  17904         return;
  17905       }
  17906     }
  17907   }
  17908   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
  17909 }
  17910 
  17911 void Assembler::vhadd(
  17912     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  17913   VIXL_ASSERT(AllowAssembler());
  17914   CheckIT(cond);
  17915   Dt_U_size_1 encoded_dt(dt);
  17916   if (IsUsingT32()) {
  17917     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  17918     if (encoded_dt.IsValid()) {
  17919       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17920         EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  17921                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  17922                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  17923         AdvanceIT();
  17924         return;
  17925       }
  17926     }
  17927   } else {
  17928     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  17929     if (encoded_dt.IsValid()) {
  17930       if (cond.Is(al)) {
  17931         EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  17932                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  17933                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  17934         return;
  17935       }
  17936     }
  17937   }
  17938   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
  17939 }
  17940 
  17941 void Assembler::vhsub(
  17942     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  17943   VIXL_ASSERT(AllowAssembler());
  17944   CheckIT(cond);
  17945   Dt_U_size_1 encoded_dt(dt);
  17946   if (IsUsingT32()) {
  17947     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  17948     if (encoded_dt.IsValid()) {
  17949       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17950         EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  17951                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  17952                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  17953         AdvanceIT();
  17954         return;
  17955       }
  17956     }
  17957   } else {
  17958     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  17959     if (encoded_dt.IsValid()) {
  17960       if (cond.Is(al)) {
  17961         EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  17962                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  17963                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  17964         return;
  17965       }
  17966     }
  17967   }
  17968   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
  17969 }
  17970 
  17971 void Assembler::vhsub(
  17972     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  17973   VIXL_ASSERT(AllowAssembler());
  17974   CheckIT(cond);
  17975   Dt_U_size_1 encoded_dt(dt);
  17976   if (IsUsingT32()) {
  17977     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  17978     if (encoded_dt.IsValid()) {
  17979       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  17980         EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  17981                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  17982                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  17983         AdvanceIT();
  17984         return;
  17985       }
  17986     }
  17987   } else {
  17988     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  17989     if (encoded_dt.IsValid()) {
  17990       if (cond.Is(al)) {
  17991         EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  17992                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  17993                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  17994         return;
  17995       }
  17996     }
  17997   }
  17998   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
  17999 }
  18000 
  18001 void Assembler::vld1(Condition cond,
  18002                      DataType dt,
  18003                      const NeonRegisterList& nreglist,
  18004                      const AlignedMemOperand& operand) {
  18005   VIXL_ASSERT(AllowAssembler());
  18006   CheckIT(cond);
  18007   if (operand.IsImmediateZero()) {
  18008     Register rn = operand.GetBaseRegister();
  18009     Alignment align = operand.GetAlignment();
  18010     Dt_size_6 encoded_dt(dt);
  18011     Dt_size_7 encoded_dt_2(dt);
  18012     Align_align_1 encoded_align_1(align, nreglist);
  18013     Align_a_1 encoded_align_2(align, dt);
  18014     Align_index_align_1 encoded_align_3(align, nreglist, dt);
  18015     if (IsUsingT32()) {
  18016       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  18017       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18018           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  18019           operand.IsOffset() && encoded_align_1.IsValid() &&
  18020           (!rn.IsPC() || AllowUnpredictable())) {
  18021         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18022           const DRegister& first = nreglist.GetFirstDRegister();
  18023           uint32_t len_encoding;
  18024           switch (nreglist.GetLength()) {
  18025             default:
  18026               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  18027             case 1:
  18028               len_encoding = 0x7;
  18029               break;
  18030             case 2:
  18031               len_encoding = 0xa;
  18032               break;
  18033             case 3:
  18034               len_encoding = 0x6;
  18035               break;
  18036             case 4:
  18037               len_encoding = 0x2;
  18038               break;
  18039           }
  18040           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
  18041                      (encoded_align_1.GetEncodingValue() << 4) |
  18042                      first.Encode(22, 12) | (len_encoding << 8) |
  18043                      (rn.GetCode() << 16));
  18044           AdvanceIT();
  18045           return;
  18046         }
  18047       }
  18048       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  18049       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18050           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  18051           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  18052           (!rn.IsPC() || AllowUnpredictable())) {
  18053         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18054           const DRegister& first = nreglist.GetFirstDRegister();
  18055           uint32_t len_encoding;
  18056           switch (nreglist.GetLength()) {
  18057             default:
  18058               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  18059             case 1:
  18060               len_encoding = 0x7;
  18061               break;
  18062             case 2:
  18063               len_encoding = 0xa;
  18064               break;
  18065             case 3:
  18066               len_encoding = 0x6;
  18067               break;
  18068             case 4:
  18069               len_encoding = 0x2;
  18070               break;
  18071           }
  18072           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
  18073                      (encoded_align_1.GetEncodingValue() << 4) |
  18074                      first.Encode(22, 12) | (len_encoding << 8) |
  18075                      (rn.GetCode() << 16));
  18076           AdvanceIT();
  18077           return;
  18078         }
  18079       }
  18080       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  18081       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  18082           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
  18083           operand.IsOffset() && encoded_align_2.IsValid() &&
  18084           (!rn.IsPC() || AllowUnpredictable())) {
  18085         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18086           const DRegister& first = nreglist.GetFirstDRegister();
  18087           uint32_t len_encoding = nreglist.GetLength() - 1;
  18088           EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
  18089                      (encoded_align_2.GetEncodingValue() << 4) |
  18090                      first.Encode(22, 12) | (len_encoding << 5) |
  18091                      (rn.GetCode() << 16));
  18092           AdvanceIT();
  18093           return;
  18094         }
  18095       }
  18096       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  18097       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  18098           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
  18099           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  18100           (!rn.IsPC() || AllowUnpredictable())) {
  18101         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18102           const DRegister& first = nreglist.GetFirstDRegister();
  18103           uint32_t len_encoding = nreglist.GetLength() - 1;
  18104           EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
  18105                      (encoded_align_2.GetEncodingValue() << 4) |
  18106                      first.Encode(22, 12) | (len_encoding << 5) |
  18107                      (rn.GetCode() << 16));
  18108           AdvanceIT();
  18109           return;
  18110         }
  18111       }
  18112       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  18113       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  18114           (nreglist.GetLength() == 1) && operand.IsOffset() &&
  18115           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  18116         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18117           const DRegister& first = nreglist.GetFirstDRegister();
  18118           EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
  18119                      (encoded_align_3.GetEncodingValue() << 4) |
  18120                      first.Encode(22, 12) | (rn.GetCode() << 16));
  18121           AdvanceIT();
  18122           return;
  18123         }
  18124       }
  18125       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  18126       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  18127           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
  18128           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  18129         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18130           const DRegister& first = nreglist.GetFirstDRegister();
  18131           EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
  18132                      (encoded_align_3.GetEncodingValue() << 4) |
  18133                      first.Encode(22, 12) | (rn.GetCode() << 16));
  18134           AdvanceIT();
  18135           return;
  18136         }
  18137       }
  18138     } else {
  18139       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  18140       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18141           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  18142           operand.IsOffset() && encoded_align_1.IsValid() &&
  18143           (!rn.IsPC() || AllowUnpredictable())) {
  18144         if (cond.Is(al)) {
  18145           const DRegister& first = nreglist.GetFirstDRegister();
  18146           uint32_t len_encoding;
  18147           switch (nreglist.GetLength()) {
  18148             default:
  18149               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  18150             case 1:
  18151               len_encoding = 0x7;
  18152               break;
  18153             case 2:
  18154               len_encoding = 0xa;
  18155               break;
  18156             case 3:
  18157               len_encoding = 0x6;
  18158               break;
  18159             case 4:
  18160               len_encoding = 0x2;
  18161               break;
  18162           }
  18163           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
  18164                   (encoded_align_1.GetEncodingValue() << 4) |
  18165                   first.Encode(22, 12) | (len_encoding << 8) |
  18166                   (rn.GetCode() << 16));
  18167           return;
  18168         }
  18169       }
  18170       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  18171       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18172           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  18173           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  18174           (!rn.IsPC() || AllowUnpredictable())) {
  18175         if (cond.Is(al)) {
  18176           const DRegister& first = nreglist.GetFirstDRegister();
  18177           uint32_t len_encoding;
  18178           switch (nreglist.GetLength()) {
  18179             default:
  18180               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  18181             case 1:
  18182               len_encoding = 0x7;
  18183               break;
  18184             case 2:
  18185               len_encoding = 0xa;
  18186               break;
  18187             case 3:
  18188               len_encoding = 0x6;
  18189               break;
  18190             case 4:
  18191               len_encoding = 0x2;
  18192               break;
  18193           }
  18194           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
  18195                   (encoded_align_1.GetEncodingValue() << 4) |
  18196                   first.Encode(22, 12) | (len_encoding << 8) |
  18197                   (rn.GetCode() << 16));
  18198           return;
  18199         }
  18200       }
  18201       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  18202       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  18203           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
  18204           operand.IsOffset() && encoded_align_2.IsValid() &&
  18205           (!rn.IsPC() || AllowUnpredictable())) {
  18206         if (cond.Is(al)) {
  18207           const DRegister& first = nreglist.GetFirstDRegister();
  18208           uint32_t len_encoding = nreglist.GetLength() - 1;
  18209           EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
  18210                   (encoded_align_2.GetEncodingValue() << 4) |
  18211                   first.Encode(22, 12) | (len_encoding << 5) |
  18212                   (rn.GetCode() << 16));
  18213           return;
  18214         }
  18215       }
  18216       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  18217       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  18218           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
  18219           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  18220           (!rn.IsPC() || AllowUnpredictable())) {
  18221         if (cond.Is(al)) {
  18222           const DRegister& first = nreglist.GetFirstDRegister();
  18223           uint32_t len_encoding = nreglist.GetLength() - 1;
  18224           EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
  18225                   (encoded_align_2.GetEncodingValue() << 4) |
  18226                   first.Encode(22, 12) | (len_encoding << 5) |
  18227                   (rn.GetCode() << 16));
  18228           return;
  18229         }
  18230       }
  18231       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  18232       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  18233           (nreglist.GetLength() == 1) && operand.IsOffset() &&
  18234           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  18235         if (cond.Is(al)) {
  18236           const DRegister& first = nreglist.GetFirstDRegister();
  18237           EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
  18238                   (encoded_align_3.GetEncodingValue() << 4) |
  18239                   first.Encode(22, 12) | (rn.GetCode() << 16));
  18240           return;
  18241         }
  18242       }
  18243       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  18244       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  18245           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
  18246           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  18247         if (cond.Is(al)) {
  18248           const DRegister& first = nreglist.GetFirstDRegister();
  18249           EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
  18250                   (encoded_align_3.GetEncodingValue() << 4) |
  18251                   first.Encode(22, 12) | (rn.GetCode() << 16));
  18252           return;
  18253         }
  18254       }
  18255     }
  18256   }
  18257   if (operand.IsPlainRegister()) {
  18258     Register rn = operand.GetBaseRegister();
  18259     Alignment align = operand.GetAlignment();
  18260     Register rm = operand.GetOffsetRegister();
  18261     Dt_size_6 encoded_dt(dt);
  18262     Dt_size_7 encoded_dt_2(dt);
  18263     Align_align_1 encoded_align_1(align, nreglist);
  18264     Align_a_1 encoded_align_2(align, dt);
  18265     Align_index_align_1 encoded_align_3(align, nreglist, dt);
  18266     if (IsUsingT32()) {
  18267       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  18268       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18269           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  18270           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18271         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18272           const DRegister& first = nreglist.GetFirstDRegister();
  18273           uint32_t len_encoding;
  18274           switch (nreglist.GetLength()) {
  18275             default:
  18276               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  18277             case 1:
  18278               len_encoding = 0x7;
  18279               break;
  18280             case 2:
  18281               len_encoding = 0xa;
  18282               break;
  18283             case 3:
  18284               len_encoding = 0x6;
  18285               break;
  18286             case 4:
  18287               len_encoding = 0x2;
  18288               break;
  18289           }
  18290           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
  18291                      (encoded_align_1.GetEncodingValue() << 4) |
  18292                      first.Encode(22, 12) | (len_encoding << 8) |
  18293                      (rn.GetCode() << 16) | rm.GetCode());
  18294           AdvanceIT();
  18295           return;
  18296         }
  18297       }
  18298       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  18299       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  18300           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
  18301           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18302         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18303           const DRegister& first = nreglist.GetFirstDRegister();
  18304           uint32_t len_encoding = nreglist.GetLength() - 1;
  18305           EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
  18306                      (encoded_align_2.GetEncodingValue() << 4) |
  18307                      first.Encode(22, 12) | (len_encoding << 5) |
  18308                      (rn.GetCode() << 16) | rm.GetCode());
  18309           AdvanceIT();
  18310           return;
  18311         }
  18312       }
  18313       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  18314       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  18315           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
  18316           (!rn.IsPC() || AllowUnpredictable())) {
  18317         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18318           const DRegister& first = nreglist.GetFirstDRegister();
  18319           EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
  18320                      (encoded_align_3.GetEncodingValue() << 4) |
  18321                      first.Encode(22, 12) | (rn.GetCode() << 16) |
  18322                      rm.GetCode());
  18323           AdvanceIT();
  18324           return;
  18325         }
  18326       }
  18327     } else {
  18328       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  18329       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18330           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  18331           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18332         if (cond.Is(al)) {
  18333           const DRegister& first = nreglist.GetFirstDRegister();
  18334           uint32_t len_encoding;
  18335           switch (nreglist.GetLength()) {
  18336             default:
  18337               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  18338             case 1:
  18339               len_encoding = 0x7;
  18340               break;
  18341             case 2:
  18342               len_encoding = 0xa;
  18343               break;
  18344             case 3:
  18345               len_encoding = 0x6;
  18346               break;
  18347             case 4:
  18348               len_encoding = 0x2;
  18349               break;
  18350           }
  18351           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
  18352                   (encoded_align_1.GetEncodingValue() << 4) |
  18353                   first.Encode(22, 12) | (len_encoding << 8) |
  18354                   (rn.GetCode() << 16) | rm.GetCode());
  18355           return;
  18356         }
  18357       }
  18358       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  18359       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  18360           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
  18361           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18362         if (cond.Is(al)) {
  18363           const DRegister& first = nreglist.GetFirstDRegister();
  18364           uint32_t len_encoding = nreglist.GetLength() - 1;
  18365           EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
  18366                   (encoded_align_2.GetEncodingValue() << 4) |
  18367                   first.Encode(22, 12) | (len_encoding << 5) |
  18368                   (rn.GetCode() << 16) | rm.GetCode());
  18369           return;
  18370         }
  18371       }
  18372       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  18373       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  18374           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
  18375           (!rn.IsPC() || AllowUnpredictable())) {
  18376         if (cond.Is(al)) {
  18377           const DRegister& first = nreglist.GetFirstDRegister();
  18378           EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
  18379                   (encoded_align_3.GetEncodingValue() << 4) |
  18380                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
  18381           return;
  18382         }
  18383       }
  18384     }
  18385   }
  18386   Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
  18387 }
  18388 
  18389 void Assembler::vld2(Condition cond,
  18390                      DataType dt,
  18391                      const NeonRegisterList& nreglist,
  18392                      const AlignedMemOperand& operand) {
  18393   VIXL_ASSERT(AllowAssembler());
  18394   CheckIT(cond);
  18395   if (operand.IsImmediateZero()) {
  18396     Register rn = operand.GetBaseRegister();
  18397     Alignment align = operand.GetAlignment();
  18398     Dt_size_7 encoded_dt(dt);
  18399     Align_align_2 encoded_align_1(align, nreglist);
  18400     Align_a_2 encoded_align_2(align, dt);
  18401     Align_index_align_2 encoded_align_3(align, nreglist, dt);
  18402     if (IsUsingT32()) {
  18403       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  18404       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18405           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18406            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  18407            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  18408           operand.IsOffset() && encoded_align_1.IsValid() &&
  18409           (!rn.IsPC() || AllowUnpredictable())) {
  18410         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18411           const DRegister& first = nreglist.GetFirstDRegister();
  18412           uint32_t len_encoding;
  18413           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  18414             len_encoding = 0x8;
  18415           }
  18416           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  18417             len_encoding = 0x9;
  18418           }
  18419           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  18420             len_encoding = 0x3;
  18421           }
  18422           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
  18423                      (encoded_align_1.GetEncodingValue() << 4) |
  18424                      first.Encode(22, 12) | (len_encoding << 8) |
  18425                      (rn.GetCode() << 16));
  18426           AdvanceIT();
  18427           return;
  18428         }
  18429       }
  18430       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  18431       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18432           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18433            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  18434            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  18435           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  18436           (!rn.IsPC() || AllowUnpredictable())) {
  18437         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18438           const DRegister& first = nreglist.GetFirstDRegister();
  18439           uint32_t len_encoding;
  18440           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  18441             len_encoding = 0x8;
  18442           }
  18443           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  18444             len_encoding = 0x9;
  18445           }
  18446           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  18447             len_encoding = 0x3;
  18448           }
  18449           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
  18450                      (encoded_align_1.GetEncodingValue() << 4) |
  18451                      first.Encode(22, 12) | (len_encoding << 8) |
  18452                      (rn.GetCode() << 16));
  18453           AdvanceIT();
  18454           return;
  18455         }
  18456       }
  18457       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  18458       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18459           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18460            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18461           operand.IsOffset() && encoded_align_2.IsValid() &&
  18462           (!rn.IsPC() || AllowUnpredictable())) {
  18463         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18464           const DRegister& first = nreglist.GetFirstDRegister();
  18465           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18466           EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
  18467                      (encoded_align_2.GetEncodingValue() << 4) |
  18468                      first.Encode(22, 12) | (len_encoding << 5) |
  18469                      (rn.GetCode() << 16));
  18470           AdvanceIT();
  18471           return;
  18472         }
  18473       }
  18474       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  18475       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18476           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18477            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18478           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  18479           (!rn.IsPC() || AllowUnpredictable())) {
  18480         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18481           const DRegister& first = nreglist.GetFirstDRegister();
  18482           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18483           EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
  18484                      (encoded_align_2.GetEncodingValue() << 4) |
  18485                      first.Encode(22, 12) | (len_encoding << 5) |
  18486                      (rn.GetCode() << 16));
  18487           AdvanceIT();
  18488           return;
  18489         }
  18490       }
  18491       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  18492       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18493           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18494            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18495           operand.IsOffset() && encoded_align_3.IsValid() &&
  18496           (!rn.IsPC() || AllowUnpredictable())) {
  18497         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18498           const DRegister& first = nreglist.GetFirstDRegister();
  18499           EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
  18500                      (encoded_align_3.GetEncodingValue() << 4) |
  18501                      first.Encode(22, 12) | (rn.GetCode() << 16));
  18502           AdvanceIT();
  18503           return;
  18504         }
  18505       }
  18506       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  18507       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18508           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18509            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18510           operand.IsPostIndex() && encoded_align_3.IsValid() &&
  18511           (!rn.IsPC() || AllowUnpredictable())) {
  18512         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18513           const DRegister& first = nreglist.GetFirstDRegister();
  18514           EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
  18515                      (encoded_align_3.GetEncodingValue() << 4) |
  18516                      first.Encode(22, 12) | (rn.GetCode() << 16));
  18517           AdvanceIT();
  18518           return;
  18519         }
  18520       }
  18521     } else {
  18522       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  18523       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18524           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18525            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  18526            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  18527           operand.IsOffset() && encoded_align_1.IsValid() &&
  18528           (!rn.IsPC() || AllowUnpredictable())) {
  18529         if (cond.Is(al)) {
  18530           const DRegister& first = nreglist.GetFirstDRegister();
  18531           uint32_t len_encoding;
  18532           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  18533             len_encoding = 0x8;
  18534           }
  18535           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  18536             len_encoding = 0x9;
  18537           }
  18538           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  18539             len_encoding = 0x3;
  18540           }
  18541           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
  18542                   (encoded_align_1.GetEncodingValue() << 4) |
  18543                   first.Encode(22, 12) | (len_encoding << 8) |
  18544                   (rn.GetCode() << 16));
  18545           return;
  18546         }
  18547       }
  18548       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  18549       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18550           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18551            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  18552            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  18553           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  18554           (!rn.IsPC() || AllowUnpredictable())) {
  18555         if (cond.Is(al)) {
  18556           const DRegister& first = nreglist.GetFirstDRegister();
  18557           uint32_t len_encoding;
  18558           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  18559             len_encoding = 0x8;
  18560           }
  18561           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  18562             len_encoding = 0x9;
  18563           }
  18564           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  18565             len_encoding = 0x3;
  18566           }
  18567           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
  18568                   (encoded_align_1.GetEncodingValue() << 4) |
  18569                   first.Encode(22, 12) | (len_encoding << 8) |
  18570                   (rn.GetCode() << 16));
  18571           return;
  18572         }
  18573       }
  18574       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  18575       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18576           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18577            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18578           operand.IsOffset() && encoded_align_2.IsValid() &&
  18579           (!rn.IsPC() || AllowUnpredictable())) {
  18580         if (cond.Is(al)) {
  18581           const DRegister& first = nreglist.GetFirstDRegister();
  18582           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18583           EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
  18584                   (encoded_align_2.GetEncodingValue() << 4) |
  18585                   first.Encode(22, 12) | (len_encoding << 5) |
  18586                   (rn.GetCode() << 16));
  18587           return;
  18588         }
  18589       }
  18590       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  18591       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18592           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18593            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18594           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  18595           (!rn.IsPC() || AllowUnpredictable())) {
  18596         if (cond.Is(al)) {
  18597           const DRegister& first = nreglist.GetFirstDRegister();
  18598           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18599           EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
  18600                   (encoded_align_2.GetEncodingValue() << 4) |
  18601                   first.Encode(22, 12) | (len_encoding << 5) |
  18602                   (rn.GetCode() << 16));
  18603           return;
  18604         }
  18605       }
  18606       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  18607       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18608           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18609            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18610           operand.IsOffset() && encoded_align_3.IsValid() &&
  18611           (!rn.IsPC() || AllowUnpredictable())) {
  18612         if (cond.Is(al)) {
  18613           const DRegister& first = nreglist.GetFirstDRegister();
  18614           EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
  18615                   (encoded_align_3.GetEncodingValue() << 4) |
  18616                   first.Encode(22, 12) | (rn.GetCode() << 16));
  18617           return;
  18618         }
  18619       }
  18620       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  18621       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18622           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18623            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18624           operand.IsPostIndex() && encoded_align_3.IsValid() &&
  18625           (!rn.IsPC() || AllowUnpredictable())) {
  18626         if (cond.Is(al)) {
  18627           const DRegister& first = nreglist.GetFirstDRegister();
  18628           EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
  18629                   (encoded_align_3.GetEncodingValue() << 4) |
  18630                   first.Encode(22, 12) | (rn.GetCode() << 16));
  18631           return;
  18632         }
  18633       }
  18634     }
  18635   }
  18636   if (operand.IsPlainRegister()) {
  18637     Register rn = operand.GetBaseRegister();
  18638     Alignment align = operand.GetAlignment();
  18639     Register rm = operand.GetOffsetRegister();
  18640     Dt_size_7 encoded_dt(dt);
  18641     Align_align_2 encoded_align_1(align, nreglist);
  18642     Align_a_2 encoded_align_2(align, dt);
  18643     Align_index_align_2 encoded_align_3(align, nreglist, dt);
  18644     if (IsUsingT32()) {
  18645       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  18646       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18647           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18648            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  18649            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  18650           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18651         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18652           const DRegister& first = nreglist.GetFirstDRegister();
  18653           uint32_t len_encoding;
  18654           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  18655             len_encoding = 0x8;
  18656           }
  18657           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  18658             len_encoding = 0x9;
  18659           }
  18660           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  18661             len_encoding = 0x3;
  18662           }
  18663           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
  18664                      (encoded_align_1.GetEncodingValue() << 4) |
  18665                      first.Encode(22, 12) | (len_encoding << 8) |
  18666                      (rn.GetCode() << 16) | rm.GetCode());
  18667           AdvanceIT();
  18668           return;
  18669         }
  18670       }
  18671       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  18672       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18673           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18674            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18675           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18676         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18677           const DRegister& first = nreglist.GetFirstDRegister();
  18678           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18679           EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
  18680                      (encoded_align_2.GetEncodingValue() << 4) |
  18681                      first.Encode(22, 12) | (len_encoding << 5) |
  18682                      (rn.GetCode() << 16) | rm.GetCode());
  18683           AdvanceIT();
  18684           return;
  18685         }
  18686       }
  18687       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  18688       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18689           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18690            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18691           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18692         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18693           const DRegister& first = nreglist.GetFirstDRegister();
  18694           EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
  18695                      (encoded_align_3.GetEncodingValue() << 4) |
  18696                      first.Encode(22, 12) | (rn.GetCode() << 16) |
  18697                      rm.GetCode());
  18698           AdvanceIT();
  18699           return;
  18700         }
  18701       }
  18702     } else {
  18703       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  18704       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18705           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18706            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  18707            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  18708           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18709         if (cond.Is(al)) {
  18710           const DRegister& first = nreglist.GetFirstDRegister();
  18711           uint32_t len_encoding;
  18712           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  18713             len_encoding = 0x8;
  18714           }
  18715           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  18716             len_encoding = 0x9;
  18717           }
  18718           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  18719             len_encoding = 0x3;
  18720           }
  18721           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
  18722                   (encoded_align_1.GetEncodingValue() << 4) |
  18723                   first.Encode(22, 12) | (len_encoding << 8) |
  18724                   (rn.GetCode() << 16) | rm.GetCode());
  18725           return;
  18726         }
  18727       }
  18728       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  18729       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18730           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18731            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18732           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18733         if (cond.Is(al)) {
  18734           const DRegister& first = nreglist.GetFirstDRegister();
  18735           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18736           EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
  18737                   (encoded_align_2.GetEncodingValue() << 4) |
  18738                   first.Encode(22, 12) | (len_encoding << 5) |
  18739                   (rn.GetCode() << 16) | rm.GetCode());
  18740           return;
  18741         }
  18742       }
  18743       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  18744       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18745           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  18746            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  18747           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18748         if (cond.Is(al)) {
  18749           const DRegister& first = nreglist.GetFirstDRegister();
  18750           EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
  18751                   (encoded_align_3.GetEncodingValue() << 4) |
  18752                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
  18753           return;
  18754         }
  18755       }
  18756     }
  18757   }
  18758   Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
  18759 }
  18760 
  18761 void Assembler::vld3(Condition cond,
  18762                      DataType dt,
  18763                      const NeonRegisterList& nreglist,
  18764                      const AlignedMemOperand& operand) {
  18765   VIXL_ASSERT(AllowAssembler());
  18766   CheckIT(cond);
  18767   if (operand.IsImmediateZero()) {
  18768     Register rn = operand.GetBaseRegister();
  18769     Alignment align = operand.GetAlignment();
  18770     Dt_size_7 encoded_dt(dt);
  18771     Align_align_3 encoded_align_1(align);
  18772     if (IsUsingT32()) {
  18773       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  18774       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18775           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18776            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18777           operand.IsOffset() && encoded_align_1.IsValid() &&
  18778           (!rn.IsPC() || AllowUnpredictable())) {
  18779         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18780           const DRegister& first = nreglist.GetFirstDRegister();
  18781           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  18782           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
  18783                      (encoded_align_1.GetEncodingValue() << 4) |
  18784                      first.Encode(22, 12) | (len_encoding << 8) |
  18785                      (rn.GetCode() << 16));
  18786           AdvanceIT();
  18787           return;
  18788         }
  18789       }
  18790       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  18791       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18792           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18793            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18794           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  18795           (!rn.IsPC() || AllowUnpredictable())) {
  18796         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18797           const DRegister& first = nreglist.GetFirstDRegister();
  18798           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  18799           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
  18800                      (encoded_align_1.GetEncodingValue() << 4) |
  18801                      first.Encode(22, 12) | (len_encoding << 8) |
  18802                      (rn.GetCode() << 16));
  18803           AdvanceIT();
  18804           return;
  18805         }
  18806       }
  18807     } else {
  18808       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  18809       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18810           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18811            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18812           operand.IsOffset() && encoded_align_1.IsValid() &&
  18813           (!rn.IsPC() || AllowUnpredictable())) {
  18814         if (cond.Is(al)) {
  18815           const DRegister& first = nreglist.GetFirstDRegister();
  18816           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  18817           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
  18818                   (encoded_align_1.GetEncodingValue() << 4) |
  18819                   first.Encode(22, 12) | (len_encoding << 8) |
  18820                   (rn.GetCode() << 16));
  18821           return;
  18822         }
  18823       }
  18824       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  18825       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18826           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18827            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18828           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  18829           (!rn.IsPC() || AllowUnpredictable())) {
  18830         if (cond.Is(al)) {
  18831           const DRegister& first = nreglist.GetFirstDRegister();
  18832           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  18833           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
  18834                   (encoded_align_1.GetEncodingValue() << 4) |
  18835                   first.Encode(22, 12) | (len_encoding << 8) |
  18836                   (rn.GetCode() << 16));
  18837           return;
  18838         }
  18839       }
  18840     }
  18841   }
  18842   if (operand.IsPlainRegister()) {
  18843     Register rn = operand.GetBaseRegister();
  18844     Alignment align = operand.GetAlignment();
  18845     Register rm = operand.GetOffsetRegister();
  18846     Dt_size_7 encoded_dt(dt);
  18847     Align_align_3 encoded_align_1(align);
  18848     if (IsUsingT32()) {
  18849       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  18850       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18851           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18852            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18853           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18854         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18855           const DRegister& first = nreglist.GetFirstDRegister();
  18856           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  18857           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
  18858                      (encoded_align_1.GetEncodingValue() << 4) |
  18859                      first.Encode(22, 12) | (len_encoding << 8) |
  18860                      (rn.GetCode() << 16) | rm.GetCode());
  18861           AdvanceIT();
  18862           return;
  18863         }
  18864       }
  18865     } else {
  18866       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  18867       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  18868           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18869            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18870           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  18871         if (cond.Is(al)) {
  18872           const DRegister& first = nreglist.GetFirstDRegister();
  18873           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  18874           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
  18875                   (encoded_align_1.GetEncodingValue() << 4) |
  18876                   first.Encode(22, 12) | (len_encoding << 8) |
  18877                   (rn.GetCode() << 16) | rm.GetCode());
  18878           return;
  18879         }
  18880       }
  18881     }
  18882   }
  18883   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
  18884 }
  18885 
  18886 void Assembler::vld3(Condition cond,
  18887                      DataType dt,
  18888                      const NeonRegisterList& nreglist,
  18889                      const MemOperand& operand) {
  18890   VIXL_ASSERT(AllowAssembler());
  18891   CheckIT(cond);
  18892   if (operand.IsImmediateZero()) {
  18893     Register rn = operand.GetBaseRegister();
  18894     Dt_size_7 encoded_dt(dt);
  18895     Index_1 encoded_align_1(nreglist, dt);
  18896     if (IsUsingT32()) {
  18897       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
  18898       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18899           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18900            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18901           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
  18902         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18903           const DRegister& first = nreglist.GetFirstDRegister();
  18904           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18905           EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
  18906                      first.Encode(22, 12) | (len_encoding << 5) |
  18907                      (rn.GetCode() << 16));
  18908           AdvanceIT();
  18909           return;
  18910         }
  18911       }
  18912       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
  18913       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18914           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18915            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18916           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
  18917         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18918           const DRegister& first = nreglist.GetFirstDRegister();
  18919           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18920           EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
  18921                      first.Encode(22, 12) | (len_encoding << 5) |
  18922                      (rn.GetCode() << 16));
  18923           AdvanceIT();
  18924           return;
  18925         }
  18926       }
  18927       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
  18928       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18929           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18930            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18931           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
  18932         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18933           const DRegister& first = nreglist.GetFirstDRegister();
  18934           EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
  18935                      (encoded_align_1.GetEncodingValue() << 4) |
  18936                      first.Encode(22, 12) | (rn.GetCode() << 16));
  18937           AdvanceIT();
  18938           return;
  18939         }
  18940       }
  18941       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
  18942       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18943           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18944            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18945           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
  18946         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  18947           const DRegister& first = nreglist.GetFirstDRegister();
  18948           EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
  18949                      (encoded_align_1.GetEncodingValue() << 4) |
  18950                      first.Encode(22, 12) | (rn.GetCode() << 16));
  18951           AdvanceIT();
  18952           return;
  18953         }
  18954       }
  18955     } else {
  18956       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
  18957       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18958           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18959            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18960           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
  18961         if (cond.Is(al)) {
  18962           const DRegister& first = nreglist.GetFirstDRegister();
  18963           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18964           EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
  18965                   first.Encode(22, 12) | (len_encoding << 5) |
  18966                   (rn.GetCode() << 16));
  18967           return;
  18968         }
  18969       }
  18970       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
  18971       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  18972           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18973            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18974           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
  18975         if (cond.Is(al)) {
  18976           const DRegister& first = nreglist.GetFirstDRegister();
  18977           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  18978           EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
  18979                   first.Encode(22, 12) | (len_encoding << 5) |
  18980                   (rn.GetCode() << 16));
  18981           return;
  18982         }
  18983       }
  18984       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
  18985       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18986           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  18987            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  18988           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
  18989         if (cond.Is(al)) {
  18990           const DRegister& first = nreglist.GetFirstDRegister();
  18991           EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
  18992                   (encoded_align_1.GetEncodingValue() << 4) |
  18993                   first.Encode(22, 12) | (rn.GetCode() << 16));
  18994           return;
  18995         }
  18996       }
  18997       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
  18998       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  18999           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  19000            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  19001           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
  19002         if (cond.Is(al)) {
  19003           const DRegister& first = nreglist.GetFirstDRegister();
  19004           EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
  19005                   (encoded_align_1.GetEncodingValue() << 4) |
  19006                   first.Encode(22, 12) | (rn.GetCode() << 16));
  19007           return;
  19008         }
  19009       }
  19010     }
  19011   }
  19012   if (operand.IsPlainRegister()) {
  19013     Register rn = operand.GetBaseRegister();
  19014     Sign sign = operand.GetSign();
  19015     Register rm = operand.GetOffsetRegister();
  19016     Dt_size_7 encoded_dt(dt);
  19017     Index_1 encoded_align_1(nreglist, dt);
  19018     if (IsUsingT32()) {
  19019       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
  19020       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  19021           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  19022            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  19023           sign.IsPlus() && operand.IsPostIndex() &&
  19024           (!rn.IsPC() || AllowUnpredictable())) {
  19025         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19026           const DRegister& first = nreglist.GetFirstDRegister();
  19027           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19028           EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
  19029                      first.Encode(22, 12) | (len_encoding << 5) |
  19030                      (rn.GetCode() << 16) | rm.GetCode());
  19031           AdvanceIT();
  19032           return;
  19033         }
  19034       }
  19035       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
  19036       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  19037           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  19038            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  19039           sign.IsPlus() && operand.IsPostIndex() &&
  19040           (!rn.IsPC() || AllowUnpredictable())) {
  19041         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19042           const DRegister& first = nreglist.GetFirstDRegister();
  19043           EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
  19044                      (encoded_align_1.GetEncodingValue() << 4) |
  19045                      first.Encode(22, 12) | (rn.GetCode() << 16) |
  19046                      rm.GetCode());
  19047           AdvanceIT();
  19048           return;
  19049         }
  19050       }
  19051     } else {
  19052       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
  19053       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
  19054           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  19055            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  19056           sign.IsPlus() && operand.IsPostIndex() &&
  19057           (!rn.IsPC() || AllowUnpredictable())) {
  19058         if (cond.Is(al)) {
  19059           const DRegister& first = nreglist.GetFirstDRegister();
  19060           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19061           EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
  19062                   first.Encode(22, 12) | (len_encoding << 5) |
  19063                   (rn.GetCode() << 16) | rm.GetCode());
  19064           return;
  19065         }
  19066       }
  19067       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
  19068       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  19069           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  19070            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  19071           sign.IsPlus() && operand.IsPostIndex() &&
  19072           (!rn.IsPC() || AllowUnpredictable())) {
  19073         if (cond.Is(al)) {
  19074           const DRegister& first = nreglist.GetFirstDRegister();
  19075           EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
  19076                   (encoded_align_1.GetEncodingValue() << 4) |
  19077                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
  19078           return;
  19079         }
  19080       }
  19081     }
  19082   }
  19083   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
  19084 }
  19085 
  19086 void Assembler::vld4(Condition cond,
  19087                      DataType dt,
  19088                      const NeonRegisterList& nreglist,
  19089                      const AlignedMemOperand& operand) {
  19090   VIXL_ASSERT(AllowAssembler());
  19091   CheckIT(cond);
  19092   if (operand.IsImmediateZero()) {
  19093     Register rn = operand.GetBaseRegister();
  19094     Alignment align = operand.GetAlignment();
  19095     Dt_size_7 encoded_dt(dt);
  19096     Dt_size_8 encoded_dt_2(dt, align);
  19097     Align_align_4 encoded_align_1(align);
  19098     Align_a_3 encoded_align_2(align, dt);
  19099     Align_index_align_3 encoded_align_3(align, nreglist, dt);
  19100     if (IsUsingT32()) {
  19101       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  19102       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  19103           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19104            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19105           operand.IsOffset() && encoded_align_1.IsValid() &&
  19106           (!rn.IsPC() || AllowUnpredictable())) {
  19107         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19108           const DRegister& first = nreglist.GetFirstDRegister();
  19109           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19110           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
  19111                      (encoded_align_1.GetEncodingValue() << 4) |
  19112                      first.Encode(22, 12) | (len_encoding << 8) |
  19113                      (rn.GetCode() << 16));
  19114           AdvanceIT();
  19115           return;
  19116         }
  19117       }
  19118       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  19119       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  19120           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19121            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19122           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  19123           (!rn.IsPC() || AllowUnpredictable())) {
  19124         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19125           const DRegister& first = nreglist.GetFirstDRegister();
  19126           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19127           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
  19128                      (encoded_align_1.GetEncodingValue() << 4) |
  19129                      first.Encode(22, 12) | (len_encoding << 8) |
  19130                      (rn.GetCode() << 16));
  19131           AdvanceIT();
  19132           return;
  19133         }
  19134       }
  19135       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  19136       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  19137           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19138            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19139           operand.IsOffset() && encoded_align_2.IsValid() &&
  19140           (!rn.IsPC() || AllowUnpredictable())) {
  19141         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19142           const DRegister& first = nreglist.GetFirstDRegister();
  19143           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19144           EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
  19145                      (encoded_align_2.GetEncodingValue() << 4) |
  19146                      first.Encode(22, 12) | (len_encoding << 5) |
  19147                      (rn.GetCode() << 16));
  19148           AdvanceIT();
  19149           return;
  19150         }
  19151       }
  19152       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  19153       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  19154           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19155            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19156           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  19157           (!rn.IsPC() || AllowUnpredictable())) {
  19158         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19159           const DRegister& first = nreglist.GetFirstDRegister();
  19160           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19161           EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
  19162                      (encoded_align_2.GetEncodingValue() << 4) |
  19163                      first.Encode(22, 12) | (len_encoding << 5) |
  19164                      (rn.GetCode() << 16));
  19165           AdvanceIT();
  19166           return;
  19167         }
  19168       }
  19169       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  19170       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  19171           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19172            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19173           operand.IsOffset() && encoded_align_3.IsValid() &&
  19174           (!rn.IsPC() || AllowUnpredictable())) {
  19175         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19176           const DRegister& first = nreglist.GetFirstDRegister();
  19177           EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
  19178                      (encoded_align_3.GetEncodingValue() << 4) |
  19179                      first.Encode(22, 12) | (rn.GetCode() << 16));
  19180           AdvanceIT();
  19181           return;
  19182         }
  19183       }
  19184       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  19185       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  19186           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19187            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19188           operand.IsPostIndex() && encoded_align_3.IsValid() &&
  19189           (!rn.IsPC() || AllowUnpredictable())) {
  19190         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19191           const DRegister& first = nreglist.GetFirstDRegister();
  19192           EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
  19193                      (encoded_align_3.GetEncodingValue() << 4) |
  19194                      first.Encode(22, 12) | (rn.GetCode() << 16));
  19195           AdvanceIT();
  19196           return;
  19197         }
  19198       }
  19199     } else {
  19200       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  19201       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  19202           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19203            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19204           operand.IsOffset() && encoded_align_1.IsValid() &&
  19205           (!rn.IsPC() || AllowUnpredictable())) {
  19206         if (cond.Is(al)) {
  19207           const DRegister& first = nreglist.GetFirstDRegister();
  19208           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19209           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
  19210                   (encoded_align_1.GetEncodingValue() << 4) |
  19211                   first.Encode(22, 12) | (len_encoding << 8) |
  19212                   (rn.GetCode() << 16));
  19213           return;
  19214         }
  19215       }
  19216       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  19217       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  19218           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19219            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19220           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  19221           (!rn.IsPC() || AllowUnpredictable())) {
  19222         if (cond.Is(al)) {
  19223           const DRegister& first = nreglist.GetFirstDRegister();
  19224           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19225           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
  19226                   (encoded_align_1.GetEncodingValue() << 4) |
  19227                   first.Encode(22, 12) | (len_encoding << 8) |
  19228                   (rn.GetCode() << 16));
  19229           return;
  19230         }
  19231       }
  19232       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  19233       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  19234           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19235            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19236           operand.IsOffset() && encoded_align_2.IsValid() &&
  19237           (!rn.IsPC() || AllowUnpredictable())) {
  19238         if (cond.Is(al)) {
  19239           const DRegister& first = nreglist.GetFirstDRegister();
  19240           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19241           EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
  19242                   (encoded_align_2.GetEncodingValue() << 4) |
  19243                   first.Encode(22, 12) | (len_encoding << 5) |
  19244                   (rn.GetCode() << 16));
  19245           return;
  19246         }
  19247       }
  19248       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  19249       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  19250           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19251            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19252           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  19253           (!rn.IsPC() || AllowUnpredictable())) {
  19254         if (cond.Is(al)) {
  19255           const DRegister& first = nreglist.GetFirstDRegister();
  19256           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19257           EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
  19258                   (encoded_align_2.GetEncodingValue() << 4) |
  19259                   first.Encode(22, 12) | (len_encoding << 5) |
  19260                   (rn.GetCode() << 16));
  19261           return;
  19262         }
  19263       }
  19264       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  19265       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  19266           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19267            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19268           operand.IsOffset() && encoded_align_3.IsValid() &&
  19269           (!rn.IsPC() || AllowUnpredictable())) {
  19270         if (cond.Is(al)) {
  19271           const DRegister& first = nreglist.GetFirstDRegister();
  19272           EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
  19273                   (encoded_align_3.GetEncodingValue() << 4) |
  19274                   first.Encode(22, 12) | (rn.GetCode() << 16));
  19275           return;
  19276         }
  19277       }
  19278       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  19279       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  19280           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19281            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19282           operand.IsPostIndex() && encoded_align_3.IsValid() &&
  19283           (!rn.IsPC() || AllowUnpredictable())) {
  19284         if (cond.Is(al)) {
  19285           const DRegister& first = nreglist.GetFirstDRegister();
  19286           EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
  19287                   (encoded_align_3.GetEncodingValue() << 4) |
  19288                   first.Encode(22, 12) | (rn.GetCode() << 16));
  19289           return;
  19290         }
  19291       }
  19292     }
  19293   }
  19294   if (operand.IsPlainRegister()) {
  19295     Register rn = operand.GetBaseRegister();
  19296     Alignment align = operand.GetAlignment();
  19297     Register rm = operand.GetOffsetRegister();
  19298     Dt_size_7 encoded_dt(dt);
  19299     Dt_size_8 encoded_dt_2(dt, align);
  19300     Align_align_4 encoded_align_1(align);
  19301     Align_a_3 encoded_align_2(align, dt);
  19302     Align_index_align_3 encoded_align_3(align, nreglist, dt);
  19303     if (IsUsingT32()) {
  19304       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  19305       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  19306           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19307            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19308           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  19309         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19310           const DRegister& first = nreglist.GetFirstDRegister();
  19311           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19312           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
  19313                      (encoded_align_1.GetEncodingValue() << 4) |
  19314                      first.Encode(22, 12) | (len_encoding << 8) |
  19315                      (rn.GetCode() << 16) | rm.GetCode());
  19316           AdvanceIT();
  19317           return;
  19318         }
  19319       }
  19320       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  19321       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  19322           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19323            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19324           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  19325         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19326           const DRegister& first = nreglist.GetFirstDRegister();
  19327           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19328           EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
  19329                      (encoded_align_2.GetEncodingValue() << 4) |
  19330                      first.Encode(22, 12) | (len_encoding << 5) |
  19331                      (rn.GetCode() << 16) | rm.GetCode());
  19332           AdvanceIT();
  19333           return;
  19334         }
  19335       }
  19336       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  19337       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  19338           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19339            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19340           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  19341         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19342           const DRegister& first = nreglist.GetFirstDRegister();
  19343           EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
  19344                      (encoded_align_3.GetEncodingValue() << 4) |
  19345                      first.Encode(22, 12) | (rn.GetCode() << 16) |
  19346                      rm.GetCode());
  19347           AdvanceIT();
  19348           return;
  19349         }
  19350       }
  19351     } else {
  19352       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  19353       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  19354           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19355            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19356           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  19357         if (cond.Is(al)) {
  19358           const DRegister& first = nreglist.GetFirstDRegister();
  19359           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19360           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
  19361                   (encoded_align_1.GetEncodingValue() << 4) |
  19362                   first.Encode(22, 12) | (len_encoding << 8) |
  19363                   (rn.GetCode() << 16) | rm.GetCode());
  19364           return;
  19365         }
  19366       }
  19367       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  19368       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
  19369           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19370            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19371           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  19372         if (cond.Is(al)) {
  19373           const DRegister& first = nreglist.GetFirstDRegister();
  19374           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  19375           EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
  19376                   (encoded_align_2.GetEncodingValue() << 4) |
  19377                   first.Encode(22, 12) | (len_encoding << 5) |
  19378                   (rn.GetCode() << 16) | rm.GetCode());
  19379           return;
  19380         }
  19381       }
  19382       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  19383       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  19384           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  19385            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  19386           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  19387         if (cond.Is(al)) {
  19388           const DRegister& first = nreglist.GetFirstDRegister();
  19389           EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
  19390                   (encoded_align_3.GetEncodingValue() << 4) |
  19391                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
  19392           return;
  19393         }
  19394       }
  19395     }
  19396   }
  19397   Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
  19398 }
  19399 
  19400 void Assembler::vldm(Condition cond,
  19401                      DataType dt,
  19402                      Register rn,
  19403                      WriteBack write_back,
  19404                      DRegisterList dreglist) {
  19405   VIXL_ASSERT(AllowAssembler());
  19406   CheckIT(cond);
  19407   USE(dt);
  19408   if (IsUsingT32()) {
  19409     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
  19410     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
  19411          AllowUnpredictable())) {
  19412       const DRegister& dreg = dreglist.GetFirstDRegister();
  19413       unsigned len = dreglist.GetLength() * 2;
  19414       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
  19415                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
  19416                  (len & 0xff));
  19417       AdvanceIT();
  19418       return;
  19419     }
  19420   } else {
  19421     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
  19422     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
  19423                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
  19424                               AllowUnpredictable())) {
  19425       const DRegister& dreg = dreglist.GetFirstDRegister();
  19426       unsigned len = dreglist.GetLength() * 2;
  19427       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  19428               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
  19429               (len & 0xff));
  19430       return;
  19431     }
  19432   }
  19433   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
  19434 }
  19435 
  19436 void Assembler::vldm(Condition cond,
  19437                      DataType dt,
  19438                      Register rn,
  19439                      WriteBack write_back,
  19440                      SRegisterList sreglist) {
  19441   VIXL_ASSERT(AllowAssembler());
  19442   CheckIT(cond);
  19443   USE(dt);
  19444   if (IsUsingT32()) {
  19445     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
  19446     if ((!rn.IsPC() || AllowUnpredictable())) {
  19447       const SRegister& sreg = sreglist.GetFirstSRegister();
  19448       unsigned len = sreglist.GetLength();
  19449       EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
  19450                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
  19451                  (len & 0xff));
  19452       AdvanceIT();
  19453       return;
  19454     }
  19455   } else {
  19456     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
  19457     if (cond.IsNotNever() &&
  19458         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
  19459       const SRegister& sreg = sreglist.GetFirstSRegister();
  19460       unsigned len = sreglist.GetLength();
  19461       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  19462               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
  19463               (len & 0xff));
  19464       return;
  19465     }
  19466   }
  19467   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
  19468 }
  19469 
  19470 void Assembler::vldmdb(Condition cond,
  19471                        DataType dt,
  19472                        Register rn,
  19473                        WriteBack write_back,
  19474                        DRegisterList dreglist) {
  19475   VIXL_ASSERT(AllowAssembler());
  19476   CheckIT(cond);
  19477   USE(dt);
  19478   if (IsUsingT32()) {
  19479     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
  19480     if (write_back.DoesWriteBack() &&
  19481         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
  19482          AllowUnpredictable())) {
  19483       const DRegister& dreg = dreglist.GetFirstDRegister();
  19484       unsigned len = dreglist.GetLength() * 2;
  19485       EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
  19486                  (len & 0xff));
  19487       AdvanceIT();
  19488       return;
  19489     }
  19490   } else {
  19491     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
  19492     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
  19493         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
  19494          AllowUnpredictable())) {
  19495       const DRegister& dreg = dreglist.GetFirstDRegister();
  19496       unsigned len = dreglist.GetLength() * 2;
  19497       EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  19498               dreg.Encode(22, 12) | (len & 0xff));
  19499       return;
  19500     }
  19501   }
  19502   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
  19503 }
  19504 
  19505 void Assembler::vldmdb(Condition cond,
  19506                        DataType dt,
  19507                        Register rn,
  19508                        WriteBack write_back,
  19509                        SRegisterList sreglist) {
  19510   VIXL_ASSERT(AllowAssembler());
  19511   CheckIT(cond);
  19512   USE(dt);
  19513   if (IsUsingT32()) {
  19514     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
  19515     if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) {
  19516       const SRegister& sreg = sreglist.GetFirstSRegister();
  19517       unsigned len = sreglist.GetLength();
  19518       EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
  19519                  (len & 0xff));
  19520       AdvanceIT();
  19521       return;
  19522     }
  19523   } else {
  19524     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
  19525     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
  19526         (!rn.IsPC() || AllowUnpredictable())) {
  19527       const SRegister& sreg = sreglist.GetFirstSRegister();
  19528       unsigned len = sreglist.GetLength();
  19529       EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  19530               sreg.Encode(22, 12) | (len & 0xff));
  19531       return;
  19532     }
  19533   }
  19534   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
  19535 }
  19536 
  19537 void Assembler::vldmia(Condition cond,
  19538                        DataType dt,
  19539                        Register rn,
  19540                        WriteBack write_back,
  19541                        DRegisterList dreglist) {
  19542   VIXL_ASSERT(AllowAssembler());
  19543   CheckIT(cond);
  19544   USE(dt);
  19545   if (IsUsingT32()) {
  19546     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
  19547     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
  19548          AllowUnpredictable())) {
  19549       const DRegister& dreg = dreglist.GetFirstDRegister();
  19550       unsigned len = dreglist.GetLength() * 2;
  19551       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
  19552                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
  19553                  (len & 0xff));
  19554       AdvanceIT();
  19555       return;
  19556     }
  19557   } else {
  19558     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
  19559     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
  19560                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
  19561                               AllowUnpredictable())) {
  19562       const DRegister& dreg = dreglist.GetFirstDRegister();
  19563       unsigned len = dreglist.GetLength() * 2;
  19564       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  19565               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
  19566               (len & 0xff));
  19567       return;
  19568     }
  19569   }
  19570   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
  19571 }
  19572 
  19573 void Assembler::vldmia(Condition cond,
  19574                        DataType dt,
  19575                        Register rn,
  19576                        WriteBack write_back,
  19577                        SRegisterList sreglist) {
  19578   VIXL_ASSERT(AllowAssembler());
  19579   CheckIT(cond);
  19580   USE(dt);
  19581   if (IsUsingT32()) {
  19582     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
  19583     if ((!rn.IsPC() || AllowUnpredictable())) {
  19584       const SRegister& sreg = sreglist.GetFirstSRegister();
  19585       unsigned len = sreglist.GetLength();
  19586       EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
  19587                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
  19588                  (len & 0xff));
  19589       AdvanceIT();
  19590       return;
  19591     }
  19592   } else {
  19593     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
  19594     if (cond.IsNotNever() &&
  19595         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
  19596       const SRegister& sreg = sreglist.GetFirstSRegister();
  19597       unsigned len = sreglist.GetLength();
  19598       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  19599               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
  19600               (len & 0xff));
  19601       return;
  19602     }
  19603   }
  19604   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
  19605 }
  19606 
  19607 void Assembler::vldr(Condition cond,
  19608                      DataType dt,
  19609                      DRegister rd,
  19610                      Location* location) {
  19611   VIXL_ASSERT(AllowAssembler());
  19612   CheckIT(cond);
  19613   Location::Offset offset =
  19614       location->IsBound()
  19615           ? location->GetLocation() -
  19616                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
  19617           : 0;
  19618   if (IsUsingT32()) {
  19619     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
  19620     if (dt.IsNoneOr(Untyped64) &&
  19621         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
  19622           ((offset & 0x3) == 0)) ||
  19623          !location->IsBound())) {
  19624       static class EmitOp : public Location::EmitOperator {
  19625        public:
  19626         EmitOp() : Location::EmitOperator(T32) {}
  19627         virtual uint32_t Encode(uint32_t instr,
  19628                                 Location::Offset program_counter,
  19629                                 const Location* loc) const VIXL_OVERRIDE {
  19630           program_counter += kT32PcDelta;
  19631           Location::Offset off =
  19632               loc->GetLocation() - AlignDown(program_counter, 4);
  19633           VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
  19634           int32_t target = off >> 2;
  19635           uint32_t U = (target >= 0);
  19636           target = abs(target) | (U << 8);
  19637           return instr | (target & 0xff) | ((target & 0x100) << 15);
  19638         }
  19639       } immop;
  19640       EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12),
  19641                       location,
  19642                       immop,
  19643                       &kT32DataInfo));
  19644       AdvanceIT();
  19645       return;
  19646     }
  19647   } else {
  19648     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
  19649     if (dt.IsNoneOr(Untyped64) &&
  19650         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
  19651           ((offset & 0x3) == 0)) ||
  19652          !location->IsBound()) &&
  19653         cond.IsNotNever()) {
  19654       static class EmitOp : public Location::EmitOperator {
  19655        public:
  19656         EmitOp() : Location::EmitOperator(A32) {}
  19657         virtual uint32_t Encode(uint32_t instr,
  19658                                 Location::Offset program_counter,
  19659                                 const Location* loc) const VIXL_OVERRIDE {
  19660           program_counter += kA32PcDelta;
  19661           Location::Offset off =
  19662               loc->GetLocation() - AlignDown(program_counter, 4);
  19663           VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
  19664           int32_t target = off >> 2;
  19665           uint32_t U = (target >= 0);
  19666           target = abs(target) | (U << 8);
  19667           return instr | (target & 0xff) | ((target & 0x100) << 15);
  19668         }
  19669       } immop;
  19670       EmitA32(
  19671           Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
  19672                location,
  19673                immop,
  19674                &kA32DataInfo));
  19675       return;
  19676     }
  19677   }
  19678   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location);
  19679 }
  19680 
  19681 bool Assembler::vldr_info(Condition cond,
  19682                           DataType dt,
  19683                           DRegister rd,
  19684                           Location* location,
  19685                           const struct ReferenceInfo** info) {
  19686   VIXL_ASSERT(!location->IsBound());
  19687   USE(location);
  19688   USE(rd);
  19689   if (IsUsingT32()) {
  19690     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
  19691     if (dt.IsNoneOr(Untyped64)) {
  19692       *info = &kT32DataInfo;
  19693       return true;
  19694     }
  19695   } else {
  19696     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
  19697     if (dt.IsNoneOr(Untyped64) && cond.IsNotNever()) {
  19698       *info = &kA32DataInfo;
  19699       return true;
  19700     }
  19701   }
  19702   return false;
  19703 }
  19704 
  19705 void Assembler::vldr(Condition cond,
  19706                      DataType dt,
  19707                      DRegister rd,
  19708                      const MemOperand& operand) {
  19709   VIXL_ASSERT(AllowAssembler());
  19710   CheckIT(cond);
  19711   if (operand.IsImmediate()) {
  19712     Register rn = operand.GetBaseRegister();
  19713     int32_t offset = operand.GetOffsetImmediate();
  19714     if (IsUsingT32()) {
  19715       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
  19716       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
  19717           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
  19718         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  19719         uint32_t offset_ = abs(offset) >> 2;
  19720         EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
  19721         AdvanceIT();
  19722         return;
  19723       }
  19724       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
  19725       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
  19726           ((offset % 4) == 0) && operand.IsOffset() &&
  19727           ((rn.GetCode() & 0xf) != 0xf)) {
  19728         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  19729         uint32_t offset_ = abs(offset) >> 2;
  19730         EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
  19731                    offset_ | (sign << 23));
  19732         AdvanceIT();
  19733         return;
  19734       }
  19735     } else {
  19736       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
  19737       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
  19738           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
  19739           cond.IsNotNever()) {
  19740         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  19741         uint32_t offset_ = abs(offset) >> 2;
  19742         EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  19743                 offset_ | (sign << 23));
  19744         return;
  19745       }
  19746       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
  19747       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
  19748           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
  19749           ((rn.GetCode() & 0xf) != 0xf)) {
  19750         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  19751         uint32_t offset_ = abs(offset) >> 2;
  19752         EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  19753                 (rn.GetCode() << 16) | offset_ | (sign << 23));
  19754         return;
  19755       }
  19756     }
  19757   }
  19758   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
  19759 }
  19760 
  19761 void Assembler::vldr(Condition cond,
  19762                      DataType dt,
  19763                      SRegister rd,
  19764                      Location* location) {
  19765   VIXL_ASSERT(AllowAssembler());
  19766   CheckIT(cond);
  19767   Location::Offset offset =
  19768       location->IsBound()
  19769           ? location->GetLocation() -
  19770                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
  19771           : 0;
  19772   if (IsUsingT32()) {
  19773     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
  19774     if (dt.IsNoneOr(Untyped32) &&
  19775         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
  19776           ((offset & 0x3) == 0)) ||
  19777          !location->IsBound())) {
  19778       static class EmitOp : public Location::EmitOperator {
  19779        public:
  19780         EmitOp() : Location::EmitOperator(T32) {}
  19781         virtual uint32_t Encode(uint32_t instr,
  19782                                 Location::Offset program_counter,
  19783                                 const Location* loc) const VIXL_OVERRIDE {
  19784           program_counter += kT32PcDelta;
  19785           Location::Offset off =
  19786               loc->GetLocation() - AlignDown(program_counter, 4);
  19787           VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
  19788           int32_t target = off >> 2;
  19789           uint32_t U = (target >= 0);
  19790           target = abs(target) | (U << 8);
  19791           return instr | (target & 0xff) | ((target & 0x100) << 15);
  19792         }
  19793       } immop;
  19794       EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12),
  19795                       location,
  19796                       immop,
  19797                       &kT32DataInfo));
  19798       AdvanceIT();
  19799       return;
  19800     }
  19801   } else {
  19802     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
  19803     if (dt.IsNoneOr(Untyped32) &&
  19804         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
  19805           ((offset & 0x3) == 0)) ||
  19806          !location->IsBound()) &&
  19807         cond.IsNotNever()) {
  19808       static class EmitOp : public Location::EmitOperator {
  19809        public:
  19810         EmitOp() : Location::EmitOperator(A32) {}
  19811         virtual uint32_t Encode(uint32_t instr,
  19812                                 Location::Offset program_counter,
  19813                                 const Location* loc) const VIXL_OVERRIDE {
  19814           program_counter += kA32PcDelta;
  19815           Location::Offset off =
  19816               loc->GetLocation() - AlignDown(program_counter, 4);
  19817           VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
  19818           int32_t target = off >> 2;
  19819           uint32_t U = (target >= 0);
  19820           target = abs(target) | (U << 8);
  19821           return instr | (target & 0xff) | ((target & 0x100) << 15);
  19822         }
  19823       } immop;
  19824       EmitA32(
  19825           Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
  19826                location,
  19827                immop,
  19828                &kA32DataInfo));
  19829       return;
  19830     }
  19831   }
  19832   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location);
  19833 }
  19834 
  19835 bool Assembler::vldr_info(Condition cond,
  19836                           DataType dt,
  19837                           SRegister rd,
  19838                           Location* location,
  19839                           const struct ReferenceInfo** info) {
  19840   VIXL_ASSERT(!location->IsBound());
  19841   USE(location);
  19842   USE(rd);
  19843   if (IsUsingT32()) {
  19844     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
  19845     if (dt.IsNoneOr(Untyped32)) {
  19846       *info = &kT32DataInfo;
  19847       return true;
  19848     }
  19849   } else {
  19850     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
  19851     if (dt.IsNoneOr(Untyped32) && cond.IsNotNever()) {
  19852       *info = &kA32DataInfo;
  19853       return true;
  19854     }
  19855   }
  19856   return false;
  19857 }
  19858 
  19859 void Assembler::vldr(Condition cond,
  19860                      DataType dt,
  19861                      SRegister rd,
  19862                      const MemOperand& operand) {
  19863   VIXL_ASSERT(AllowAssembler());
  19864   CheckIT(cond);
  19865   if (operand.IsImmediate()) {
  19866     Register rn = operand.GetBaseRegister();
  19867     int32_t offset = operand.GetOffsetImmediate();
  19868     if (IsUsingT32()) {
  19869       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
  19870       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
  19871           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
  19872         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  19873         uint32_t offset_ = abs(offset) >> 2;
  19874         EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
  19875         AdvanceIT();
  19876         return;
  19877       }
  19878       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
  19879       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
  19880           ((offset % 4) == 0) && operand.IsOffset() &&
  19881           ((rn.GetCode() & 0xf) != 0xf)) {
  19882         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  19883         uint32_t offset_ = abs(offset) >> 2;
  19884         EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
  19885                    offset_ | (sign << 23));
  19886         AdvanceIT();
  19887         return;
  19888       }
  19889     } else {
  19890       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
  19891       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
  19892           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
  19893           cond.IsNotNever()) {
  19894         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  19895         uint32_t offset_ = abs(offset) >> 2;
  19896         EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  19897                 offset_ | (sign << 23));
  19898         return;
  19899       }
  19900       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
  19901       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
  19902           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
  19903           ((rn.GetCode() & 0xf) != 0xf)) {
  19904         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  19905         uint32_t offset_ = abs(offset) >> 2;
  19906         EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  19907                 (rn.GetCode() << 16) | offset_ | (sign << 23));
  19908         return;
  19909       }
  19910     }
  19911   }
  19912   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
  19913 }
  19914 
  19915 void Assembler::vmax(
  19916     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  19917   VIXL_ASSERT(AllowAssembler());
  19918   CheckIT(cond);
  19919   Dt_U_size_1 encoded_dt(dt);
  19920   if (IsUsingT32()) {
  19921     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  19922     if (dt.Is(F32)) {
  19923       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19924         EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  19925                    rm.Encode(5, 0));
  19926         AdvanceIT();
  19927         return;
  19928       }
  19929     }
  19930     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  19931     if (encoded_dt.IsValid()) {
  19932       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19933         EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  19934                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  19935                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  19936         AdvanceIT();
  19937         return;
  19938       }
  19939     }
  19940   } else {
  19941     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  19942     if (dt.Is(F32)) {
  19943       if (cond.Is(al)) {
  19944         EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  19945                 rm.Encode(5, 0));
  19946         return;
  19947       }
  19948     }
  19949     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  19950     if (encoded_dt.IsValid()) {
  19951       if (cond.Is(al)) {
  19952         EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  19953                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  19954                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  19955         return;
  19956       }
  19957     }
  19958   }
  19959   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
  19960 }
  19961 
  19962 void Assembler::vmax(
  19963     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  19964   VIXL_ASSERT(AllowAssembler());
  19965   CheckIT(cond);
  19966   Dt_U_size_1 encoded_dt(dt);
  19967   if (IsUsingT32()) {
  19968     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  19969     if (dt.Is(F32)) {
  19970       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19971         EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  19972                    rm.Encode(5, 0));
  19973         AdvanceIT();
  19974         return;
  19975       }
  19976     }
  19977     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  19978     if (encoded_dt.IsValid()) {
  19979       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  19980         EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  19981                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  19982                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  19983         AdvanceIT();
  19984         return;
  19985       }
  19986     }
  19987   } else {
  19988     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  19989     if (dt.Is(F32)) {
  19990       if (cond.Is(al)) {
  19991         EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  19992                 rm.Encode(5, 0));
  19993         return;
  19994       }
  19995     }
  19996     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  19997     if (encoded_dt.IsValid()) {
  19998       if (cond.Is(al)) {
  19999         EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  20000                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  20001                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20002         return;
  20003       }
  20004     }
  20005   }
  20006   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
  20007 }
  20008 
  20009 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  20010   VIXL_ASSERT(AllowAssembler());
  20011   CheckIT(al);
  20012   if (IsUsingT32()) {
  20013     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
  20014     if (OutsideITBlock() && dt.Is(F32)) {
  20015       EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20016                  rm.Encode(5, 0));
  20017       AdvanceIT();
  20018       return;
  20019     }
  20020     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
  20021     if (OutsideITBlock() && dt.Is(F64)) {
  20022       EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20023                  rm.Encode(5, 0));
  20024       AdvanceIT();
  20025       return;
  20026     }
  20027   } else {
  20028     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
  20029     if (dt.Is(F32)) {
  20030       EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20031               rm.Encode(5, 0));
  20032       return;
  20033     }
  20034     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
  20035     if (dt.Is(F64)) {
  20036       EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20037               rm.Encode(5, 0));
  20038       return;
  20039     }
  20040   }
  20041   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
  20042 }
  20043 
  20044 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  20045   VIXL_ASSERT(AllowAssembler());
  20046   CheckIT(al);
  20047   if (IsUsingT32()) {
  20048     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
  20049     if (OutsideITBlock() && dt.Is(F32)) {
  20050       EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20051                  rm.Encode(5, 0));
  20052       AdvanceIT();
  20053       return;
  20054     }
  20055   } else {
  20056     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
  20057     if (dt.Is(F32)) {
  20058       EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20059               rm.Encode(5, 0));
  20060       return;
  20061     }
  20062   }
  20063   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
  20064 }
  20065 
  20066 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  20067   VIXL_ASSERT(AllowAssembler());
  20068   CheckIT(al);
  20069   if (IsUsingT32()) {
  20070     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
  20071     if (OutsideITBlock() && dt.Is(F32)) {
  20072       EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20073                  rm.Encode(5, 0));
  20074       AdvanceIT();
  20075       return;
  20076     }
  20077   } else {
  20078     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
  20079     if (dt.Is(F32)) {
  20080       EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20081               rm.Encode(5, 0));
  20082       return;
  20083     }
  20084   }
  20085   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
  20086 }
  20087 
  20088 void Assembler::vmin(
  20089     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  20090   VIXL_ASSERT(AllowAssembler());
  20091   CheckIT(cond);
  20092   Dt_U_size_1 encoded_dt(dt);
  20093   if (IsUsingT32()) {
  20094     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  20095     if (dt.Is(F32)) {
  20096       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20097         EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20098                    rm.Encode(5, 0));
  20099         AdvanceIT();
  20100         return;
  20101       }
  20102     }
  20103     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  20104     if (encoded_dt.IsValid()) {
  20105       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20106         EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  20107                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  20108                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20109         AdvanceIT();
  20110         return;
  20111       }
  20112     }
  20113   } else {
  20114     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  20115     if (dt.Is(F32)) {
  20116       if (cond.Is(al)) {
  20117         EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20118                 rm.Encode(5, 0));
  20119         return;
  20120       }
  20121     }
  20122     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  20123     if (encoded_dt.IsValid()) {
  20124       if (cond.Is(al)) {
  20125         EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  20126                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  20127                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20128         return;
  20129       }
  20130     }
  20131   }
  20132   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
  20133 }
  20134 
  20135 void Assembler::vmin(
  20136     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  20137   VIXL_ASSERT(AllowAssembler());
  20138   CheckIT(cond);
  20139   Dt_U_size_1 encoded_dt(dt);
  20140   if (IsUsingT32()) {
  20141     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  20142     if (dt.Is(F32)) {
  20143       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20144         EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20145                    rm.Encode(5, 0));
  20146         AdvanceIT();
  20147         return;
  20148       }
  20149     }
  20150     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  20151     if (encoded_dt.IsValid()) {
  20152       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20153         EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  20154                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  20155                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20156         AdvanceIT();
  20157         return;
  20158       }
  20159     }
  20160   } else {
  20161     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  20162     if (dt.Is(F32)) {
  20163       if (cond.Is(al)) {
  20164         EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20165                 rm.Encode(5, 0));
  20166         return;
  20167       }
  20168     }
  20169     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  20170     if (encoded_dt.IsValid()) {
  20171       if (cond.Is(al)) {
  20172         EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  20173                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  20174                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20175         return;
  20176       }
  20177     }
  20178   }
  20179   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
  20180 }
  20181 
  20182 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  20183   VIXL_ASSERT(AllowAssembler());
  20184   CheckIT(al);
  20185   if (IsUsingT32()) {
  20186     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
  20187     if (OutsideITBlock() && dt.Is(F32)) {
  20188       EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20189                  rm.Encode(5, 0));
  20190       AdvanceIT();
  20191       return;
  20192     }
  20193     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
  20194     if (OutsideITBlock() && dt.Is(F64)) {
  20195       EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20196                  rm.Encode(5, 0));
  20197       AdvanceIT();
  20198       return;
  20199     }
  20200   } else {
  20201     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
  20202     if (dt.Is(F32)) {
  20203       EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20204               rm.Encode(5, 0));
  20205       return;
  20206     }
  20207     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
  20208     if (dt.Is(F64)) {
  20209       EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20210               rm.Encode(5, 0));
  20211       return;
  20212     }
  20213   }
  20214   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
  20215 }
  20216 
  20217 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  20218   VIXL_ASSERT(AllowAssembler());
  20219   CheckIT(al);
  20220   if (IsUsingT32()) {
  20221     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
  20222     if (OutsideITBlock() && dt.Is(F32)) {
  20223       EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20224                  rm.Encode(5, 0));
  20225       AdvanceIT();
  20226       return;
  20227     }
  20228   } else {
  20229     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
  20230     if (dt.Is(F32)) {
  20231       EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20232               rm.Encode(5, 0));
  20233       return;
  20234     }
  20235   }
  20236   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
  20237 }
  20238 
  20239 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  20240   VIXL_ASSERT(AllowAssembler());
  20241   CheckIT(al);
  20242   if (IsUsingT32()) {
  20243     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
  20244     if (OutsideITBlock() && dt.Is(F32)) {
  20245       EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20246                  rm.Encode(5, 0));
  20247       AdvanceIT();
  20248       return;
  20249     }
  20250   } else {
  20251     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
  20252     if (dt.Is(F32)) {
  20253       EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20254               rm.Encode(5, 0));
  20255       return;
  20256     }
  20257   }
  20258   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
  20259 }
  20260 
  20261 void Assembler::vmla(
  20262     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
  20263   VIXL_ASSERT(AllowAssembler());
  20264   CheckIT(cond);
  20265   Dt_size_9 encoded_dt(dt);
  20266   if (IsUsingT32()) {
  20267     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
  20268     if (encoded_dt.IsValid() &&
  20269         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20270          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20271           (rm.GetLane() <= 1)))) {
  20272       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20273         EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
  20274                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20275                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20276         AdvanceIT();
  20277         return;
  20278       }
  20279     }
  20280   } else {
  20281     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
  20282     if (encoded_dt.IsValid() &&
  20283         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20284          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20285           (rm.GetLane() <= 1)))) {
  20286       if (cond.Is(al)) {
  20287         EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
  20288                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20289                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20290         return;
  20291       }
  20292     }
  20293   }
  20294   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
  20295 }
  20296 
  20297 void Assembler::vmla(
  20298     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
  20299   VIXL_ASSERT(AllowAssembler());
  20300   CheckIT(cond);
  20301   Dt_size_9 encoded_dt(dt);
  20302   if (IsUsingT32()) {
  20303     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
  20304     if (encoded_dt.IsValid() &&
  20305         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20306          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20307           (rm.GetLane() <= 1)))) {
  20308       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20309         EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
  20310                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20311                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20312         AdvanceIT();
  20313         return;
  20314       }
  20315     }
  20316   } else {
  20317     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
  20318     if (encoded_dt.IsValid() &&
  20319         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20320          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20321           (rm.GetLane() <= 1)))) {
  20322       if (cond.Is(al)) {
  20323         EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
  20324                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20325                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20326         return;
  20327       }
  20328     }
  20329   }
  20330   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
  20331 }
  20332 
  20333 void Assembler::vmla(
  20334     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  20335   VIXL_ASSERT(AllowAssembler());
  20336   CheckIT(cond);
  20337   Dt_size_10 encoded_dt(dt);
  20338   if (IsUsingT32()) {
  20339     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
  20340     if (dt.Is(F32)) {
  20341       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20342         EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20343                    rm.Encode(5, 0));
  20344         AdvanceIT();
  20345         return;
  20346       }
  20347     }
  20348     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
  20349     if (dt.Is(F64)) {
  20350       EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20351                  rm.Encode(5, 0));
  20352       AdvanceIT();
  20353       return;
  20354     }
  20355     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
  20356     if (encoded_dt.IsValid()) {
  20357       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20358         EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
  20359                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20360         AdvanceIT();
  20361         return;
  20362       }
  20363     }
  20364   } else {
  20365     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
  20366     if (dt.Is(F32)) {
  20367       if (cond.Is(al)) {
  20368         EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20369                 rm.Encode(5, 0));
  20370         return;
  20371       }
  20372     }
  20373     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
  20374     if (dt.Is(F64) && cond.IsNotNever()) {
  20375       EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  20376               rn.Encode(7, 16) | rm.Encode(5, 0));
  20377       return;
  20378     }
  20379     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
  20380     if (encoded_dt.IsValid()) {
  20381       if (cond.Is(al)) {
  20382         EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
  20383                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20384         return;
  20385       }
  20386     }
  20387   }
  20388   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
  20389 }
  20390 
  20391 void Assembler::vmla(
  20392     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  20393   VIXL_ASSERT(AllowAssembler());
  20394   CheckIT(cond);
  20395   Dt_size_10 encoded_dt(dt);
  20396   if (IsUsingT32()) {
  20397     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
  20398     if (dt.Is(F32)) {
  20399       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20400         EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20401                    rm.Encode(5, 0));
  20402         AdvanceIT();
  20403         return;
  20404       }
  20405     }
  20406     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
  20407     if (encoded_dt.IsValid()) {
  20408       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20409         EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
  20410                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20411         AdvanceIT();
  20412         return;
  20413       }
  20414     }
  20415   } else {
  20416     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
  20417     if (dt.Is(F32)) {
  20418       if (cond.Is(al)) {
  20419         EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20420                 rm.Encode(5, 0));
  20421         return;
  20422       }
  20423     }
  20424     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
  20425     if (encoded_dt.IsValid()) {
  20426       if (cond.Is(al)) {
  20427         EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
  20428                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20429         return;
  20430       }
  20431     }
  20432   }
  20433   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
  20434 }
  20435 
  20436 void Assembler::vmla(
  20437     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  20438   VIXL_ASSERT(AllowAssembler());
  20439   CheckIT(cond);
  20440   if (IsUsingT32()) {
  20441     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
  20442     if (dt.Is(F32)) {
  20443       EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20444                  rm.Encode(5, 0));
  20445       AdvanceIT();
  20446       return;
  20447     }
  20448   } else {
  20449     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
  20450     if (dt.Is(F32) && cond.IsNotNever()) {
  20451       EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  20452               rn.Encode(7, 16) | rm.Encode(5, 0));
  20453       return;
  20454     }
  20455   }
  20456   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
  20457 }
  20458 
  20459 void Assembler::vmlal(
  20460     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
  20461   VIXL_ASSERT(AllowAssembler());
  20462   CheckIT(cond);
  20463   Dt_size_11 encoded_dt(dt);
  20464   if (IsUsingT32()) {
  20465     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
  20466     if (encoded_dt.IsValid() &&
  20467         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20468          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20469           (rm.GetLane() <= 1)))) {
  20470       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20471         EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
  20472                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20473                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20474         AdvanceIT();
  20475         return;
  20476       }
  20477     }
  20478   } else {
  20479     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
  20480     if (encoded_dt.IsValid() &&
  20481         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20482          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20483           (rm.GetLane() <= 1)))) {
  20484       if (cond.Is(al)) {
  20485         EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
  20486                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20487                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20488         return;
  20489       }
  20490     }
  20491   }
  20492   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
  20493 }
  20494 
  20495 void Assembler::vmlal(
  20496     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  20497   VIXL_ASSERT(AllowAssembler());
  20498   CheckIT(cond);
  20499   Dt_size_12 encoded_dt(dt);
  20500   if (IsUsingT32()) {
  20501     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
  20502     if (encoded_dt.IsValid()) {
  20503       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20504         EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
  20505                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20506                    rn.Encode(7, 16) | rm.Encode(5, 0));
  20507         AdvanceIT();
  20508         return;
  20509       }
  20510     }
  20511   } else {
  20512     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
  20513     if (encoded_dt.IsValid()) {
  20514       if (cond.Is(al)) {
  20515         EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
  20516                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20517                 rn.Encode(7, 16) | rm.Encode(5, 0));
  20518         return;
  20519       }
  20520     }
  20521   }
  20522   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
  20523 }
  20524 
  20525 void Assembler::vmls(
  20526     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
  20527   VIXL_ASSERT(AllowAssembler());
  20528   CheckIT(cond);
  20529   Dt_size_9 encoded_dt(dt);
  20530   if (IsUsingT32()) {
  20531     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
  20532     if (encoded_dt.IsValid() &&
  20533         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20534          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20535           (rm.GetLane() <= 1)))) {
  20536       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20537         EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
  20538                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20539                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20540         AdvanceIT();
  20541         return;
  20542       }
  20543     }
  20544   } else {
  20545     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
  20546     if (encoded_dt.IsValid() &&
  20547         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20548          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20549           (rm.GetLane() <= 1)))) {
  20550       if (cond.Is(al)) {
  20551         EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
  20552                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20553                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20554         return;
  20555       }
  20556     }
  20557   }
  20558   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
  20559 }
  20560 
  20561 void Assembler::vmls(
  20562     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
  20563   VIXL_ASSERT(AllowAssembler());
  20564   CheckIT(cond);
  20565   Dt_size_9 encoded_dt(dt);
  20566   if (IsUsingT32()) {
  20567     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
  20568     if (encoded_dt.IsValid() &&
  20569         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20570          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20571           (rm.GetLane() <= 1)))) {
  20572       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20573         EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
  20574                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20575                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20576         AdvanceIT();
  20577         return;
  20578       }
  20579     }
  20580   } else {
  20581     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
  20582     if (encoded_dt.IsValid() &&
  20583         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20584          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20585           (rm.GetLane() <= 1)))) {
  20586       if (cond.Is(al)) {
  20587         EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
  20588                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20589                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20590         return;
  20591       }
  20592     }
  20593   }
  20594   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
  20595 }
  20596 
  20597 void Assembler::vmls(
  20598     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  20599   VIXL_ASSERT(AllowAssembler());
  20600   CheckIT(cond);
  20601   Dt_size_10 encoded_dt(dt);
  20602   if (IsUsingT32()) {
  20603     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
  20604     if (dt.Is(F32)) {
  20605       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20606         EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20607                    rm.Encode(5, 0));
  20608         AdvanceIT();
  20609         return;
  20610       }
  20611     }
  20612     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
  20613     if (dt.Is(F64)) {
  20614       EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20615                  rm.Encode(5, 0));
  20616       AdvanceIT();
  20617       return;
  20618     }
  20619     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
  20620     if (encoded_dt.IsValid()) {
  20621       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20622         EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
  20623                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20624         AdvanceIT();
  20625         return;
  20626       }
  20627     }
  20628   } else {
  20629     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
  20630     if (dt.Is(F32)) {
  20631       if (cond.Is(al)) {
  20632         EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20633                 rm.Encode(5, 0));
  20634         return;
  20635       }
  20636     }
  20637     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
  20638     if (dt.Is(F64) && cond.IsNotNever()) {
  20639       EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  20640               rn.Encode(7, 16) | rm.Encode(5, 0));
  20641       return;
  20642     }
  20643     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
  20644     if (encoded_dt.IsValid()) {
  20645       if (cond.Is(al)) {
  20646         EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
  20647                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20648         return;
  20649       }
  20650     }
  20651   }
  20652   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
  20653 }
  20654 
  20655 void Assembler::vmls(
  20656     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  20657   VIXL_ASSERT(AllowAssembler());
  20658   CheckIT(cond);
  20659   Dt_size_10 encoded_dt(dt);
  20660   if (IsUsingT32()) {
  20661     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
  20662     if (dt.Is(F32)) {
  20663       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20664         EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20665                    rm.Encode(5, 0));
  20666         AdvanceIT();
  20667         return;
  20668       }
  20669     }
  20670     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
  20671     if (encoded_dt.IsValid()) {
  20672       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20673         EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
  20674                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20675         AdvanceIT();
  20676         return;
  20677       }
  20678     }
  20679   } else {
  20680     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
  20681     if (dt.Is(F32)) {
  20682       if (cond.Is(al)) {
  20683         EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20684                 rm.Encode(5, 0));
  20685         return;
  20686       }
  20687     }
  20688     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
  20689     if (encoded_dt.IsValid()) {
  20690       if (cond.Is(al)) {
  20691         EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
  20692                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  20693         return;
  20694       }
  20695     }
  20696   }
  20697   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
  20698 }
  20699 
  20700 void Assembler::vmls(
  20701     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  20702   VIXL_ASSERT(AllowAssembler());
  20703   CheckIT(cond);
  20704   if (IsUsingT32()) {
  20705     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
  20706     if (dt.Is(F32)) {
  20707       EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  20708                  rm.Encode(5, 0));
  20709       AdvanceIT();
  20710       return;
  20711     }
  20712   } else {
  20713     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
  20714     if (dt.Is(F32) && cond.IsNotNever()) {
  20715       EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  20716               rn.Encode(7, 16) | rm.Encode(5, 0));
  20717       return;
  20718     }
  20719   }
  20720   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
  20721 }
  20722 
  20723 void Assembler::vmlsl(
  20724     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
  20725   VIXL_ASSERT(AllowAssembler());
  20726   CheckIT(cond);
  20727   Dt_size_11 encoded_dt(dt);
  20728   if (IsUsingT32()) {
  20729     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
  20730     if (encoded_dt.IsValid() &&
  20731         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20732          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20733           (rm.GetLane() <= 1)))) {
  20734       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20735         EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
  20736                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20737                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20738         AdvanceIT();
  20739         return;
  20740       }
  20741     }
  20742   } else {
  20743     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
  20744     if (encoded_dt.IsValid() &&
  20745         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  20746          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  20747           (rm.GetLane() <= 1)))) {
  20748       if (cond.Is(al)) {
  20749         EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
  20750                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20751                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  20752         return;
  20753       }
  20754     }
  20755   }
  20756   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
  20757 }
  20758 
  20759 void Assembler::vmlsl(
  20760     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  20761   VIXL_ASSERT(AllowAssembler());
  20762   CheckIT(cond);
  20763   Dt_size_12 encoded_dt(dt);
  20764   if (IsUsingT32()) {
  20765     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
  20766     if (encoded_dt.IsValid()) {
  20767       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20768         EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
  20769                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20770                    rn.Encode(7, 16) | rm.Encode(5, 0));
  20771         AdvanceIT();
  20772         return;
  20773       }
  20774     }
  20775   } else {
  20776     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
  20777     if (encoded_dt.IsValid()) {
  20778       if (cond.Is(al)) {
  20779         EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
  20780                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
  20781                 rn.Encode(7, 16) | rm.Encode(5, 0));
  20782         return;
  20783       }
  20784     }
  20785   }
  20786   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
  20787 }
  20788 
  20789 void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
  20790   VIXL_ASSERT(AllowAssembler());
  20791   CheckIT(cond);
  20792   if (IsUsingT32()) {
  20793     // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
  20794     if ((!rt.IsPC() || AllowUnpredictable())) {
  20795       EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
  20796       AdvanceIT();
  20797       return;
  20798     }
  20799   } else {
  20800     // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
  20801     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  20802       EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
  20803               rn.Encode(7, 16));
  20804       return;
  20805     }
  20806   }
  20807   Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
  20808 }
  20809 
  20810 void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
  20811   VIXL_ASSERT(AllowAssembler());
  20812   CheckIT(cond);
  20813   if (IsUsingT32()) {
  20814     // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
  20815     if ((!rt.IsPC() || AllowUnpredictable())) {
  20816       EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
  20817       AdvanceIT();
  20818       return;
  20819     }
  20820   } else {
  20821     // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
  20822     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  20823       EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
  20824               (rt.GetCode() << 12));
  20825       return;
  20826     }
  20827   }
  20828   Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
  20829 }
  20830 
  20831 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
  20832   VIXL_ASSERT(AllowAssembler());
  20833   CheckIT(cond);
  20834   if (IsUsingT32()) {
  20835     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
  20836     if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  20837       EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
  20838                  rm.Encode(5, 0));
  20839       AdvanceIT();
  20840       return;
  20841     }
  20842   } else {
  20843     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
  20844     if (cond.IsNotNever() &&
  20845         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  20846       EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
  20847               (rt2.GetCode() << 16) | rm.Encode(5, 0));
  20848       return;
  20849     }
  20850   }
  20851   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
  20852 }
  20853 
  20854 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
  20855   VIXL_ASSERT(AllowAssembler());
  20856   CheckIT(cond);
  20857   if (IsUsingT32()) {
  20858     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
  20859     if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  20860       EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
  20861                  (rt2.GetCode() << 16));
  20862       AdvanceIT();
  20863       return;
  20864     }
  20865   } else {
  20866     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
  20867     if (cond.IsNotNever() &&
  20868         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  20869       EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
  20870               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
  20871       return;
  20872     }
  20873   }
  20874   Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
  20875 }
  20876 
  20877 void Assembler::vmov(
  20878     Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
  20879   VIXL_ASSERT(AllowAssembler());
  20880   CheckIT(cond);
  20881   if (IsUsingT32()) {
  20882     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
  20883     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
  20884         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  20885       EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
  20886                  rm.Encode(5, 0));
  20887       AdvanceIT();
  20888       return;
  20889     }
  20890   } else {
  20891     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
  20892     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
  20893         cond.IsNotNever() &&
  20894         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  20895       EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
  20896               (rt2.GetCode() << 16) | rm.Encode(5, 0));
  20897       return;
  20898     }
  20899   }
  20900   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
  20901 }
  20902 
  20903 void Assembler::vmov(
  20904     Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
  20905   VIXL_ASSERT(AllowAssembler());
  20906   CheckIT(cond);
  20907   if (IsUsingT32()) {
  20908     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
  20909     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
  20910         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  20911       EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
  20912                  (rt2.GetCode() << 16));
  20913       AdvanceIT();
  20914       return;
  20915     }
  20916   } else {
  20917     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
  20918     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
  20919         cond.IsNotNever() &&
  20920         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
  20921       EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
  20922               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
  20923       return;
  20924     }
  20925   }
  20926   Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
  20927 }
  20928 
  20929 void Assembler::vmov(Condition cond,
  20930                      DataType dt,
  20931                      DRegisterLane rd,
  20932                      Register rt) {
  20933   VIXL_ASSERT(AllowAssembler());
  20934   CheckIT(cond);
  20935   Dt_opc1_opc2_1 encoded_dt(dt, rd);
  20936   if (IsUsingT32()) {
  20937     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
  20938     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
  20939       EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
  20940                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
  20941                  rd.Encode(7, 16) | (rt.GetCode() << 12));
  20942       AdvanceIT();
  20943       return;
  20944     }
  20945   } else {
  20946     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
  20947     if (encoded_dt.IsValid() && cond.IsNotNever() &&
  20948         (!rt.IsPC() || AllowUnpredictable())) {
  20949       EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
  20950               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
  20951               ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
  20952               (rt.GetCode() << 12));
  20953       return;
  20954     }
  20955   }
  20956   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
  20957 }
  20958 
  20959 void Assembler::vmov(Condition cond,
  20960                      DataType dt,
  20961                      DRegister rd,
  20962                      const DOperand& operand) {
  20963   VIXL_ASSERT(AllowAssembler());
  20964   CheckIT(cond);
  20965   if (operand.IsImmediate()) {
  20966     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
  20967     if (IsUsingT32()) {
  20968       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
  20969       if (encoded_dt.IsValid()) {
  20970         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  20971           EmitT32_32(
  20972               0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
  20973               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
  20974               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  20975               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  20976               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  20977           AdvanceIT();
  20978           return;
  20979         }
  20980       }
  20981     } else {
  20982       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
  20983       if (encoded_dt.IsValid()) {
  20984         if (cond.Is(al)) {
  20985           EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
  20986                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
  20987                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  20988                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  20989                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  20990           return;
  20991         }
  20992       }
  20993     }
  20994   }
  20995   if (operand.IsImmediate()) {
  20996     ImmediateVFP vfp(operand.GetNeonImmediate());
  20997     if (IsUsingT32()) {
  20998       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
  20999       if (dt.Is(F64) && vfp.IsValid()) {
  21000         EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
  21001                    (vfp.GetEncodingValue() & 0xf) |
  21002                    ((vfp.GetEncodingValue() & 0xf0) << 12));
  21003         AdvanceIT();
  21004         return;
  21005       }
  21006     } else {
  21007       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
  21008       if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
  21009         EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21010                 (vfp.GetEncodingValue() & 0xf) |
  21011                 ((vfp.GetEncodingValue() & 0xf0) << 12));
  21012         return;
  21013       }
  21014     }
  21015   }
  21016   if (operand.IsRegister()) {
  21017     DRegister rm = operand.GetRegister();
  21018     if (IsUsingT32()) {
  21019       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
  21020       if (dt.Is(F64)) {
  21021         EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  21022         AdvanceIT();
  21023         return;
  21024       }
  21025       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
  21026       if (!dt.Is(F64)) {
  21027         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21028           EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  21029                      rm.Encode(5, 0));
  21030           AdvanceIT();
  21031           return;
  21032         }
  21033       }
  21034     } else {
  21035       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
  21036       if (dt.Is(F64) && cond.IsNotNever()) {
  21037         EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21038                 rm.Encode(5, 0));
  21039         return;
  21040       }
  21041       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
  21042       if (!dt.Is(F64)) {
  21043         if (cond.Is(al)) {
  21044           EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  21045                   rm.Encode(5, 0));
  21046           return;
  21047         }
  21048       }
  21049     }
  21050   }
  21051   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
  21052 }
  21053 
  21054 void Assembler::vmov(Condition cond,
  21055                      DataType dt,
  21056                      QRegister rd,
  21057                      const QOperand& operand) {
  21058   VIXL_ASSERT(AllowAssembler());
  21059   CheckIT(cond);
  21060   if (operand.IsImmediate()) {
  21061     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
  21062     if (IsUsingT32()) {
  21063       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
  21064       if (encoded_dt.IsValid()) {
  21065         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21066           EmitT32_32(
  21067               0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
  21068               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
  21069               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  21070               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  21071               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  21072           AdvanceIT();
  21073           return;
  21074         }
  21075       }
  21076     } else {
  21077       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
  21078       if (encoded_dt.IsValid()) {
  21079         if (cond.Is(al)) {
  21080           EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
  21081                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
  21082                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  21083                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  21084                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  21085           return;
  21086         }
  21087       }
  21088     }
  21089   }
  21090   if (operand.IsRegister()) {
  21091     QRegister rm = operand.GetRegister();
  21092     if (IsUsingT32()) {
  21093       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
  21094       if (!dt.Is(F64)) {
  21095         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21096           EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  21097                      rm.Encode(5, 0));
  21098           AdvanceIT();
  21099           return;
  21100         }
  21101       }
  21102     } else {
  21103       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
  21104       if (!dt.Is(F64)) {
  21105         if (cond.Is(al)) {
  21106           EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  21107                   rm.Encode(5, 0));
  21108           return;
  21109         }
  21110       }
  21111     }
  21112   }
  21113   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
  21114 }
  21115 
  21116 void Assembler::vmov(Condition cond,
  21117                      DataType dt,
  21118                      SRegister rd,
  21119                      const SOperand& operand) {
  21120   VIXL_ASSERT(AllowAssembler());
  21121   CheckIT(cond);
  21122   if (operand.IsImmediate()) {
  21123     ImmediateVFP vfp(operand.GetNeonImmediate());
  21124     if (IsUsingT32()) {
  21125       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
  21126       if (dt.Is(F32) && vfp.IsValid()) {
  21127         EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
  21128                    (vfp.GetEncodingValue() & 0xf) |
  21129                    ((vfp.GetEncodingValue() & 0xf0) << 12));
  21130         AdvanceIT();
  21131         return;
  21132       }
  21133     } else {
  21134       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
  21135       if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
  21136         EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21137                 (vfp.GetEncodingValue() & 0xf) |
  21138                 ((vfp.GetEncodingValue() & 0xf0) << 12));
  21139         return;
  21140       }
  21141     }
  21142   }
  21143   if (operand.IsRegister()) {
  21144     SRegister rm = operand.GetRegister();
  21145     if (IsUsingT32()) {
  21146       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
  21147       if (dt.Is(F32)) {
  21148         EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  21149         AdvanceIT();
  21150         return;
  21151       }
  21152     } else {
  21153       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
  21154       if (dt.Is(F32) && cond.IsNotNever()) {
  21155         EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21156                 rm.Encode(5, 0));
  21157         return;
  21158       }
  21159     }
  21160   }
  21161   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
  21162 }
  21163 
  21164 void Assembler::vmov(Condition cond,
  21165                      DataType dt,
  21166                      Register rt,
  21167                      DRegisterLane rn) {
  21168   VIXL_ASSERT(AllowAssembler());
  21169   CheckIT(cond);
  21170   Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
  21171   if (IsUsingT32()) {
  21172     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
  21173     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
  21174       EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
  21175                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
  21176                  ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
  21177                  (rt.GetCode() << 12) | rn.Encode(7, 16));
  21178       AdvanceIT();
  21179       return;
  21180     }
  21181   } else {
  21182     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
  21183     if (encoded_dt.IsValid() && cond.IsNotNever() &&
  21184         (!rt.IsPC() || AllowUnpredictable())) {
  21185       EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
  21186               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
  21187               ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
  21188               ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
  21189               (rt.GetCode() << 12) | rn.Encode(7, 16));
  21190       return;
  21191     }
  21192   }
  21193   Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
  21194 }
  21195 
  21196 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
  21197   VIXL_ASSERT(AllowAssembler());
  21198   CheckIT(cond);
  21199   Dt_U_imm3H_1 encoded_dt(dt);
  21200   if (IsUsingT32()) {
  21201     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
  21202     if (encoded_dt.IsValid()) {
  21203       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21204         EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  21205                    ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
  21206                    rd.Encode(22, 12) | rm.Encode(5, 0));
  21207         AdvanceIT();
  21208         return;
  21209       }
  21210     }
  21211   } else {
  21212     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
  21213     if (encoded_dt.IsValid()) {
  21214       if (cond.Is(al)) {
  21215         EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  21216                 ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
  21217                 rd.Encode(22, 12) | rm.Encode(5, 0));
  21218         return;
  21219       }
  21220     }
  21221   }
  21222   Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
  21223 }
  21224 
  21225 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
  21226   VIXL_ASSERT(AllowAssembler());
  21227   CheckIT(cond);
  21228   Dt_size_3 encoded_dt(dt);
  21229   if (IsUsingT32()) {
  21230     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
  21231     if (encoded_dt.IsValid()) {
  21232       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21233         EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
  21234                    rd.Encode(22, 12) | rm.Encode(5, 0));
  21235         AdvanceIT();
  21236         return;
  21237       }
  21238     }
  21239   } else {
  21240     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
  21241     if (encoded_dt.IsValid()) {
  21242       if (cond.Is(al)) {
  21243         EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
  21244                 rd.Encode(22, 12) | rm.Encode(5, 0));
  21245         return;
  21246       }
  21247     }
  21248   }
  21249   Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
  21250 }
  21251 
  21252 void Assembler::vmrs(Condition cond,
  21253                      RegisterOrAPSR_nzcv rt,
  21254                      SpecialFPRegister spec_reg) {
  21255   VIXL_ASSERT(AllowAssembler());
  21256   CheckIT(cond);
  21257   if (IsUsingT32()) {
  21258     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
  21259     EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
  21260     AdvanceIT();
  21261     return;
  21262   } else {
  21263     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
  21264     if (cond.IsNotNever()) {
  21265       EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
  21266               (spec_reg.GetReg() << 16));
  21267       return;
  21268     }
  21269   }
  21270   Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
  21271 }
  21272 
  21273 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
  21274   VIXL_ASSERT(AllowAssembler());
  21275   CheckIT(cond);
  21276   if (IsUsingT32()) {
  21277     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
  21278     if ((!rt.IsPC() || AllowUnpredictable())) {
  21279       EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) |
  21280                  (rt.GetCode() << 12));
  21281       AdvanceIT();
  21282       return;
  21283     }
  21284   } else {
  21285     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
  21286     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
  21287       EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
  21288               (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
  21289       return;
  21290     }
  21291   }
  21292   Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
  21293 }
  21294 
  21295 void Assembler::vmul(Condition cond,
  21296                      DataType dt,
  21297                      DRegister rd,
  21298                      DRegister rn,
  21299                      DRegister dm,
  21300                      unsigned index) {
  21301   VIXL_ASSERT(AllowAssembler());
  21302   CheckIT(cond);
  21303   Dt_F_size_3 encoded_dt(dt);
  21304   if (IsUsingT32()) {
  21305     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
  21306     if (encoded_dt.IsValid() &&
  21307         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
  21308          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
  21309       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21310         uint32_t shift = 4;
  21311         if (dt.Is(I16)) {
  21312           shift = 3;
  21313         }
  21314         uint32_t mvm = dm.GetCode() | index << shift;
  21315         EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21316                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  21317                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  21318                    ((mvm & 0x10) << 1));
  21319         AdvanceIT();
  21320         return;
  21321       }
  21322     }
  21323   } else {
  21324     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
  21325     if (encoded_dt.IsValid() &&
  21326         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
  21327          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
  21328       if (cond.Is(al)) {
  21329         uint32_t shift = 4;
  21330         if (dt.Is(I16)) {
  21331           shift = 3;
  21332         }
  21333         uint32_t mvm = dm.GetCode() | index << shift;
  21334         EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21335                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  21336                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  21337                 ((mvm & 0x10) << 1));
  21338         return;
  21339       }
  21340     }
  21341   }
  21342   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
  21343 }
  21344 
  21345 void Assembler::vmul(Condition cond,
  21346                      DataType dt,
  21347                      QRegister rd,
  21348                      QRegister rn,
  21349                      DRegister dm,
  21350                      unsigned index) {
  21351   VIXL_ASSERT(AllowAssembler());
  21352   CheckIT(cond);
  21353   Dt_F_size_3 encoded_dt(dt);
  21354   if (IsUsingT32()) {
  21355     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
  21356     if (encoded_dt.IsValid() &&
  21357         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
  21358          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
  21359       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21360         uint32_t shift = 4;
  21361         if (dt.Is(I16)) {
  21362           shift = 3;
  21363         }
  21364         uint32_t mvm = dm.GetCode() | index << shift;
  21365         EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21366                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  21367                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  21368                    ((mvm & 0x10) << 1));
  21369         AdvanceIT();
  21370         return;
  21371       }
  21372     }
  21373   } else {
  21374     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
  21375     if (encoded_dt.IsValid() &&
  21376         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
  21377          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
  21378       if (cond.Is(al)) {
  21379         uint32_t shift = 4;
  21380         if (dt.Is(I16)) {
  21381           shift = 3;
  21382         }
  21383         uint32_t mvm = dm.GetCode() | index << shift;
  21384         EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21385                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  21386                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  21387                 ((mvm & 0x10) << 1));
  21388         return;
  21389       }
  21390     }
  21391   }
  21392   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
  21393 }
  21394 
  21395 void Assembler::vmul(
  21396     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  21397   VIXL_ASSERT(AllowAssembler());
  21398   CheckIT(cond);
  21399   Dt_op_size_1 encoded_dt(dt);
  21400   if (IsUsingT32()) {
  21401     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  21402     if (dt.Is(F32)) {
  21403       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21404         EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21405                    rm.Encode(5, 0));
  21406         AdvanceIT();
  21407         return;
  21408       }
  21409     }
  21410     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
  21411     if (dt.Is(F64)) {
  21412       EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21413                  rm.Encode(5, 0));
  21414       AdvanceIT();
  21415       return;
  21416     }
  21417     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  21418     if (encoded_dt.IsValid()) {
  21419       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21420         EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21421                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  21422                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  21423         AdvanceIT();
  21424         return;
  21425       }
  21426     }
  21427   } else {
  21428     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  21429     if (dt.Is(F32)) {
  21430       if (cond.Is(al)) {
  21431         EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21432                 rm.Encode(5, 0));
  21433         return;
  21434       }
  21435     }
  21436     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
  21437     if (dt.Is(F64) && cond.IsNotNever()) {
  21438       EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21439               rn.Encode(7, 16) | rm.Encode(5, 0));
  21440       return;
  21441     }
  21442     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  21443     if (encoded_dt.IsValid()) {
  21444       if (cond.Is(al)) {
  21445         EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21446                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  21447                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  21448         return;
  21449       }
  21450     }
  21451   }
  21452   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
  21453 }
  21454 
  21455 void Assembler::vmul(
  21456     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  21457   VIXL_ASSERT(AllowAssembler());
  21458   CheckIT(cond);
  21459   Dt_op_size_1 encoded_dt(dt);
  21460   if (IsUsingT32()) {
  21461     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  21462     if (dt.Is(F32)) {
  21463       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21464         EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21465                    rm.Encode(5, 0));
  21466         AdvanceIT();
  21467         return;
  21468       }
  21469     }
  21470     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  21471     if (encoded_dt.IsValid()) {
  21472       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21473         EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21474                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  21475                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  21476         AdvanceIT();
  21477         return;
  21478       }
  21479     }
  21480   } else {
  21481     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  21482     if (dt.Is(F32)) {
  21483       if (cond.Is(al)) {
  21484         EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21485                 rm.Encode(5, 0));
  21486         return;
  21487       }
  21488     }
  21489     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  21490     if (encoded_dt.IsValid()) {
  21491       if (cond.Is(al)) {
  21492         EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21493                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  21494                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  21495         return;
  21496       }
  21497     }
  21498   }
  21499   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
  21500 }
  21501 
  21502 void Assembler::vmul(
  21503     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  21504   VIXL_ASSERT(AllowAssembler());
  21505   CheckIT(cond);
  21506   if (IsUsingT32()) {
  21507     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
  21508     if (dt.Is(F32)) {
  21509       EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21510                  rm.Encode(5, 0));
  21511       AdvanceIT();
  21512       return;
  21513     }
  21514   } else {
  21515     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
  21516     if (dt.Is(F32) && cond.IsNotNever()) {
  21517       EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21518               rn.Encode(7, 16) | rm.Encode(5, 0));
  21519       return;
  21520     }
  21521   }
  21522   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
  21523 }
  21524 
  21525 void Assembler::vmull(Condition cond,
  21526                       DataType dt,
  21527                       QRegister rd,
  21528                       DRegister rn,
  21529                       DRegister dm,
  21530                       unsigned index) {
  21531   VIXL_ASSERT(AllowAssembler());
  21532   CheckIT(cond);
  21533   Dt_U_size_2 encoded_dt(dt);
  21534   if (IsUsingT32()) {
  21535     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
  21536     if (encoded_dt.IsValid() &&
  21537         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
  21538          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) &&
  21539           (dm.GetCode() <= 15)))) {
  21540       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21541         uint32_t shift = 4;
  21542         if (dt.Is(S16) || dt.Is(U16)) {
  21543           shift = 3;
  21544         }
  21545         uint32_t mvm = dm.GetCode() | index << shift;
  21546         EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21547                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  21548                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  21549                    ((mvm & 0x10) << 1));
  21550         AdvanceIT();
  21551         return;
  21552       }
  21553     }
  21554   } else {
  21555     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
  21556     if (encoded_dt.IsValid() &&
  21557         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
  21558          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) &&
  21559           (dm.GetCode() <= 15)))) {
  21560       if (cond.Is(al)) {
  21561         uint32_t shift = 4;
  21562         if (dt.Is(S16) || dt.Is(U16)) {
  21563           shift = 3;
  21564         }
  21565         uint32_t mvm = dm.GetCode() | index << shift;
  21566         EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21567                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  21568                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  21569                 ((mvm & 0x10) << 1));
  21570         return;
  21571       }
  21572     }
  21573   }
  21574   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
  21575 }
  21576 
  21577 void Assembler::vmull(
  21578     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  21579   VIXL_ASSERT(AllowAssembler());
  21580   CheckIT(cond);
  21581   Dt_op_U_size_1 encoded_dt(dt);
  21582   if (IsUsingT32()) {
  21583     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
  21584     if (encoded_dt.IsValid()) {
  21585       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21586         EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21587                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  21588                    ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
  21589                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  21590         AdvanceIT();
  21591         return;
  21592       }
  21593     }
  21594   } else {
  21595     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
  21596     if (encoded_dt.IsValid()) {
  21597       if (cond.Is(al)) {
  21598         EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  21599                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  21600                 ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
  21601                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  21602         return;
  21603       }
  21604     }
  21605   }
  21606   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
  21607 }
  21608 
  21609 void Assembler::vmvn(Condition cond,
  21610                      DataType dt,
  21611                      DRegister rd,
  21612                      const DOperand& operand) {
  21613   VIXL_ASSERT(AllowAssembler());
  21614   CheckIT(cond);
  21615   if (operand.IsImmediate()) {
  21616     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
  21617     if (IsUsingT32()) {
  21618       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
  21619       if (encoded_dt.IsValid()) {
  21620         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21621           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
  21622                      rd.Encode(22, 12) |
  21623                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  21624                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  21625                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  21626           AdvanceIT();
  21627           return;
  21628         }
  21629       }
  21630     } else {
  21631       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
  21632       if (encoded_dt.IsValid()) {
  21633         if (cond.Is(al)) {
  21634           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
  21635                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  21636                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  21637                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  21638           return;
  21639         }
  21640       }
  21641     }
  21642   }
  21643   if (operand.IsRegister()) {
  21644     DRegister rm = operand.GetRegister();
  21645     USE(dt);
  21646     if (IsUsingT32()) {
  21647       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
  21648       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21649         EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
  21650         AdvanceIT();
  21651         return;
  21652       }
  21653     } else {
  21654       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
  21655       if (cond.Is(al)) {
  21656         EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
  21657         return;
  21658       }
  21659     }
  21660   }
  21661   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
  21662 }
  21663 
  21664 void Assembler::vmvn(Condition cond,
  21665                      DataType dt,
  21666                      QRegister rd,
  21667                      const QOperand& operand) {
  21668   VIXL_ASSERT(AllowAssembler());
  21669   CheckIT(cond);
  21670   if (operand.IsImmediate()) {
  21671     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
  21672     if (IsUsingT32()) {
  21673       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
  21674       if (encoded_dt.IsValid()) {
  21675         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21676           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
  21677                      rd.Encode(22, 12) |
  21678                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  21679                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  21680                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  21681           AdvanceIT();
  21682           return;
  21683         }
  21684       }
  21685     } else {
  21686       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
  21687       if (encoded_dt.IsValid()) {
  21688         if (cond.Is(al)) {
  21689           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
  21690                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  21691                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  21692                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  21693           return;
  21694         }
  21695       }
  21696     }
  21697   }
  21698   if (operand.IsRegister()) {
  21699     QRegister rm = operand.GetRegister();
  21700     USE(dt);
  21701     if (IsUsingT32()) {
  21702       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
  21703       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21704         EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  21705         AdvanceIT();
  21706         return;
  21707       }
  21708     } else {
  21709       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
  21710       if (cond.Is(al)) {
  21711         EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  21712         return;
  21713       }
  21714     }
  21715   }
  21716   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
  21717 }
  21718 
  21719 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  21720   VIXL_ASSERT(AllowAssembler());
  21721   CheckIT(cond);
  21722   Dt_F_size_1 encoded_dt(dt);
  21723   if (IsUsingT32()) {
  21724     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  21725     if (encoded_dt.IsValid()) {
  21726       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21727         EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  21728                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  21729                    rd.Encode(22, 12) | rm.Encode(5, 0));
  21730         AdvanceIT();
  21731         return;
  21732       }
  21733     }
  21734     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
  21735     if (dt.Is(F64)) {
  21736       EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  21737       AdvanceIT();
  21738       return;
  21739     }
  21740   } else {
  21741     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  21742     if (encoded_dt.IsValid()) {
  21743       if (cond.Is(al)) {
  21744         EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  21745                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  21746                 rd.Encode(22, 12) | rm.Encode(5, 0));
  21747         return;
  21748       }
  21749     }
  21750     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
  21751     if (dt.Is(F64) && cond.IsNotNever()) {
  21752       EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21753               rm.Encode(5, 0));
  21754       return;
  21755     }
  21756   }
  21757   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
  21758 }
  21759 
  21760 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  21761   VIXL_ASSERT(AllowAssembler());
  21762   CheckIT(cond);
  21763   Dt_F_size_1 encoded_dt(dt);
  21764   if (IsUsingT32()) {
  21765     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  21766     if (encoded_dt.IsValid()) {
  21767       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21768         EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  21769                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  21770                    rd.Encode(22, 12) | rm.Encode(5, 0));
  21771         AdvanceIT();
  21772         return;
  21773       }
  21774     }
  21775   } else {
  21776     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  21777     if (encoded_dt.IsValid()) {
  21778       if (cond.Is(al)) {
  21779         EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  21780                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
  21781                 rd.Encode(22, 12) | rm.Encode(5, 0));
  21782         return;
  21783       }
  21784     }
  21785   }
  21786   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
  21787 }
  21788 
  21789 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
  21790   VIXL_ASSERT(AllowAssembler());
  21791   CheckIT(cond);
  21792   if (IsUsingT32()) {
  21793     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
  21794     if (dt.Is(F32)) {
  21795       EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  21796       AdvanceIT();
  21797       return;
  21798     }
  21799   } else {
  21800     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
  21801     if (dt.Is(F32) && cond.IsNotNever()) {
  21802       EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21803               rm.Encode(5, 0));
  21804       return;
  21805     }
  21806   }
  21807   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
  21808 }
  21809 
  21810 void Assembler::vnmla(
  21811     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  21812   VIXL_ASSERT(AllowAssembler());
  21813   CheckIT(cond);
  21814   if (IsUsingT32()) {
  21815     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
  21816     if (dt.Is(F32)) {
  21817       EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21818                  rm.Encode(5, 0));
  21819       AdvanceIT();
  21820       return;
  21821     }
  21822   } else {
  21823     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
  21824     if (dt.Is(F32) && cond.IsNotNever()) {
  21825       EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21826               rn.Encode(7, 16) | rm.Encode(5, 0));
  21827       return;
  21828     }
  21829   }
  21830   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
  21831 }
  21832 
  21833 void Assembler::vnmla(
  21834     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  21835   VIXL_ASSERT(AllowAssembler());
  21836   CheckIT(cond);
  21837   if (IsUsingT32()) {
  21838     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
  21839     if (dt.Is(F64)) {
  21840       EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21841                  rm.Encode(5, 0));
  21842       AdvanceIT();
  21843       return;
  21844     }
  21845   } else {
  21846     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
  21847     if (dt.Is(F64) && cond.IsNotNever()) {
  21848       EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21849               rn.Encode(7, 16) | rm.Encode(5, 0));
  21850       return;
  21851     }
  21852   }
  21853   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
  21854 }
  21855 
  21856 void Assembler::vnmls(
  21857     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  21858   VIXL_ASSERT(AllowAssembler());
  21859   CheckIT(cond);
  21860   if (IsUsingT32()) {
  21861     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
  21862     if (dt.Is(F32)) {
  21863       EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21864                  rm.Encode(5, 0));
  21865       AdvanceIT();
  21866       return;
  21867     }
  21868   } else {
  21869     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
  21870     if (dt.Is(F32) && cond.IsNotNever()) {
  21871       EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21872               rn.Encode(7, 16) | rm.Encode(5, 0));
  21873       return;
  21874     }
  21875   }
  21876   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
  21877 }
  21878 
  21879 void Assembler::vnmls(
  21880     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  21881   VIXL_ASSERT(AllowAssembler());
  21882   CheckIT(cond);
  21883   if (IsUsingT32()) {
  21884     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
  21885     if (dt.Is(F64)) {
  21886       EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21887                  rm.Encode(5, 0));
  21888       AdvanceIT();
  21889       return;
  21890     }
  21891   } else {
  21892     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
  21893     if (dt.Is(F64) && cond.IsNotNever()) {
  21894       EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21895               rn.Encode(7, 16) | rm.Encode(5, 0));
  21896       return;
  21897     }
  21898   }
  21899   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
  21900 }
  21901 
  21902 void Assembler::vnmul(
  21903     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  21904   VIXL_ASSERT(AllowAssembler());
  21905   CheckIT(cond);
  21906   if (IsUsingT32()) {
  21907     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
  21908     if (dt.Is(F32)) {
  21909       EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21910                  rm.Encode(5, 0));
  21911       AdvanceIT();
  21912       return;
  21913     }
  21914   } else {
  21915     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
  21916     if (dt.Is(F32) && cond.IsNotNever()) {
  21917       EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21918               rn.Encode(7, 16) | rm.Encode(5, 0));
  21919       return;
  21920     }
  21921   }
  21922   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
  21923 }
  21924 
  21925 void Assembler::vnmul(
  21926     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  21927   VIXL_ASSERT(AllowAssembler());
  21928   CheckIT(cond);
  21929   if (IsUsingT32()) {
  21930     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
  21931     if (dt.Is(F64)) {
  21932       EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21933                  rm.Encode(5, 0));
  21934       AdvanceIT();
  21935       return;
  21936     }
  21937   } else {
  21938     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
  21939     if (dt.Is(F64) && cond.IsNotNever()) {
  21940       EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  21941               rn.Encode(7, 16) | rm.Encode(5, 0));
  21942       return;
  21943     }
  21944   }
  21945   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
  21946 }
  21947 
  21948 void Assembler::vorn(Condition cond,
  21949                      DataType dt,
  21950                      DRegister rd,
  21951                      DRegister rn,
  21952                      const DOperand& operand) {
  21953   VIXL_ASSERT(AllowAssembler());
  21954   CheckIT(cond);
  21955   if (operand.IsImmediate()) {
  21956     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
  21957     if (IsUsingT32()) {
  21958       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
  21959       if (encoded_dt.IsValid() && rd.Is(rn)) {
  21960         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21961           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
  21962                      rd.Encode(22, 12) |
  21963                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  21964                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  21965                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  21966           AdvanceIT();
  21967           return;
  21968         }
  21969       }
  21970     } else {
  21971       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
  21972       if (encoded_dt.IsValid() && rd.Is(rn)) {
  21973         if (cond.Is(al)) {
  21974           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
  21975                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  21976                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  21977                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  21978           return;
  21979         }
  21980       }
  21981     }
  21982   }
  21983   if (operand.IsRegister()) {
  21984     DRegister rm = operand.GetRegister();
  21985     USE(dt);
  21986     if (IsUsingT32()) {
  21987       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
  21988       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  21989         EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21990                    rm.Encode(5, 0));
  21991         AdvanceIT();
  21992         return;
  21993       }
  21994     } else {
  21995       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
  21996       if (cond.Is(al)) {
  21997         EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  21998                 rm.Encode(5, 0));
  21999         return;
  22000       }
  22001     }
  22002   }
  22003   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
  22004 }
  22005 
  22006 void Assembler::vorn(Condition cond,
  22007                      DataType dt,
  22008                      QRegister rd,
  22009                      QRegister rn,
  22010                      const QOperand& operand) {
  22011   VIXL_ASSERT(AllowAssembler());
  22012   CheckIT(cond);
  22013   if (operand.IsImmediate()) {
  22014     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
  22015     if (IsUsingT32()) {
  22016       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
  22017       if (encoded_dt.IsValid() && rd.Is(rn)) {
  22018         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22019           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
  22020                      rd.Encode(22, 12) |
  22021                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  22022                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  22023                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  22024           AdvanceIT();
  22025           return;
  22026         }
  22027       }
  22028     } else {
  22029       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
  22030       if (encoded_dt.IsValid() && rd.Is(rn)) {
  22031         if (cond.Is(al)) {
  22032           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
  22033                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  22034                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  22035                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  22036           return;
  22037         }
  22038       }
  22039     }
  22040   }
  22041   if (operand.IsRegister()) {
  22042     QRegister rm = operand.GetRegister();
  22043     USE(dt);
  22044     if (IsUsingT32()) {
  22045       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
  22046       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22047         EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22048                    rm.Encode(5, 0));
  22049         AdvanceIT();
  22050         return;
  22051       }
  22052     } else {
  22053       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
  22054       if (cond.Is(al)) {
  22055         EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22056                 rm.Encode(5, 0));
  22057         return;
  22058       }
  22059     }
  22060   }
  22061   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
  22062 }
  22063 
  22064 void Assembler::vorr(Condition cond,
  22065                      DataType dt,
  22066                      DRegister rd,
  22067                      DRegister rn,
  22068                      const DOperand& operand) {
  22069   VIXL_ASSERT(AllowAssembler());
  22070   CheckIT(cond);
  22071   if (operand.IsRegister()) {
  22072     DRegister rm = operand.GetRegister();
  22073     USE(dt);
  22074     if (IsUsingT32()) {
  22075       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
  22076       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22077         EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22078                    rm.Encode(5, 0));
  22079         AdvanceIT();
  22080         return;
  22081       }
  22082     } else {
  22083       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
  22084       if (cond.Is(al)) {
  22085         EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22086                 rm.Encode(5, 0));
  22087         return;
  22088       }
  22089     }
  22090   }
  22091   if (operand.IsImmediate()) {
  22092     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
  22093     if (IsUsingT32()) {
  22094       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
  22095       if (encoded_dt.IsValid() && rd.Is(rn)) {
  22096         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22097           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
  22098                      rd.Encode(22, 12) |
  22099                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  22100                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  22101                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  22102           AdvanceIT();
  22103           return;
  22104         }
  22105       }
  22106     } else {
  22107       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
  22108       if (encoded_dt.IsValid() && rd.Is(rn)) {
  22109         if (cond.Is(al)) {
  22110           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
  22111                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  22112                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  22113                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  22114           return;
  22115         }
  22116       }
  22117     }
  22118   }
  22119   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
  22120 }
  22121 
  22122 void Assembler::vorr(Condition cond,
  22123                      DataType dt,
  22124                      QRegister rd,
  22125                      QRegister rn,
  22126                      const QOperand& operand) {
  22127   VIXL_ASSERT(AllowAssembler());
  22128   CheckIT(cond);
  22129   if (operand.IsRegister()) {
  22130     QRegister rm = operand.GetRegister();
  22131     USE(dt);
  22132     if (IsUsingT32()) {
  22133       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
  22134       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22135         EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22136                    rm.Encode(5, 0));
  22137         AdvanceIT();
  22138         return;
  22139       }
  22140     } else {
  22141       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
  22142       if (cond.Is(al)) {
  22143         EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22144                 rm.Encode(5, 0));
  22145         return;
  22146       }
  22147     }
  22148   }
  22149   if (operand.IsImmediate()) {
  22150     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
  22151     if (IsUsingT32()) {
  22152       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
  22153       if (encoded_dt.IsValid() && rd.Is(rn)) {
  22154         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22155           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
  22156                      rd.Encode(22, 12) |
  22157                      (encoded_dt.GetEncodedImmediate() & 0xf) |
  22158                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  22159                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
  22160           AdvanceIT();
  22161           return;
  22162         }
  22163       }
  22164     } else {
  22165       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
  22166       if (encoded_dt.IsValid() && rd.Is(rn)) {
  22167         if (cond.Is(al)) {
  22168           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
  22169                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
  22170                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
  22171                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
  22172           return;
  22173         }
  22174       }
  22175     }
  22176   }
  22177   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
  22178 }
  22179 
  22180 void Assembler::vpadal(Condition cond,
  22181                        DataType dt,
  22182                        DRegister rd,
  22183                        DRegister rm) {
  22184   VIXL_ASSERT(AllowAssembler());
  22185   CheckIT(cond);
  22186   Dt_op_size_2 encoded_dt(dt);
  22187   if (IsUsingT32()) {
  22188     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  22189     if (encoded_dt.IsValid()) {
  22190       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22191         EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  22192                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
  22193                    rd.Encode(22, 12) | rm.Encode(5, 0));
  22194         AdvanceIT();
  22195         return;
  22196       }
  22197     }
  22198   } else {
  22199     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  22200     if (encoded_dt.IsValid()) {
  22201       if (cond.Is(al)) {
  22202         EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  22203                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
  22204                 rd.Encode(22, 12) | rm.Encode(5, 0));
  22205         return;
  22206       }
  22207     }
  22208   }
  22209   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
  22210 }
  22211 
  22212 void Assembler::vpadal(Condition cond,
  22213                        DataType dt,
  22214                        QRegister rd,
  22215                        QRegister rm) {
  22216   VIXL_ASSERT(AllowAssembler());
  22217   CheckIT(cond);
  22218   Dt_op_size_2 encoded_dt(dt);
  22219   if (IsUsingT32()) {
  22220     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  22221     if (encoded_dt.IsValid()) {
  22222       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22223         EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  22224                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
  22225                    rd.Encode(22, 12) | rm.Encode(5, 0));
  22226         AdvanceIT();
  22227         return;
  22228       }
  22229     }
  22230   } else {
  22231     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  22232     if (encoded_dt.IsValid()) {
  22233       if (cond.Is(al)) {
  22234         EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  22235                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
  22236                 rd.Encode(22, 12) | rm.Encode(5, 0));
  22237         return;
  22238       }
  22239     }
  22240   }
  22241   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
  22242 }
  22243 
  22244 void Assembler::vpadd(
  22245     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  22246   VIXL_ASSERT(AllowAssembler());
  22247   CheckIT(cond);
  22248   Dt_size_4 encoded_dt(dt);
  22249   if (IsUsingT32()) {
  22250     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  22251     if (dt.Is(F32)) {
  22252       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22253         EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22254                    rm.Encode(5, 0));
  22255         AdvanceIT();
  22256         return;
  22257       }
  22258     }
  22259     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  22260     if (encoded_dt.IsValid()) {
  22261       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22262         EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
  22263                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22264         AdvanceIT();
  22265         return;
  22266       }
  22267     }
  22268   } else {
  22269     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  22270     if (dt.Is(F32)) {
  22271       if (cond.Is(al)) {
  22272         EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22273                 rm.Encode(5, 0));
  22274         return;
  22275       }
  22276     }
  22277     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  22278     if (encoded_dt.IsValid()) {
  22279       if (cond.Is(al)) {
  22280         EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
  22281                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22282         return;
  22283       }
  22284     }
  22285   }
  22286   Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
  22287 }
  22288 
  22289 void Assembler::vpaddl(Condition cond,
  22290                        DataType dt,
  22291                        DRegister rd,
  22292                        DRegister rm) {
  22293   VIXL_ASSERT(AllowAssembler());
  22294   CheckIT(cond);
  22295   Dt_op_size_2 encoded_dt(dt);
  22296   if (IsUsingT32()) {
  22297     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  22298     if (encoded_dt.IsValid()) {
  22299       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22300         EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  22301                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
  22302                    rd.Encode(22, 12) | rm.Encode(5, 0));
  22303         AdvanceIT();
  22304         return;
  22305       }
  22306     }
  22307   } else {
  22308     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  22309     if (encoded_dt.IsValid()) {
  22310       if (cond.Is(al)) {
  22311         EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  22312                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
  22313                 rd.Encode(22, 12) | rm.Encode(5, 0));
  22314         return;
  22315       }
  22316     }
  22317   }
  22318   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
  22319 }
  22320 
  22321 void Assembler::vpaddl(Condition cond,
  22322                        DataType dt,
  22323                        QRegister rd,
  22324                        QRegister rm) {
  22325   VIXL_ASSERT(AllowAssembler());
  22326   CheckIT(cond);
  22327   Dt_op_size_2 encoded_dt(dt);
  22328   if (IsUsingT32()) {
  22329     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  22330     if (encoded_dt.IsValid()) {
  22331       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22332         EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  22333                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
  22334                    rd.Encode(22, 12) | rm.Encode(5, 0));
  22335         AdvanceIT();
  22336         return;
  22337       }
  22338     }
  22339   } else {
  22340     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  22341     if (encoded_dt.IsValid()) {
  22342       if (cond.Is(al)) {
  22343         EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  22344                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
  22345                 rd.Encode(22, 12) | rm.Encode(5, 0));
  22346         return;
  22347       }
  22348     }
  22349   }
  22350   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
  22351 }
  22352 
  22353 void Assembler::vpmax(
  22354     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  22355   VIXL_ASSERT(AllowAssembler());
  22356   CheckIT(cond);
  22357   Dt_U_size_1 encoded_dt(dt);
  22358   if (IsUsingT32()) {
  22359     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  22360     if (dt.Is(F32)) {
  22361       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22362         EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22363                    rm.Encode(5, 0));
  22364         AdvanceIT();
  22365         return;
  22366       }
  22367     }
  22368     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  22369     if (encoded_dt.IsValid()) {
  22370       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22371         EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  22372                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  22373                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22374         AdvanceIT();
  22375         return;
  22376       }
  22377     }
  22378   } else {
  22379     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  22380     if (dt.Is(F32)) {
  22381       if (cond.Is(al)) {
  22382         EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22383                 rm.Encode(5, 0));
  22384         return;
  22385       }
  22386     }
  22387     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  22388     if (encoded_dt.IsValid()) {
  22389       if (cond.Is(al)) {
  22390         EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  22391                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  22392                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22393         return;
  22394       }
  22395     }
  22396   }
  22397   Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
  22398 }
  22399 
  22400 void Assembler::vpmin(
  22401     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  22402   VIXL_ASSERT(AllowAssembler());
  22403   CheckIT(cond);
  22404   Dt_U_size_1 encoded_dt(dt);
  22405   if (IsUsingT32()) {
  22406     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  22407     if (dt.Is(F32)) {
  22408       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22409         EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22410                    rm.Encode(5, 0));
  22411         AdvanceIT();
  22412         return;
  22413       }
  22414     }
  22415     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  22416     if (encoded_dt.IsValid()) {
  22417       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22418         EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  22419                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  22420                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22421         AdvanceIT();
  22422         return;
  22423       }
  22424     }
  22425   } else {
  22426     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  22427     if (dt.Is(F32)) {
  22428       if (cond.Is(al)) {
  22429         EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  22430                 rm.Encode(5, 0));
  22431         return;
  22432       }
  22433     }
  22434     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  22435     if (encoded_dt.IsValid()) {
  22436       if (cond.Is(al)) {
  22437         EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  22438                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  22439                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22440         return;
  22441       }
  22442     }
  22443   }
  22444   Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
  22445 }
  22446 
  22447 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
  22448   VIXL_ASSERT(AllowAssembler());
  22449   CheckIT(cond);
  22450   USE(dt);
  22451   if (IsUsingT32()) {
  22452     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
  22453     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
  22454       const DRegister& dreg = dreglist.GetFirstDRegister();
  22455       unsigned len = dreglist.GetLength() * 2;
  22456       EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
  22457       AdvanceIT();
  22458       return;
  22459     }
  22460   } else {
  22461     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
  22462     if (cond.IsNotNever() &&
  22463         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
  22464       const DRegister& dreg = dreglist.GetFirstDRegister();
  22465       unsigned len = dreglist.GetLength() * 2;
  22466       EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
  22467               (len & 0xff));
  22468       return;
  22469     }
  22470   }
  22471   Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
  22472 }
  22473 
  22474 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
  22475   VIXL_ASSERT(AllowAssembler());
  22476   CheckIT(cond);
  22477   USE(dt);
  22478   if (IsUsingT32()) {
  22479     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
  22480     const SRegister& sreg = sreglist.GetFirstSRegister();
  22481     unsigned len = sreglist.GetLength();
  22482     EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
  22483     AdvanceIT();
  22484     return;
  22485   } else {
  22486     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
  22487     if (cond.IsNotNever()) {
  22488       const SRegister& sreg = sreglist.GetFirstSRegister();
  22489       unsigned len = sreglist.GetLength();
  22490       EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
  22491               (len & 0xff));
  22492       return;
  22493     }
  22494   }
  22495   Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
  22496 }
  22497 
  22498 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
  22499   VIXL_ASSERT(AllowAssembler());
  22500   CheckIT(cond);
  22501   USE(dt);
  22502   if (IsUsingT32()) {
  22503     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
  22504     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
  22505       const DRegister& dreg = dreglist.GetFirstDRegister();
  22506       unsigned len = dreglist.GetLength() * 2;
  22507       EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
  22508       AdvanceIT();
  22509       return;
  22510     }
  22511   } else {
  22512     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
  22513     if (cond.IsNotNever() &&
  22514         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
  22515       const DRegister& dreg = dreglist.GetFirstDRegister();
  22516       unsigned len = dreglist.GetLength() * 2;
  22517       EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
  22518               (len & 0xff));
  22519       return;
  22520     }
  22521   }
  22522   Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
  22523 }
  22524 
  22525 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
  22526   VIXL_ASSERT(AllowAssembler());
  22527   CheckIT(cond);
  22528   USE(dt);
  22529   if (IsUsingT32()) {
  22530     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
  22531     const SRegister& sreg = sreglist.GetFirstSRegister();
  22532     unsigned len = sreglist.GetLength();
  22533     EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
  22534     AdvanceIT();
  22535     return;
  22536   } else {
  22537     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
  22538     if (cond.IsNotNever()) {
  22539       const SRegister& sreg = sreglist.GetFirstSRegister();
  22540       unsigned len = sreglist.GetLength();
  22541       EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
  22542               (len & 0xff));
  22543       return;
  22544     }
  22545   }
  22546   Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
  22547 }
  22548 
  22549 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  22550   VIXL_ASSERT(AllowAssembler());
  22551   CheckIT(cond);
  22552   Dt_size_5 encoded_dt(dt);
  22553   if (IsUsingT32()) {
  22554     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  22555     if (encoded_dt.IsValid()) {
  22556       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22557         EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
  22558                    rd.Encode(22, 12) | rm.Encode(5, 0));
  22559         AdvanceIT();
  22560         return;
  22561       }
  22562     }
  22563   } else {
  22564     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  22565     if (encoded_dt.IsValid()) {
  22566       if (cond.Is(al)) {
  22567         EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
  22568                 rd.Encode(22, 12) | rm.Encode(5, 0));
  22569         return;
  22570       }
  22571     }
  22572   }
  22573   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
  22574 }
  22575 
  22576 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  22577   VIXL_ASSERT(AllowAssembler());
  22578   CheckIT(cond);
  22579   Dt_size_5 encoded_dt(dt);
  22580   if (IsUsingT32()) {
  22581     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  22582     if (encoded_dt.IsValid()) {
  22583       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22584         EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
  22585                    rd.Encode(22, 12) | rm.Encode(5, 0));
  22586         AdvanceIT();
  22587         return;
  22588       }
  22589     }
  22590   } else {
  22591     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  22592     if (encoded_dt.IsValid()) {
  22593       if (cond.Is(al)) {
  22594         EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
  22595                 rd.Encode(22, 12) | rm.Encode(5, 0));
  22596         return;
  22597       }
  22598     }
  22599   }
  22600   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
  22601 }
  22602 
  22603 void Assembler::vqadd(
  22604     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  22605   VIXL_ASSERT(AllowAssembler());
  22606   CheckIT(cond);
  22607   Dt_U_size_3 encoded_dt(dt);
  22608   if (IsUsingT32()) {
  22609     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  22610     if (encoded_dt.IsValid()) {
  22611       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22612         EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  22613                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  22614                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22615         AdvanceIT();
  22616         return;
  22617       }
  22618     }
  22619   } else {
  22620     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  22621     if (encoded_dt.IsValid()) {
  22622       if (cond.Is(al)) {
  22623         EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  22624                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  22625                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22626         return;
  22627       }
  22628     }
  22629   }
  22630   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
  22631 }
  22632 
  22633 void Assembler::vqadd(
  22634     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  22635   VIXL_ASSERT(AllowAssembler());
  22636   CheckIT(cond);
  22637   Dt_U_size_3 encoded_dt(dt);
  22638   if (IsUsingT32()) {
  22639     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  22640     if (encoded_dt.IsValid()) {
  22641       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22642         EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  22643                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  22644                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22645         AdvanceIT();
  22646         return;
  22647       }
  22648     }
  22649   } else {
  22650     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  22651     if (encoded_dt.IsValid()) {
  22652       if (cond.Is(al)) {
  22653         EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  22654                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  22655                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22656         return;
  22657       }
  22658     }
  22659   }
  22660   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
  22661 }
  22662 
  22663 void Assembler::vqdmlal(
  22664     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  22665   VIXL_ASSERT(AllowAssembler());
  22666   CheckIT(cond);
  22667   Dt_size_13 encoded_dt(dt);
  22668   if (IsUsingT32()) {
  22669     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
  22670     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
  22671       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22672         EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
  22673                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22674         AdvanceIT();
  22675         return;
  22676       }
  22677     }
  22678   } else {
  22679     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
  22680     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
  22681       if (cond.Is(al)) {
  22682         EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
  22683                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22684         return;
  22685       }
  22686     }
  22687   }
  22688   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
  22689 }
  22690 
  22691 void Assembler::vqdmlal(Condition cond,
  22692                         DataType dt,
  22693                         QRegister rd,
  22694                         DRegister rn,
  22695                         DRegister dm,
  22696                         unsigned index) {
  22697   VIXL_ASSERT(AllowAssembler());
  22698   CheckIT(cond);
  22699   Dt_size_13 encoded_dt(dt);
  22700   if (IsUsingT32()) {
  22701     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
  22702     if (encoded_dt.IsValid() &&
  22703         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
  22704          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
  22705         (dt.Is(S16) || dt.Is(S32))) {
  22706       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22707         uint32_t shift = 4;
  22708         if (dt.Is(S16)) {
  22709           shift = 3;
  22710         }
  22711         uint32_t mvm = dm.GetCode() | index << shift;
  22712         EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
  22713                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  22714                    ((mvm & 0x10) << 1));
  22715         AdvanceIT();
  22716         return;
  22717       }
  22718     }
  22719   } else {
  22720     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
  22721     if (encoded_dt.IsValid() &&
  22722         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
  22723          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
  22724         (dt.Is(S16) || dt.Is(S32))) {
  22725       if (cond.Is(al)) {
  22726         uint32_t shift = 4;
  22727         if (dt.Is(S16)) {
  22728           shift = 3;
  22729         }
  22730         uint32_t mvm = dm.GetCode() | index << shift;
  22731         EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
  22732                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  22733                 ((mvm & 0x10) << 1));
  22734         return;
  22735       }
  22736     }
  22737   }
  22738   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
  22739 }
  22740 
  22741 void Assembler::vqdmlsl(
  22742     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  22743   VIXL_ASSERT(AllowAssembler());
  22744   CheckIT(cond);
  22745   Dt_size_13 encoded_dt(dt);
  22746   if (IsUsingT32()) {
  22747     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
  22748     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
  22749       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22750         EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
  22751                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22752         AdvanceIT();
  22753         return;
  22754       }
  22755     }
  22756   } else {
  22757     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
  22758     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
  22759       if (cond.Is(al)) {
  22760         EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
  22761                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22762         return;
  22763       }
  22764     }
  22765   }
  22766   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
  22767 }
  22768 
  22769 void Assembler::vqdmlsl(Condition cond,
  22770                         DataType dt,
  22771                         QRegister rd,
  22772                         DRegister rn,
  22773                         DRegister dm,
  22774                         unsigned index) {
  22775   VIXL_ASSERT(AllowAssembler());
  22776   CheckIT(cond);
  22777   Dt_size_13 encoded_dt(dt);
  22778   if (IsUsingT32()) {
  22779     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
  22780     if (encoded_dt.IsValid() &&
  22781         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
  22782          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
  22783         (dt.Is(S16) || dt.Is(S32))) {
  22784       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22785         uint32_t shift = 4;
  22786         if (dt.Is(S16)) {
  22787           shift = 3;
  22788         }
  22789         uint32_t mvm = dm.GetCode() | index << shift;
  22790         EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
  22791                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  22792                    ((mvm & 0x10) << 1));
  22793         AdvanceIT();
  22794         return;
  22795       }
  22796     }
  22797   } else {
  22798     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
  22799     if (encoded_dt.IsValid() &&
  22800         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
  22801          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
  22802         (dt.Is(S16) || dt.Is(S32))) {
  22803       if (cond.Is(al)) {
  22804         uint32_t shift = 4;
  22805         if (dt.Is(S16)) {
  22806           shift = 3;
  22807         }
  22808         uint32_t mvm = dm.GetCode() | index << shift;
  22809         EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
  22810                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
  22811                 ((mvm & 0x10) << 1));
  22812         return;
  22813       }
  22814     }
  22815   }
  22816   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
  22817 }
  22818 
  22819 void Assembler::vqdmulh(
  22820     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  22821   VIXL_ASSERT(AllowAssembler());
  22822   CheckIT(cond);
  22823   Dt_size_13 encoded_dt(dt);
  22824   if (IsUsingT32()) {
  22825     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  22826     if (encoded_dt.IsValid()) {
  22827       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22828         EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
  22829                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22830         AdvanceIT();
  22831         return;
  22832       }
  22833     }
  22834   } else {
  22835     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  22836     if (encoded_dt.IsValid()) {
  22837       if (cond.Is(al)) {
  22838         EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
  22839                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22840         return;
  22841       }
  22842     }
  22843   }
  22844   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
  22845 }
  22846 
  22847 void Assembler::vqdmulh(
  22848     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  22849   VIXL_ASSERT(AllowAssembler());
  22850   CheckIT(cond);
  22851   Dt_size_13 encoded_dt(dt);
  22852   if (IsUsingT32()) {
  22853     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  22854     if (encoded_dt.IsValid()) {
  22855       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22856         EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
  22857                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22858         AdvanceIT();
  22859         return;
  22860       }
  22861     }
  22862   } else {
  22863     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  22864     if (encoded_dt.IsValid()) {
  22865       if (cond.Is(al)) {
  22866         EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
  22867                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22868         return;
  22869       }
  22870     }
  22871   }
  22872   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
  22873 }
  22874 
  22875 void Assembler::vqdmulh(
  22876     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
  22877   VIXL_ASSERT(AllowAssembler());
  22878   CheckIT(cond);
  22879   Dt_size_13 encoded_dt(dt);
  22880   if (IsUsingT32()) {
  22881     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
  22882     if (encoded_dt.IsValid() &&
  22883         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  22884          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  22885           (rm.GetLane() <= 1))) &&
  22886         (dt.Is(S16) || dt.Is(S32))) {
  22887       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22888         EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
  22889                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  22890         AdvanceIT();
  22891         return;
  22892       }
  22893     }
  22894   } else {
  22895     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
  22896     if (encoded_dt.IsValid() &&
  22897         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  22898          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  22899           (rm.GetLane() <= 1))) &&
  22900         (dt.Is(S16) || dt.Is(S32))) {
  22901       if (cond.Is(al)) {
  22902         EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
  22903                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  22904         return;
  22905       }
  22906     }
  22907   }
  22908   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
  22909 }
  22910 
  22911 void Assembler::vqdmulh(
  22912     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
  22913   VIXL_ASSERT(AllowAssembler());
  22914   CheckIT(cond);
  22915   Dt_size_13 encoded_dt(dt);
  22916   if (IsUsingT32()) {
  22917     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
  22918     if (encoded_dt.IsValid() &&
  22919         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  22920          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  22921           (rm.GetLane() <= 1))) &&
  22922         (dt.Is(S16) || dt.Is(S32))) {
  22923       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22924         EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
  22925                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  22926         AdvanceIT();
  22927         return;
  22928       }
  22929     }
  22930   } else {
  22931     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
  22932     if (encoded_dt.IsValid() &&
  22933         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  22934          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  22935           (rm.GetLane() <= 1))) &&
  22936         (dt.Is(S16) || dt.Is(S32))) {
  22937       if (cond.Is(al)) {
  22938         EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
  22939                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  22940         return;
  22941       }
  22942     }
  22943   }
  22944   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
  22945 }
  22946 
  22947 void Assembler::vqdmull(
  22948     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  22949   VIXL_ASSERT(AllowAssembler());
  22950   CheckIT(cond);
  22951   Dt_size_13 encoded_dt(dt);
  22952   if (IsUsingT32()) {
  22953     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
  22954     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
  22955       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22956         EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
  22957                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22958         AdvanceIT();
  22959         return;
  22960       }
  22961     }
  22962   } else {
  22963     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
  22964     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
  22965       if (cond.Is(al)) {
  22966         EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
  22967                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  22968         return;
  22969       }
  22970     }
  22971   }
  22972   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
  22973 }
  22974 
  22975 void Assembler::vqdmull(
  22976     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
  22977   VIXL_ASSERT(AllowAssembler());
  22978   CheckIT(cond);
  22979   Dt_size_13 encoded_dt(dt);
  22980   if (IsUsingT32()) {
  22981     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
  22982     if (encoded_dt.IsValid() &&
  22983         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  22984          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  22985           (rm.GetLane() <= 1))) &&
  22986         (dt.Is(S16) || dt.Is(S32))) {
  22987       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  22988         EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
  22989                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  22990         AdvanceIT();
  22991         return;
  22992       }
  22993     }
  22994   } else {
  22995     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
  22996     if (encoded_dt.IsValid() &&
  22997         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  22998          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  22999           (rm.GetLane() <= 1))) &&
  23000         (dt.Is(S16) || dt.Is(S32))) {
  23001       if (cond.Is(al)) {
  23002         EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
  23003                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  23004         return;
  23005       }
  23006     }
  23007   }
  23008   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
  23009 }
  23010 
  23011 void Assembler::vqmovn(Condition cond,
  23012                        DataType dt,
  23013                        DRegister rd,
  23014                        QRegister rm) {
  23015   VIXL_ASSERT(AllowAssembler());
  23016   CheckIT(cond);
  23017   Dt_op_size_3 encoded_dt(dt);
  23018   if (IsUsingT32()) {
  23019     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
  23020     if (encoded_dt.IsValid()) {
  23021       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23022         EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23023                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
  23024                    rd.Encode(22, 12) | rm.Encode(5, 0));
  23025         AdvanceIT();
  23026         return;
  23027       }
  23028     }
  23029   } else {
  23030     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
  23031     if (encoded_dt.IsValid()) {
  23032       if (cond.Is(al)) {
  23033         EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23034                 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
  23035                 rd.Encode(22, 12) | rm.Encode(5, 0));
  23036         return;
  23037       }
  23038     }
  23039   }
  23040   Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
  23041 }
  23042 
  23043 void Assembler::vqmovun(Condition cond,
  23044                         DataType dt,
  23045                         DRegister rd,
  23046                         QRegister rm) {
  23047   VIXL_ASSERT(AllowAssembler());
  23048   CheckIT(cond);
  23049   Dt_size_14 encoded_dt(dt);
  23050   if (IsUsingT32()) {
  23051     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
  23052     if (encoded_dt.IsValid()) {
  23053       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23054         EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
  23055                    rd.Encode(22, 12) | rm.Encode(5, 0));
  23056         AdvanceIT();
  23057         return;
  23058       }
  23059     }
  23060   } else {
  23061     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
  23062     if (encoded_dt.IsValid()) {
  23063       if (cond.Is(al)) {
  23064         EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
  23065                 rd.Encode(22, 12) | rm.Encode(5, 0));
  23066         return;
  23067       }
  23068     }
  23069   }
  23070   Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
  23071 }
  23072 
  23073 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  23074   VIXL_ASSERT(AllowAssembler());
  23075   CheckIT(cond);
  23076   Dt_size_5 encoded_dt(dt);
  23077   if (IsUsingT32()) {
  23078     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  23079     if (encoded_dt.IsValid()) {
  23080       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23081         EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
  23082                    rd.Encode(22, 12) | rm.Encode(5, 0));
  23083         AdvanceIT();
  23084         return;
  23085       }
  23086     }
  23087   } else {
  23088     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  23089     if (encoded_dt.IsValid()) {
  23090       if (cond.Is(al)) {
  23091         EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
  23092                 rd.Encode(22, 12) | rm.Encode(5, 0));
  23093         return;
  23094       }
  23095     }
  23096   }
  23097   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
  23098 }
  23099 
  23100 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  23101   VIXL_ASSERT(AllowAssembler());
  23102   CheckIT(cond);
  23103   Dt_size_5 encoded_dt(dt);
  23104   if (IsUsingT32()) {
  23105     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  23106     if (encoded_dt.IsValid()) {
  23107       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23108         EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
  23109                    rd.Encode(22, 12) | rm.Encode(5, 0));
  23110         AdvanceIT();
  23111         return;
  23112       }
  23113     }
  23114   } else {
  23115     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  23116     if (encoded_dt.IsValid()) {
  23117       if (cond.Is(al)) {
  23118         EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
  23119                 rd.Encode(22, 12) | rm.Encode(5, 0));
  23120         return;
  23121       }
  23122     }
  23123   }
  23124   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
  23125 }
  23126 
  23127 void Assembler::vqrdmulh(
  23128     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  23129   VIXL_ASSERT(AllowAssembler());
  23130   CheckIT(cond);
  23131   Dt_size_13 encoded_dt(dt);
  23132   if (IsUsingT32()) {
  23133     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  23134     if (encoded_dt.IsValid()) {
  23135       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23136         EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
  23137                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23138         AdvanceIT();
  23139         return;
  23140       }
  23141     }
  23142   } else {
  23143     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  23144     if (encoded_dt.IsValid()) {
  23145       if (cond.Is(al)) {
  23146         EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
  23147                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23148         return;
  23149       }
  23150     }
  23151   }
  23152   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
  23153 }
  23154 
  23155 void Assembler::vqrdmulh(
  23156     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  23157   VIXL_ASSERT(AllowAssembler());
  23158   CheckIT(cond);
  23159   Dt_size_13 encoded_dt(dt);
  23160   if (IsUsingT32()) {
  23161     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  23162     if (encoded_dt.IsValid()) {
  23163       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23164         EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
  23165                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23166         AdvanceIT();
  23167         return;
  23168       }
  23169     }
  23170   } else {
  23171     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  23172     if (encoded_dt.IsValid()) {
  23173       if (cond.Is(al)) {
  23174         EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
  23175                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23176         return;
  23177       }
  23178     }
  23179   }
  23180   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
  23181 }
  23182 
  23183 void Assembler::vqrdmulh(
  23184     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
  23185   VIXL_ASSERT(AllowAssembler());
  23186   CheckIT(cond);
  23187   Dt_size_13 encoded_dt(dt);
  23188   if (IsUsingT32()) {
  23189     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
  23190     if (encoded_dt.IsValid() &&
  23191         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  23192          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  23193           (rm.GetLane() <= 1))) &&
  23194         (dt.Is(S16) || dt.Is(S32))) {
  23195       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23196         EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
  23197                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  23198         AdvanceIT();
  23199         return;
  23200       }
  23201     }
  23202   } else {
  23203     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
  23204     if (encoded_dt.IsValid() &&
  23205         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  23206          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  23207           (rm.GetLane() <= 1))) &&
  23208         (dt.Is(S16) || dt.Is(S32))) {
  23209       if (cond.Is(al)) {
  23210         EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
  23211                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  23212         return;
  23213       }
  23214     }
  23215   }
  23216   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
  23217 }
  23218 
  23219 void Assembler::vqrdmulh(
  23220     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
  23221   VIXL_ASSERT(AllowAssembler());
  23222   CheckIT(cond);
  23223   Dt_size_13 encoded_dt(dt);
  23224   if (IsUsingT32()) {
  23225     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
  23226     if (encoded_dt.IsValid() &&
  23227         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  23228          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  23229           (rm.GetLane() <= 1))) &&
  23230         (dt.Is(S16) || dt.Is(S32))) {
  23231       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23232         EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
  23233                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  23234         AdvanceIT();
  23235         return;
  23236       }
  23237     }
  23238   } else {
  23239     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
  23240     if (encoded_dt.IsValid() &&
  23241         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
  23242          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
  23243           (rm.GetLane() <= 1))) &&
  23244         (dt.Is(S16) || dt.Is(S32))) {
  23245       if (cond.Is(al)) {
  23246         EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
  23247                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
  23248         return;
  23249       }
  23250     }
  23251   }
  23252   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
  23253 }
  23254 
  23255 void Assembler::vqrshl(
  23256     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
  23257   VIXL_ASSERT(AllowAssembler());
  23258   CheckIT(cond);
  23259   Dt_U_size_3 encoded_dt(dt);
  23260   if (IsUsingT32()) {
  23261     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
  23262     if (encoded_dt.IsValid()) {
  23263       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23264         EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23265                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  23266                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  23267         AdvanceIT();
  23268         return;
  23269       }
  23270     }
  23271   } else {
  23272     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
  23273     if (encoded_dt.IsValid()) {
  23274       if (cond.Is(al)) {
  23275         EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23276                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  23277                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  23278         return;
  23279       }
  23280     }
  23281   }
  23282   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
  23283 }
  23284 
  23285 void Assembler::vqrshl(
  23286     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
  23287   VIXL_ASSERT(AllowAssembler());
  23288   CheckIT(cond);
  23289   Dt_U_size_3 encoded_dt(dt);
  23290   if (IsUsingT32()) {
  23291     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
  23292     if (encoded_dt.IsValid()) {
  23293       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23294         EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23295                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  23296                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  23297         AdvanceIT();
  23298         return;
  23299       }
  23300     }
  23301   } else {
  23302     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
  23303     if (encoded_dt.IsValid()) {
  23304       if (cond.Is(al)) {
  23305         EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23306                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  23307                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  23308         return;
  23309       }
  23310     }
  23311   }
  23312   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
  23313 }
  23314 
  23315 void Assembler::vqrshrn(Condition cond,
  23316                         DataType dt,
  23317                         DRegister rd,
  23318                         QRegister rm,
  23319                         const QOperand& operand) {
  23320   VIXL_ASSERT(AllowAssembler());
  23321   CheckIT(cond);
  23322   if (operand.IsImmediate()) {
  23323     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  23324       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  23325       Dt_op_size_3 encoded_dt(dt);
  23326       Dt_imm6_1 encoded_dt_2(dt);
  23327       if (IsUsingT32()) {
  23328         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
  23329         if (encoded_dt.IsValid() && (imm == 0)) {
  23330           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23331             EmitT32_32(0xffb20280U |
  23332                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23333                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
  23334                        rd.Encode(22, 12) | rm.Encode(5, 0));
  23335             AdvanceIT();
  23336             return;
  23337           }
  23338         }
  23339         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
  23340         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  23341           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23342             uint32_t imm6 = dt.GetSize() / 2 - imm;
  23343             EmitT32_32(0xef800950U |
  23344                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
  23345                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
  23346                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23347             AdvanceIT();
  23348             return;
  23349           }
  23350         }
  23351       } else {
  23352         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
  23353         if (encoded_dt.IsValid() && (imm == 0)) {
  23354           if (cond.Is(al)) {
  23355             EmitA32(0xf3b20280U |
  23356                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23357                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
  23358                     rd.Encode(22, 12) | rm.Encode(5, 0));
  23359             return;
  23360           }
  23361         }
  23362         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
  23363         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  23364           if (cond.Is(al)) {
  23365             uint32_t imm6 = dt.GetSize() / 2 - imm;
  23366             EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
  23367                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
  23368                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23369             return;
  23370           }
  23371         }
  23372       }
  23373     }
  23374   }
  23375   Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
  23376 }
  23377 
  23378 void Assembler::vqrshrun(Condition cond,
  23379                          DataType dt,
  23380                          DRegister rd,
  23381                          QRegister rm,
  23382                          const QOperand& operand) {
  23383   VIXL_ASSERT(AllowAssembler());
  23384   CheckIT(cond);
  23385   if (operand.IsImmediate()) {
  23386     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  23387       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  23388       Dt_imm6_2 encoded_dt(dt);
  23389       Dt_size_14 encoded_dt_2(dt);
  23390       if (IsUsingT32()) {
  23391         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
  23392         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  23393           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23394             uint32_t imm6 = dt.GetSize() / 2 - imm;
  23395             EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
  23396                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23397                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23398             AdvanceIT();
  23399             return;
  23400           }
  23401         }
  23402         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
  23403         if (encoded_dt_2.IsValid() && (imm == 0)) {
  23404           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23405             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
  23406                        rd.Encode(22, 12) | rm.Encode(5, 0));
  23407             AdvanceIT();
  23408             return;
  23409           }
  23410         }
  23411       } else {
  23412         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
  23413         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  23414           if (cond.Is(al)) {
  23415             uint32_t imm6 = dt.GetSize() / 2 - imm;
  23416             EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
  23417                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23418                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23419             return;
  23420           }
  23421         }
  23422         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
  23423         if (encoded_dt_2.IsValid() && (imm == 0)) {
  23424           if (cond.Is(al)) {
  23425             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
  23426                     rd.Encode(22, 12) | rm.Encode(5, 0));
  23427             return;
  23428           }
  23429         }
  23430       }
  23431     }
  23432   }
  23433   Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
  23434 }
  23435 
  23436 void Assembler::vqshl(Condition cond,
  23437                       DataType dt,
  23438                       DRegister rd,
  23439                       DRegister rm,
  23440                       const DOperand& operand) {
  23441   VIXL_ASSERT(AllowAssembler());
  23442   CheckIT(cond);
  23443   if (operand.IsRegister()) {
  23444     DRegister rn = operand.GetRegister();
  23445     Dt_U_size_3 encoded_dt(dt);
  23446     if (IsUsingT32()) {
  23447       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
  23448       if (encoded_dt.IsValid()) {
  23449         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23450           EmitT32_32(0xef000410U |
  23451                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23452                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  23453                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  23454           AdvanceIT();
  23455           return;
  23456         }
  23457       }
  23458     } else {
  23459       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
  23460       if (encoded_dt.IsValid()) {
  23461         if (cond.Is(al)) {
  23462           EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23463                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  23464                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  23465           return;
  23466         }
  23467       }
  23468     }
  23469   }
  23470   if (operand.IsImmediate()) {
  23471     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  23472       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  23473       Dt_L_imm6_1 encoded_dt(dt);
  23474       if (IsUsingT32()) {
  23475         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
  23476         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  23477           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23478             uint32_t imm6 = imm;
  23479             EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
  23480                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23481                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  23482                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23483             AdvanceIT();
  23484             return;
  23485           }
  23486         }
  23487       } else {
  23488         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
  23489         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  23490           if (cond.Is(al)) {
  23491             uint32_t imm6 = imm;
  23492             EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
  23493                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23494                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  23495                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23496             return;
  23497           }
  23498         }
  23499       }
  23500     }
  23501   }
  23502   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
  23503 }
  23504 
  23505 void Assembler::vqshl(Condition cond,
  23506                       DataType dt,
  23507                       QRegister rd,
  23508                       QRegister rm,
  23509                       const QOperand& operand) {
  23510   VIXL_ASSERT(AllowAssembler());
  23511   CheckIT(cond);
  23512   if (operand.IsRegister()) {
  23513     QRegister rn = operand.GetRegister();
  23514     Dt_U_size_3 encoded_dt(dt);
  23515     if (IsUsingT32()) {
  23516       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
  23517       if (encoded_dt.IsValid()) {
  23518         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23519           EmitT32_32(0xef000450U |
  23520                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23521                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  23522                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  23523           AdvanceIT();
  23524           return;
  23525         }
  23526       }
  23527     } else {
  23528       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
  23529       if (encoded_dt.IsValid()) {
  23530         if (cond.Is(al)) {
  23531           EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23532                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  23533                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  23534           return;
  23535         }
  23536       }
  23537     }
  23538   }
  23539   if (operand.IsImmediate()) {
  23540     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  23541       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  23542       Dt_L_imm6_1 encoded_dt(dt);
  23543       if (IsUsingT32()) {
  23544         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
  23545         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  23546           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23547             uint32_t imm6 = imm;
  23548             EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
  23549                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23550                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  23551                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23552             AdvanceIT();
  23553             return;
  23554           }
  23555         }
  23556       } else {
  23557         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
  23558         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  23559           if (cond.Is(al)) {
  23560             uint32_t imm6 = imm;
  23561             EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
  23562                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23563                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  23564                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23565             return;
  23566           }
  23567         }
  23568       }
  23569     }
  23570   }
  23571   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
  23572 }
  23573 
  23574 void Assembler::vqshlu(Condition cond,
  23575                        DataType dt,
  23576                        DRegister rd,
  23577                        DRegister rm,
  23578                        const DOperand& operand) {
  23579   VIXL_ASSERT(AllowAssembler());
  23580   CheckIT(cond);
  23581   if (operand.IsImmediate()) {
  23582     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  23583       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  23584       Dt_L_imm6_2 encoded_dt(dt);
  23585       if (IsUsingT32()) {
  23586         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
  23587         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  23588           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23589             uint32_t imm6 = imm;
  23590             EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
  23591                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23592                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  23593                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23594             AdvanceIT();
  23595             return;
  23596           }
  23597         }
  23598       } else {
  23599         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
  23600         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  23601           if (cond.Is(al)) {
  23602             uint32_t imm6 = imm;
  23603             EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
  23604                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23605                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  23606                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23607             return;
  23608           }
  23609         }
  23610       }
  23611     }
  23612   }
  23613   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
  23614 }
  23615 
  23616 void Assembler::vqshlu(Condition cond,
  23617                        DataType dt,
  23618                        QRegister rd,
  23619                        QRegister rm,
  23620                        const QOperand& operand) {
  23621   VIXL_ASSERT(AllowAssembler());
  23622   CheckIT(cond);
  23623   if (operand.IsImmediate()) {
  23624     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  23625       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  23626       Dt_L_imm6_2 encoded_dt(dt);
  23627       if (IsUsingT32()) {
  23628         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
  23629         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  23630           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23631             uint32_t imm6 = imm;
  23632             EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
  23633                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23634                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  23635                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23636             AdvanceIT();
  23637             return;
  23638           }
  23639         }
  23640       } else {
  23641         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
  23642         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  23643           if (cond.Is(al)) {
  23644             uint32_t imm6 = imm;
  23645             EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
  23646                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23647                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  23648                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23649             return;
  23650           }
  23651         }
  23652       }
  23653     }
  23654   }
  23655   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
  23656 }
  23657 
  23658 void Assembler::vqshrn(Condition cond,
  23659                        DataType dt,
  23660                        DRegister rd,
  23661                        QRegister rm,
  23662                        const QOperand& operand) {
  23663   VIXL_ASSERT(AllowAssembler());
  23664   CheckIT(cond);
  23665   if (operand.IsImmediate()) {
  23666     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  23667       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  23668       Dt_op_size_3 encoded_dt(dt);
  23669       Dt_imm6_1 encoded_dt_2(dt);
  23670       if (IsUsingT32()) {
  23671         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
  23672         if (encoded_dt.IsValid() && (imm == 0)) {
  23673           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23674             EmitT32_32(0xffb20280U |
  23675                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23676                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
  23677                        rd.Encode(22, 12) | rm.Encode(5, 0));
  23678             AdvanceIT();
  23679             return;
  23680           }
  23681         }
  23682         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
  23683         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  23684           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23685             uint32_t imm6 = dt.GetSize() / 2 - imm;
  23686             EmitT32_32(0xef800910U |
  23687                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
  23688                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
  23689                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23690             AdvanceIT();
  23691             return;
  23692           }
  23693         }
  23694       } else {
  23695         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
  23696         if (encoded_dt.IsValid() && (imm == 0)) {
  23697           if (cond.Is(al)) {
  23698             EmitA32(0xf3b20280U |
  23699                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23700                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
  23701                     rd.Encode(22, 12) | rm.Encode(5, 0));
  23702             return;
  23703           }
  23704         }
  23705         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
  23706         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  23707           if (cond.Is(al)) {
  23708             uint32_t imm6 = dt.GetSize() / 2 - imm;
  23709             EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
  23710                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
  23711                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23712             return;
  23713           }
  23714         }
  23715       }
  23716     }
  23717   }
  23718   Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
  23719 }
  23720 
  23721 void Assembler::vqshrun(Condition cond,
  23722                         DataType dt,
  23723                         DRegister rd,
  23724                         QRegister rm,
  23725                         const QOperand& operand) {
  23726   VIXL_ASSERT(AllowAssembler());
  23727   CheckIT(cond);
  23728   if (operand.IsImmediate()) {
  23729     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  23730       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  23731       Dt_imm6_2 encoded_dt(dt);
  23732       Dt_size_14 encoded_dt_2(dt);
  23733       if (IsUsingT32()) {
  23734         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
  23735         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  23736           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23737             uint32_t imm6 = dt.GetSize() / 2 - imm;
  23738             EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
  23739                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23740                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23741             AdvanceIT();
  23742             return;
  23743           }
  23744         }
  23745         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
  23746         if (encoded_dt_2.IsValid() && (imm == 0)) {
  23747           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23748             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
  23749                        rd.Encode(22, 12) | rm.Encode(5, 0));
  23750             AdvanceIT();
  23751             return;
  23752           }
  23753         }
  23754       } else {
  23755         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
  23756         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  23757           if (cond.Is(al)) {
  23758             uint32_t imm6 = dt.GetSize() / 2 - imm;
  23759             EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
  23760                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  23761                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  23762             return;
  23763           }
  23764         }
  23765         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
  23766         if (encoded_dt_2.IsValid() && (imm == 0)) {
  23767           if (cond.Is(al)) {
  23768             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
  23769                     rd.Encode(22, 12) | rm.Encode(5, 0));
  23770             return;
  23771           }
  23772         }
  23773       }
  23774     }
  23775   }
  23776   Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
  23777 }
  23778 
  23779 void Assembler::vqsub(
  23780     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  23781   VIXL_ASSERT(AllowAssembler());
  23782   CheckIT(cond);
  23783   Dt_U_size_3 encoded_dt(dt);
  23784   if (IsUsingT32()) {
  23785     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  23786     if (encoded_dt.IsValid()) {
  23787       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23788         EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23789                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  23790                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23791         AdvanceIT();
  23792         return;
  23793       }
  23794     }
  23795   } else {
  23796     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  23797     if (encoded_dt.IsValid()) {
  23798       if (cond.Is(al)) {
  23799         EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23800                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  23801                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23802         return;
  23803       }
  23804     }
  23805   }
  23806   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
  23807 }
  23808 
  23809 void Assembler::vqsub(
  23810     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  23811   VIXL_ASSERT(AllowAssembler());
  23812   CheckIT(cond);
  23813   Dt_U_size_3 encoded_dt(dt);
  23814   if (IsUsingT32()) {
  23815     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  23816     if (encoded_dt.IsValid()) {
  23817       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23818         EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23819                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  23820                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23821         AdvanceIT();
  23822         return;
  23823       }
  23824     }
  23825   } else {
  23826     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  23827     if (encoded_dt.IsValid()) {
  23828       if (cond.Is(al)) {
  23829         EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  23830                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  23831                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23832         return;
  23833       }
  23834     }
  23835   }
  23836   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
  23837 }
  23838 
  23839 void Assembler::vraddhn(
  23840     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
  23841   VIXL_ASSERT(AllowAssembler());
  23842   CheckIT(cond);
  23843   Dt_size_3 encoded_dt(dt);
  23844   if (IsUsingT32()) {
  23845     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
  23846     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
  23847       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23848         EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) |
  23849                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23850         AdvanceIT();
  23851         return;
  23852       }
  23853     }
  23854   } else {
  23855     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
  23856     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
  23857       if (cond.Is(al)) {
  23858         EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
  23859                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  23860         return;
  23861       }
  23862     }
  23863   }
  23864   Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
  23865 }
  23866 
  23867 void Assembler::vrecpe(Condition cond,
  23868                        DataType dt,
  23869                        DRegister rd,
  23870                        DRegister rm) {
  23871   VIXL_ASSERT(AllowAssembler());
  23872   CheckIT(cond);
  23873   Dt_F_size_4 encoded_dt(dt);
  23874   if (IsUsingT32()) {
  23875     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  23876     if (encoded_dt.IsValid()) {
  23877       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23878         EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23879                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  23880                    rd.Encode(22, 12) | rm.Encode(5, 0));
  23881         AdvanceIT();
  23882         return;
  23883       }
  23884     }
  23885   } else {
  23886     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  23887     if (encoded_dt.IsValid()) {
  23888       if (cond.Is(al)) {
  23889         EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23890                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  23891                 rd.Encode(22, 12) | rm.Encode(5, 0));
  23892         return;
  23893       }
  23894     }
  23895   }
  23896   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
  23897 }
  23898 
  23899 void Assembler::vrecpe(Condition cond,
  23900                        DataType dt,
  23901                        QRegister rd,
  23902                        QRegister rm) {
  23903   VIXL_ASSERT(AllowAssembler());
  23904   CheckIT(cond);
  23905   Dt_F_size_4 encoded_dt(dt);
  23906   if (IsUsingT32()) {
  23907     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  23908     if (encoded_dt.IsValid()) {
  23909       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23910         EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23911                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  23912                    rd.Encode(22, 12) | rm.Encode(5, 0));
  23913         AdvanceIT();
  23914         return;
  23915       }
  23916     }
  23917   } else {
  23918     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  23919     if (encoded_dt.IsValid()) {
  23920       if (cond.Is(al)) {
  23921         EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  23922                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  23923                 rd.Encode(22, 12) | rm.Encode(5, 0));
  23924         return;
  23925       }
  23926     }
  23927   }
  23928   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
  23929 }
  23930 
  23931 void Assembler::vrecps(
  23932     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  23933   VIXL_ASSERT(AllowAssembler());
  23934   CheckIT(cond);
  23935   if (IsUsingT32()) {
  23936     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  23937     if (dt.Is(F32)) {
  23938       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23939         EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  23940                    rm.Encode(5, 0));
  23941         AdvanceIT();
  23942         return;
  23943       }
  23944     }
  23945   } else {
  23946     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  23947     if (dt.Is(F32)) {
  23948       if (cond.Is(al)) {
  23949         EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  23950                 rm.Encode(5, 0));
  23951         return;
  23952       }
  23953     }
  23954   }
  23955   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
  23956 }
  23957 
  23958 void Assembler::vrecps(
  23959     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  23960   VIXL_ASSERT(AllowAssembler());
  23961   CheckIT(cond);
  23962   if (IsUsingT32()) {
  23963     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  23964     if (dt.Is(F32)) {
  23965       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23966         EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  23967                    rm.Encode(5, 0));
  23968         AdvanceIT();
  23969         return;
  23970       }
  23971     }
  23972   } else {
  23973     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  23974     if (dt.Is(F32)) {
  23975       if (cond.Is(al)) {
  23976         EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  23977                 rm.Encode(5, 0));
  23978         return;
  23979       }
  23980     }
  23981   }
  23982   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
  23983 }
  23984 
  23985 void Assembler::vrev16(Condition cond,
  23986                        DataType dt,
  23987                        DRegister rd,
  23988                        DRegister rm) {
  23989   VIXL_ASSERT(AllowAssembler());
  23990   CheckIT(cond);
  23991   Dt_size_1 encoded_dt(dt);
  23992   if (IsUsingT32()) {
  23993     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  23994     if (encoded_dt.IsValid()) {
  23995       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  23996         EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
  23997                    rd.Encode(22, 12) | rm.Encode(5, 0));
  23998         AdvanceIT();
  23999         return;
  24000       }
  24001     }
  24002   } else {
  24003     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  24004     if (encoded_dt.IsValid()) {
  24005       if (cond.Is(al)) {
  24006         EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
  24007                 rd.Encode(22, 12) | rm.Encode(5, 0));
  24008         return;
  24009       }
  24010     }
  24011   }
  24012   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
  24013 }
  24014 
  24015 void Assembler::vrev16(Condition cond,
  24016                        DataType dt,
  24017                        QRegister rd,
  24018                        QRegister rm) {
  24019   VIXL_ASSERT(AllowAssembler());
  24020   CheckIT(cond);
  24021   Dt_size_1 encoded_dt(dt);
  24022   if (IsUsingT32()) {
  24023     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  24024     if (encoded_dt.IsValid()) {
  24025       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24026         EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
  24027                    rd.Encode(22, 12) | rm.Encode(5, 0));
  24028         AdvanceIT();
  24029         return;
  24030       }
  24031     }
  24032   } else {
  24033     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  24034     if (encoded_dt.IsValid()) {
  24035       if (cond.Is(al)) {
  24036         EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
  24037                 rd.Encode(22, 12) | rm.Encode(5, 0));
  24038         return;
  24039       }
  24040     }
  24041   }
  24042   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
  24043 }
  24044 
  24045 void Assembler::vrev32(Condition cond,
  24046                        DataType dt,
  24047                        DRegister rd,
  24048                        DRegister rm) {
  24049   VIXL_ASSERT(AllowAssembler());
  24050   CheckIT(cond);
  24051   Dt_size_15 encoded_dt(dt);
  24052   if (IsUsingT32()) {
  24053     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  24054     if (encoded_dt.IsValid()) {
  24055       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24056         EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
  24057                    rd.Encode(22, 12) | rm.Encode(5, 0));
  24058         AdvanceIT();
  24059         return;
  24060       }
  24061     }
  24062   } else {
  24063     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  24064     if (encoded_dt.IsValid()) {
  24065       if (cond.Is(al)) {
  24066         EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
  24067                 rd.Encode(22, 12) | rm.Encode(5, 0));
  24068         return;
  24069       }
  24070     }
  24071   }
  24072   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
  24073 }
  24074 
  24075 void Assembler::vrev32(Condition cond,
  24076                        DataType dt,
  24077                        QRegister rd,
  24078                        QRegister rm) {
  24079   VIXL_ASSERT(AllowAssembler());
  24080   CheckIT(cond);
  24081   Dt_size_15 encoded_dt(dt);
  24082   if (IsUsingT32()) {
  24083     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  24084     if (encoded_dt.IsValid()) {
  24085       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24086         EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
  24087                    rd.Encode(22, 12) | rm.Encode(5, 0));
  24088         AdvanceIT();
  24089         return;
  24090       }
  24091     }
  24092   } else {
  24093     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  24094     if (encoded_dt.IsValid()) {
  24095       if (cond.Is(al)) {
  24096         EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
  24097                 rd.Encode(22, 12) | rm.Encode(5, 0));
  24098         return;
  24099       }
  24100     }
  24101   }
  24102   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
  24103 }
  24104 
  24105 void Assembler::vrev64(Condition cond,
  24106                        DataType dt,
  24107                        DRegister rd,
  24108                        DRegister rm) {
  24109   VIXL_ASSERT(AllowAssembler());
  24110   CheckIT(cond);
  24111   Dt_size_7 encoded_dt(dt);
  24112   if (IsUsingT32()) {
  24113     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  24114     if (encoded_dt.IsValid()) {
  24115       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24116         EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
  24117                    rd.Encode(22, 12) | rm.Encode(5, 0));
  24118         AdvanceIT();
  24119         return;
  24120       }
  24121     }
  24122   } else {
  24123     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  24124     if (encoded_dt.IsValid()) {
  24125       if (cond.Is(al)) {
  24126         EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
  24127                 rd.Encode(22, 12) | rm.Encode(5, 0));
  24128         return;
  24129       }
  24130     }
  24131   }
  24132   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
  24133 }
  24134 
  24135 void Assembler::vrev64(Condition cond,
  24136                        DataType dt,
  24137                        QRegister rd,
  24138                        QRegister rm) {
  24139   VIXL_ASSERT(AllowAssembler());
  24140   CheckIT(cond);
  24141   Dt_size_7 encoded_dt(dt);
  24142   if (IsUsingT32()) {
  24143     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  24144     if (encoded_dt.IsValid()) {
  24145       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24146         EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
  24147                    rd.Encode(22, 12) | rm.Encode(5, 0));
  24148         AdvanceIT();
  24149         return;
  24150       }
  24151     }
  24152   } else {
  24153     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  24154     if (encoded_dt.IsValid()) {
  24155       if (cond.Is(al)) {
  24156         EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
  24157                 rd.Encode(22, 12) | rm.Encode(5, 0));
  24158         return;
  24159       }
  24160     }
  24161   }
  24162   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
  24163 }
  24164 
  24165 void Assembler::vrhadd(
  24166     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  24167   VIXL_ASSERT(AllowAssembler());
  24168   CheckIT(cond);
  24169   Dt_U_size_1 encoded_dt(dt);
  24170   if (IsUsingT32()) {
  24171     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  24172     if (encoded_dt.IsValid()) {
  24173       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24174         EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  24175                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  24176                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  24177         AdvanceIT();
  24178         return;
  24179       }
  24180     }
  24181   } else {
  24182     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  24183     if (encoded_dt.IsValid()) {
  24184       if (cond.Is(al)) {
  24185         EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  24186                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  24187                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  24188         return;
  24189       }
  24190     }
  24191   }
  24192   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
  24193 }
  24194 
  24195 void Assembler::vrhadd(
  24196     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  24197   VIXL_ASSERT(AllowAssembler());
  24198   CheckIT(cond);
  24199   Dt_U_size_1 encoded_dt(dt);
  24200   if (IsUsingT32()) {
  24201     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  24202     if (encoded_dt.IsValid()) {
  24203       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24204         EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  24205                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  24206                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  24207         AdvanceIT();
  24208         return;
  24209       }
  24210     }
  24211   } else {
  24212     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  24213     if (encoded_dt.IsValid()) {
  24214       if (cond.Is(al)) {
  24215         EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  24216                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  24217                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  24218         return;
  24219       }
  24220     }
  24221   }
  24222   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
  24223 }
  24224 
  24225 void Assembler::vrinta(DataType dt, DRegister rd, DRegister rm) {
  24226   VIXL_ASSERT(AllowAssembler());
  24227   CheckIT(al);
  24228   Dt_size_16 encoded_dt(dt);
  24229   if (IsUsingT32()) {
  24230     // VRINTA{<q>}.<dt> <Dd>, <Dm> ; T1
  24231     if (encoded_dt.IsValid()) {
  24232       EmitT32_32(0xffb20500U | (encoded_dt.GetEncodingValue() << 18) |
  24233                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24234       AdvanceIT();
  24235       return;
  24236     }
  24237     // VRINTA{<q>}.F64 <Dd>, <Dm> ; T1
  24238     if (dt.Is(F64)) {
  24239       EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24240       AdvanceIT();
  24241       return;
  24242     }
  24243   } else {
  24244     // VRINTA{<q>}.<dt> <Dd>, <Dm> ; A1
  24245     if (encoded_dt.IsValid()) {
  24246       EmitA32(0xf3b20500U | (encoded_dt.GetEncodingValue() << 18) |
  24247               rd.Encode(22, 12) | rm.Encode(5, 0));
  24248       return;
  24249     }
  24250     // VRINTA{<q>}.F64 <Dd>, <Dm> ; A1
  24251     if (dt.Is(F64)) {
  24252       EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24253       return;
  24254     }
  24255   }
  24256   Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
  24257 }
  24258 
  24259 void Assembler::vrinta(DataType dt, QRegister rd, QRegister rm) {
  24260   VIXL_ASSERT(AllowAssembler());
  24261   CheckIT(al);
  24262   Dt_size_16 encoded_dt(dt);
  24263   if (IsUsingT32()) {
  24264     // VRINTA{<q>}.<dt> <Qd>, <Qm> ; T1
  24265     if (encoded_dt.IsValid()) {
  24266       EmitT32_32(0xffb20540U | (encoded_dt.GetEncodingValue() << 18) |
  24267                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24268       AdvanceIT();
  24269       return;
  24270     }
  24271   } else {
  24272     // VRINTA{<q>}.<dt> <Qd>, <Qm> ; A1
  24273     if (encoded_dt.IsValid()) {
  24274       EmitA32(0xf3b20540U | (encoded_dt.GetEncodingValue() << 18) |
  24275               rd.Encode(22, 12) | rm.Encode(5, 0));
  24276       return;
  24277     }
  24278   }
  24279   Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
  24280 }
  24281 
  24282 void Assembler::vrinta(DataType dt, SRegister rd, SRegister rm) {
  24283   VIXL_ASSERT(AllowAssembler());
  24284   CheckIT(al);
  24285   if (IsUsingT32()) {
  24286     // VRINTA{<q>}.F32 <Sd>, <Sm> ; T1
  24287     if (dt.Is(F32)) {
  24288       EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24289       AdvanceIT();
  24290       return;
  24291     }
  24292   } else {
  24293     // VRINTA{<q>}.F32 <Sd>, <Sm> ; A1
  24294     if (dt.Is(F32)) {
  24295       EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24296       return;
  24297     }
  24298   }
  24299   Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
  24300 }
  24301 
  24302 void Assembler::vrintm(DataType dt, DRegister rd, DRegister rm) {
  24303   VIXL_ASSERT(AllowAssembler());
  24304   CheckIT(al);
  24305   Dt_size_16 encoded_dt(dt);
  24306   if (IsUsingT32()) {
  24307     // VRINTM{<q>}.<dt> <Dd>, <Dm> ; T1
  24308     if (encoded_dt.IsValid()) {
  24309       EmitT32_32(0xffb20680U | (encoded_dt.GetEncodingValue() << 18) |
  24310                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24311       AdvanceIT();
  24312       return;
  24313     }
  24314     // VRINTM{<q>}.F64 <Dd>, <Dm> ; T1
  24315     if (dt.Is(F64)) {
  24316       EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24317       AdvanceIT();
  24318       return;
  24319     }
  24320   } else {
  24321     // VRINTM{<q>}.<dt> <Dd>, <Dm> ; A1
  24322     if (encoded_dt.IsValid()) {
  24323       EmitA32(0xf3b20680U | (encoded_dt.GetEncodingValue() << 18) |
  24324               rd.Encode(22, 12) | rm.Encode(5, 0));
  24325       return;
  24326     }
  24327     // VRINTM{<q>}.F64 <Dd>, <Dm> ; A1
  24328     if (dt.Is(F64)) {
  24329       EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24330       return;
  24331     }
  24332   }
  24333   Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
  24334 }
  24335 
  24336 void Assembler::vrintm(DataType dt, QRegister rd, QRegister rm) {
  24337   VIXL_ASSERT(AllowAssembler());
  24338   CheckIT(al);
  24339   Dt_size_16 encoded_dt(dt);
  24340   if (IsUsingT32()) {
  24341     // VRINTM{<q>}.<dt> <Qd>, <Qm> ; T1
  24342     if (encoded_dt.IsValid()) {
  24343       EmitT32_32(0xffb206c0U | (encoded_dt.GetEncodingValue() << 18) |
  24344                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24345       AdvanceIT();
  24346       return;
  24347     }
  24348   } else {
  24349     // VRINTM{<q>}.<dt> <Qd>, <Qm> ; A1
  24350     if (encoded_dt.IsValid()) {
  24351       EmitA32(0xf3b206c0U | (encoded_dt.GetEncodingValue() << 18) |
  24352               rd.Encode(22, 12) | rm.Encode(5, 0));
  24353       return;
  24354     }
  24355   }
  24356   Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
  24357 }
  24358 
  24359 void Assembler::vrintm(DataType dt, SRegister rd, SRegister rm) {
  24360   VIXL_ASSERT(AllowAssembler());
  24361   CheckIT(al);
  24362   if (IsUsingT32()) {
  24363     // VRINTM{<q>}.F32 <Sd>, <Sm> ; T1
  24364     if (dt.Is(F32)) {
  24365       EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24366       AdvanceIT();
  24367       return;
  24368     }
  24369   } else {
  24370     // VRINTM{<q>}.F32 <Sd>, <Sm> ; A1
  24371     if (dt.Is(F32)) {
  24372       EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24373       return;
  24374     }
  24375   }
  24376   Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
  24377 }
  24378 
  24379 void Assembler::vrintn(DataType dt, DRegister rd, DRegister rm) {
  24380   VIXL_ASSERT(AllowAssembler());
  24381   CheckIT(al);
  24382   Dt_size_16 encoded_dt(dt);
  24383   if (IsUsingT32()) {
  24384     // VRINTN{<q>}.<dt> <Dd>, <Dm> ; T1
  24385     if (encoded_dt.IsValid()) {
  24386       EmitT32_32(0xffb20400U | (encoded_dt.GetEncodingValue() << 18) |
  24387                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24388       AdvanceIT();
  24389       return;
  24390     }
  24391     // VRINTN{<q>}.F64 <Dd>, <Dm> ; T1
  24392     if (dt.Is(F64)) {
  24393       EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24394       AdvanceIT();
  24395       return;
  24396     }
  24397   } else {
  24398     // VRINTN{<q>}.<dt> <Dd>, <Dm> ; A1
  24399     if (encoded_dt.IsValid()) {
  24400       EmitA32(0xf3b20400U | (encoded_dt.GetEncodingValue() << 18) |
  24401               rd.Encode(22, 12) | rm.Encode(5, 0));
  24402       return;
  24403     }
  24404     // VRINTN{<q>}.F64 <Dd>, <Dm> ; A1
  24405     if (dt.Is(F64)) {
  24406       EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24407       return;
  24408     }
  24409   }
  24410   Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
  24411 }
  24412 
  24413 void Assembler::vrintn(DataType dt, QRegister rd, QRegister rm) {
  24414   VIXL_ASSERT(AllowAssembler());
  24415   CheckIT(al);
  24416   Dt_size_16 encoded_dt(dt);
  24417   if (IsUsingT32()) {
  24418     // VRINTN{<q>}.<dt> <Qd>, <Qm> ; T1
  24419     if (encoded_dt.IsValid()) {
  24420       EmitT32_32(0xffb20440U | (encoded_dt.GetEncodingValue() << 18) |
  24421                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24422       AdvanceIT();
  24423       return;
  24424     }
  24425   } else {
  24426     // VRINTN{<q>}.<dt> <Qd>, <Qm> ; A1
  24427     if (encoded_dt.IsValid()) {
  24428       EmitA32(0xf3b20440U | (encoded_dt.GetEncodingValue() << 18) |
  24429               rd.Encode(22, 12) | rm.Encode(5, 0));
  24430       return;
  24431     }
  24432   }
  24433   Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
  24434 }
  24435 
  24436 void Assembler::vrintn(DataType dt, SRegister rd, SRegister rm) {
  24437   VIXL_ASSERT(AllowAssembler());
  24438   CheckIT(al);
  24439   if (IsUsingT32()) {
  24440     // VRINTN{<q>}.F32 <Sd>, <Sm> ; T1
  24441     if (dt.Is(F32)) {
  24442       EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24443       AdvanceIT();
  24444       return;
  24445     }
  24446   } else {
  24447     // VRINTN{<q>}.F32 <Sd>, <Sm> ; A1
  24448     if (dt.Is(F32)) {
  24449       EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24450       return;
  24451     }
  24452   }
  24453   Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
  24454 }
  24455 
  24456 void Assembler::vrintp(DataType dt, DRegister rd, DRegister rm) {
  24457   VIXL_ASSERT(AllowAssembler());
  24458   CheckIT(al);
  24459   Dt_size_16 encoded_dt(dt);
  24460   if (IsUsingT32()) {
  24461     // VRINTP{<q>}.<dt> <Dd>, <Dm> ; T1
  24462     if (encoded_dt.IsValid()) {
  24463       EmitT32_32(0xffb20780U | (encoded_dt.GetEncodingValue() << 18) |
  24464                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24465       AdvanceIT();
  24466       return;
  24467     }
  24468     // VRINTP{<q>}.F64 <Dd>, <Dm> ; T1
  24469     if (dt.Is(F64)) {
  24470       EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24471       AdvanceIT();
  24472       return;
  24473     }
  24474   } else {
  24475     // VRINTP{<q>}.<dt> <Dd>, <Dm> ; A1
  24476     if (encoded_dt.IsValid()) {
  24477       EmitA32(0xf3b20780U | (encoded_dt.GetEncodingValue() << 18) |
  24478               rd.Encode(22, 12) | rm.Encode(5, 0));
  24479       return;
  24480     }
  24481     // VRINTP{<q>}.F64 <Dd>, <Dm> ; A1
  24482     if (dt.Is(F64)) {
  24483       EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24484       return;
  24485     }
  24486   }
  24487   Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
  24488 }
  24489 
  24490 void Assembler::vrintp(DataType dt, QRegister rd, QRegister rm) {
  24491   VIXL_ASSERT(AllowAssembler());
  24492   CheckIT(al);
  24493   Dt_size_16 encoded_dt(dt);
  24494   if (IsUsingT32()) {
  24495     // VRINTP{<q>}.<dt> <Qd>, <Qm> ; T1
  24496     if (encoded_dt.IsValid()) {
  24497       EmitT32_32(0xffb207c0U | (encoded_dt.GetEncodingValue() << 18) |
  24498                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24499       AdvanceIT();
  24500       return;
  24501     }
  24502   } else {
  24503     // VRINTP{<q>}.<dt> <Qd>, <Qm> ; A1
  24504     if (encoded_dt.IsValid()) {
  24505       EmitA32(0xf3b207c0U | (encoded_dt.GetEncodingValue() << 18) |
  24506               rd.Encode(22, 12) | rm.Encode(5, 0));
  24507       return;
  24508     }
  24509   }
  24510   Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
  24511 }
  24512 
  24513 void Assembler::vrintp(DataType dt, SRegister rd, SRegister rm) {
  24514   VIXL_ASSERT(AllowAssembler());
  24515   CheckIT(al);
  24516   if (IsUsingT32()) {
  24517     // VRINTP{<q>}.F32 <Sd>, <Sm> ; T1
  24518     if (dt.Is(F32)) {
  24519       EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24520       AdvanceIT();
  24521       return;
  24522     }
  24523   } else {
  24524     // VRINTP{<q>}.F32 <Sd>, <Sm> ; A1
  24525     if (dt.Is(F32)) {
  24526       EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24527       return;
  24528     }
  24529   }
  24530   Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
  24531 }
  24532 
  24533 void Assembler::vrintr(Condition cond,
  24534                        DataType dt,
  24535                        SRegister rd,
  24536                        SRegister rm) {
  24537   VIXL_ASSERT(AllowAssembler());
  24538   CheckIT(cond);
  24539   if (IsUsingT32()) {
  24540     // VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
  24541     if (dt.Is(F32)) {
  24542       EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24543       AdvanceIT();
  24544       return;
  24545     }
  24546   } else {
  24547     // VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
  24548     if (dt.Is(F32) && cond.IsNotNever()) {
  24549       EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  24550               rm.Encode(5, 0));
  24551       return;
  24552     }
  24553   }
  24554   Delegate(kVrintr, &Assembler::vrintr, cond, dt, rd, rm);
  24555 }
  24556 
  24557 void Assembler::vrintr(Condition cond,
  24558                        DataType dt,
  24559                        DRegister rd,
  24560                        DRegister rm) {
  24561   VIXL_ASSERT(AllowAssembler());
  24562   CheckIT(cond);
  24563   if (IsUsingT32()) {
  24564     // VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
  24565     if (dt.Is(F64)) {
  24566       EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24567       AdvanceIT();
  24568       return;
  24569     }
  24570   } else {
  24571     // VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
  24572     if (dt.Is(F64) && cond.IsNotNever()) {
  24573       EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  24574               rm.Encode(5, 0));
  24575       return;
  24576     }
  24577   }
  24578   Delegate(kVrintr, &Assembler::vrintr, cond, dt, rd, rm);
  24579 }
  24580 
  24581 void Assembler::vrintx(Condition cond,
  24582                        DataType dt,
  24583                        DRegister rd,
  24584                        DRegister rm) {
  24585   VIXL_ASSERT(AllowAssembler());
  24586   CheckIT(cond);
  24587   Dt_size_16 encoded_dt(dt);
  24588   if (IsUsingT32()) {
  24589     // VRINTX{<q>}.<dt> <Dd>, <Dm> ; T1
  24590     if (encoded_dt.IsValid()) {
  24591       EmitT32_32(0xffb20480U | (encoded_dt.GetEncodingValue() << 18) |
  24592                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24593       AdvanceIT();
  24594       return;
  24595     }
  24596     // VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
  24597     if (dt.Is(F64)) {
  24598       EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24599       AdvanceIT();
  24600       return;
  24601     }
  24602   } else {
  24603     // VRINTX{<q>}.<dt> <Dd>, <Dm> ; A1
  24604     if (encoded_dt.IsValid()) {
  24605       EmitA32(0xf3b20480U | (encoded_dt.GetEncodingValue() << 18) |
  24606               rd.Encode(22, 12) | rm.Encode(5, 0));
  24607       return;
  24608     }
  24609     // VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
  24610     if (dt.Is(F64) && cond.IsNotNever()) {
  24611       EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  24612               rm.Encode(5, 0));
  24613       return;
  24614     }
  24615   }
  24616   Delegate(kVrintx, &Assembler::vrintx, cond, dt, rd, rm);
  24617 }
  24618 
  24619 void Assembler::vrintx(DataType dt, QRegister rd, QRegister rm) {
  24620   VIXL_ASSERT(AllowAssembler());
  24621   CheckIT(al);
  24622   Dt_size_16 encoded_dt(dt);
  24623   if (IsUsingT32()) {
  24624     // VRINTX{<q>}.<dt> <Qd>, <Qm> ; T1
  24625     if (encoded_dt.IsValid()) {
  24626       EmitT32_32(0xffb204c0U | (encoded_dt.GetEncodingValue() << 18) |
  24627                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24628       AdvanceIT();
  24629       return;
  24630     }
  24631   } else {
  24632     // VRINTX{<q>}.<dt> <Qd>, <Qm> ; A1
  24633     if (encoded_dt.IsValid()) {
  24634       EmitA32(0xf3b204c0U | (encoded_dt.GetEncodingValue() << 18) |
  24635               rd.Encode(22, 12) | rm.Encode(5, 0));
  24636       return;
  24637     }
  24638   }
  24639   Delegate(kVrintx, &Assembler::vrintx, dt, rd, rm);
  24640 }
  24641 
  24642 void Assembler::vrintx(Condition cond,
  24643                        DataType dt,
  24644                        SRegister rd,
  24645                        SRegister rm) {
  24646   VIXL_ASSERT(AllowAssembler());
  24647   CheckIT(cond);
  24648   if (IsUsingT32()) {
  24649     // VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
  24650     if (dt.Is(F32)) {
  24651       EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24652       AdvanceIT();
  24653       return;
  24654     }
  24655   } else {
  24656     // VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
  24657     if (dt.Is(F32) && cond.IsNotNever()) {
  24658       EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  24659               rm.Encode(5, 0));
  24660       return;
  24661     }
  24662   }
  24663   Delegate(kVrintx, &Assembler::vrintx, cond, dt, rd, rm);
  24664 }
  24665 
  24666 void Assembler::vrintz(Condition cond,
  24667                        DataType dt,
  24668                        DRegister rd,
  24669                        DRegister rm) {
  24670   VIXL_ASSERT(AllowAssembler());
  24671   CheckIT(cond);
  24672   Dt_size_16 encoded_dt(dt);
  24673   if (IsUsingT32()) {
  24674     // VRINTZ{<q>}.<dt> <Dd>, <Dm> ; T1
  24675     if (encoded_dt.IsValid()) {
  24676       EmitT32_32(0xffb20580U | (encoded_dt.GetEncodingValue() << 18) |
  24677                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24678       AdvanceIT();
  24679       return;
  24680     }
  24681     // VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
  24682     if (dt.Is(F64)) {
  24683       EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24684       AdvanceIT();
  24685       return;
  24686     }
  24687   } else {
  24688     // VRINTZ{<q>}.<dt> <Dd>, <Dm> ; A1
  24689     if (encoded_dt.IsValid()) {
  24690       EmitA32(0xf3b20580U | (encoded_dt.GetEncodingValue() << 18) |
  24691               rd.Encode(22, 12) | rm.Encode(5, 0));
  24692       return;
  24693     }
  24694     // VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
  24695     if (dt.Is(F64) && cond.IsNotNever()) {
  24696       EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  24697               rm.Encode(5, 0));
  24698       return;
  24699     }
  24700   }
  24701   Delegate(kVrintz, &Assembler::vrintz, cond, dt, rd, rm);
  24702 }
  24703 
  24704 void Assembler::vrintz(DataType dt, QRegister rd, QRegister rm) {
  24705   VIXL_ASSERT(AllowAssembler());
  24706   CheckIT(al);
  24707   Dt_size_16 encoded_dt(dt);
  24708   if (IsUsingT32()) {
  24709     // VRINTZ{<q>}.<dt> <Qd>, <Qm> ; T1
  24710     if (encoded_dt.IsValid()) {
  24711       EmitT32_32(0xffb205c0U | (encoded_dt.GetEncodingValue() << 18) |
  24712                  rd.Encode(22, 12) | rm.Encode(5, 0));
  24713       AdvanceIT();
  24714       return;
  24715     }
  24716   } else {
  24717     // VRINTZ{<q>}.<dt> <Qd>, <Qm> ; A1
  24718     if (encoded_dt.IsValid()) {
  24719       EmitA32(0xf3b205c0U | (encoded_dt.GetEncodingValue() << 18) |
  24720               rd.Encode(22, 12) | rm.Encode(5, 0));
  24721       return;
  24722     }
  24723   }
  24724   Delegate(kVrintz, &Assembler::vrintz, dt, rd, rm);
  24725 }
  24726 
  24727 void Assembler::vrintz(Condition cond,
  24728                        DataType dt,
  24729                        SRegister rd,
  24730                        SRegister rm) {
  24731   VIXL_ASSERT(AllowAssembler());
  24732   CheckIT(cond);
  24733   if (IsUsingT32()) {
  24734     // VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
  24735     if (dt.Is(F32)) {
  24736       EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  24737       AdvanceIT();
  24738       return;
  24739     }
  24740   } else {
  24741     // VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
  24742     if (dt.Is(F32) && cond.IsNotNever()) {
  24743       EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  24744               rm.Encode(5, 0));
  24745       return;
  24746     }
  24747   }
  24748   Delegate(kVrintz, &Assembler::vrintz, cond, dt, rd, rm);
  24749 }
  24750 
  24751 void Assembler::vrshl(
  24752     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
  24753   VIXL_ASSERT(AllowAssembler());
  24754   CheckIT(cond);
  24755   Dt_U_size_3 encoded_dt(dt);
  24756   if (IsUsingT32()) {
  24757     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
  24758     if (encoded_dt.IsValid()) {
  24759       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24760         EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  24761                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  24762                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  24763         AdvanceIT();
  24764         return;
  24765       }
  24766     }
  24767   } else {
  24768     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
  24769     if (encoded_dt.IsValid()) {
  24770       if (cond.Is(al)) {
  24771         EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  24772                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  24773                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  24774         return;
  24775       }
  24776     }
  24777   }
  24778   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
  24779 }
  24780 
  24781 void Assembler::vrshl(
  24782     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
  24783   VIXL_ASSERT(AllowAssembler());
  24784   CheckIT(cond);
  24785   Dt_U_size_3 encoded_dt(dt);
  24786   if (IsUsingT32()) {
  24787     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
  24788     if (encoded_dt.IsValid()) {
  24789       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24790         EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  24791                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  24792                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  24793         AdvanceIT();
  24794         return;
  24795       }
  24796     }
  24797   } else {
  24798     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
  24799     if (encoded_dt.IsValid()) {
  24800       if (cond.Is(al)) {
  24801         EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  24802                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  24803                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  24804         return;
  24805       }
  24806     }
  24807   }
  24808   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
  24809 }
  24810 
  24811 void Assembler::vrshr(Condition cond,
  24812                       DataType dt,
  24813                       DRegister rd,
  24814                       DRegister rm,
  24815                       const DOperand& operand) {
  24816   VIXL_ASSERT(AllowAssembler());
  24817   CheckIT(cond);
  24818   if (operand.IsImmediate()) {
  24819     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  24820       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  24821       Dt_L_imm6_1 encoded_dt(dt);
  24822       if (IsUsingT32()) {
  24823         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
  24824         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  24825           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24826             uint32_t imm6 = dt.GetSize() - imm;
  24827             EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
  24828                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  24829                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  24830                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  24831             AdvanceIT();
  24832             return;
  24833           }
  24834         }
  24835         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
  24836         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
  24837           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24838             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  24839                        rm.Encode(5, 0));
  24840             AdvanceIT();
  24841             return;
  24842           }
  24843         }
  24844       } else {
  24845         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
  24846         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  24847           if (cond.Is(al)) {
  24848             uint32_t imm6 = dt.GetSize() - imm;
  24849             EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
  24850                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  24851                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  24852                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  24853             return;
  24854           }
  24855         }
  24856         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
  24857         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
  24858           if (cond.Is(al)) {
  24859             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  24860                     rm.Encode(5, 0));
  24861             return;
  24862           }
  24863         }
  24864       }
  24865     }
  24866   }
  24867   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
  24868 }
  24869 
  24870 void Assembler::vrshr(Condition cond,
  24871                       DataType dt,
  24872                       QRegister rd,
  24873                       QRegister rm,
  24874                       const QOperand& operand) {
  24875   VIXL_ASSERT(AllowAssembler());
  24876   CheckIT(cond);
  24877   if (operand.IsImmediate()) {
  24878     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  24879       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  24880       Dt_L_imm6_1 encoded_dt(dt);
  24881       if (IsUsingT32()) {
  24882         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
  24883         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  24884           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24885             uint32_t imm6 = dt.GetSize() - imm;
  24886             EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
  24887                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  24888                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  24889                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  24890             AdvanceIT();
  24891             return;
  24892           }
  24893         }
  24894         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
  24895         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
  24896           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24897             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  24898                        rm.Encode(5, 0));
  24899             AdvanceIT();
  24900             return;
  24901           }
  24902         }
  24903       } else {
  24904         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
  24905         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  24906           if (cond.Is(al)) {
  24907             uint32_t imm6 = dt.GetSize() - imm;
  24908             EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
  24909                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  24910                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  24911                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  24912             return;
  24913           }
  24914         }
  24915         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
  24916         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
  24917           if (cond.Is(al)) {
  24918             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  24919                     rm.Encode(5, 0));
  24920             return;
  24921           }
  24922         }
  24923       }
  24924     }
  24925   }
  24926   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
  24927 }
  24928 
  24929 void Assembler::vrshrn(Condition cond,
  24930                        DataType dt,
  24931                        DRegister rd,
  24932                        QRegister rm,
  24933                        const QOperand& operand) {
  24934   VIXL_ASSERT(AllowAssembler());
  24935   CheckIT(cond);
  24936   if (operand.IsImmediate()) {
  24937     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  24938       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  24939       Dt_imm6_3 encoded_dt(dt);
  24940       Dt_size_3 encoded_dt_2(dt);
  24941       if (IsUsingT32()) {
  24942         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
  24943         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  24944           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24945             uint32_t imm6 = dt.GetSize() / 2 - imm;
  24946             EmitT32_32(0xef800850U |
  24947                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  24948                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  24949             AdvanceIT();
  24950             return;
  24951           }
  24952         }
  24953         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
  24954         if (encoded_dt_2.IsValid() && (imm == 0)) {
  24955           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24956             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
  24957                        rd.Encode(22, 12) | rm.Encode(5, 0));
  24958             AdvanceIT();
  24959             return;
  24960           }
  24961         }
  24962       } else {
  24963         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
  24964         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  24965           if (cond.Is(al)) {
  24966             uint32_t imm6 = dt.GetSize() / 2 - imm;
  24967             EmitA32(0xf2800850U |
  24968                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  24969                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  24970             return;
  24971           }
  24972         }
  24973         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
  24974         if (encoded_dt_2.IsValid() && (imm == 0)) {
  24975           if (cond.Is(al)) {
  24976             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
  24977                     rd.Encode(22, 12) | rm.Encode(5, 0));
  24978             return;
  24979           }
  24980         }
  24981       }
  24982     }
  24983   }
  24984   Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
  24985 }
  24986 
  24987 void Assembler::vrsqrte(Condition cond,
  24988                         DataType dt,
  24989                         DRegister rd,
  24990                         DRegister rm) {
  24991   VIXL_ASSERT(AllowAssembler());
  24992   CheckIT(cond);
  24993   Dt_F_size_4 encoded_dt(dt);
  24994   if (IsUsingT32()) {
  24995     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  24996     if (encoded_dt.IsValid()) {
  24997       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  24998         EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  24999                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  25000                    rd.Encode(22, 12) | rm.Encode(5, 0));
  25001         AdvanceIT();
  25002         return;
  25003       }
  25004     }
  25005   } else {
  25006     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  25007     if (encoded_dt.IsValid()) {
  25008       if (cond.Is(al)) {
  25009         EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  25010                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  25011                 rd.Encode(22, 12) | rm.Encode(5, 0));
  25012         return;
  25013       }
  25014     }
  25015   }
  25016   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
  25017 }
  25018 
  25019 void Assembler::vrsqrte(Condition cond,
  25020                         DataType dt,
  25021                         QRegister rd,
  25022                         QRegister rm) {
  25023   VIXL_ASSERT(AllowAssembler());
  25024   CheckIT(cond);
  25025   Dt_F_size_4 encoded_dt(dt);
  25026   if (IsUsingT32()) {
  25027     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  25028     if (encoded_dt.IsValid()) {
  25029       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25030         EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  25031                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  25032                    rd.Encode(22, 12) | rm.Encode(5, 0));
  25033         AdvanceIT();
  25034         return;
  25035       }
  25036     }
  25037   } else {
  25038     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  25039     if (encoded_dt.IsValid()) {
  25040       if (cond.Is(al)) {
  25041         EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
  25042                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
  25043                 rd.Encode(22, 12) | rm.Encode(5, 0));
  25044         return;
  25045       }
  25046     }
  25047   }
  25048   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
  25049 }
  25050 
  25051 void Assembler::vrsqrts(
  25052     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  25053   VIXL_ASSERT(AllowAssembler());
  25054   CheckIT(cond);
  25055   if (IsUsingT32()) {
  25056     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  25057     if (dt.Is(F32)) {
  25058       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25059         EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25060                    rm.Encode(5, 0));
  25061         AdvanceIT();
  25062         return;
  25063       }
  25064     }
  25065   } else {
  25066     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  25067     if (dt.Is(F32)) {
  25068       if (cond.Is(al)) {
  25069         EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25070                 rm.Encode(5, 0));
  25071         return;
  25072       }
  25073     }
  25074   }
  25075   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
  25076 }
  25077 
  25078 void Assembler::vrsqrts(
  25079     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  25080   VIXL_ASSERT(AllowAssembler());
  25081   CheckIT(cond);
  25082   if (IsUsingT32()) {
  25083     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  25084     if (dt.Is(F32)) {
  25085       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25086         EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25087                    rm.Encode(5, 0));
  25088         AdvanceIT();
  25089         return;
  25090       }
  25091     }
  25092   } else {
  25093     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  25094     if (dt.Is(F32)) {
  25095       if (cond.Is(al)) {
  25096         EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25097                 rm.Encode(5, 0));
  25098         return;
  25099       }
  25100     }
  25101   }
  25102   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
  25103 }
  25104 
  25105 void Assembler::vrsra(Condition cond,
  25106                       DataType dt,
  25107                       DRegister rd,
  25108                       DRegister rm,
  25109                       const DOperand& operand) {
  25110   VIXL_ASSERT(AllowAssembler());
  25111   CheckIT(cond);
  25112   if (operand.IsImmediate()) {
  25113     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25114       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25115       Dt_L_imm6_1 encoded_dt(dt);
  25116       if (IsUsingT32()) {
  25117         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
  25118         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25119           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25120             uint32_t imm6 = dt.GetSize() - imm;
  25121             EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
  25122                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25123                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25124                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25125             AdvanceIT();
  25126             return;
  25127           }
  25128         }
  25129       } else {
  25130         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
  25131         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25132           if (cond.Is(al)) {
  25133             uint32_t imm6 = dt.GetSize() - imm;
  25134             EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
  25135                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25136                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25137                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25138             return;
  25139           }
  25140         }
  25141       }
  25142     }
  25143   }
  25144   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
  25145 }
  25146 
  25147 void Assembler::vrsra(Condition cond,
  25148                       DataType dt,
  25149                       QRegister rd,
  25150                       QRegister rm,
  25151                       const QOperand& operand) {
  25152   VIXL_ASSERT(AllowAssembler());
  25153   CheckIT(cond);
  25154   if (operand.IsImmediate()) {
  25155     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25156       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25157       Dt_L_imm6_1 encoded_dt(dt);
  25158       if (IsUsingT32()) {
  25159         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
  25160         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25161           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25162             uint32_t imm6 = dt.GetSize() - imm;
  25163             EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
  25164                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25165                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25166                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25167             AdvanceIT();
  25168             return;
  25169           }
  25170         }
  25171       } else {
  25172         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
  25173         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25174           if (cond.Is(al)) {
  25175             uint32_t imm6 = dt.GetSize() - imm;
  25176             EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
  25177                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25178                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25179                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25180             return;
  25181           }
  25182         }
  25183       }
  25184     }
  25185   }
  25186   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
  25187 }
  25188 
  25189 void Assembler::vrsubhn(
  25190     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
  25191   VIXL_ASSERT(AllowAssembler());
  25192   CheckIT(cond);
  25193   Dt_size_3 encoded_dt(dt);
  25194   if (IsUsingT32()) {
  25195     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
  25196     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
  25197       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25198         EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
  25199                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  25200         AdvanceIT();
  25201         return;
  25202       }
  25203     }
  25204   } else {
  25205     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
  25206     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
  25207       if (cond.Is(al)) {
  25208         EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
  25209                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  25210         return;
  25211       }
  25212     }
  25213   }
  25214   Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
  25215 }
  25216 
  25217 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  25218   VIXL_ASSERT(AllowAssembler());
  25219   CheckIT(al);
  25220   if (IsUsingT32()) {
  25221     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
  25222     if (OutsideITBlock() && dt.Is(F64)) {
  25223       EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25224                  rm.Encode(5, 0));
  25225       AdvanceIT();
  25226       return;
  25227     }
  25228   } else {
  25229     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
  25230     if (dt.Is(F64)) {
  25231       EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25232               rm.Encode(5, 0));
  25233       return;
  25234     }
  25235   }
  25236   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
  25237 }
  25238 
  25239 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  25240   VIXL_ASSERT(AllowAssembler());
  25241   CheckIT(al);
  25242   if (IsUsingT32()) {
  25243     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
  25244     if (OutsideITBlock() && dt.Is(F32)) {
  25245       EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25246                  rm.Encode(5, 0));
  25247       AdvanceIT();
  25248       return;
  25249     }
  25250   } else {
  25251     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
  25252     if (dt.Is(F32)) {
  25253       EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25254               rm.Encode(5, 0));
  25255       return;
  25256     }
  25257   }
  25258   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
  25259 }
  25260 
  25261 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  25262   VIXL_ASSERT(AllowAssembler());
  25263   CheckIT(al);
  25264   if (IsUsingT32()) {
  25265     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
  25266     if (OutsideITBlock() && dt.Is(F64)) {
  25267       EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25268                  rm.Encode(5, 0));
  25269       AdvanceIT();
  25270       return;
  25271     }
  25272   } else {
  25273     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
  25274     if (dt.Is(F64)) {
  25275       EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25276               rm.Encode(5, 0));
  25277       return;
  25278     }
  25279   }
  25280   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
  25281 }
  25282 
  25283 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  25284   VIXL_ASSERT(AllowAssembler());
  25285   CheckIT(al);
  25286   if (IsUsingT32()) {
  25287     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
  25288     if (OutsideITBlock() && dt.Is(F32)) {
  25289       EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25290                  rm.Encode(5, 0));
  25291       AdvanceIT();
  25292       return;
  25293     }
  25294   } else {
  25295     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
  25296     if (dt.Is(F32)) {
  25297       EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25298               rm.Encode(5, 0));
  25299       return;
  25300     }
  25301   }
  25302   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
  25303 }
  25304 
  25305 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  25306   VIXL_ASSERT(AllowAssembler());
  25307   CheckIT(al);
  25308   if (IsUsingT32()) {
  25309     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
  25310     if (OutsideITBlock() && dt.Is(F64)) {
  25311       EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25312                  rm.Encode(5, 0));
  25313       AdvanceIT();
  25314       return;
  25315     }
  25316   } else {
  25317     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
  25318     if (dt.Is(F64)) {
  25319       EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25320               rm.Encode(5, 0));
  25321       return;
  25322     }
  25323   }
  25324   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
  25325 }
  25326 
  25327 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  25328   VIXL_ASSERT(AllowAssembler());
  25329   CheckIT(al);
  25330   if (IsUsingT32()) {
  25331     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
  25332     if (OutsideITBlock() && dt.Is(F32)) {
  25333       EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25334                  rm.Encode(5, 0));
  25335       AdvanceIT();
  25336       return;
  25337     }
  25338   } else {
  25339     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
  25340     if (dt.Is(F32)) {
  25341       EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25342               rm.Encode(5, 0));
  25343       return;
  25344     }
  25345   }
  25346   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
  25347 }
  25348 
  25349 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  25350   VIXL_ASSERT(AllowAssembler());
  25351   CheckIT(al);
  25352   if (IsUsingT32()) {
  25353     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
  25354     if (OutsideITBlock() && dt.Is(F64)) {
  25355       EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25356                  rm.Encode(5, 0));
  25357       AdvanceIT();
  25358       return;
  25359     }
  25360   } else {
  25361     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
  25362     if (dt.Is(F64)) {
  25363       EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25364               rm.Encode(5, 0));
  25365       return;
  25366     }
  25367   }
  25368   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
  25369 }
  25370 
  25371 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  25372   VIXL_ASSERT(AllowAssembler());
  25373   CheckIT(al);
  25374   if (IsUsingT32()) {
  25375     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
  25376     if (OutsideITBlock() && dt.Is(F32)) {
  25377       EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25378                  rm.Encode(5, 0));
  25379       AdvanceIT();
  25380       return;
  25381     }
  25382   } else {
  25383     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
  25384     if (dt.Is(F32)) {
  25385       EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  25386               rm.Encode(5, 0));
  25387       return;
  25388     }
  25389   }
  25390   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
  25391 }
  25392 
  25393 void Assembler::vshl(Condition cond,
  25394                      DataType dt,
  25395                      DRegister rd,
  25396                      DRegister rm,
  25397                      const DOperand& operand) {
  25398   VIXL_ASSERT(AllowAssembler());
  25399   CheckIT(cond);
  25400   if (operand.IsImmediate()) {
  25401     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25402       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25403       Dt_L_imm6_3 encoded_dt(dt);
  25404       if (IsUsingT32()) {
  25405         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
  25406         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  25407           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25408             uint32_t imm6 = imm;
  25409             EmitT32_32(0xef800510U |
  25410                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25411                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25412                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25413             AdvanceIT();
  25414             return;
  25415           }
  25416         }
  25417       } else {
  25418         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
  25419         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  25420           if (cond.Is(al)) {
  25421             uint32_t imm6 = imm;
  25422             EmitA32(0xf2800510U |
  25423                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25424                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25425                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25426             return;
  25427           }
  25428         }
  25429       }
  25430     }
  25431   }
  25432   if (operand.IsRegister()) {
  25433     DRegister rn = operand.GetRegister();
  25434     Dt_U_size_3 encoded_dt(dt);
  25435     if (IsUsingT32()) {
  25436       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
  25437       if (encoded_dt.IsValid()) {
  25438         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25439           EmitT32_32(0xef000400U |
  25440                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  25441                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  25442                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  25443           AdvanceIT();
  25444           return;
  25445         }
  25446       }
  25447     } else {
  25448       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
  25449       if (encoded_dt.IsValid()) {
  25450         if (cond.Is(al)) {
  25451           EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  25452                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  25453                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  25454           return;
  25455         }
  25456       }
  25457     }
  25458   }
  25459   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
  25460 }
  25461 
  25462 void Assembler::vshl(Condition cond,
  25463                      DataType dt,
  25464                      QRegister rd,
  25465                      QRegister rm,
  25466                      const QOperand& operand) {
  25467   VIXL_ASSERT(AllowAssembler());
  25468   CheckIT(cond);
  25469   if (operand.IsImmediate()) {
  25470     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25471       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25472       Dt_L_imm6_3 encoded_dt(dt);
  25473       if (IsUsingT32()) {
  25474         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
  25475         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  25476           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25477             uint32_t imm6 = imm;
  25478             EmitT32_32(0xef800550U |
  25479                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25480                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25481                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25482             AdvanceIT();
  25483             return;
  25484           }
  25485         }
  25486       } else {
  25487         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
  25488         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  25489           if (cond.Is(al)) {
  25490             uint32_t imm6 = imm;
  25491             EmitA32(0xf2800550U |
  25492                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25493                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25494                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25495             return;
  25496           }
  25497         }
  25498       }
  25499     }
  25500   }
  25501   if (operand.IsRegister()) {
  25502     QRegister rn = operand.GetRegister();
  25503     Dt_U_size_3 encoded_dt(dt);
  25504     if (IsUsingT32()) {
  25505       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
  25506       if (encoded_dt.IsValid()) {
  25507         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25508           EmitT32_32(0xef000440U |
  25509                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  25510                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  25511                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  25512           AdvanceIT();
  25513           return;
  25514         }
  25515       }
  25516     } else {
  25517       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
  25518       if (encoded_dt.IsValid()) {
  25519         if (cond.Is(al)) {
  25520           EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  25521                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  25522                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
  25523           return;
  25524         }
  25525       }
  25526     }
  25527   }
  25528   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
  25529 }
  25530 
  25531 void Assembler::vshll(Condition cond,
  25532                       DataType dt,
  25533                       QRegister rd,
  25534                       DRegister rm,
  25535                       const DOperand& operand) {
  25536   VIXL_ASSERT(AllowAssembler());
  25537   CheckIT(cond);
  25538   if (operand.IsImmediate()) {
  25539     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25540       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25541       Dt_imm6_4 encoded_dt(dt);
  25542       Dt_size_17 encoded_dt_2(dt);
  25543       if (IsUsingT32()) {
  25544         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
  25545         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
  25546           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25547             uint32_t imm6 = dt.GetSize() + imm;
  25548             EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
  25549                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25550                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25551             AdvanceIT();
  25552             return;
  25553           }
  25554         }
  25555         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
  25556         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
  25557           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25558             EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
  25559                        rd.Encode(22, 12) | rm.Encode(5, 0));
  25560             AdvanceIT();
  25561             return;
  25562           }
  25563         }
  25564       } else {
  25565         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
  25566         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
  25567           if (cond.Is(al)) {
  25568             uint32_t imm6 = dt.GetSize() + imm;
  25569             EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
  25570                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25571                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25572             return;
  25573           }
  25574         }
  25575         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
  25576         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
  25577           if (cond.Is(al)) {
  25578             EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
  25579                     rd.Encode(22, 12) | rm.Encode(5, 0));
  25580             return;
  25581           }
  25582         }
  25583       }
  25584     }
  25585   }
  25586   Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
  25587 }
  25588 
  25589 void Assembler::vshr(Condition cond,
  25590                      DataType dt,
  25591                      DRegister rd,
  25592                      DRegister rm,
  25593                      const DOperand& operand) {
  25594   VIXL_ASSERT(AllowAssembler());
  25595   CheckIT(cond);
  25596   if (operand.IsImmediate()) {
  25597     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25598       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25599       Dt_L_imm6_1 encoded_dt(dt);
  25600       if (IsUsingT32()) {
  25601         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
  25602         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25603           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25604             uint32_t imm6 = dt.GetSize() - imm;
  25605             EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
  25606                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25607                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25608                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25609             AdvanceIT();
  25610             return;
  25611           }
  25612         }
  25613         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
  25614         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
  25615           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25616             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  25617                        rm.Encode(5, 0));
  25618             AdvanceIT();
  25619             return;
  25620           }
  25621         }
  25622       } else {
  25623         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
  25624         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25625           if (cond.Is(al)) {
  25626             uint32_t imm6 = dt.GetSize() - imm;
  25627             EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
  25628                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25629                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25630                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25631             return;
  25632           }
  25633         }
  25634         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
  25635         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
  25636           if (cond.Is(al)) {
  25637             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  25638                     rm.Encode(5, 0));
  25639             return;
  25640           }
  25641         }
  25642       }
  25643     }
  25644   }
  25645   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
  25646 }
  25647 
  25648 void Assembler::vshr(Condition cond,
  25649                      DataType dt,
  25650                      QRegister rd,
  25651                      QRegister rm,
  25652                      const QOperand& operand) {
  25653   VIXL_ASSERT(AllowAssembler());
  25654   CheckIT(cond);
  25655   if (operand.IsImmediate()) {
  25656     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25657       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25658       Dt_L_imm6_1 encoded_dt(dt);
  25659       if (IsUsingT32()) {
  25660         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
  25661         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25662           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25663             uint32_t imm6 = dt.GetSize() - imm;
  25664             EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
  25665                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25666                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25667                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25668             AdvanceIT();
  25669             return;
  25670           }
  25671         }
  25672         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
  25673         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
  25674           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25675             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  25676                        rm.Encode(5, 0));
  25677             AdvanceIT();
  25678             return;
  25679           }
  25680         }
  25681       } else {
  25682         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
  25683         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25684           if (cond.Is(al)) {
  25685             uint32_t imm6 = dt.GetSize() - imm;
  25686             EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
  25687                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25688                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25689                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25690             return;
  25691           }
  25692         }
  25693         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
  25694         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
  25695           if (cond.Is(al)) {
  25696             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
  25697                     rm.Encode(5, 0));
  25698             return;
  25699           }
  25700         }
  25701       }
  25702     }
  25703   }
  25704   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
  25705 }
  25706 
  25707 void Assembler::vshrn(Condition cond,
  25708                       DataType dt,
  25709                       DRegister rd,
  25710                       QRegister rm,
  25711                       const QOperand& operand) {
  25712   VIXL_ASSERT(AllowAssembler());
  25713   CheckIT(cond);
  25714   if (operand.IsImmediate()) {
  25715     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25716       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25717       Dt_imm6_3 encoded_dt(dt);
  25718       Dt_size_3 encoded_dt_2(dt);
  25719       if (IsUsingT32()) {
  25720         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
  25721         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  25722           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25723             uint32_t imm6 = dt.GetSize() / 2 - imm;
  25724             EmitT32_32(0xef800810U |
  25725                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25726                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25727             AdvanceIT();
  25728             return;
  25729           }
  25730         }
  25731         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
  25732         if (encoded_dt_2.IsValid() && (imm == 0)) {
  25733           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25734             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
  25735                        rd.Encode(22, 12) | rm.Encode(5, 0));
  25736             AdvanceIT();
  25737             return;
  25738           }
  25739         }
  25740       } else {
  25741         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
  25742         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
  25743           if (cond.Is(al)) {
  25744             uint32_t imm6 = dt.GetSize() / 2 - imm;
  25745             EmitA32(0xf2800810U |
  25746                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25747                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25748             return;
  25749           }
  25750         }
  25751         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
  25752         if (encoded_dt_2.IsValid() && (imm == 0)) {
  25753           if (cond.Is(al)) {
  25754             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
  25755                     rd.Encode(22, 12) | rm.Encode(5, 0));
  25756             return;
  25757           }
  25758         }
  25759       }
  25760     }
  25761   }
  25762   Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
  25763 }
  25764 
  25765 void Assembler::vsli(Condition cond,
  25766                      DataType dt,
  25767                      DRegister rd,
  25768                      DRegister rm,
  25769                      const DOperand& operand) {
  25770   VIXL_ASSERT(AllowAssembler());
  25771   CheckIT(cond);
  25772   if (operand.IsImmediate()) {
  25773     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25774       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25775       Dt_L_imm6_4 encoded_dt(dt);
  25776       if (IsUsingT32()) {
  25777         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
  25778         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  25779           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25780             uint32_t imm6 = imm;
  25781             EmitT32_32(0xff800510U |
  25782                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25783                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25784                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25785             AdvanceIT();
  25786             return;
  25787           }
  25788         }
  25789       } else {
  25790         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
  25791         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  25792           if (cond.Is(al)) {
  25793             uint32_t imm6 = imm;
  25794             EmitA32(0xf3800510U |
  25795                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25796                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25797                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25798             return;
  25799           }
  25800         }
  25801       }
  25802     }
  25803   }
  25804   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
  25805 }
  25806 
  25807 void Assembler::vsli(Condition cond,
  25808                      DataType dt,
  25809                      QRegister rd,
  25810                      QRegister rm,
  25811                      const QOperand& operand) {
  25812   VIXL_ASSERT(AllowAssembler());
  25813   CheckIT(cond);
  25814   if (operand.IsImmediate()) {
  25815     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25816       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25817       Dt_L_imm6_4 encoded_dt(dt);
  25818       if (IsUsingT32()) {
  25819         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
  25820         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  25821           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25822             uint32_t imm6 = imm;
  25823             EmitT32_32(0xff800550U |
  25824                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25825                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25826                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25827             AdvanceIT();
  25828             return;
  25829           }
  25830         }
  25831       } else {
  25832         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
  25833         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
  25834           if (cond.Is(al)) {
  25835             uint32_t imm6 = imm;
  25836             EmitA32(0xf3800550U |
  25837                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25838                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25839                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25840             return;
  25841           }
  25842         }
  25843       }
  25844     }
  25845   }
  25846   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
  25847 }
  25848 
  25849 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
  25850   VIXL_ASSERT(AllowAssembler());
  25851   CheckIT(cond);
  25852   if (IsUsingT32()) {
  25853     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
  25854     if (dt.Is(F32)) {
  25855       EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  25856       AdvanceIT();
  25857       return;
  25858     }
  25859   } else {
  25860     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
  25861     if (dt.Is(F32) && cond.IsNotNever()) {
  25862       EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  25863               rm.Encode(5, 0));
  25864       return;
  25865     }
  25866   }
  25867   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
  25868 }
  25869 
  25870 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  25871   VIXL_ASSERT(AllowAssembler());
  25872   CheckIT(cond);
  25873   if (IsUsingT32()) {
  25874     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
  25875     if (dt.Is(F64)) {
  25876       EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
  25877       AdvanceIT();
  25878       return;
  25879     }
  25880   } else {
  25881     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
  25882     if (dt.Is(F64) && cond.IsNotNever()) {
  25883       EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  25884               rm.Encode(5, 0));
  25885       return;
  25886     }
  25887   }
  25888   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
  25889 }
  25890 
  25891 void Assembler::vsra(Condition cond,
  25892                      DataType dt,
  25893                      DRegister rd,
  25894                      DRegister rm,
  25895                      const DOperand& operand) {
  25896   VIXL_ASSERT(AllowAssembler());
  25897   CheckIT(cond);
  25898   if (operand.IsImmediate()) {
  25899     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25900       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25901       Dt_L_imm6_1 encoded_dt(dt);
  25902       if (IsUsingT32()) {
  25903         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
  25904         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25905           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25906             uint32_t imm6 = dt.GetSize() - imm;
  25907             EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
  25908                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25909                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25910                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25911             AdvanceIT();
  25912             return;
  25913           }
  25914         }
  25915       } else {
  25916         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
  25917         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25918           if (cond.Is(al)) {
  25919             uint32_t imm6 = dt.GetSize() - imm;
  25920             EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
  25921                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25922                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25923                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25924             return;
  25925           }
  25926         }
  25927       }
  25928     }
  25929   }
  25930   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
  25931 }
  25932 
  25933 void Assembler::vsra(Condition cond,
  25934                      DataType dt,
  25935                      QRegister rd,
  25936                      QRegister rm,
  25937                      const QOperand& operand) {
  25938   VIXL_ASSERT(AllowAssembler());
  25939   CheckIT(cond);
  25940   if (operand.IsImmediate()) {
  25941     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25942       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25943       Dt_L_imm6_1 encoded_dt(dt);
  25944       if (IsUsingT32()) {
  25945         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
  25946         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25947           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25948             uint32_t imm6 = dt.GetSize() - imm;
  25949             EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
  25950                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25951                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25952                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25953             AdvanceIT();
  25954             return;
  25955           }
  25956         }
  25957       } else {
  25958         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
  25959         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25960           if (cond.Is(al)) {
  25961             uint32_t imm6 = dt.GetSize() - imm;
  25962             EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
  25963                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25964                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25965                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25966             return;
  25967           }
  25968         }
  25969       }
  25970     }
  25971   }
  25972   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
  25973 }
  25974 
  25975 void Assembler::vsri(Condition cond,
  25976                      DataType dt,
  25977                      DRegister rd,
  25978                      DRegister rm,
  25979                      const DOperand& operand) {
  25980   VIXL_ASSERT(AllowAssembler());
  25981   CheckIT(cond);
  25982   if (operand.IsImmediate()) {
  25983     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  25984       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  25985       Dt_L_imm6_4 encoded_dt(dt);
  25986       if (IsUsingT32()) {
  25987         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
  25988         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  25989           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  25990             uint32_t imm6 = dt.GetSize() - imm;
  25991             EmitT32_32(0xff800410U |
  25992                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  25993                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  25994                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  25995             AdvanceIT();
  25996             return;
  25997           }
  25998         }
  25999       } else {
  26000         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
  26001         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  26002           if (cond.Is(al)) {
  26003             uint32_t imm6 = dt.GetSize() - imm;
  26004             EmitA32(0xf3800410U |
  26005                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  26006                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  26007                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  26008             return;
  26009           }
  26010         }
  26011       }
  26012     }
  26013   }
  26014   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
  26015 }
  26016 
  26017 void Assembler::vsri(Condition cond,
  26018                      DataType dt,
  26019                      QRegister rd,
  26020                      QRegister rm,
  26021                      const QOperand& operand) {
  26022   VIXL_ASSERT(AllowAssembler());
  26023   CheckIT(cond);
  26024   if (operand.IsImmediate()) {
  26025     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
  26026       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
  26027       Dt_L_imm6_4 encoded_dt(dt);
  26028       if (IsUsingT32()) {
  26029         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
  26030         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  26031           if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26032             uint32_t imm6 = dt.GetSize() - imm;
  26033             EmitT32_32(0xff800450U |
  26034                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  26035                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  26036                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  26037             AdvanceIT();
  26038             return;
  26039           }
  26040         }
  26041       } else {
  26042         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
  26043         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
  26044           if (cond.Is(al)) {
  26045             uint32_t imm6 = dt.GetSize() - imm;
  26046             EmitA32(0xf3800450U |
  26047                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
  26048                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
  26049                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
  26050             return;
  26051           }
  26052         }
  26053       }
  26054     }
  26055   }
  26056   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
  26057 }
  26058 
  26059 void Assembler::vst1(Condition cond,
  26060                      DataType dt,
  26061                      const NeonRegisterList& nreglist,
  26062                      const AlignedMemOperand& operand) {
  26063   VIXL_ASSERT(AllowAssembler());
  26064   CheckIT(cond);
  26065   if (operand.IsImmediateZero()) {
  26066     Register rn = operand.GetBaseRegister();
  26067     Alignment align = operand.GetAlignment();
  26068     Dt_size_6 encoded_dt(dt);
  26069     Dt_size_7 encoded_dt_2(dt);
  26070     Align_align_5 encoded_align_1(align, nreglist);
  26071     Align_index_align_1 encoded_align_2(align, nreglist, dt);
  26072     if (IsUsingT32()) {
  26073       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  26074       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26075           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  26076           operand.IsOffset() && encoded_align_1.IsValid() &&
  26077           (!rn.IsPC() || AllowUnpredictable())) {
  26078         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26079           const DRegister& first = nreglist.GetFirstDRegister();
  26080           uint32_t len_encoding;
  26081           switch (nreglist.GetLength()) {
  26082             default:
  26083               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  26084             case 1:
  26085               len_encoding = 0x7;
  26086               break;
  26087             case 2:
  26088               len_encoding = 0xa;
  26089               break;
  26090             case 3:
  26091               len_encoding = 0x6;
  26092               break;
  26093             case 4:
  26094               len_encoding = 0x2;
  26095               break;
  26096           }
  26097           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
  26098                      (encoded_align_1.GetEncodingValue() << 4) |
  26099                      first.Encode(22, 12) | (len_encoding << 8) |
  26100                      (rn.GetCode() << 16));
  26101           AdvanceIT();
  26102           return;
  26103         }
  26104       }
  26105       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  26106       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26107           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  26108           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  26109           (!rn.IsPC() || AllowUnpredictable())) {
  26110         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26111           const DRegister& first = nreglist.GetFirstDRegister();
  26112           uint32_t len_encoding;
  26113           switch (nreglist.GetLength()) {
  26114             default:
  26115               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  26116             case 1:
  26117               len_encoding = 0x7;
  26118               break;
  26119             case 2:
  26120               len_encoding = 0xa;
  26121               break;
  26122             case 3:
  26123               len_encoding = 0x6;
  26124               break;
  26125             case 4:
  26126               len_encoding = 0x2;
  26127               break;
  26128           }
  26129           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
  26130                      (encoded_align_1.GetEncodingValue() << 4) |
  26131                      first.Encode(22, 12) | (len_encoding << 8) |
  26132                      (rn.GetCode() << 16));
  26133           AdvanceIT();
  26134           return;
  26135         }
  26136       }
  26137       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  26138       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  26139           (nreglist.GetLength() == 1) && operand.IsOffset() &&
  26140           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  26141         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26142           const DRegister& first = nreglist.GetFirstDRegister();
  26143           EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
  26144                      (encoded_align_2.GetEncodingValue() << 4) |
  26145                      first.Encode(22, 12) | (rn.GetCode() << 16));
  26146           AdvanceIT();
  26147           return;
  26148         }
  26149       }
  26150       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  26151       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  26152           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
  26153           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  26154         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26155           const DRegister& first = nreglist.GetFirstDRegister();
  26156           EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
  26157                      (encoded_align_2.GetEncodingValue() << 4) |
  26158                      first.Encode(22, 12) | (rn.GetCode() << 16));
  26159           AdvanceIT();
  26160           return;
  26161         }
  26162       }
  26163     } else {
  26164       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  26165       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26166           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  26167           operand.IsOffset() && encoded_align_1.IsValid() &&
  26168           (!rn.IsPC() || AllowUnpredictable())) {
  26169         if (cond.Is(al)) {
  26170           const DRegister& first = nreglist.GetFirstDRegister();
  26171           uint32_t len_encoding;
  26172           switch (nreglist.GetLength()) {
  26173             default:
  26174               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  26175             case 1:
  26176               len_encoding = 0x7;
  26177               break;
  26178             case 2:
  26179               len_encoding = 0xa;
  26180               break;
  26181             case 3:
  26182               len_encoding = 0x6;
  26183               break;
  26184             case 4:
  26185               len_encoding = 0x2;
  26186               break;
  26187           }
  26188           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
  26189                   (encoded_align_1.GetEncodingValue() << 4) |
  26190                   first.Encode(22, 12) | (len_encoding << 8) |
  26191                   (rn.GetCode() << 16));
  26192           return;
  26193         }
  26194       }
  26195       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  26196       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26197           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  26198           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  26199           (!rn.IsPC() || AllowUnpredictable())) {
  26200         if (cond.Is(al)) {
  26201           const DRegister& first = nreglist.GetFirstDRegister();
  26202           uint32_t len_encoding;
  26203           switch (nreglist.GetLength()) {
  26204             default:
  26205               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  26206             case 1:
  26207               len_encoding = 0x7;
  26208               break;
  26209             case 2:
  26210               len_encoding = 0xa;
  26211               break;
  26212             case 3:
  26213               len_encoding = 0x6;
  26214               break;
  26215             case 4:
  26216               len_encoding = 0x2;
  26217               break;
  26218           }
  26219           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
  26220                   (encoded_align_1.GetEncodingValue() << 4) |
  26221                   first.Encode(22, 12) | (len_encoding << 8) |
  26222                   (rn.GetCode() << 16));
  26223           return;
  26224         }
  26225       }
  26226       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  26227       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  26228           (nreglist.GetLength() == 1) && operand.IsOffset() &&
  26229           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  26230         if (cond.Is(al)) {
  26231           const DRegister& first = nreglist.GetFirstDRegister();
  26232           EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
  26233                   (encoded_align_2.GetEncodingValue() << 4) |
  26234                   first.Encode(22, 12) | (rn.GetCode() << 16));
  26235           return;
  26236         }
  26237       }
  26238       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  26239       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  26240           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
  26241           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
  26242         if (cond.Is(al)) {
  26243           const DRegister& first = nreglist.GetFirstDRegister();
  26244           EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
  26245                   (encoded_align_2.GetEncodingValue() << 4) |
  26246                   first.Encode(22, 12) | (rn.GetCode() << 16));
  26247           return;
  26248         }
  26249       }
  26250     }
  26251   }
  26252   if (operand.IsPlainRegister()) {
  26253     Register rn = operand.GetBaseRegister();
  26254     Alignment align = operand.GetAlignment();
  26255     Register rm = operand.GetOffsetRegister();
  26256     Dt_size_6 encoded_dt(dt);
  26257     Dt_size_7 encoded_dt_2(dt);
  26258     Align_align_5 encoded_align_1(align, nreglist);
  26259     Align_index_align_1 encoded_align_2(align, nreglist, dt);
  26260     if (IsUsingT32()) {
  26261       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  26262       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26263           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  26264           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  26265         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26266           const DRegister& first = nreglist.GetFirstDRegister();
  26267           uint32_t len_encoding;
  26268           switch (nreglist.GetLength()) {
  26269             default:
  26270               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  26271             case 1:
  26272               len_encoding = 0x7;
  26273               break;
  26274             case 2:
  26275               len_encoding = 0xa;
  26276               break;
  26277             case 3:
  26278               len_encoding = 0x6;
  26279               break;
  26280             case 4:
  26281               len_encoding = 0x2;
  26282               break;
  26283           }
  26284           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
  26285                      (encoded_align_1.GetEncodingValue() << 4) |
  26286                      first.Encode(22, 12) | (len_encoding << 8) |
  26287                      (rn.GetCode() << 16) | rm.GetCode());
  26288           AdvanceIT();
  26289           return;
  26290         }
  26291       }
  26292       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  26293       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  26294           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
  26295           (!rn.IsPC() || AllowUnpredictable())) {
  26296         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26297           const DRegister& first = nreglist.GetFirstDRegister();
  26298           EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
  26299                      (encoded_align_2.GetEncodingValue() << 4) |
  26300                      first.Encode(22, 12) | (rn.GetCode() << 16) |
  26301                      rm.GetCode());
  26302           AdvanceIT();
  26303           return;
  26304         }
  26305       }
  26306     } else {
  26307       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  26308       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26309           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
  26310           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  26311         if (cond.Is(al)) {
  26312           const DRegister& first = nreglist.GetFirstDRegister();
  26313           uint32_t len_encoding;
  26314           switch (nreglist.GetLength()) {
  26315             default:
  26316               VIXL_UNREACHABLE_OR_FALLTHROUGH();
  26317             case 1:
  26318               len_encoding = 0x7;
  26319               break;
  26320             case 2:
  26321               len_encoding = 0xa;
  26322               break;
  26323             case 3:
  26324               len_encoding = 0x6;
  26325               break;
  26326             case 4:
  26327               len_encoding = 0x2;
  26328               break;
  26329           }
  26330           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
  26331                   (encoded_align_1.GetEncodingValue() << 4) |
  26332                   first.Encode(22, 12) | (len_encoding << 8) |
  26333                   (rn.GetCode() << 16) | rm.GetCode());
  26334           return;
  26335         }
  26336       }
  26337       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  26338       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
  26339           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
  26340           (!rn.IsPC() || AllowUnpredictable())) {
  26341         if (cond.Is(al)) {
  26342           const DRegister& first = nreglist.GetFirstDRegister();
  26343           EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
  26344                   (encoded_align_2.GetEncodingValue() << 4) |
  26345                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
  26346           return;
  26347         }
  26348       }
  26349     }
  26350   }
  26351   Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
  26352 }
  26353 
  26354 void Assembler::vst2(Condition cond,
  26355                      DataType dt,
  26356                      const NeonRegisterList& nreglist,
  26357                      const AlignedMemOperand& operand) {
  26358   VIXL_ASSERT(AllowAssembler());
  26359   CheckIT(cond);
  26360   if (operand.IsImmediateZero()) {
  26361     Register rn = operand.GetBaseRegister();
  26362     Alignment align = operand.GetAlignment();
  26363     Dt_size_7 encoded_dt(dt);
  26364     Align_align_2 encoded_align_1(align, nreglist);
  26365     Align_index_align_2 encoded_align_2(align, nreglist, dt);
  26366     if (IsUsingT32()) {
  26367       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  26368       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26369           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26370            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  26371            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  26372           operand.IsOffset() && encoded_align_1.IsValid() &&
  26373           (!rn.IsPC() || AllowUnpredictable())) {
  26374         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26375           const DRegister& first = nreglist.GetFirstDRegister();
  26376           uint32_t len_encoding;
  26377           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  26378             len_encoding = 0x8;
  26379           }
  26380           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  26381             len_encoding = 0x9;
  26382           }
  26383           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  26384             len_encoding = 0x3;
  26385           }
  26386           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
  26387                      (encoded_align_1.GetEncodingValue() << 4) |
  26388                      first.Encode(22, 12) | (len_encoding << 8) |
  26389                      (rn.GetCode() << 16));
  26390           AdvanceIT();
  26391           return;
  26392         }
  26393       }
  26394       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  26395       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26396           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26397            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  26398            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  26399           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  26400           (!rn.IsPC() || AllowUnpredictable())) {
  26401         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26402           const DRegister& first = nreglist.GetFirstDRegister();
  26403           uint32_t len_encoding;
  26404           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  26405             len_encoding = 0x8;
  26406           }
  26407           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  26408             len_encoding = 0x9;
  26409           }
  26410           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  26411             len_encoding = 0x3;
  26412           }
  26413           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
  26414                      (encoded_align_1.GetEncodingValue() << 4) |
  26415                      first.Encode(22, 12) | (len_encoding << 8) |
  26416                      (rn.GetCode() << 16));
  26417           AdvanceIT();
  26418           return;
  26419         }
  26420       }
  26421       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  26422       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26423           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26424            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  26425           operand.IsOffset() && encoded_align_2.IsValid() &&
  26426           (!rn.IsPC() || AllowUnpredictable())) {
  26427         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26428           const DRegister& first = nreglist.GetFirstDRegister();
  26429           EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
  26430                      (encoded_align_2.GetEncodingValue() << 4) |
  26431                      first.Encode(22, 12) | (rn.GetCode() << 16));
  26432           AdvanceIT();
  26433           return;
  26434         }
  26435       }
  26436       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  26437       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26438           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26439            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  26440           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  26441           (!rn.IsPC() || AllowUnpredictable())) {
  26442         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26443           const DRegister& first = nreglist.GetFirstDRegister();
  26444           EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
  26445                      (encoded_align_2.GetEncodingValue() << 4) |
  26446                      first.Encode(22, 12) | (rn.GetCode() << 16));
  26447           AdvanceIT();
  26448           return;
  26449         }
  26450       }
  26451     } else {
  26452       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  26453       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26454           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26455            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  26456            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  26457           operand.IsOffset() && encoded_align_1.IsValid() &&
  26458           (!rn.IsPC() || AllowUnpredictable())) {
  26459         if (cond.Is(al)) {
  26460           const DRegister& first = nreglist.GetFirstDRegister();
  26461           uint32_t len_encoding;
  26462           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  26463             len_encoding = 0x8;
  26464           }
  26465           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  26466             len_encoding = 0x9;
  26467           }
  26468           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  26469             len_encoding = 0x3;
  26470           }
  26471           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
  26472                   (encoded_align_1.GetEncodingValue() << 4) |
  26473                   first.Encode(22, 12) | (len_encoding << 8) |
  26474                   (rn.GetCode() << 16));
  26475           return;
  26476         }
  26477       }
  26478       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  26479       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26480           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26481            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  26482            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  26483           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  26484           (!rn.IsPC() || AllowUnpredictable())) {
  26485         if (cond.Is(al)) {
  26486           const DRegister& first = nreglist.GetFirstDRegister();
  26487           uint32_t len_encoding;
  26488           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  26489             len_encoding = 0x8;
  26490           }
  26491           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  26492             len_encoding = 0x9;
  26493           }
  26494           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  26495             len_encoding = 0x3;
  26496           }
  26497           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
  26498                   (encoded_align_1.GetEncodingValue() << 4) |
  26499                   first.Encode(22, 12) | (len_encoding << 8) |
  26500                   (rn.GetCode() << 16));
  26501           return;
  26502         }
  26503       }
  26504       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  26505       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26506           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26507            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  26508           operand.IsOffset() && encoded_align_2.IsValid() &&
  26509           (!rn.IsPC() || AllowUnpredictable())) {
  26510         if (cond.Is(al)) {
  26511           const DRegister& first = nreglist.GetFirstDRegister();
  26512           EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
  26513                   (encoded_align_2.GetEncodingValue() << 4) |
  26514                   first.Encode(22, 12) | (rn.GetCode() << 16));
  26515           return;
  26516         }
  26517       }
  26518       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  26519       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26520           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26521            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  26522           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  26523           (!rn.IsPC() || AllowUnpredictable())) {
  26524         if (cond.Is(al)) {
  26525           const DRegister& first = nreglist.GetFirstDRegister();
  26526           EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
  26527                   (encoded_align_2.GetEncodingValue() << 4) |
  26528                   first.Encode(22, 12) | (rn.GetCode() << 16));
  26529           return;
  26530         }
  26531       }
  26532     }
  26533   }
  26534   if (operand.IsPlainRegister()) {
  26535     Register rn = operand.GetBaseRegister();
  26536     Alignment align = operand.GetAlignment();
  26537     Register rm = operand.GetOffsetRegister();
  26538     Dt_size_7 encoded_dt(dt);
  26539     Align_align_2 encoded_align_1(align, nreglist);
  26540     Align_index_align_2 encoded_align_2(align, nreglist, dt);
  26541     if (IsUsingT32()) {
  26542       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  26543       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26544           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26545            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  26546            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  26547           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  26548         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26549           const DRegister& first = nreglist.GetFirstDRegister();
  26550           uint32_t len_encoding;
  26551           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  26552             len_encoding = 0x8;
  26553           }
  26554           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  26555             len_encoding = 0x9;
  26556           }
  26557           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  26558             len_encoding = 0x3;
  26559           }
  26560           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
  26561                      (encoded_align_1.GetEncodingValue() << 4) |
  26562                      first.Encode(22, 12) | (len_encoding << 8) |
  26563                      (rn.GetCode() << 16) | rm.GetCode());
  26564           AdvanceIT();
  26565           return;
  26566         }
  26567       }
  26568       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  26569       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26570           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26571            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  26572           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  26573         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26574           const DRegister& first = nreglist.GetFirstDRegister();
  26575           EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
  26576                      (encoded_align_2.GetEncodingValue() << 4) |
  26577                      first.Encode(22, 12) | (rn.GetCode() << 16) |
  26578                      rm.GetCode());
  26579           AdvanceIT();
  26580           return;
  26581         }
  26582       }
  26583     } else {
  26584       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  26585       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26586           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26587            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
  26588            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
  26589           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  26590         if (cond.Is(al)) {
  26591           const DRegister& first = nreglist.GetFirstDRegister();
  26592           uint32_t len_encoding;
  26593           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
  26594             len_encoding = 0x8;
  26595           }
  26596           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
  26597             len_encoding = 0x9;
  26598           }
  26599           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
  26600             len_encoding = 0x3;
  26601           }
  26602           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
  26603                   (encoded_align_1.GetEncodingValue() << 4) |
  26604                   first.Encode(22, 12) | (len_encoding << 8) |
  26605                   (rn.GetCode() << 16) | rm.GetCode());
  26606           return;
  26607         }
  26608       }
  26609       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  26610       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26611           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
  26612            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
  26613           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  26614         if (cond.Is(al)) {
  26615           const DRegister& first = nreglist.GetFirstDRegister();
  26616           EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
  26617                   (encoded_align_2.GetEncodingValue() << 4) |
  26618                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
  26619           return;
  26620         }
  26621       }
  26622     }
  26623   }
  26624   Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
  26625 }
  26626 
  26627 void Assembler::vst3(Condition cond,
  26628                      DataType dt,
  26629                      const NeonRegisterList& nreglist,
  26630                      const AlignedMemOperand& operand) {
  26631   VIXL_ASSERT(AllowAssembler());
  26632   CheckIT(cond);
  26633   if (operand.IsImmediateZero()) {
  26634     Register rn = operand.GetBaseRegister();
  26635     Alignment align = operand.GetAlignment();
  26636     Dt_size_7 encoded_dt(dt);
  26637     Align_align_3 encoded_align_1(align);
  26638     if (IsUsingT32()) {
  26639       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  26640       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26641           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26642            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26643           operand.IsOffset() && encoded_align_1.IsValid() &&
  26644           (!rn.IsPC() || AllowUnpredictable())) {
  26645         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26646           const DRegister& first = nreglist.GetFirstDRegister();
  26647           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  26648           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
  26649                      (encoded_align_1.GetEncodingValue() << 4) |
  26650                      first.Encode(22, 12) | (len_encoding << 8) |
  26651                      (rn.GetCode() << 16));
  26652           AdvanceIT();
  26653           return;
  26654         }
  26655       }
  26656       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  26657       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26658           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26659            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26660           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  26661           (!rn.IsPC() || AllowUnpredictable())) {
  26662         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26663           const DRegister& first = nreglist.GetFirstDRegister();
  26664           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  26665           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
  26666                      (encoded_align_1.GetEncodingValue() << 4) |
  26667                      first.Encode(22, 12) | (len_encoding << 8) |
  26668                      (rn.GetCode() << 16));
  26669           AdvanceIT();
  26670           return;
  26671         }
  26672       }
  26673     } else {
  26674       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  26675       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26676           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26677            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26678           operand.IsOffset() && encoded_align_1.IsValid() &&
  26679           (!rn.IsPC() || AllowUnpredictable())) {
  26680         if (cond.Is(al)) {
  26681           const DRegister& first = nreglist.GetFirstDRegister();
  26682           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  26683           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
  26684                   (encoded_align_1.GetEncodingValue() << 4) |
  26685                   first.Encode(22, 12) | (len_encoding << 8) |
  26686                   (rn.GetCode() << 16));
  26687           return;
  26688         }
  26689       }
  26690       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  26691       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26692           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26693            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26694           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  26695           (!rn.IsPC() || AllowUnpredictable())) {
  26696         if (cond.Is(al)) {
  26697           const DRegister& first = nreglist.GetFirstDRegister();
  26698           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  26699           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
  26700                   (encoded_align_1.GetEncodingValue() << 4) |
  26701                   first.Encode(22, 12) | (len_encoding << 8) |
  26702                   (rn.GetCode() << 16));
  26703           return;
  26704         }
  26705       }
  26706     }
  26707   }
  26708   if (operand.IsPlainRegister()) {
  26709     Register rn = operand.GetBaseRegister();
  26710     Alignment align = operand.GetAlignment();
  26711     Register rm = operand.GetOffsetRegister();
  26712     Dt_size_7 encoded_dt(dt);
  26713     Align_align_3 encoded_align_1(align);
  26714     if (IsUsingT32()) {
  26715       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  26716       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26717           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26718            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26719           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  26720         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26721           const DRegister& first = nreglist.GetFirstDRegister();
  26722           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  26723           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
  26724                      (encoded_align_1.GetEncodingValue() << 4) |
  26725                      first.Encode(22, 12) | (len_encoding << 8) |
  26726                      (rn.GetCode() << 16) | rm.GetCode());
  26727           AdvanceIT();
  26728           return;
  26729         }
  26730       }
  26731     } else {
  26732       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  26733       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26734           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26735            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26736           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  26737         if (cond.Is(al)) {
  26738           const DRegister& first = nreglist.GetFirstDRegister();
  26739           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
  26740           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
  26741                   (encoded_align_1.GetEncodingValue() << 4) |
  26742                   first.Encode(22, 12) | (len_encoding << 8) |
  26743                   (rn.GetCode() << 16) | rm.GetCode());
  26744           return;
  26745         }
  26746       }
  26747     }
  26748   }
  26749   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
  26750 }
  26751 
  26752 void Assembler::vst3(Condition cond,
  26753                      DataType dt,
  26754                      const NeonRegisterList& nreglist,
  26755                      const MemOperand& operand) {
  26756   VIXL_ASSERT(AllowAssembler());
  26757   CheckIT(cond);
  26758   if (operand.IsImmediateZero()) {
  26759     Register rn = operand.GetBaseRegister();
  26760     Dt_size_7 encoded_dt(dt);
  26761     Index_1 encoded_align_1(nreglist, dt);
  26762     if (IsUsingT32()) {
  26763       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
  26764       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26765           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26766            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26767           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
  26768         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26769           const DRegister& first = nreglist.GetFirstDRegister();
  26770           EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
  26771                      (encoded_align_1.GetEncodingValue() << 4) |
  26772                      first.Encode(22, 12) | (rn.GetCode() << 16));
  26773           AdvanceIT();
  26774           return;
  26775         }
  26776       }
  26777       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
  26778       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26779           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26780            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26781           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
  26782         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26783           const DRegister& first = nreglist.GetFirstDRegister();
  26784           EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
  26785                      (encoded_align_1.GetEncodingValue() << 4) |
  26786                      first.Encode(22, 12) | (rn.GetCode() << 16));
  26787           AdvanceIT();
  26788           return;
  26789         }
  26790       }
  26791     } else {
  26792       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
  26793       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26794           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26795            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26796           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
  26797         if (cond.Is(al)) {
  26798           const DRegister& first = nreglist.GetFirstDRegister();
  26799           EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
  26800                   (encoded_align_1.GetEncodingValue() << 4) |
  26801                   first.Encode(22, 12) | (rn.GetCode() << 16));
  26802           return;
  26803         }
  26804       }
  26805       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
  26806       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26807           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26808            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26809           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
  26810         if (cond.Is(al)) {
  26811           const DRegister& first = nreglist.GetFirstDRegister();
  26812           EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
  26813                   (encoded_align_1.GetEncodingValue() << 4) |
  26814                   first.Encode(22, 12) | (rn.GetCode() << 16));
  26815           return;
  26816         }
  26817       }
  26818     }
  26819   }
  26820   if (operand.IsPlainRegister()) {
  26821     Register rn = operand.GetBaseRegister();
  26822     Sign sign = operand.GetSign();
  26823     Register rm = operand.GetOffsetRegister();
  26824     Dt_size_7 encoded_dt(dt);
  26825     Index_1 encoded_align_1(nreglist, dt);
  26826     if (IsUsingT32()) {
  26827       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
  26828       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26829           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26830            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26831           sign.IsPlus() && operand.IsPostIndex() &&
  26832           (!rn.IsPC() || AllowUnpredictable())) {
  26833         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26834           const DRegister& first = nreglist.GetFirstDRegister();
  26835           EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
  26836                      (encoded_align_1.GetEncodingValue() << 4) |
  26837                      first.Encode(22, 12) | (rn.GetCode() << 16) |
  26838                      rm.GetCode());
  26839           AdvanceIT();
  26840           return;
  26841         }
  26842       }
  26843     } else {
  26844       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
  26845       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26846           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
  26847            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
  26848           sign.IsPlus() && operand.IsPostIndex() &&
  26849           (!rn.IsPC() || AllowUnpredictable())) {
  26850         if (cond.Is(al)) {
  26851           const DRegister& first = nreglist.GetFirstDRegister();
  26852           EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
  26853                   (encoded_align_1.GetEncodingValue() << 4) |
  26854                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
  26855           return;
  26856         }
  26857       }
  26858     }
  26859   }
  26860   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
  26861 }
  26862 
  26863 void Assembler::vst4(Condition cond,
  26864                      DataType dt,
  26865                      const NeonRegisterList& nreglist,
  26866                      const AlignedMemOperand& operand) {
  26867   VIXL_ASSERT(AllowAssembler());
  26868   CheckIT(cond);
  26869   if (operand.IsImmediateZero()) {
  26870     Register rn = operand.GetBaseRegister();
  26871     Alignment align = operand.GetAlignment();
  26872     Dt_size_7 encoded_dt(dt);
  26873     Align_align_4 encoded_align_1(align);
  26874     Align_index_align_3 encoded_align_2(align, nreglist, dt);
  26875     if (IsUsingT32()) {
  26876       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  26877       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26878           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  26879            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  26880           operand.IsOffset() && encoded_align_1.IsValid() &&
  26881           (!rn.IsPC() || AllowUnpredictable())) {
  26882         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26883           const DRegister& first = nreglist.GetFirstDRegister();
  26884           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  26885           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
  26886                      (encoded_align_1.GetEncodingValue() << 4) |
  26887                      first.Encode(22, 12) | (len_encoding << 8) |
  26888                      (rn.GetCode() << 16));
  26889           AdvanceIT();
  26890           return;
  26891         }
  26892       }
  26893       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  26894       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26895           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  26896            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  26897           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  26898           (!rn.IsPC() || AllowUnpredictable())) {
  26899         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26900           const DRegister& first = nreglist.GetFirstDRegister();
  26901           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  26902           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
  26903                      (encoded_align_1.GetEncodingValue() << 4) |
  26904                      first.Encode(22, 12) | (len_encoding << 8) |
  26905                      (rn.GetCode() << 16));
  26906           AdvanceIT();
  26907           return;
  26908         }
  26909       }
  26910       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
  26911       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26912           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  26913            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  26914           operand.IsOffset() && encoded_align_2.IsValid() &&
  26915           (!rn.IsPC() || AllowUnpredictable())) {
  26916         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26917           const DRegister& first = nreglist.GetFirstDRegister();
  26918           EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
  26919                      (encoded_align_2.GetEncodingValue() << 4) |
  26920                      first.Encode(22, 12) | (rn.GetCode() << 16));
  26921           AdvanceIT();
  26922           return;
  26923         }
  26924       }
  26925       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
  26926       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26927           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  26928            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  26929           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  26930           (!rn.IsPC() || AllowUnpredictable())) {
  26931         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  26932           const DRegister& first = nreglist.GetFirstDRegister();
  26933           EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
  26934                      (encoded_align_2.GetEncodingValue() << 4) |
  26935                      first.Encode(22, 12) | (rn.GetCode() << 16));
  26936           AdvanceIT();
  26937           return;
  26938         }
  26939       }
  26940     } else {
  26941       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  26942       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26943           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  26944            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  26945           operand.IsOffset() && encoded_align_1.IsValid() &&
  26946           (!rn.IsPC() || AllowUnpredictable())) {
  26947         if (cond.Is(al)) {
  26948           const DRegister& first = nreglist.GetFirstDRegister();
  26949           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  26950           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
  26951                   (encoded_align_1.GetEncodingValue() << 4) |
  26952                   first.Encode(22, 12) | (len_encoding << 8) |
  26953                   (rn.GetCode() << 16));
  26954           return;
  26955         }
  26956       }
  26957       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  26958       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  26959           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  26960            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  26961           operand.IsPostIndex() && encoded_align_1.IsValid() &&
  26962           (!rn.IsPC() || AllowUnpredictable())) {
  26963         if (cond.Is(al)) {
  26964           const DRegister& first = nreglist.GetFirstDRegister();
  26965           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  26966           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
  26967                   (encoded_align_1.GetEncodingValue() << 4) |
  26968                   first.Encode(22, 12) | (len_encoding << 8) |
  26969                   (rn.GetCode() << 16));
  26970           return;
  26971         }
  26972       }
  26973       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
  26974       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26975           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  26976            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  26977           operand.IsOffset() && encoded_align_2.IsValid() &&
  26978           (!rn.IsPC() || AllowUnpredictable())) {
  26979         if (cond.Is(al)) {
  26980           const DRegister& first = nreglist.GetFirstDRegister();
  26981           EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
  26982                   (encoded_align_2.GetEncodingValue() << 4) |
  26983                   first.Encode(22, 12) | (rn.GetCode() << 16));
  26984           return;
  26985         }
  26986       }
  26987       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
  26988       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  26989           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  26990            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  26991           operand.IsPostIndex() && encoded_align_2.IsValid() &&
  26992           (!rn.IsPC() || AllowUnpredictable())) {
  26993         if (cond.Is(al)) {
  26994           const DRegister& first = nreglist.GetFirstDRegister();
  26995           EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
  26996                   (encoded_align_2.GetEncodingValue() << 4) |
  26997                   first.Encode(22, 12) | (rn.GetCode() << 16));
  26998           return;
  26999         }
  27000       }
  27001     }
  27002   }
  27003   if (operand.IsPlainRegister()) {
  27004     Register rn = operand.GetBaseRegister();
  27005     Alignment align = operand.GetAlignment();
  27006     Register rm = operand.GetOffsetRegister();
  27007     Dt_size_7 encoded_dt(dt);
  27008     Align_align_4 encoded_align_1(align);
  27009     Align_index_align_3 encoded_align_2(align, nreglist, dt);
  27010     if (IsUsingT32()) {
  27011       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  27012       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  27013           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  27014            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  27015           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  27016         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27017           const DRegister& first = nreglist.GetFirstDRegister();
  27018           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  27019           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
  27020                      (encoded_align_1.GetEncodingValue() << 4) |
  27021                      first.Encode(22, 12) | (len_encoding << 8) |
  27022                      (rn.GetCode() << 16) | rm.GetCode());
  27023           AdvanceIT();
  27024           return;
  27025         }
  27026       }
  27027       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
  27028       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  27029           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  27030            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  27031           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  27032         if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27033           const DRegister& first = nreglist.GetFirstDRegister();
  27034           EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
  27035                      (encoded_align_2.GetEncodingValue() << 4) |
  27036                      first.Encode(22, 12) | (rn.GetCode() << 16) |
  27037                      rm.GetCode());
  27038           AdvanceIT();
  27039           return;
  27040         }
  27041       }
  27042     } else {
  27043       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  27044       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
  27045           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  27046            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  27047           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  27048         if (cond.Is(al)) {
  27049           const DRegister& first = nreglist.GetFirstDRegister();
  27050           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
  27051           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
  27052                   (encoded_align_1.GetEncodingValue() << 4) |
  27053                   first.Encode(22, 12) | (len_encoding << 8) |
  27054                   (rn.GetCode() << 16) | rm.GetCode());
  27055           return;
  27056         }
  27057       }
  27058       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
  27059       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
  27060           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
  27061            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
  27062           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
  27063         if (cond.Is(al)) {
  27064           const DRegister& first = nreglist.GetFirstDRegister();
  27065           EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
  27066                   (encoded_align_2.GetEncodingValue() << 4) |
  27067                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
  27068           return;
  27069         }
  27070       }
  27071     }
  27072   }
  27073   Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
  27074 }
  27075 
  27076 void Assembler::vstm(Condition cond,
  27077                      DataType dt,
  27078                      Register rn,
  27079                      WriteBack write_back,
  27080                      DRegisterList dreglist) {
  27081   VIXL_ASSERT(AllowAssembler());
  27082   CheckIT(cond);
  27083   USE(dt);
  27084   if (IsUsingT32()) {
  27085     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
  27086     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
  27087          AllowUnpredictable())) {
  27088       const DRegister& dreg = dreglist.GetFirstDRegister();
  27089       unsigned len = dreglist.GetLength() * 2;
  27090       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
  27091                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
  27092                  (len & 0xff));
  27093       AdvanceIT();
  27094       return;
  27095     }
  27096   } else {
  27097     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
  27098     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
  27099                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
  27100                               AllowUnpredictable())) {
  27101       const DRegister& dreg = dreglist.GetFirstDRegister();
  27102       unsigned len = dreglist.GetLength() * 2;
  27103       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  27104               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
  27105               (len & 0xff));
  27106       return;
  27107     }
  27108   }
  27109   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
  27110 }
  27111 
  27112 void Assembler::vstm(Condition cond,
  27113                      DataType dt,
  27114                      Register rn,
  27115                      WriteBack write_back,
  27116                      SRegisterList sreglist) {
  27117   VIXL_ASSERT(AllowAssembler());
  27118   CheckIT(cond);
  27119   USE(dt);
  27120   if (IsUsingT32()) {
  27121     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
  27122     if ((!rn.IsPC() || AllowUnpredictable())) {
  27123       const SRegister& sreg = sreglist.GetFirstSRegister();
  27124       unsigned len = sreglist.GetLength();
  27125       EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
  27126                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
  27127                  (len & 0xff));
  27128       AdvanceIT();
  27129       return;
  27130     }
  27131   } else {
  27132     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
  27133     if (cond.IsNotNever() &&
  27134         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
  27135       const SRegister& sreg = sreglist.GetFirstSRegister();
  27136       unsigned len = sreglist.GetLength();
  27137       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  27138               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
  27139               (len & 0xff));
  27140       return;
  27141     }
  27142   }
  27143   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
  27144 }
  27145 
  27146 void Assembler::vstmdb(Condition cond,
  27147                        DataType dt,
  27148                        Register rn,
  27149                        WriteBack write_back,
  27150                        DRegisterList dreglist) {
  27151   VIXL_ASSERT(AllowAssembler());
  27152   CheckIT(cond);
  27153   USE(dt);
  27154   if (IsUsingT32()) {
  27155     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
  27156     if (write_back.DoesWriteBack() &&
  27157         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
  27158          AllowUnpredictable())) {
  27159       const DRegister& dreg = dreglist.GetFirstDRegister();
  27160       unsigned len = dreglist.GetLength() * 2;
  27161       EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
  27162                  (len & 0xff));
  27163       AdvanceIT();
  27164       return;
  27165     }
  27166   } else {
  27167     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
  27168     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
  27169         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
  27170          AllowUnpredictable())) {
  27171       const DRegister& dreg = dreglist.GetFirstDRegister();
  27172       unsigned len = dreglist.GetLength() * 2;
  27173       EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  27174               dreg.Encode(22, 12) | (len & 0xff));
  27175       return;
  27176     }
  27177   }
  27178   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
  27179 }
  27180 
  27181 void Assembler::vstmdb(Condition cond,
  27182                        DataType dt,
  27183                        Register rn,
  27184                        WriteBack write_back,
  27185                        SRegisterList sreglist) {
  27186   VIXL_ASSERT(AllowAssembler());
  27187   CheckIT(cond);
  27188   USE(dt);
  27189   if (IsUsingT32()) {
  27190     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
  27191     if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) {
  27192       const SRegister& sreg = sreglist.GetFirstSRegister();
  27193       unsigned len = sreglist.GetLength();
  27194       EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
  27195                  (len & 0xff));
  27196       AdvanceIT();
  27197       return;
  27198     }
  27199   } else {
  27200     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
  27201     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
  27202         (!rn.IsPC() || AllowUnpredictable())) {
  27203       const SRegister& sreg = sreglist.GetFirstSRegister();
  27204       unsigned len = sreglist.GetLength();
  27205       EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  27206               sreg.Encode(22, 12) | (len & 0xff));
  27207       return;
  27208     }
  27209   }
  27210   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
  27211 }
  27212 
  27213 void Assembler::vstmia(Condition cond,
  27214                        DataType dt,
  27215                        Register rn,
  27216                        WriteBack write_back,
  27217                        DRegisterList dreglist) {
  27218   VIXL_ASSERT(AllowAssembler());
  27219   CheckIT(cond);
  27220   USE(dt);
  27221   if (IsUsingT32()) {
  27222     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
  27223     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
  27224          AllowUnpredictable())) {
  27225       const DRegister& dreg = dreglist.GetFirstDRegister();
  27226       unsigned len = dreglist.GetLength() * 2;
  27227       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
  27228                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
  27229                  (len & 0xff));
  27230       AdvanceIT();
  27231       return;
  27232     }
  27233   } else {
  27234     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
  27235     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
  27236                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
  27237                               AllowUnpredictable())) {
  27238       const DRegister& dreg = dreglist.GetFirstDRegister();
  27239       unsigned len = dreglist.GetLength() * 2;
  27240       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  27241               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
  27242               (len & 0xff));
  27243       return;
  27244     }
  27245   }
  27246   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
  27247 }
  27248 
  27249 void Assembler::vstmia(Condition cond,
  27250                        DataType dt,
  27251                        Register rn,
  27252                        WriteBack write_back,
  27253                        SRegisterList sreglist) {
  27254   VIXL_ASSERT(AllowAssembler());
  27255   CheckIT(cond);
  27256   USE(dt);
  27257   if (IsUsingT32()) {
  27258     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
  27259     if ((!rn.IsPC() || AllowUnpredictable())) {
  27260       const SRegister& sreg = sreglist.GetFirstSRegister();
  27261       unsigned len = sreglist.GetLength();
  27262       EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
  27263                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
  27264                  (len & 0xff));
  27265       AdvanceIT();
  27266       return;
  27267     }
  27268   } else {
  27269     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
  27270     if (cond.IsNotNever() &&
  27271         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
  27272       const SRegister& sreg = sreglist.GetFirstSRegister();
  27273       unsigned len = sreglist.GetLength();
  27274       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
  27275               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
  27276               (len & 0xff));
  27277       return;
  27278     }
  27279   }
  27280   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
  27281 }
  27282 
  27283 void Assembler::vstr(Condition cond,
  27284                      DataType dt,
  27285                      DRegister rd,
  27286                      const MemOperand& operand) {
  27287   VIXL_ASSERT(AllowAssembler());
  27288   CheckIT(cond);
  27289   if (operand.IsImmediate()) {
  27290     Register rn = operand.GetBaseRegister();
  27291     int32_t offset = operand.GetOffsetImmediate();
  27292     if (IsUsingT32()) {
  27293       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
  27294       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
  27295           ((offset % 4) == 0) && operand.IsOffset() &&
  27296           (!rn.IsPC() || AllowUnpredictable())) {
  27297         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  27298         uint32_t offset_ = abs(offset) >> 2;
  27299         EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
  27300                    offset_ | (sign << 23));
  27301         AdvanceIT();
  27302         return;
  27303       }
  27304     } else {
  27305       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
  27306       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
  27307           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
  27308         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  27309         uint32_t offset_ = abs(offset) >> 2;
  27310         EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  27311                 (rn.GetCode() << 16) | offset_ | (sign << 23));
  27312         return;
  27313       }
  27314     }
  27315   }
  27316   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
  27317 }
  27318 
  27319 void Assembler::vstr(Condition cond,
  27320                      DataType dt,
  27321                      SRegister rd,
  27322                      const MemOperand& operand) {
  27323   VIXL_ASSERT(AllowAssembler());
  27324   CheckIT(cond);
  27325   if (operand.IsImmediate()) {
  27326     Register rn = operand.GetBaseRegister();
  27327     int32_t offset = operand.GetOffsetImmediate();
  27328     if (IsUsingT32()) {
  27329       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
  27330       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
  27331           ((offset % 4) == 0) && operand.IsOffset() &&
  27332           (!rn.IsPC() || AllowUnpredictable())) {
  27333         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  27334         uint32_t offset_ = abs(offset) >> 2;
  27335         EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
  27336                    offset_ | (sign << 23));
  27337         AdvanceIT();
  27338         return;
  27339       }
  27340     } else {
  27341       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
  27342       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
  27343           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
  27344         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
  27345         uint32_t offset_ = abs(offset) >> 2;
  27346         EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  27347                 (rn.GetCode() << 16) | offset_ | (sign << 23));
  27348         return;
  27349       }
  27350     }
  27351   }
  27352   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
  27353 }
  27354 
  27355 void Assembler::vsub(
  27356     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  27357   VIXL_ASSERT(AllowAssembler());
  27358   CheckIT(cond);
  27359   Dt_size_2 encoded_dt(dt);
  27360   if (IsUsingT32()) {
  27361     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
  27362     if (dt.Is(F32)) {
  27363       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27364         EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  27365                    rm.Encode(5, 0));
  27366         AdvanceIT();
  27367         return;
  27368       }
  27369     }
  27370     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
  27371     if (dt.Is(F64)) {
  27372       EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  27373                  rm.Encode(5, 0));
  27374       AdvanceIT();
  27375       return;
  27376     }
  27377     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  27378     if (encoded_dt.IsValid()) {
  27379       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27380         EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
  27381                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27382         AdvanceIT();
  27383         return;
  27384       }
  27385     }
  27386   } else {
  27387     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
  27388     if (dt.Is(F32)) {
  27389       if (cond.Is(al)) {
  27390         EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  27391                 rm.Encode(5, 0));
  27392         return;
  27393       }
  27394     }
  27395     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
  27396     if (dt.Is(F64) && cond.IsNotNever()) {
  27397       EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  27398               rn.Encode(7, 16) | rm.Encode(5, 0));
  27399       return;
  27400     }
  27401     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  27402     if (encoded_dt.IsValid()) {
  27403       if (cond.Is(al)) {
  27404         EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
  27405                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27406         return;
  27407       }
  27408     }
  27409   }
  27410   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
  27411 }
  27412 
  27413 void Assembler::vsub(
  27414     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  27415   VIXL_ASSERT(AllowAssembler());
  27416   CheckIT(cond);
  27417   Dt_size_2 encoded_dt(dt);
  27418   if (IsUsingT32()) {
  27419     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
  27420     if (dt.Is(F32)) {
  27421       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27422         EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  27423                    rm.Encode(5, 0));
  27424         AdvanceIT();
  27425         return;
  27426       }
  27427     }
  27428     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  27429     if (encoded_dt.IsValid()) {
  27430       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27431         EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
  27432                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27433         AdvanceIT();
  27434         return;
  27435       }
  27436     }
  27437   } else {
  27438     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
  27439     if (dt.Is(F32)) {
  27440       if (cond.Is(al)) {
  27441         EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  27442                 rm.Encode(5, 0));
  27443         return;
  27444       }
  27445     }
  27446     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  27447     if (encoded_dt.IsValid()) {
  27448       if (cond.Is(al)) {
  27449         EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
  27450                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27451         return;
  27452       }
  27453     }
  27454   }
  27455   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
  27456 }
  27457 
  27458 void Assembler::vsub(
  27459     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
  27460   VIXL_ASSERT(AllowAssembler());
  27461   CheckIT(cond);
  27462   if (IsUsingT32()) {
  27463     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
  27464     if (dt.Is(F32)) {
  27465       EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
  27466                  rm.Encode(5, 0));
  27467       AdvanceIT();
  27468       return;
  27469     }
  27470   } else {
  27471     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
  27472     if (dt.Is(F32) && cond.IsNotNever()) {
  27473       EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
  27474               rn.Encode(7, 16) | rm.Encode(5, 0));
  27475       return;
  27476     }
  27477   }
  27478   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
  27479 }
  27480 
  27481 void Assembler::vsubhn(
  27482     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
  27483   VIXL_ASSERT(AllowAssembler());
  27484   CheckIT(cond);
  27485   Dt_size_3 encoded_dt(dt);
  27486   if (IsUsingT32()) {
  27487     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
  27488     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
  27489       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27490         EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
  27491                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27492         AdvanceIT();
  27493         return;
  27494       }
  27495     }
  27496   } else {
  27497     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
  27498     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
  27499       if (cond.Is(al)) {
  27500         EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
  27501                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27502         return;
  27503       }
  27504     }
  27505   }
  27506   Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
  27507 }
  27508 
  27509 void Assembler::vsubl(
  27510     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
  27511   VIXL_ASSERT(AllowAssembler());
  27512   CheckIT(cond);
  27513   Dt_U_size_1 encoded_dt(dt);
  27514   if (IsUsingT32()) {
  27515     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
  27516     if (encoded_dt.IsValid()) {
  27517       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27518         EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  27519                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  27520                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27521         AdvanceIT();
  27522         return;
  27523       }
  27524     }
  27525   } else {
  27526     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
  27527     if (encoded_dt.IsValid()) {
  27528       if (cond.Is(al)) {
  27529         EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  27530                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  27531                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27532         return;
  27533       }
  27534     }
  27535   }
  27536   Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
  27537 }
  27538 
  27539 void Assembler::vsubw(
  27540     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
  27541   VIXL_ASSERT(AllowAssembler());
  27542   CheckIT(cond);
  27543   Dt_U_size_1 encoded_dt(dt);
  27544   if (IsUsingT32()) {
  27545     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
  27546     if (encoded_dt.IsValid()) {
  27547       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27548         EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  27549                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
  27550                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27551         AdvanceIT();
  27552         return;
  27553       }
  27554     }
  27555   } else {
  27556     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
  27557     if (encoded_dt.IsValid()) {
  27558       if (cond.Is(al)) {
  27559         EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
  27560                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
  27561                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27562         return;
  27563       }
  27564     }
  27565   }
  27566   Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
  27567 }
  27568 
  27569 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  27570   VIXL_ASSERT(AllowAssembler());
  27571   CheckIT(cond);
  27572   USE(dt);
  27573   if (IsUsingT32()) {
  27574     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
  27575     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27576       EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
  27577       AdvanceIT();
  27578       return;
  27579     }
  27580   } else {
  27581     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
  27582     if (cond.Is(al)) {
  27583       EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
  27584       return;
  27585     }
  27586   }
  27587   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
  27588 }
  27589 
  27590 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  27591   VIXL_ASSERT(AllowAssembler());
  27592   CheckIT(cond);
  27593   USE(dt);
  27594   if (IsUsingT32()) {
  27595     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
  27596     if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27597       EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
  27598       AdvanceIT();
  27599       return;
  27600     }
  27601   } else {
  27602     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
  27603     if (cond.Is(al)) {
  27604       EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
  27605       return;
  27606     }
  27607   }
  27608   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
  27609 }
  27610 
  27611 void Assembler::vtbl(Condition cond,
  27612                      DataType dt,
  27613                      DRegister rd,
  27614                      const NeonRegisterList& nreglist,
  27615                      DRegister rm) {
  27616   VIXL_ASSERT(AllowAssembler());
  27617   CheckIT(cond);
  27618   if (IsUsingT32()) {
  27619     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
  27620     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
  27621         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
  27622       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27623         const DRegister& first = nreglist.GetFirstDRegister();
  27624         uint32_t len_encoding = nreglist.GetLength() - 1;
  27625         EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
  27626                    (len_encoding << 8) | rm.Encode(5, 0));
  27627         AdvanceIT();
  27628         return;
  27629       }
  27630     }
  27631   } else {
  27632     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
  27633     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
  27634         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
  27635       if (cond.Is(al)) {
  27636         const DRegister& first = nreglist.GetFirstDRegister();
  27637         uint32_t len_encoding = nreglist.GetLength() - 1;
  27638         EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
  27639                 (len_encoding << 8) | rm.Encode(5, 0));
  27640         return;
  27641       }
  27642     }
  27643   }
  27644   Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
  27645 }
  27646 
  27647 void Assembler::vtbx(Condition cond,
  27648                      DataType dt,
  27649                      DRegister rd,
  27650                      const NeonRegisterList& nreglist,
  27651                      DRegister rm) {
  27652   VIXL_ASSERT(AllowAssembler());
  27653   CheckIT(cond);
  27654   if (IsUsingT32()) {
  27655     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
  27656     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
  27657         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
  27658       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27659         const DRegister& first = nreglist.GetFirstDRegister();
  27660         uint32_t len_encoding = nreglist.GetLength() - 1;
  27661         EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
  27662                    (len_encoding << 8) | rm.Encode(5, 0));
  27663         AdvanceIT();
  27664         return;
  27665       }
  27666     }
  27667   } else {
  27668     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
  27669     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
  27670         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
  27671       if (cond.Is(al)) {
  27672         const DRegister& first = nreglist.GetFirstDRegister();
  27673         uint32_t len_encoding = nreglist.GetLength() - 1;
  27674         EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
  27675                 (len_encoding << 8) | rm.Encode(5, 0));
  27676         return;
  27677       }
  27678     }
  27679   }
  27680   Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
  27681 }
  27682 
  27683 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  27684   VIXL_ASSERT(AllowAssembler());
  27685   CheckIT(cond);
  27686   Dt_size_7 encoded_dt(dt);
  27687   if (IsUsingT32()) {
  27688     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  27689     if (encoded_dt.IsValid()) {
  27690       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27691         EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
  27692                    rd.Encode(22, 12) | rm.Encode(5, 0));
  27693         AdvanceIT();
  27694         return;
  27695       }
  27696     }
  27697   } else {
  27698     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  27699     if (encoded_dt.IsValid()) {
  27700       if (cond.Is(al)) {
  27701         EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
  27702                 rd.Encode(22, 12) | rm.Encode(5, 0));
  27703         return;
  27704       }
  27705     }
  27706   }
  27707   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
  27708 }
  27709 
  27710 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  27711   VIXL_ASSERT(AllowAssembler());
  27712   CheckIT(cond);
  27713   Dt_size_7 encoded_dt(dt);
  27714   if (IsUsingT32()) {
  27715     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  27716     if (encoded_dt.IsValid()) {
  27717       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27718         EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
  27719                    rd.Encode(22, 12) | rm.Encode(5, 0));
  27720         AdvanceIT();
  27721         return;
  27722       }
  27723     }
  27724   } else {
  27725     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  27726     if (encoded_dt.IsValid()) {
  27727       if (cond.Is(al)) {
  27728         EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
  27729                 rd.Encode(22, 12) | rm.Encode(5, 0));
  27730         return;
  27731       }
  27732     }
  27733   }
  27734   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
  27735 }
  27736 
  27737 void Assembler::vtst(
  27738     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
  27739   VIXL_ASSERT(AllowAssembler());
  27740   CheckIT(cond);
  27741   Dt_size_7 encoded_dt(dt);
  27742   if (IsUsingT32()) {
  27743     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
  27744     if (encoded_dt.IsValid()) {
  27745       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27746         EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
  27747                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27748         AdvanceIT();
  27749         return;
  27750       }
  27751     }
  27752   } else {
  27753     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
  27754     if (encoded_dt.IsValid()) {
  27755       if (cond.Is(al)) {
  27756         EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
  27757                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27758         return;
  27759       }
  27760     }
  27761   }
  27762   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
  27763 }
  27764 
  27765 void Assembler::vtst(
  27766     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
  27767   VIXL_ASSERT(AllowAssembler());
  27768   CheckIT(cond);
  27769   Dt_size_7 encoded_dt(dt);
  27770   if (IsUsingT32()) {
  27771     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
  27772     if (encoded_dt.IsValid()) {
  27773       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27774         EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
  27775                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27776         AdvanceIT();
  27777         return;
  27778       }
  27779     }
  27780   } else {
  27781     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
  27782     if (encoded_dt.IsValid()) {
  27783       if (cond.Is(al)) {
  27784         EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
  27785                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
  27786         return;
  27787       }
  27788     }
  27789   }
  27790   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
  27791 }
  27792 
  27793 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  27794   VIXL_ASSERT(AllowAssembler());
  27795   CheckIT(cond);
  27796   Dt_size_15 encoded_dt(dt);
  27797   if (IsUsingT32()) {
  27798     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  27799     if (encoded_dt.IsValid()) {
  27800       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27801         EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
  27802                    rd.Encode(22, 12) | rm.Encode(5, 0));
  27803         AdvanceIT();
  27804         return;
  27805       }
  27806     }
  27807     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
  27808     if (dt.Is(Untyped32)) {
  27809       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27810         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
  27811         AdvanceIT();
  27812         return;
  27813       }
  27814     }
  27815   } else {
  27816     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  27817     if (encoded_dt.IsValid()) {
  27818       if (cond.Is(al)) {
  27819         EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
  27820                 rd.Encode(22, 12) | rm.Encode(5, 0));
  27821         return;
  27822       }
  27823     }
  27824     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
  27825     if (dt.Is(Untyped32)) {
  27826       if (cond.Is(al)) {
  27827         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
  27828         return;
  27829       }
  27830     }
  27831   }
  27832   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
  27833 }
  27834 
  27835 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  27836   VIXL_ASSERT(AllowAssembler());
  27837   CheckIT(cond);
  27838   Dt_size_7 encoded_dt(dt);
  27839   if (IsUsingT32()) {
  27840     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  27841     if (encoded_dt.IsValid()) {
  27842       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27843         EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
  27844                    rd.Encode(22, 12) | rm.Encode(5, 0));
  27845         AdvanceIT();
  27846         return;
  27847       }
  27848     }
  27849   } else {
  27850     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  27851     if (encoded_dt.IsValid()) {
  27852       if (cond.Is(al)) {
  27853         EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
  27854                 rd.Encode(22, 12) | rm.Encode(5, 0));
  27855         return;
  27856       }
  27857     }
  27858   }
  27859   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
  27860 }
  27861 
  27862 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
  27863   VIXL_ASSERT(AllowAssembler());
  27864   CheckIT(cond);
  27865   Dt_size_15 encoded_dt(dt);
  27866   if (IsUsingT32()) {
  27867     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
  27868     if (encoded_dt.IsValid()) {
  27869       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27870         EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
  27871                    rd.Encode(22, 12) | rm.Encode(5, 0));
  27872         AdvanceIT();
  27873         return;
  27874       }
  27875     }
  27876     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
  27877     if (dt.Is(Untyped32)) {
  27878       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27879         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
  27880         AdvanceIT();
  27881         return;
  27882       }
  27883     }
  27884   } else {
  27885     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
  27886     if (encoded_dt.IsValid()) {
  27887       if (cond.Is(al)) {
  27888         EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
  27889                 rd.Encode(22, 12) | rm.Encode(5, 0));
  27890         return;
  27891       }
  27892     }
  27893     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
  27894     if (dt.Is(Untyped32)) {
  27895       if (cond.Is(al)) {
  27896         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
  27897         return;
  27898       }
  27899     }
  27900   }
  27901   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
  27902 }
  27903 
  27904 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
  27905   VIXL_ASSERT(AllowAssembler());
  27906   CheckIT(cond);
  27907   Dt_size_7 encoded_dt(dt);
  27908   if (IsUsingT32()) {
  27909     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
  27910     if (encoded_dt.IsValid()) {
  27911       if (cond.Is(al) || AllowStronglyDiscouraged()) {
  27912         EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
  27913                    rd.Encode(22, 12) | rm.Encode(5, 0));
  27914         AdvanceIT();
  27915         return;
  27916       }
  27917     }
  27918   } else {
  27919     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
  27920     if (encoded_dt.IsValid()) {
  27921       if (cond.Is(al)) {
  27922         EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
  27923                 rd.Encode(22, 12) | rm.Encode(5, 0));
  27924         return;
  27925       }
  27926     }
  27927   }
  27928   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
  27929 }
  27930 
  27931 void Assembler::yield(Condition cond, EncodingSize size) {
  27932   VIXL_ASSERT(AllowAssembler());
  27933   CheckIT(cond);
  27934   if (IsUsingT32()) {
  27935     // YIELD{<c>}{<q>} ; T1
  27936     if (!size.IsWide()) {
  27937       EmitT32_16(0xbf10);
  27938       AdvanceIT();
  27939       return;
  27940     }
  27941     // YIELD{<c>}.W ; T2
  27942     if (!size.IsNarrow()) {
  27943       EmitT32_32(0xf3af8001U);
  27944       AdvanceIT();
  27945       return;
  27946     }
  27947   } else {
  27948     // YIELD{<c>}{<q>} ; A1
  27949     if (cond.IsNotNever()) {
  27950       EmitA32(0x0320f001U | (cond.GetCondition() << 28));
  27951       return;
  27952     }
  27953   }
  27954   Delegate(kYield, &Assembler::yield, cond, size);
  27955 }
  27956 // End of generated code.
  27957 
  27958 }  // namespace aarch32
  27959 }  // namespace vixl