Home | History | Annotate | Download | only in aarch32
      1 // Copyright 2015, VIXL authors
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 extern "C" {
     28 #include <stdint.h>
     29 }
     30 
     31 #include <cassert>
     32 #include <cstdio>
     33 #include <cstdlib>
     34 #include <cstring>
     35 #include <iostream>
     36 
     37 #include "utils-vixl.h"
     38 #include "aarch32/constants-aarch32.h"
     39 #include "aarch32/instructions-aarch32.h"
     40 #include "aarch32/operands-aarch32.h"
     41 #include "aarch32/assembler-aarch32.h"
     42 
     43 namespace vixl {
     44 namespace aarch32 {
     45 
     46 void Assembler::EmitT32_16(uint16_t instr) {
     47   VIXL_ASSERT(buffer_.Is16bitAligned());
     48   buffer_.Emit16(instr);
     49 }
     50 
     51 
     52 void Assembler::EmitT32_32(uint32_t instr) {
     53   VIXL_ASSERT(buffer_.Is16bitAligned());
     54   buffer_.Emit16(static_cast<uint16_t>(instr >> 16));
     55   buffer_.Emit16(static_cast<uint16_t>(instr & 0xffff));
     56 }
     57 
     58 
     59 void Assembler::EmitA32(uint32_t instr) {
     60   VIXL_ASSERT(buffer_.Is32bitAligned());
     61   buffer_.Emit32(instr);
     62 }
     63 
     64 
     65 #ifdef VIXL_DEBUG
     66 void Assembler::PerformCheckIT(Condition condition) {
     67   if (it_mask_ == 0) {
     68     VIXL_ASSERT(IsUsingA32() || condition.Is(al));
     69   } else {
     70     VIXL_ASSERT(condition.Is(first_condition_));
     71     first_condition_ =
     72         Condition((first_condition_.GetCondition() & 0xe) | (it_mask_ >> 3));
     73     // For A32, AdavanceIT() is not called by the assembler. We must call it
     74     // in order to check that IT instructions are used consistently with
     75     // the following conditional instructions.
     76     if (IsUsingA32()) AdvanceIT();
     77   }
     78 }
     79 #endif
     80 
     81 
     82 void Assembler::BindHelper(Label* label) {
     83   VIXL_ASSERT(!label->IsBound());
     84   label->Bind(GetCursorOffset(), GetInstructionSetInUse());
     85 
     86   for (Label::ForwardRefList::iterator ref = label->GetFirstForwardRef();
     87        ref != label->GetEndForwardRef();
     88        ref++) {
     89     EncodeLabelFor(*ref, label);
     90   }
     91   if (label->IsInVeneerPool()) {
     92     label->GetVeneerPoolManager()->RemoveLabel(label);
     93   }
     94 }
     95 
     96 
     97 uint32_t Assembler::Link(uint32_t instr,
     98                          Label* label,
     99                          const Label::LabelEmitOperator& op) {
    100   label->SetReferenced();
    101   if (label->IsBound()) {
    102     return op.Encode(instr,
    103                      GetCursorOffset() + GetArchitectureStatePCOffset(),
    104                      label);
    105   }
    106   label->AddForwardRef(GetCursorOffset(), GetInstructionSetInUse(), op);
    107   return instr;
    108 }
    109 
    110 
    111 void Assembler::EncodeLabelFor(const Label::ForwardReference& forward,
    112                                Label* label) {
    113   const uint32_t location = forward.GetLocation();
    114   const uint32_t from = location + forward.GetStatePCOffset();
    115   const Label::LabelEmitOperator& encoder = forward.GetEmitOperator();
    116   if (forward.IsUsingT32()) {
    117     uint16_t* instr_ptr = buffer_.GetOffsetAddress<uint16_t*>(location);
    118     if (Is16BitEncoding(instr_ptr[0])) {
    119       // The Encode methods always deals with uint32_t types so we need
    120       // to explicitely cast it.
    121       uint32_t instr = static_cast<uint32_t>(instr_ptr[0]);
    122       instr = encoder.Encode(instr, from, label);
    123       // The Encode method should not ever set the top 16 bits.
    124       VIXL_ASSERT((instr & ~0xffff) == 0);
    125       instr_ptr[0] = static_cast<uint16_t>(instr);
    126     } else {
    127       uint32_t instr =
    128           instr_ptr[1] | (static_cast<uint32_t>(instr_ptr[0]) << 16);
    129       instr = encoder.Encode(instr, from, label);
    130       instr_ptr[0] = static_cast<uint16_t>(instr >> 16);
    131       instr_ptr[1] = static_cast<uint16_t>(instr);
    132     }
    133   } else {
    134     uint32_t* instr_ptr = buffer_.GetOffsetAddress<uint32_t*>(location);
    135     instr_ptr[0] = encoder.Encode(instr_ptr[0], from, label);
    136   }
    137 }
    138 
    139 
    140 // Start of generated code.
    141 class Dt_L_imm6_1 : public EncodingValue {
    142   uint32_t type_;
    143 
    144  public:
    145   explicit Dt_L_imm6_1(DataType dt);
    146   uint32_t GetTypeEncodingValue() const { return type_; }
    147 };
    148 
    149 Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
    150   switch (dt.GetValue()) {
    151     case S8:
    152       type_ = 0x0;
    153       SetEncodingValue(0x1);
    154       break;
    155     case U8:
    156       type_ = 0x1;
    157       SetEncodingValue(0x1);
    158       break;
    159     case S16:
    160       type_ = 0x0;
    161       SetEncodingValue(0x2);
    162       break;
    163     case U16:
    164       type_ = 0x1;
    165       SetEncodingValue(0x2);
    166       break;
    167     case S32:
    168       type_ = 0x0;
    169       SetEncodingValue(0x4);
    170       break;
    171     case U32:
    172       type_ = 0x1;
    173       SetEncodingValue(0x4);
    174       break;
    175     case S64:
    176       type_ = 0x0;
    177       SetEncodingValue(0x8);
    178       break;
    179     case U64:
    180       type_ = 0x1;
    181       SetEncodingValue(0x8);
    182       break;
    183     default:
    184       VIXL_UNREACHABLE();
    185       type_ = 0x0;
    186       break;
    187   }
    188 }
    189 
    190 class Dt_L_imm6_2 : public EncodingValue {
    191   uint32_t type_;
    192 
    193  public:
    194   explicit Dt_L_imm6_2(DataType dt);
    195   uint32_t GetTypeEncodingValue() const { return type_; }
    196 };
    197 
    198 Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
    199   switch (dt.GetValue()) {
    200     case S8:
    201       type_ = 0x1;
    202       SetEncodingValue(0x1);
    203       break;
    204     case S16:
    205       type_ = 0x1;
    206       SetEncodingValue(0x2);
    207       break;
    208     case S32:
    209       type_ = 0x1;
    210       SetEncodingValue(0x4);
    211       break;
    212     case S64:
    213       type_ = 0x1;
    214       SetEncodingValue(0x8);
    215       break;
    216     default:
    217       VIXL_UNREACHABLE();
    218       type_ = 0x0;
    219       break;
    220   }
    221 }
    222 
    223 class Dt_L_imm6_3 : public EncodingValue {
    224  public:
    225   explicit Dt_L_imm6_3(DataType dt);
    226 };
    227 
    228 Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
    229   switch (dt.GetValue()) {
    230     case I8:
    231       SetEncodingValue(0x1);
    232       break;
    233     case I16:
    234       SetEncodingValue(0x2);
    235       break;
    236     case I32:
    237       SetEncodingValue(0x4);
    238       break;
    239     case I64:
    240       SetEncodingValue(0x8);
    241       break;
    242     default:
    243       break;
    244   }
    245 }
    246 
    247 class Dt_L_imm6_4 : public EncodingValue {
    248  public:
    249   explicit Dt_L_imm6_4(DataType dt);
    250 };
    251 
    252 Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
    253   switch (dt.GetValue()) {
    254     case Untyped8:
    255       SetEncodingValue(0x1);
    256       break;
    257     case Untyped16:
    258       SetEncodingValue(0x2);
    259       break;
    260     case Untyped32:
    261       SetEncodingValue(0x4);
    262       break;
    263     case Untyped64:
    264       SetEncodingValue(0x8);
    265       break;
    266     default:
    267       break;
    268   }
    269 }
    270 
    271 class Dt_imm6_1 : public EncodingValue {
    272   uint32_t type_;
    273 
    274  public:
    275   explicit Dt_imm6_1(DataType dt);
    276   uint32_t GetTypeEncodingValue() const { return type_; }
    277 };
    278 
    279 Dt_imm6_1::Dt_imm6_1(DataType dt) {
    280   switch (dt.GetValue()) {
    281     case S16:
    282       type_ = 0x0;
    283       SetEncodingValue(0x1);
    284       break;
    285     case U16:
    286       type_ = 0x1;
    287       SetEncodingValue(0x1);
    288       break;
    289     case S32:
    290       type_ = 0x0;
    291       SetEncodingValue(0x2);
    292       break;
    293     case U32:
    294       type_ = 0x1;
    295       SetEncodingValue(0x2);
    296       break;
    297     case S64:
    298       type_ = 0x0;
    299       SetEncodingValue(0x4);
    300       break;
    301     case U64:
    302       type_ = 0x1;
    303       SetEncodingValue(0x4);
    304       break;
    305     default:
    306       VIXL_UNREACHABLE();
    307       type_ = 0x0;
    308       break;
    309   }
    310 }
    311 
    312 class Dt_imm6_2 : public EncodingValue {
    313   uint32_t type_;
    314 
    315  public:
    316   explicit Dt_imm6_2(DataType dt);
    317   uint32_t GetTypeEncodingValue() const { return type_; }
    318 };
    319 
    320 Dt_imm6_2::Dt_imm6_2(DataType dt) {
    321   switch (dt.GetValue()) {
    322     case S16:
    323       type_ = 0x1;
    324       SetEncodingValue(0x1);
    325       break;
    326     case S32:
    327       type_ = 0x1;
    328       SetEncodingValue(0x2);
    329       break;
    330     case S64:
    331       type_ = 0x1;
    332       SetEncodingValue(0x4);
    333       break;
    334     default:
    335       VIXL_UNREACHABLE();
    336       type_ = 0x0;
    337       break;
    338   }
    339 }
    340 
    341 class Dt_imm6_3 : public EncodingValue {
    342  public:
    343   explicit Dt_imm6_3(DataType dt);
    344 };
    345 
    346 Dt_imm6_3::Dt_imm6_3(DataType dt) {
    347   switch (dt.GetValue()) {
    348     case I16:
    349       SetEncodingValue(0x1);
    350       break;
    351     case I32:
    352       SetEncodingValue(0x2);
    353       break;
    354     case I64:
    355       SetEncodingValue(0x4);
    356       break;
    357     default:
    358       break;
    359   }
    360 }
    361 
    362 class Dt_imm6_4 : public EncodingValue {
    363   uint32_t type_;
    364 
    365  public:
    366   explicit Dt_imm6_4(DataType dt);
    367   uint32_t GetTypeEncodingValue() const { return type_; }
    368 };
    369 
    370 Dt_imm6_4::Dt_imm6_4(DataType dt) {
    371   switch (dt.GetValue()) {
    372     case S8:
    373       type_ = 0x0;
    374       SetEncodingValue(0x1);
    375       break;
    376     case U8:
    377       type_ = 0x1;
    378       SetEncodingValue(0x1);
    379       break;
    380     case S16:
    381       type_ = 0x0;
    382       SetEncodingValue(0x2);
    383       break;
    384     case U16:
    385       type_ = 0x1;
    386       SetEncodingValue(0x2);
    387       break;
    388     case S32:
    389       type_ = 0x0;
    390       SetEncodingValue(0x4);
    391       break;
    392     case U32:
    393       type_ = 0x1;
    394       SetEncodingValue(0x4);
    395       break;
    396     default:
    397       VIXL_UNREACHABLE();
    398       type_ = 0x0;
    399       break;
    400   }
    401 }
    402 
    403 class Dt_op_U_size_1 : public EncodingValue {
    404  public:
    405   explicit Dt_op_U_size_1(DataType dt);
    406 };
    407 
    408 Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
    409   switch (dt.GetValue()) {
    410     case S8:
    411       SetEncodingValue(0x0);
    412       break;
    413     case S16:
    414       SetEncodingValue(0x1);
    415       break;
    416     case S32:
    417       SetEncodingValue(0x2);
    418       break;
    419     case U8:
    420       SetEncodingValue(0x4);
    421       break;
    422     case U16:
    423       SetEncodingValue(0x5);
    424       break;
    425     case U32:
    426       SetEncodingValue(0x6);
    427       break;
    428     case P8:
    429       SetEncodingValue(0x8);
    430       break;
    431     case P64:
    432       SetEncodingValue(0xa);
    433       break;
    434     default:
    435       break;
    436   }
    437 }
    438 
    439 class Dt_op_size_1 : public EncodingValue {
    440  public:
    441   explicit Dt_op_size_1(DataType dt);
    442 };
    443 
    444 Dt_op_size_1::Dt_op_size_1(DataType dt) {
    445   switch (dt.GetValue()) {
    446     case I8:
    447       SetEncodingValue(0x0);
    448       break;
    449     case I16:
    450       SetEncodingValue(0x1);
    451       break;
    452     case I32:
    453       SetEncodingValue(0x2);
    454       break;
    455     case P8:
    456       SetEncodingValue(0x4);
    457       break;
    458     default:
    459       break;
    460   }
    461 }
    462 
    463 class Dt_op_size_2 : public EncodingValue {
    464  public:
    465   explicit Dt_op_size_2(DataType dt);
    466 };
    467 
    468 Dt_op_size_2::Dt_op_size_2(DataType dt) {
    469   switch (dt.GetValue()) {
    470     case S8:
    471       SetEncodingValue(0x0);
    472       break;
    473     case S16:
    474       SetEncodingValue(0x1);
    475       break;
    476     case S32:
    477       SetEncodingValue(0x2);
    478       break;
    479     case U8:
    480       SetEncodingValue(0x4);
    481       break;
    482     case U16:
    483       SetEncodingValue(0x5);
    484       break;
    485     case U32:
    486       SetEncodingValue(0x6);
    487       break;
    488     default:
    489       break;
    490   }
    491 }
    492 
    493 class Dt_op_size_3 : public EncodingValue {
    494  public:
    495   explicit Dt_op_size_3(DataType dt);
    496 };
    497 
    498 Dt_op_size_3::Dt_op_size_3(DataType dt) {
    499   switch (dt.GetValue()) {
    500     case S16:
    501       SetEncodingValue(0x0);
    502       break;
    503     case S32:
    504       SetEncodingValue(0x1);
    505       break;
    506     case S64:
    507       SetEncodingValue(0x2);
    508       break;
    509     case U16:
    510       SetEncodingValue(0x4);
    511       break;
    512     case U32:
    513       SetEncodingValue(0x5);
    514       break;
    515     case U64:
    516       SetEncodingValue(0x6);
    517       break;
    518     default:
    519       break;
    520   }
    521 }
    522 
    523 class Dt_U_imm3H_1 : public EncodingValue {
    524  public:
    525   explicit Dt_U_imm3H_1(DataType dt);
    526 };
    527 
    528 Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
    529   switch (dt.GetValue()) {
    530     case S8:
    531       SetEncodingValue(0x1);
    532       break;
    533     case S16:
    534       SetEncodingValue(0x2);
    535       break;
    536     case S32:
    537       SetEncodingValue(0x4);
    538       break;
    539     case U8:
    540       SetEncodingValue(0x9);
    541       break;
    542     case U16:
    543       SetEncodingValue(0xa);
    544       break;
    545     case U32:
    546       SetEncodingValue(0xc);
    547       break;
    548     default:
    549       break;
    550   }
    551 }
    552 
    553 class Dt_U_opc1_opc2_1 : public EncodingValue {
    554  public:
    555   explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
    556 };
    557 
    558 Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
    559   switch (dt.GetValue()) {
    560     case S8:
    561       if ((lane.GetLane() & 7) != lane.GetLane()) {
    562         return;
    563       }
    564       SetEncodingValue(0x8 | lane.GetLane());
    565       break;
    566     case S16:
    567       if ((lane.GetLane() & 3) != lane.GetLane()) {
    568         return;
    569       }
    570       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    571       break;
    572     case U8:
    573       if ((lane.GetLane() & 7) != lane.GetLane()) {
    574         return;
    575       }
    576       SetEncodingValue(0x18 | lane.GetLane());
    577       break;
    578     case U16:
    579       if ((lane.GetLane() & 3) != lane.GetLane()) {
    580         return;
    581       }
    582       SetEncodingValue(0x11 | (lane.GetLane() << 1));
    583       break;
    584     case Untyped32:
    585       if ((lane.GetLane() & 1) != lane.GetLane()) {
    586         return;
    587       }
    588       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    589       break;
    590     case kDataTypeValueNone:
    591       if ((lane.GetLane() & 1) != lane.GetLane()) {
    592         return;
    593       }
    594       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    595       break;
    596     default:
    597       break;
    598   }
    599 }
    600 
    601 class Dt_opc1_opc2_1 : public EncodingValue {
    602  public:
    603   explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
    604 };
    605 
    606 Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
    607   switch (dt.GetValue()) {
    608     case Untyped8:
    609       if ((lane.GetLane() & 7) != lane.GetLane()) {
    610         return;
    611       }
    612       SetEncodingValue(0x8 | lane.GetLane());
    613       break;
    614     case Untyped16:
    615       if ((lane.GetLane() & 3) != lane.GetLane()) {
    616         return;
    617       }
    618       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    619       break;
    620     case Untyped32:
    621       if ((lane.GetLane() & 1) != lane.GetLane()) {
    622         return;
    623       }
    624       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    625       break;
    626     case kDataTypeValueNone:
    627       if ((lane.GetLane() & 1) != lane.GetLane()) {
    628         return;
    629       }
    630       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    631       break;
    632     default:
    633       break;
    634   }
    635 }
    636 
    637 class Dt_imm4_1 : public EncodingValue {
    638  public:
    639   explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
    640 };
    641 
    642 Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
    643   switch (dt.GetValue()) {
    644     case Untyped8:
    645       if ((lane.GetLane() & 7) != lane.GetLane()) {
    646         return;
    647       }
    648       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    649       break;
    650     case Untyped16:
    651       if ((lane.GetLane() & 3) != lane.GetLane()) {
    652         return;
    653       }
    654       SetEncodingValue(0x2 | (lane.GetLane() << 2));
    655       break;
    656     case Untyped32:
    657       if ((lane.GetLane() & 1) != lane.GetLane()) {
    658         return;
    659       }
    660       SetEncodingValue(0x4 | (lane.GetLane() << 3));
    661       break;
    662     default:
    663       break;
    664   }
    665 }
    666 
    667 class Dt_B_E_1 : public EncodingValue {
    668  public:
    669   explicit Dt_B_E_1(DataType dt);
    670 };
    671 
    672 Dt_B_E_1::Dt_B_E_1(DataType dt) {
    673   switch (dt.GetValue()) {
    674     case Untyped8:
    675       SetEncodingValue(0x2);
    676       break;
    677     case Untyped16:
    678       SetEncodingValue(0x1);
    679       break;
    680     case Untyped32:
    681       SetEncodingValue(0x0);
    682       break;
    683     default:
    684       break;
    685   }
    686 }
    687 
    688 class Dt_op_1 : public EncodingValue {
    689  public:
    690   Dt_op_1(DataType dt1, DataType dt2);
    691 };
    692 
    693 Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
    694   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
    695     SetEncodingValue(0x0);
    696     return;
    697   }
    698   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
    699     SetEncodingValue(0x1);
    700     return;
    701   }
    702   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
    703     SetEncodingValue(0x2);
    704     return;
    705   }
    706   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
    707     SetEncodingValue(0x3);
    708     return;
    709   }
    710 }
    711 
    712 class Dt_op_2 : public EncodingValue {
    713  public:
    714   explicit Dt_op_2(DataType dt);
    715 };
    716 
    717 Dt_op_2::Dt_op_2(DataType dt) {
    718   switch (dt.GetValue()) {
    719     case U32:
    720       SetEncodingValue(0x0);
    721       break;
    722     case S32:
    723       SetEncodingValue(0x1);
    724       break;
    725     default:
    726       break;
    727   }
    728 }
    729 
    730 class Dt_op_3 : public EncodingValue {
    731  public:
    732   explicit Dt_op_3(DataType dt);
    733 };
    734 
    735 Dt_op_3::Dt_op_3(DataType dt) {
    736   switch (dt.GetValue()) {
    737     case S32:
    738       SetEncodingValue(0x0);
    739       break;
    740     case U32:
    741       SetEncodingValue(0x1);
    742       break;
    743     default:
    744       break;
    745   }
    746 }
    747 
    748 class Dt_U_sx_1 : public EncodingValue {
    749  public:
    750   explicit Dt_U_sx_1(DataType dt);
    751 };
    752 
    753 Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
    754   switch (dt.GetValue()) {
    755     case S16:
    756       SetEncodingValue(0x0);
    757       break;
    758     case S32:
    759       SetEncodingValue(0x1);
    760       break;
    761     case U16:
    762       SetEncodingValue(0x2);
    763       break;
    764     case U32:
    765       SetEncodingValue(0x3);
    766       break;
    767     default:
    768       break;
    769   }
    770 }
    771 
    772 class Dt_op_U_1 : public EncodingValue {
    773  public:
    774   Dt_op_U_1(DataType dt1, DataType dt2);
    775 };
    776 
    777 Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
    778   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
    779     SetEncodingValue(0x0);
    780     return;
    781   }
    782   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
    783     SetEncodingValue(0x1);
    784     return;
    785   }
    786   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
    787     SetEncodingValue(0x2);
    788     return;
    789   }
    790   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
    791     SetEncodingValue(0x3);
    792     return;
    793   }
    794 }
    795 
    796 class Dt_sz_1 : public EncodingValue {
    797  public:
    798   explicit Dt_sz_1(DataType dt);
    799 };
    800 
    801 Dt_sz_1::Dt_sz_1(DataType dt) {
    802   switch (dt.GetValue()) {
    803     case F32:
    804       SetEncodingValue(0x0);
    805       break;
    806     default:
    807       break;
    808   }
    809 }
    810 
    811 class Dt_F_size_1 : public EncodingValue {
    812  public:
    813   explicit Dt_F_size_1(DataType dt);
    814 };
    815 
    816 Dt_F_size_1::Dt_F_size_1(DataType dt) {
    817   switch (dt.GetValue()) {
    818     case S8:
    819       SetEncodingValue(0x0);
    820       break;
    821     case S16:
    822       SetEncodingValue(0x1);
    823       break;
    824     case S32:
    825       SetEncodingValue(0x2);
    826       break;
    827     case F32:
    828       SetEncodingValue(0x6);
    829       break;
    830     default:
    831       break;
    832   }
    833 }
    834 
    835 class Dt_F_size_2 : public EncodingValue {
    836  public:
    837   explicit Dt_F_size_2(DataType dt);
    838 };
    839 
    840 Dt_F_size_2::Dt_F_size_2(DataType dt) {
    841   switch (dt.GetValue()) {
    842     case I8:
    843       SetEncodingValue(0x0);
    844       break;
    845     case I16:
    846       SetEncodingValue(0x1);
    847       break;
    848     case I32:
    849       SetEncodingValue(0x2);
    850       break;
    851     case F32:
    852       SetEncodingValue(0x6);
    853       break;
    854     default:
    855       break;
    856   }
    857 }
    858 
    859 class Dt_F_size_3 : public EncodingValue {
    860  public:
    861   explicit Dt_F_size_3(DataType dt);
    862 };
    863 
    864 Dt_F_size_3::Dt_F_size_3(DataType dt) {
    865   switch (dt.GetValue()) {
    866     case I16:
    867       SetEncodingValue(0x1);
    868       break;
    869     case I32:
    870       SetEncodingValue(0x2);
    871       break;
    872     case F32:
    873       SetEncodingValue(0x6);
    874       break;
    875     default:
    876       break;
    877   }
    878 }
    879 
    880 class Dt_F_size_4 : public EncodingValue {
    881  public:
    882   explicit Dt_F_size_4(DataType dt);
    883 };
    884 
    885 Dt_F_size_4::Dt_F_size_4(DataType dt) {
    886   switch (dt.GetValue()) {
    887     case U32:
    888       SetEncodingValue(0x2);
    889       break;
    890     case F32:
    891       SetEncodingValue(0x6);
    892       break;
    893     default:
    894       break;
    895   }
    896 }
    897 
    898 class Dt_U_size_1 : public EncodingValue {
    899  public:
    900   explicit Dt_U_size_1(DataType dt);
    901 };
    902 
    903 Dt_U_size_1::Dt_U_size_1(DataType dt) {
    904   switch (dt.GetValue()) {
    905     case S8:
    906       SetEncodingValue(0x0);
    907       break;
    908     case S16:
    909       SetEncodingValue(0x1);
    910       break;
    911     case S32:
    912       SetEncodingValue(0x2);
    913       break;
    914     case U8:
    915       SetEncodingValue(0x4);
    916       break;
    917     case U16:
    918       SetEncodingValue(0x5);
    919       break;
    920     case U32:
    921       SetEncodingValue(0x6);
    922       break;
    923     default:
    924       break;
    925   }
    926 }
    927 
    928 class Dt_U_size_2 : public EncodingValue {
    929  public:
    930   explicit Dt_U_size_2(DataType dt);
    931 };
    932 
    933 Dt_U_size_2::Dt_U_size_2(DataType dt) {
    934   switch (dt.GetValue()) {
    935     case S16:
    936       SetEncodingValue(0x1);
    937       break;
    938     case S32:
    939       SetEncodingValue(0x2);
    940       break;
    941     case U16:
    942       SetEncodingValue(0x5);
    943       break;
    944     case U32:
    945       SetEncodingValue(0x6);
    946       break;
    947     default:
    948       break;
    949   }
    950 }
    951 
    952 class Dt_U_size_3 : public EncodingValue {
    953  public:
    954   explicit Dt_U_size_3(DataType dt);
    955 };
    956 
    957 Dt_U_size_3::Dt_U_size_3(DataType dt) {
    958   switch (dt.GetValue()) {
    959     case S8:
    960       SetEncodingValue(0x0);
    961       break;
    962     case S16:
    963       SetEncodingValue(0x1);
    964       break;
    965     case S32:
    966       SetEncodingValue(0x2);
    967       break;
    968     case S64:
    969       SetEncodingValue(0x3);
    970       break;
    971     case U8:
    972       SetEncodingValue(0x4);
    973       break;
    974     case U16:
    975       SetEncodingValue(0x5);
    976       break;
    977     case U32:
    978       SetEncodingValue(0x6);
    979       break;
    980     case U64:
    981       SetEncodingValue(0x7);
    982       break;
    983     default:
    984       break;
    985   }
    986 }
    987 
    988 class Dt_size_1 : public EncodingValue {
    989  public:
    990   explicit Dt_size_1(DataType dt);
    991 };
    992 
    993 Dt_size_1::Dt_size_1(DataType dt) {
    994   switch (dt.GetValue()) {
    995     case Untyped8:
    996       SetEncodingValue(0x0);
    997       break;
    998     default:
    999       break;
   1000   }
   1001 }
   1002 
   1003 class Dt_size_2 : public EncodingValue {
   1004  public:
   1005   explicit Dt_size_2(DataType dt);
   1006 };
   1007 
   1008 Dt_size_2::Dt_size_2(DataType dt) {
   1009   switch (dt.GetValue()) {
   1010     case I8:
   1011       SetEncodingValue(0x0);
   1012       break;
   1013     case I16:
   1014       SetEncodingValue(0x1);
   1015       break;
   1016     case I32:
   1017       SetEncodingValue(0x2);
   1018       break;
   1019     case I64:
   1020       SetEncodingValue(0x3);
   1021       break;
   1022     default:
   1023       break;
   1024   }
   1025 }
   1026 
   1027 class Dt_size_3 : public EncodingValue {
   1028  public:
   1029   explicit Dt_size_3(DataType dt);
   1030 };
   1031 
   1032 Dt_size_3::Dt_size_3(DataType dt) {
   1033   switch (dt.GetValue()) {
   1034     case I16:
   1035       SetEncodingValue(0x0);
   1036       break;
   1037     case I32:
   1038       SetEncodingValue(0x1);
   1039       break;
   1040     case I64:
   1041       SetEncodingValue(0x2);
   1042       break;
   1043     default:
   1044       break;
   1045   }
   1046 }
   1047 
   1048 class Dt_size_4 : public EncodingValue {
   1049  public:
   1050   explicit Dt_size_4(DataType dt);
   1051 };
   1052 
   1053 Dt_size_4::Dt_size_4(DataType dt) {
   1054   switch (dt.GetValue()) {
   1055     case I8:
   1056       SetEncodingValue(0x0);
   1057       break;
   1058     case I16:
   1059       SetEncodingValue(0x1);
   1060       break;
   1061     case I32:
   1062       SetEncodingValue(0x2);
   1063       break;
   1064     default:
   1065       break;
   1066   }
   1067 }
   1068 
   1069 class Dt_size_5 : public EncodingValue {
   1070  public:
   1071   explicit Dt_size_5(DataType dt);
   1072 };
   1073 
   1074 Dt_size_5::Dt_size_5(DataType dt) {
   1075   switch (dt.GetValue()) {
   1076     case S8:
   1077       SetEncodingValue(0x0);
   1078       break;
   1079     case S16:
   1080       SetEncodingValue(0x1);
   1081       break;
   1082     case S32:
   1083       SetEncodingValue(0x2);
   1084       break;
   1085     default:
   1086       break;
   1087   }
   1088 }
   1089 
   1090 class Dt_size_6 : public EncodingValue {
   1091  public:
   1092   explicit Dt_size_6(DataType dt);
   1093 };
   1094 
   1095 Dt_size_6::Dt_size_6(DataType dt) {
   1096   switch (dt.GetValue()) {
   1097     case Untyped8:
   1098       SetEncodingValue(0x0);
   1099       break;
   1100     case Untyped16:
   1101       SetEncodingValue(0x1);
   1102       break;
   1103     case Untyped32:
   1104       SetEncodingValue(0x2);
   1105       break;
   1106     case Untyped64:
   1107       SetEncodingValue(0x3);
   1108       break;
   1109     default:
   1110       break;
   1111   }
   1112 }
   1113 
   1114 class Dt_size_7 : public EncodingValue {
   1115  public:
   1116   explicit Dt_size_7(DataType dt);
   1117 };
   1118 
   1119 Dt_size_7::Dt_size_7(DataType dt) {
   1120   switch (dt.GetValue()) {
   1121     case Untyped8:
   1122       SetEncodingValue(0x0);
   1123       break;
   1124     case Untyped16:
   1125       SetEncodingValue(0x1);
   1126       break;
   1127     case Untyped32:
   1128       SetEncodingValue(0x2);
   1129       break;
   1130     default:
   1131       break;
   1132   }
   1133 }
   1134 
   1135 class Dt_size_8 : public EncodingValue {
   1136  public:
   1137   Dt_size_8(DataType dt, Alignment align);
   1138 };
   1139 
   1140 Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
   1141   switch (dt.GetValue()) {
   1142     case Untyped8:
   1143       SetEncodingValue(0x0);
   1144       break;
   1145     case Untyped16:
   1146       SetEncodingValue(0x1);
   1147       break;
   1148     case Untyped32:
   1149       if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
   1150         SetEncodingValue(0x2);
   1151       } else if (align.Is(k128BitAlign)) {
   1152         SetEncodingValue(0x3);
   1153       }
   1154       break;
   1155     default:
   1156       break;
   1157   }
   1158 }
   1159 
   1160 class Dt_size_9 : public EncodingValue {
   1161   uint32_t type_;
   1162 
   1163  public:
   1164   explicit Dt_size_9(DataType dt);
   1165   uint32_t GetTypeEncodingValue() const { return type_; }
   1166 };
   1167 
   1168 Dt_size_9::Dt_size_9(DataType dt) {
   1169   switch (dt.GetValue()) {
   1170     case I16:
   1171       type_ = 0x0;
   1172       SetEncodingValue(0x1);
   1173       break;
   1174     case I32:
   1175       type_ = 0x0;
   1176       SetEncodingValue(0x2);
   1177       break;
   1178     case F32:
   1179       type_ = 0x1;
   1180       SetEncodingValue(0x2);
   1181       break;
   1182     default:
   1183       VIXL_UNREACHABLE();
   1184       type_ = 0x0;
   1185       break;
   1186   }
   1187 }
   1188 
   1189 class Dt_size_10 : public EncodingValue {
   1190  public:
   1191   explicit Dt_size_10(DataType dt);
   1192 };
   1193 
   1194 Dt_size_10::Dt_size_10(DataType dt) {
   1195   switch (dt.GetValue()) {
   1196     case S8:
   1197     case U8:
   1198     case I8:
   1199       SetEncodingValue(0x0);
   1200       break;
   1201     case S16:
   1202     case U16:
   1203     case I16:
   1204       SetEncodingValue(0x1);
   1205       break;
   1206     case S32:
   1207     case U32:
   1208     case I32:
   1209       SetEncodingValue(0x2);
   1210       break;
   1211     default:
   1212       break;
   1213   }
   1214 }
   1215 
   1216 class Dt_size_11 : public EncodingValue {
   1217   uint32_t type_;
   1218 
   1219  public:
   1220   explicit Dt_size_11(DataType dt);
   1221   uint32_t GetTypeEncodingValue() const { return type_; }
   1222 };
   1223 
   1224 Dt_size_11::Dt_size_11(DataType dt) {
   1225   switch (dt.GetValue()) {
   1226     case S16:
   1227       type_ = 0x0;
   1228       SetEncodingValue(0x1);
   1229       break;
   1230     case U16:
   1231       type_ = 0x1;
   1232       SetEncodingValue(0x1);
   1233       break;
   1234     case S32:
   1235       type_ = 0x0;
   1236       SetEncodingValue(0x2);
   1237       break;
   1238     case U32:
   1239       type_ = 0x1;
   1240       SetEncodingValue(0x2);
   1241       break;
   1242     default:
   1243       VIXL_UNREACHABLE();
   1244       type_ = 0x0;
   1245       break;
   1246   }
   1247 }
   1248 
   1249 class Dt_size_12 : public EncodingValue {
   1250   uint32_t type_;
   1251 
   1252  public:
   1253   explicit Dt_size_12(DataType dt);
   1254   uint32_t GetTypeEncodingValue() const { return type_; }
   1255 };
   1256 
   1257 Dt_size_12::Dt_size_12(DataType dt) {
   1258   switch (dt.GetValue()) {
   1259     case S8:
   1260       type_ = 0x0;
   1261       SetEncodingValue(0x0);
   1262       break;
   1263     case U8:
   1264       type_ = 0x1;
   1265       SetEncodingValue(0x0);
   1266       break;
   1267     case S16:
   1268       type_ = 0x0;
   1269       SetEncodingValue(0x1);
   1270       break;
   1271     case U16:
   1272       type_ = 0x1;
   1273       SetEncodingValue(0x1);
   1274       break;
   1275     case S32:
   1276       type_ = 0x0;
   1277       SetEncodingValue(0x2);
   1278       break;
   1279     case U32:
   1280       type_ = 0x1;
   1281       SetEncodingValue(0x2);
   1282       break;
   1283     default:
   1284       VIXL_UNREACHABLE();
   1285       type_ = 0x0;
   1286       break;
   1287   }
   1288 }
   1289 
   1290 class Dt_size_13 : public EncodingValue {
   1291  public:
   1292   explicit Dt_size_13(DataType dt);
   1293 };
   1294 
   1295 Dt_size_13::Dt_size_13(DataType dt) {
   1296   switch (dt.GetValue()) {
   1297     case S16:
   1298       SetEncodingValue(0x1);
   1299       break;
   1300     case S32:
   1301       SetEncodingValue(0x2);
   1302       break;
   1303     default:
   1304       break;
   1305   }
   1306 }
   1307 
   1308 class Dt_size_14 : public EncodingValue {
   1309  public:
   1310   explicit Dt_size_14(DataType dt);
   1311 };
   1312 
   1313 Dt_size_14::Dt_size_14(DataType dt) {
   1314   switch (dt.GetValue()) {
   1315     case S16:
   1316       SetEncodingValue(0x0);
   1317       break;
   1318     case S32:
   1319       SetEncodingValue(0x1);
   1320       break;
   1321     case S64:
   1322       SetEncodingValue(0x2);
   1323       break;
   1324     default:
   1325       break;
   1326   }
   1327 }
   1328 
   1329 class Dt_size_15 : public EncodingValue {
   1330  public:
   1331   explicit Dt_size_15(DataType dt);
   1332 };
   1333 
   1334 Dt_size_15::Dt_size_15(DataType dt) {
   1335   switch (dt.GetValue()) {
   1336     case Untyped8:
   1337       SetEncodingValue(0x0);
   1338       break;
   1339     case Untyped16:
   1340       SetEncodingValue(0x1);
   1341       break;
   1342     default:
   1343       break;
   1344   }
   1345 }
   1346 
   1347 class Dt_size_16 : public EncodingValue {
   1348  public:
   1349   explicit Dt_size_16(DataType dt);
   1350 };
   1351 
   1352 Dt_size_16::Dt_size_16(DataType dt) {
   1353   switch (dt.GetValue()) {
   1354     case I8:
   1355       SetEncodingValue(0x0);
   1356       break;
   1357     case I16:
   1358       SetEncodingValue(0x1);
   1359       break;
   1360     case I32:
   1361       SetEncodingValue(0x2);
   1362       break;
   1363     default:
   1364       break;
   1365   }
   1366 }
   1367 
   1368 class Index_1 : public EncodingValue {
   1369  public:
   1370   Index_1(const NeonRegisterList& nreglist, DataType dt);
   1371 };
   1372 
   1373 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
   1374   switch (dt.GetValue()) {
   1375     case Untyped8: {
   1376       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1377         return;
   1378       }
   1379       uint32_t value = nreglist.GetTransferLane() << 1;
   1380       if (!nreglist.IsSingleSpaced()) return;
   1381       SetEncodingValue(value);
   1382       break;
   1383     }
   1384     case Untyped16: {
   1385       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1386         return;
   1387       }
   1388       uint32_t value = nreglist.GetTransferLane() << 2;
   1389       if (nreglist.IsDoubleSpaced()) value |= 2;
   1390       SetEncodingValue(value);
   1391       break;
   1392     }
   1393     case Untyped32: {
   1394       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1395         return;
   1396       }
   1397       uint32_t value = nreglist.GetTransferLane() << 3;
   1398       if (nreglist.IsDoubleSpaced()) value |= 4;
   1399       SetEncodingValue(value);
   1400       break;
   1401     }
   1402     default:
   1403       break;
   1404   }
   1405 }
   1406 
   1407 class Align_index_align_1 : public EncodingValue {
   1408  public:
   1409   Align_index_align_1(Alignment align,
   1410                       const NeonRegisterList& nreglist,
   1411                       DataType dt);
   1412 };
   1413 
   1414 Align_index_align_1::Align_index_align_1(Alignment align,
   1415                                          const NeonRegisterList& nreglist,
   1416                                          DataType dt) {
   1417   switch (dt.GetValue()) {
   1418     case Untyped8: {
   1419       uint32_t value;
   1420       if (align.GetType() == kNoAlignment) {
   1421         value = 0;
   1422       } else {
   1423         return;
   1424       }
   1425       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1426         return;
   1427       }
   1428       value |= nreglist.GetTransferLane() << 1;
   1429       SetEncodingValue(value);
   1430       break;
   1431     }
   1432     case Untyped16: {
   1433       uint32_t value;
   1434       if (align.GetType() == k16BitAlign) {
   1435         value = 1;
   1436       } else if (align.GetType() == kNoAlignment) {
   1437         value = 0;
   1438       } else {
   1439         return;
   1440       }
   1441       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1442         return;
   1443       }
   1444       value |= nreglist.GetTransferLane() << 2;
   1445       SetEncodingValue(value);
   1446       break;
   1447     }
   1448     case Untyped32: {
   1449       uint32_t value;
   1450       if (align.GetType() == k32BitAlign) {
   1451         value = 3;
   1452       } else if (align.GetType() == kNoAlignment) {
   1453         value = 0;
   1454       } else {
   1455         return;
   1456       }
   1457       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1458         return;
   1459       }
   1460       value |= nreglist.GetTransferLane() << 3;
   1461       SetEncodingValue(value);
   1462       break;
   1463     }
   1464     default:
   1465       break;
   1466   }
   1467 }
   1468 
   1469 class Align_index_align_2 : public EncodingValue {
   1470  public:
   1471   Align_index_align_2(Alignment align,
   1472                       const NeonRegisterList& nreglist,
   1473                       DataType dt);
   1474 };
   1475 
   1476 Align_index_align_2::Align_index_align_2(Alignment align,
   1477                                          const NeonRegisterList& nreglist,
   1478                                          DataType dt) {
   1479   switch (dt.GetValue()) {
   1480     case Untyped8: {
   1481       uint32_t value;
   1482       if (align.GetType() == k16BitAlign) {
   1483         value = 1;
   1484       } else if (align.GetType() == kNoAlignment) {
   1485         value = 0;
   1486       } else {
   1487         return;
   1488       }
   1489       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1490         return;
   1491       }
   1492       value |= nreglist.GetTransferLane() << 1;
   1493       if (!nreglist.IsSingleSpaced()) return;
   1494       SetEncodingValue(value);
   1495       break;
   1496     }
   1497     case Untyped16: {
   1498       uint32_t value;
   1499       if (align.GetType() == k32BitAlign) {
   1500         value = 1;
   1501       } else if (align.GetType() == kNoAlignment) {
   1502         value = 0;
   1503       } else {
   1504         return;
   1505       }
   1506       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1507         return;
   1508       }
   1509       value |= nreglist.GetTransferLane() << 2;
   1510       if (nreglist.IsDoubleSpaced()) value |= 2;
   1511       SetEncodingValue(value);
   1512       break;
   1513     }
   1514     case Untyped32: {
   1515       uint32_t value;
   1516       if (align.GetType() == k64BitAlign) {
   1517         value = 1;
   1518       } else if (align.GetType() == kNoAlignment) {
   1519         value = 0;
   1520       } else {
   1521         return;
   1522       }
   1523       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1524         return;
   1525       }
   1526       value |= nreglist.GetTransferLane() << 3;
   1527       if (nreglist.IsDoubleSpaced()) value |= 4;
   1528       SetEncodingValue(value);
   1529       break;
   1530     }
   1531     default:
   1532       break;
   1533   }
   1534 }
   1535 
   1536 class Align_index_align_3 : public EncodingValue {
   1537  public:
   1538   Align_index_align_3(Alignment align,
   1539                       const NeonRegisterList& nreglist,
   1540                       DataType dt);
   1541 };
   1542 
   1543 Align_index_align_3::Align_index_align_3(Alignment align,
   1544                                          const NeonRegisterList& nreglist,
   1545                                          DataType dt) {
   1546   switch (dt.GetValue()) {
   1547     case Untyped8: {
   1548       uint32_t value;
   1549       if (align.GetType() == k32BitAlign) {
   1550         value = 1;
   1551       } else if (align.GetType() == kNoAlignment) {
   1552         value = 0;
   1553       } else {
   1554         return;
   1555       }
   1556       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1557         return;
   1558       }
   1559       value |= nreglist.GetTransferLane() << 1;
   1560       if (!nreglist.IsSingleSpaced()) return;
   1561       SetEncodingValue(value);
   1562       break;
   1563     }
   1564     case Untyped16: {
   1565       uint32_t value;
   1566       if (align.GetType() == k64BitAlign) {
   1567         value = 1;
   1568       } else if (align.GetType() == kNoAlignment) {
   1569         value = 0;
   1570       } else {
   1571         return;
   1572       }
   1573       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1574         return;
   1575       }
   1576       value |= nreglist.GetTransferLane() << 2;
   1577       if (nreglist.IsDoubleSpaced()) value |= 2;
   1578       SetEncodingValue(value);
   1579       break;
   1580     }
   1581     case Untyped32: {
   1582       uint32_t value;
   1583       if (align.GetType() == k64BitAlign) {
   1584         value = 1;
   1585       } else if (align.GetType() == k128BitAlign) {
   1586         value = 2;
   1587       } else if (align.GetType() == kNoAlignment) {
   1588         value = 0;
   1589       } else {
   1590         return;
   1591       }
   1592       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1593         return;
   1594       }
   1595       value |= nreglist.GetTransferLane() << 3;
   1596       if (nreglist.IsDoubleSpaced()) value |= 4;
   1597       SetEncodingValue(value);
   1598       break;
   1599     }
   1600     default:
   1601       break;
   1602   }
   1603 }
   1604 
   1605 class Align_a_1 : public EncodingValue {
   1606  public:
   1607   Align_a_1(Alignment align, DataType dt);
   1608 };
   1609 
   1610 Align_a_1::Align_a_1(Alignment align, DataType dt) {
   1611   switch (align.GetType()) {
   1612     case k16BitAlign:
   1613       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
   1614       break;
   1615     case k32BitAlign:
   1616       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1617       break;
   1618     case kNoAlignment:
   1619       SetEncodingValue(0x0);
   1620       break;
   1621     default:
   1622       break;
   1623   }
   1624 }
   1625 
   1626 class Align_a_2 : public EncodingValue {
   1627  public:
   1628   Align_a_2(Alignment align, DataType dt);
   1629 };
   1630 
   1631 Align_a_2::Align_a_2(Alignment align, DataType dt) {
   1632   switch (align.GetType()) {
   1633     case k16BitAlign:
   1634       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
   1635       break;
   1636     case k32BitAlign:
   1637       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
   1638       break;
   1639     case k64BitAlign:
   1640       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1641       break;
   1642     case kNoAlignment:
   1643       SetEncodingValue(0x0);
   1644       break;
   1645     default:
   1646       break;
   1647   }
   1648 }
   1649 
   1650 class Align_a_3 : public EncodingValue {
   1651  public:
   1652   Align_a_3(Alignment align, DataType dt);
   1653 };
   1654 
   1655 Align_a_3::Align_a_3(Alignment align, DataType dt) {
   1656   switch (align.GetType()) {
   1657     case k32BitAlign:
   1658       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
   1659       break;
   1660     case k64BitAlign:
   1661       if (dt.Is(Untyped16))
   1662         SetEncodingValue(0x1);
   1663       else if (dt.Is(Untyped32))
   1664         SetEncodingValue(0x1);
   1665       break;
   1666     case k128BitAlign:
   1667       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1668       break;
   1669     case kNoAlignment:
   1670       SetEncodingValue(0x0);
   1671       break;
   1672     default:
   1673       break;
   1674   }
   1675 }
   1676 
   1677 class Align_align_1 : public EncodingValue {
   1678  public:
   1679   Align_align_1(Alignment align, const NeonRegisterList& nreglist);
   1680 };
   1681 
   1682 Align_align_1::Align_align_1(Alignment align,
   1683                              const NeonRegisterList& nreglist) {
   1684   switch (align.GetType()) {
   1685     case k64BitAlign:
   1686       SetEncodingValue(0x1);
   1687       break;
   1688     case k128BitAlign:
   1689       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1690         SetEncodingValue(0x2);
   1691       break;
   1692     case k256BitAlign:
   1693       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1694         SetEncodingValue(0x3);
   1695       break;
   1696     case kNoAlignment:
   1697       SetEncodingValue(0x0);
   1698       break;
   1699     default:
   1700       break;
   1701   }
   1702 }
   1703 
   1704 class Align_align_2 : public EncodingValue {
   1705  public:
   1706   Align_align_2(Alignment align, const NeonRegisterList& nreglist);
   1707 };
   1708 
   1709 Align_align_2::Align_align_2(Alignment align,
   1710                              const NeonRegisterList& nreglist) {
   1711   switch (align.GetType()) {
   1712     case k64BitAlign:
   1713       SetEncodingValue(0x1);
   1714       break;
   1715     case k128BitAlign:
   1716       SetEncodingValue(0x2);
   1717       break;
   1718     case k256BitAlign:
   1719       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
   1720       break;
   1721     case kNoAlignment:
   1722       SetEncodingValue(0x0);
   1723       break;
   1724     default:
   1725       break;
   1726   }
   1727 }
   1728 
   1729 class Align_align_3 : public EncodingValue {
   1730  public:
   1731   explicit Align_align_3(Alignment align);
   1732 };
   1733 
   1734 Align_align_3::Align_align_3(Alignment align) {
   1735   switch (align.GetType()) {
   1736     case k64BitAlign:
   1737       SetEncodingValue(0x1);
   1738       break;
   1739     case kNoAlignment:
   1740       SetEncodingValue(0x0);
   1741       break;
   1742     default:
   1743       break;
   1744   }
   1745 }
   1746 
   1747 class Align_align_4 : public EncodingValue {
   1748  public:
   1749   explicit Align_align_4(Alignment align);
   1750 };
   1751 
   1752 Align_align_4::Align_align_4(Alignment align) {
   1753   switch (align.GetType()) {
   1754     case k64BitAlign:
   1755       SetEncodingValue(0x1);
   1756       break;
   1757     case k128BitAlign:
   1758       SetEncodingValue(0x2);
   1759       break;
   1760     case k256BitAlign:
   1761       SetEncodingValue(0x3);
   1762       break;
   1763     case kNoAlignment:
   1764       SetEncodingValue(0x0);
   1765       break;
   1766     default:
   1767       break;
   1768   }
   1769 }
   1770 
   1771 class Align_align_5 : public EncodingValue {
   1772  public:
   1773   Align_align_5(Alignment align, const NeonRegisterList& nreglist);
   1774 };
   1775 
   1776 Align_align_5::Align_align_5(Alignment align,
   1777                              const NeonRegisterList& nreglist) {
   1778   switch (align.GetType()) {
   1779     case k64BitAlign:
   1780       SetEncodingValue(0x1);
   1781       break;
   1782     case k128BitAlign:
   1783       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1784         SetEncodingValue(0x2);
   1785       break;
   1786     case k256BitAlign:
   1787       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
   1788       break;
   1789     case kNoAlignment:
   1790       SetEncodingValue(0x0);
   1791       break;
   1792     default:
   1793       break;
   1794   }
   1795 }
   1796 
   1797 
   1798 void Assembler::adc(Condition cond,
   1799                     EncodingSize size,
   1800                     Register rd,
   1801                     Register rn,
   1802                     const Operand& operand) {
   1803   VIXL_ASSERT(AllowAssembler());
   1804   CheckIT(cond);
   1805   if (operand.IsImmediate()) {
   1806     uint32_t imm = operand.GetImmediate();
   1807     if (IsUsingT32()) {
   1808       ImmediateT32 immediate_t32(imm);
   1809       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   1810       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   1811           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   1812         EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   1813                    (immediate_t32.GetEncodingValue() & 0xff) |
   1814                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   1815                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   1816         AdvanceIT();
   1817         return;
   1818       }
   1819     } else {
   1820       ImmediateA32 immediate_a32(imm);
   1821       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   1822       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   1823         EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
   1824                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   1825                 immediate_a32.GetEncodingValue());
   1826         return;
   1827       }
   1828     }
   1829   }
   1830   if (operand.IsImmediateShiftedRegister()) {
   1831     Register rm = operand.GetBaseRegister();
   1832     if (operand.IsPlainRegister()) {
   1833       if (IsUsingT32()) {
   1834         // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   1835         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   1836             rm.IsLow()) {
   1837           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
   1838           AdvanceIT();
   1839           return;
   1840         }
   1841       }
   1842     }
   1843     Shift shift = operand.GetShift();
   1844     uint32_t amount = operand.GetShiftAmount();
   1845     if (IsUsingT32()) {
   1846       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   1847       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   1848           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   1849         uint32_t amount_ = amount % 32;
   1850         EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   1851                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   1852                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   1853         AdvanceIT();
   1854         return;
   1855       }
   1856     } else {
   1857       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   1858       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   1859         uint32_t amount_ = amount % 32;
   1860         EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
   1861                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   1862                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   1863         return;
   1864       }
   1865     }
   1866   }
   1867   if (operand.IsRegisterShiftedRegister()) {
   1868     Register rm = operand.GetBaseRegister();
   1869     Shift shift = operand.GetShift();
   1870     if (IsUsingA32()) {
   1871       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   1872       if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
   1873                                  !operand.GetShiftRegister().IsPC()) ||
   1874                                 AllowUnpredictable())) {
   1875         EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
   1876                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   1877                 (shift.GetType() << 5) |
   1878                 (operand.GetShiftRegister().GetCode() << 8));
   1879         return;
   1880       }
   1881     }
   1882   }
   1883   Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
   1884 }
   1885 
   1886 void Assembler::adcs(Condition cond,
   1887                      EncodingSize size,
   1888                      Register rd,
   1889                      Register rn,
   1890                      const Operand& operand) {
   1891   VIXL_ASSERT(AllowAssembler());
   1892   CheckIT(cond);
   1893   if (operand.IsImmediate()) {
   1894     uint32_t imm = operand.GetImmediate();
   1895     if (IsUsingT32()) {
   1896       ImmediateT32 immediate_t32(imm);
   1897       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   1898       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   1899           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   1900         EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   1901                    (immediate_t32.GetEncodingValue() & 0xff) |
   1902                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   1903                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   1904         AdvanceIT();
   1905         return;
   1906       }
   1907     } else {
   1908       ImmediateA32 immediate_a32(imm);
   1909       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   1910       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   1911         EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
   1912                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   1913                 immediate_a32.GetEncodingValue());
   1914         return;
   1915       }
   1916     }
   1917   }
   1918   if (operand.IsImmediateShiftedRegister()) {
   1919     Register rm = operand.GetBaseRegister();
   1920     if (operand.IsPlainRegister()) {
   1921       if (IsUsingT32()) {
   1922         // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   1923         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   1924             rm.IsLow()) {
   1925           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
   1926           AdvanceIT();
   1927           return;
   1928         }
   1929       }
   1930     }
   1931     Shift shift = operand.GetShift();
   1932     uint32_t amount = operand.GetShiftAmount();
   1933     if (IsUsingT32()) {
   1934       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   1935       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   1936           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   1937         uint32_t amount_ = amount % 32;
   1938         EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   1939                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   1940                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   1941         AdvanceIT();
   1942         return;
   1943       }
   1944     } else {
   1945       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   1946       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   1947         uint32_t amount_ = amount % 32;
   1948         EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
   1949                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   1950                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   1951         return;
   1952       }
   1953     }
   1954   }
   1955   if (operand.IsRegisterShiftedRegister()) {
   1956     Register rm = operand.GetBaseRegister();
   1957     Shift shift = operand.GetShift();
   1958     if (IsUsingA32()) {
   1959       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   1960       if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
   1961                                  !operand.GetShiftRegister().IsPC()) ||
   1962                                 AllowUnpredictable())) {
   1963         EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
   1964                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   1965                 (shift.GetType() << 5) |
   1966                 (operand.GetShiftRegister().GetCode() << 8));
   1967         return;
   1968       }
   1969     }
   1970   }
   1971   Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
   1972 }
   1973 
   1974 void Assembler::add(Condition cond,
   1975                     EncodingSize size,
   1976                     Register rd,
   1977                     Register rn,
   1978                     const Operand& operand) {
   1979   VIXL_ASSERT(AllowAssembler());
   1980   CheckIT(cond);
   1981   if (operand.IsImmediate()) {
   1982     uint32_t imm = operand.GetImmediate();
   1983     if (IsUsingT32()) {
   1984       ImmediateT32 immediate_t32(imm);
   1985       // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
   1986       if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
   1987           ((imm % 4) == 0)) {
   1988         uint32_t imm_ = imm >> 2;
   1989         EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
   1990         AdvanceIT();
   1991         return;
   1992       }
   1993       // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
   1994       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   1995           (imm <= 7)) {
   1996         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   1997         AdvanceIT();
   1998         return;
   1999       }
   2000       // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   2001       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2002           (imm <= 255)) {
   2003         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2004         AdvanceIT();
   2005         return;
   2006       }
   2007       // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
   2008       if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
   2009           ((imm % 4) == 0)) {
   2010         uint32_t imm_ = imm >> 2;
   2011         EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
   2012         AdvanceIT();
   2013         return;
   2014       }
   2015       // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
   2016       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
   2017           ((imm % 4) == 0)) {
   2018         uint32_t imm_ = imm >> 2;
   2019         EmitT32_16(0xb000 | imm_);
   2020         AdvanceIT();
   2021         return;
   2022       }
   2023       // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
   2024       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
   2025           (!rd.IsPC() || AllowUnpredictable())) {
   2026         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2027                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2028         AdvanceIT();
   2029         return;
   2030       }
   2031       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   2032       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   2033           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   2034         EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2035                    (immediate_t32.GetEncodingValue() & 0xff) |
   2036                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2037                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2038         AdvanceIT();
   2039         return;
   2040       }
   2041       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   2042       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
   2043           (!rd.IsPC() || AllowUnpredictable())) {
   2044         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2045                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2046         AdvanceIT();
   2047         return;
   2048       }
   2049       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
   2050       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   2051           (!rd.IsPC() || AllowUnpredictable())) {
   2052         EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
   2053                    (immediate_t32.GetEncodingValue() & 0xff) |
   2054                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2055                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2056         AdvanceIT();
   2057         return;
   2058       }
   2059       // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
   2060       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
   2061           (!rd.IsPC() || AllowUnpredictable())) {
   2062         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2063                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2064         AdvanceIT();
   2065         return;
   2066       }
   2067     } else {
   2068       ImmediateA32 immediate_a32(imm);
   2069       // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
   2070       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2071         EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
   2072                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2073         return;
   2074       }
   2075       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2076       if (immediate_a32.IsValid() && cond.IsNotNever() &&
   2077           ((rn.GetCode() & 0xd) != 0xd)) {
   2078         EmitA32(0x02800000U | (cond.GetCondition() << 28) |
   2079                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2080                 immediate_a32.GetEncodingValue());
   2081         return;
   2082       }
   2083       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   2084       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2085         EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
   2086                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2087         return;
   2088       }
   2089     }
   2090   }
   2091   if (operand.IsImmediateShiftedRegister()) {
   2092     Register rm = operand.GetBaseRegister();
   2093     if (operand.IsPlainRegister()) {
   2094       if (IsUsingT32()) {
   2095         // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
   2096         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2097             rm.IsLow()) {
   2098           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
   2099                      (rm.GetCode() << 6));
   2100           AdvanceIT();
   2101           return;
   2102         }
   2103         // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
   2104         if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) &&
   2105             (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
   2106               (!rd.IsPC() || !rm.IsPC())) ||
   2107              AllowUnpredictable())) {
   2108           EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
   2109                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   2110           AdvanceIT();
   2111           return;
   2112         }
   2113         // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
   2114         if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) &&
   2115             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   2116              AllowUnpredictable())) {
   2117           EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
   2118                      ((rd.GetCode() & 0x8) << 4));
   2119           AdvanceIT();
   2120           return;
   2121         }
   2122         // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
   2123         if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
   2124           EmitT32_16(0x4485 | (rm.GetCode() << 3));
   2125           AdvanceIT();
   2126           return;
   2127         }
   2128       }
   2129     }
   2130     Shift shift = operand.GetShift();
   2131     uint32_t amount = operand.GetShiftAmount();
   2132     if (IsUsingT32()) {
   2133       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
   2134       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   2135           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2136         uint32_t amount_ = amount % 32;
   2137         EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2138                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2139                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2140         AdvanceIT();
   2141         return;
   2142       }
   2143       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
   2144       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   2145           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2146         uint32_t amount_ = amount % 32;
   2147         EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
   2148                    (operand.GetTypeEncodingValue() << 4) |
   2149                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2150         AdvanceIT();
   2151         return;
   2152       }
   2153     } else {
   2154       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2155       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   2156         uint32_t amount_ = amount % 32;
   2157         EmitA32(0x00800000U | (cond.GetCondition() << 28) |
   2158                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2159                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2160         return;
   2161       }
   2162       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   2163       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2164         uint32_t amount_ = amount % 32;
   2165         EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
   2166                 (rd.GetCode() << 12) | rm.GetCode() |
   2167                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2168         return;
   2169       }
   2170     }
   2171   }
   2172   if (operand.IsRegisterShiftedRegister()) {
   2173     Register rm = operand.GetBaseRegister();
   2174     Shift shift = operand.GetShift();
   2175     if (IsUsingA32()) {
   2176       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2177       if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
   2178                                  !operand.GetShiftRegister().IsPC()) ||
   2179                                 AllowUnpredictable())) {
   2180         EmitA32(0x00800010U | (cond.GetCondition() << 28) |
   2181                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2182                 (shift.GetType() << 5) |
   2183                 (operand.GetShiftRegister().GetCode() << 8));
   2184         return;
   2185       }
   2186     }
   2187   }
   2188   Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
   2189 }
   2190 
   2191 void Assembler::add(Condition cond, Register rd, const Operand& operand) {
   2192   VIXL_ASSERT(AllowAssembler());
   2193   CheckIT(cond);
   2194   if (operand.IsImmediate()) {
   2195     uint32_t imm = operand.GetImmediate();
   2196     if (IsUsingT32()) {
   2197       // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
   2198       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
   2199         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2200         AdvanceIT();
   2201         return;
   2202       }
   2203     }
   2204   }
   2205   if (operand.IsPlainRegister()) {
   2206     Register rm = operand.GetBaseRegister();
   2207     if (IsUsingT32()) {
   2208       // ADD<c>{<q>} <Rdn>, <Rm> ; T2
   2209       if (InITBlock() && !rm.Is(sp) &&
   2210           (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
   2211             (!rd.IsPC() || !rm.IsPC())) ||
   2212            AllowUnpredictable())) {
   2213         EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
   2214                    (rm.GetCode() << 3));
   2215         AdvanceIT();
   2216         return;
   2217       }
   2218     }
   2219   }
   2220   Delegate(kAdd, &Assembler::add, cond, rd, operand);
   2221 }
   2222 
   2223 void Assembler::adds(Condition cond,
   2224                      EncodingSize size,
   2225                      Register rd,
   2226                      Register rn,
   2227                      const Operand& operand) {
   2228   VIXL_ASSERT(AllowAssembler());
   2229   CheckIT(cond);
   2230   if (operand.IsImmediate()) {
   2231     uint32_t imm = operand.GetImmediate();
   2232     if (IsUsingT32()) {
   2233       ImmediateT32 immediate_t32(imm);
   2234       // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
   2235       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2236           (imm <= 7)) {
   2237         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   2238         AdvanceIT();
   2239         return;
   2240       }
   2241       // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   2242       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2243           (imm <= 255)) {
   2244         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2245         AdvanceIT();
   2246         return;
   2247       }
   2248       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   2249       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   2250           !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
   2251         EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2252                    (immediate_t32.GetEncodingValue() & 0xff) |
   2253                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2254                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2255         AdvanceIT();
   2256         return;
   2257       }
   2258       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
   2259       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   2260           !rd.Is(pc)) {
   2261         EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
   2262                    (immediate_t32.GetEncodingValue() & 0xff) |
   2263                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2264                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2265         AdvanceIT();
   2266         return;
   2267       }
   2268     } else {
   2269       ImmediateA32 immediate_a32(imm);
   2270       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2271       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
   2272         EmitA32(0x02900000U | (cond.GetCondition() << 28) |
   2273                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2274                 immediate_a32.GetEncodingValue());
   2275         return;
   2276       }
   2277       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   2278       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2279         EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
   2280                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2281         return;
   2282       }
   2283     }
   2284   }
   2285   if (operand.IsImmediateShiftedRegister()) {
   2286     Register rm = operand.GetBaseRegister();
   2287     if (operand.IsPlainRegister()) {
   2288       if (IsUsingT32()) {
   2289         // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   2290         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2291             rm.IsLow()) {
   2292           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
   2293                      (rm.GetCode() << 6));
   2294           AdvanceIT();
   2295           return;
   2296         }
   2297       }
   2298     }
   2299     Shift shift = operand.GetShift();
   2300     uint32_t amount = operand.GetShiftAmount();
   2301     if (IsUsingT32()) {
   2302       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
   2303       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   2304           !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2305         uint32_t amount_ = amount % 32;
   2306         EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2307                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2308                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2309         AdvanceIT();
   2310         return;
   2311       }
   2312       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
   2313       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   2314           !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
   2315         uint32_t amount_ = amount % 32;
   2316         EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
   2317                    (operand.GetTypeEncodingValue() << 4) |
   2318                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2319         AdvanceIT();
   2320         return;
   2321       }
   2322     } else {
   2323       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2324       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   2325         uint32_t amount_ = amount % 32;
   2326         EmitA32(0x00900000U | (cond.GetCondition() << 28) |
   2327                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2328                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2329         return;
   2330       }
   2331       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   2332       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2333         uint32_t amount_ = amount % 32;
   2334         EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
   2335                 (rd.GetCode() << 12) | rm.GetCode() |
   2336                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2337         return;
   2338       }
   2339     }
   2340   }
   2341   if (operand.IsRegisterShiftedRegister()) {
   2342     Register rm = operand.GetBaseRegister();
   2343     Shift shift = operand.GetShift();
   2344     if (IsUsingA32()) {
   2345       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2346       if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
   2347                                  !operand.GetShiftRegister().IsPC()) ||
   2348                                 AllowUnpredictable())) {
   2349         EmitA32(0x00900010U | (cond.GetCondition() << 28) |
   2350                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2351                 (shift.GetType() << 5) |
   2352                 (operand.GetShiftRegister().GetCode() << 8));
   2353         return;
   2354       }
   2355     }
   2356   }
   2357   Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
   2358 }
   2359 
   2360 void Assembler::adds(Register rd, const Operand& operand) {
   2361   VIXL_ASSERT(AllowAssembler());
   2362   CheckIT(al);
   2363   if (operand.IsImmediate()) {
   2364     uint32_t imm = operand.GetImmediate();
   2365     if (IsUsingT32()) {
   2366       // ADDS{<q>} <Rdn>, #<imm8> ; T2
   2367       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
   2368         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2369         AdvanceIT();
   2370         return;
   2371       }
   2372     }
   2373   }
   2374   Delegate(kAdds, &Assembler::adds, rd, operand);
   2375 }
   2376 
   2377 void Assembler::addw(Condition cond,
   2378                      Register rd,
   2379                      Register rn,
   2380                      const Operand& operand) {
   2381   VIXL_ASSERT(AllowAssembler());
   2382   CheckIT(cond);
   2383   if (operand.IsImmediate()) {
   2384     uint32_t imm = operand.GetImmediate();
   2385     if (IsUsingT32()) {
   2386       // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
   2387       if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2388         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2389                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2390         AdvanceIT();
   2391         return;
   2392       }
   2393       // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   2394       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
   2395           (!rd.IsPC() || AllowUnpredictable())) {
   2396         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2397                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2398         AdvanceIT();
   2399         return;
   2400       }
   2401       // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
   2402       if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2403         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2404                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2405         AdvanceIT();
   2406         return;
   2407       }
   2408     }
   2409   }
   2410   Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
   2411 }
   2412 
   2413 void Assembler::adr(Condition cond,
   2414                     EncodingSize size,
   2415                     Register rd,
   2416                     Label* label) {
   2417   VIXL_ASSERT(AllowAssembler());
   2418   CheckIT(cond);
   2419   Label::Offset offset =
   2420       label->IsBound()
   2421           ? label->GetLocation() -
   2422                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   2423           : 0;
   2424   if (IsUsingT32()) {
   2425     int32_t neg_offset = -offset;
   2426     // ADR{<c>}{<q>} <Rd>, <label> ; T1
   2427     if (!size.IsWide() && rd.IsLow() &&
   2428         ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
   2429           ((offset & 0x3) == 0)) ||
   2430          (!label->IsBound() && size.IsNarrow()))) {
   2431       static class EmitOp : public Label::LabelEmitOperator {
   2432        public:
   2433         EmitOp() : Label::LabelEmitOperator(0, 1020) {}
   2434         virtual uint32_t Encode(uint32_t instr,
   2435                                 Label::Offset pc,
   2436                                 const Label* label) const VIXL_OVERRIDE {
   2437           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   2438           VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
   2439                       ((offset & 0x3) == 0));
   2440           const int32_t target = offset >> 2;
   2441           return instr | (target & 0xff);
   2442         }
   2443       } immop;
   2444       EmitT32_16(Link(0xa000 | (rd.GetCode() << 8), label, immop));
   2445       AdvanceIT();
   2446       return;
   2447     }
   2448     // ADR{<c>}{<q>} <Rd>, <label> ; T2
   2449     if (!size.IsNarrow() && label->IsBound() && (neg_offset > 0) &&
   2450         (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2451       EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
   2452                  ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
   2453       AdvanceIT();
   2454       return;
   2455     }
   2456     // ADR{<c>}{<q>} <Rd>, <label> ; T3
   2457     if (!size.IsNarrow() &&
   2458         (!label->IsBound() || ((offset >= 0) && (offset <= 4095))) &&
   2459         (!rd.IsPC() || AllowUnpredictable())) {
   2460       static class EmitOp : public Label::LabelEmitOperator {
   2461        public:
   2462         EmitOp() : Label::LabelEmitOperator(0, 4095) {}
   2463         virtual uint32_t Encode(uint32_t instr,
   2464                                 Label::Offset pc,
   2465                                 const Label* label) const VIXL_OVERRIDE {
   2466           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   2467           int32_t target;
   2468           if ((offset >= 0) && (offset <= 4095) && !label->IsMinusZero()) {
   2469             target = offset;
   2470           } else {
   2471             target = -offset;
   2472             VIXL_ASSERT((target >= 0) && (target <= 4095));
   2473             // Emit the T2 encoding.
   2474             instr |= 0x00a00000;
   2475           }
   2476           return instr | (target & 0xff) | ((target & 0x700) << 4) |
   2477                  ((target & 0x800) << 15);
   2478         }
   2479       } immop;
   2480       EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8), label, immop));
   2481       AdvanceIT();
   2482       return;
   2483     }
   2484   } else {
   2485     ImmediateA32 positive_immediate_a32(offset);
   2486     ImmediateA32 negative_immediate_a32(-offset);
   2487     // ADR{<c>}{<q>} <Rd>, <label> ; A1
   2488     if ((!label->IsBound() || positive_immediate_a32.IsValid()) &&
   2489         cond.IsNotNever()) {
   2490       static class EmitOp : public Label::LabelEmitOperator {
   2491        public:
   2492         EmitOp() : Label::LabelEmitOperator(0, 255) {}
   2493         virtual uint32_t Encode(uint32_t instr,
   2494                                 Label::Offset pc,
   2495                                 const Label* label) const VIXL_OVERRIDE {
   2496           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   2497           int32_t target;
   2498           ImmediateA32 positive_immediate_a32(offset);
   2499           if (positive_immediate_a32.IsValid()) {
   2500             target = positive_immediate_a32.GetEncodingValue();
   2501           } else {
   2502             ImmediateA32 negative_immediate_a32(-offset);
   2503             VIXL_ASSERT(negative_immediate_a32.IsValid());
   2504             // Emit the A2 encoding.
   2505             target = negative_immediate_a32.GetEncodingValue();
   2506             instr = (instr & ~0x00f00000) | 0x00400000;
   2507           }
   2508           return instr | (target & 0xfff);
   2509         }
   2510       } immop;
   2511       EmitA32(
   2512           Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
   2513                label,
   2514                immop));
   2515       return;
   2516     }
   2517     // ADR{<c>}{<q>} <Rd>, <label> ; A2
   2518     if (label->IsBound() && negative_immediate_a32.IsValid() &&
   2519         cond.IsNotNever()) {
   2520       EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   2521               negative_immediate_a32.GetEncodingValue());
   2522       return;
   2523     }
   2524   }
   2525   Delegate(kAdr, &Assembler::adr, cond, size, rd, label);
   2526 }
   2527 
   2528 void Assembler::and_(Condition cond,
   2529                      EncodingSize size,
   2530                      Register rd,
   2531                      Register rn,
   2532                      const Operand& operand) {
   2533   VIXL_ASSERT(AllowAssembler());
   2534   CheckIT(cond);
   2535   if (operand.IsImmediate()) {
   2536     uint32_t imm = operand.GetImmediate();
   2537     if (IsUsingT32()) {
   2538       ImmediateT32 immediate_t32(imm);
   2539       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   2540       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   2541         EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2542                    (immediate_t32.GetEncodingValue() & 0xff) |
   2543                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2544                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2545         AdvanceIT();
   2546         return;
   2547       }
   2548     } else {
   2549       ImmediateA32 immediate_a32(imm);
   2550       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2551       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   2552         EmitA32(0x02000000U | (cond.GetCondition() << 28) |
   2553                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2554                 immediate_a32.GetEncodingValue());
   2555         return;
   2556       }
   2557     }
   2558   }
   2559   if (operand.IsImmediateShiftedRegister()) {
   2560     Register rm = operand.GetBaseRegister();
   2561     if (operand.IsPlainRegister()) {
   2562       if (IsUsingT32()) {
   2563         // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   2564         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2565             rm.IsLow()) {
   2566           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
   2567           AdvanceIT();
   2568           return;
   2569         }
   2570       }
   2571     }
   2572     Shift shift = operand.GetShift();
   2573     uint32_t amount = operand.GetShiftAmount();
   2574     if (IsUsingT32()) {
   2575       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   2576       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   2577         uint32_t amount_ = amount % 32;
   2578         EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2579                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2580                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2581         AdvanceIT();
   2582         return;
   2583       }
   2584     } else {
   2585       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2586       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2587         uint32_t amount_ = amount % 32;
   2588         EmitA32(0x00000000U | (cond.GetCondition() << 28) |
   2589                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2590                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2591         return;
   2592       }
   2593     }
   2594   }
   2595   if (operand.IsRegisterShiftedRegister()) {
   2596     Register rm = operand.GetBaseRegister();
   2597     Shift shift = operand.GetShift();
   2598     if (IsUsingA32()) {
   2599       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2600       if (cond.IsNotNever()) {
   2601         EmitA32(0x00000010U | (cond.GetCondition() << 28) |
   2602                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2603                 (shift.GetType() << 5) |
   2604                 (operand.GetShiftRegister().GetCode() << 8));
   2605         return;
   2606       }
   2607     }
   2608   }
   2609   Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
   2610 }
   2611 
   2612 void Assembler::ands(Condition cond,
   2613                      EncodingSize size,
   2614                      Register rd,
   2615                      Register rn,
   2616                      const Operand& operand) {
   2617   VIXL_ASSERT(AllowAssembler());
   2618   CheckIT(cond);
   2619   if (operand.IsImmediate()) {
   2620     uint32_t imm = operand.GetImmediate();
   2621     if (IsUsingT32()) {
   2622       ImmediateT32 immediate_t32(imm);
   2623       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   2624       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
   2625         EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2626                    (immediate_t32.GetEncodingValue() & 0xff) |
   2627                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2628                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2629         AdvanceIT();
   2630         return;
   2631       }
   2632     } else {
   2633       ImmediateA32 immediate_a32(imm);
   2634       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2635       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   2636         EmitA32(0x02100000U | (cond.GetCondition() << 28) |
   2637                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2638                 immediate_a32.GetEncodingValue());
   2639         return;
   2640       }
   2641     }
   2642   }
   2643   if (operand.IsImmediateShiftedRegister()) {
   2644     Register rm = operand.GetBaseRegister();
   2645     if (operand.IsPlainRegister()) {
   2646       if (IsUsingT32()) {
   2647         // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   2648         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2649             rm.IsLow()) {
   2650           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
   2651           AdvanceIT();
   2652           return;
   2653         }
   2654       }
   2655     }
   2656     Shift shift = operand.GetShift();
   2657     uint32_t amount = operand.GetShiftAmount();
   2658     if (IsUsingT32()) {
   2659       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   2660       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
   2661         uint32_t amount_ = amount % 32;
   2662         EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2663                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2664                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2665         AdvanceIT();
   2666         return;
   2667       }
   2668     } else {
   2669       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2670       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2671         uint32_t amount_ = amount % 32;
   2672         EmitA32(0x00100000U | (cond.GetCondition() << 28) |
   2673                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2674                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2675         return;
   2676       }
   2677     }
   2678   }
   2679   if (operand.IsRegisterShiftedRegister()) {
   2680     Register rm = operand.GetBaseRegister();
   2681     Shift shift = operand.GetShift();
   2682     if (IsUsingA32()) {
   2683       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2684       if (cond.IsNotNever()) {
   2685         EmitA32(0x00100010U | (cond.GetCondition() << 28) |
   2686                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2687                 (shift.GetType() << 5) |
   2688                 (operand.GetShiftRegister().GetCode() << 8));
   2689         return;
   2690       }
   2691     }
   2692   }
   2693   Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
   2694 }
   2695 
   2696 void Assembler::asr(Condition cond,
   2697                     EncodingSize size,
   2698                     Register rd,
   2699                     Register rm,
   2700                     const Operand& operand) {
   2701   VIXL_ASSERT(AllowAssembler());
   2702   CheckIT(cond);
   2703   if (operand.IsImmediate()) {
   2704     uint32_t imm = operand.GetImmediate();
   2705     if (IsUsingT32()) {
   2706       // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   2707       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   2708           (imm >= 1) && (imm <= 32)) {
   2709         uint32_t amount_ = imm % 32;
   2710         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
   2711                    (amount_ << 6));
   2712         AdvanceIT();
   2713         return;
   2714       }
   2715       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   2716       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
   2717         uint32_t amount_ = imm % 32;
   2718         EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
   2719                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2720         AdvanceIT();
   2721         return;
   2722       }
   2723     } else {
   2724       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   2725       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   2726         uint32_t amount_ = imm % 32;
   2727         EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
   2728                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   2729         return;
   2730       }
   2731     }
   2732   }
   2733   if (operand.IsPlainRegister()) {
   2734     Register rs = operand.GetBaseRegister();
   2735     if (IsUsingT32()) {
   2736       // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   2737       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   2738           rs.IsLow()) {
   2739         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   2740         AdvanceIT();
   2741         return;
   2742       }
   2743       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   2744       if (!size.IsNarrow()) {
   2745         EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   2746                    rs.GetCode());
   2747         AdvanceIT();
   2748         return;
   2749       }
   2750     } else {
   2751       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   2752       if (cond.IsNotNever()) {
   2753         EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
   2754                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   2755         return;
   2756       }
   2757     }
   2758   }
   2759   Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
   2760 }
   2761 
   2762 void Assembler::asrs(Condition cond,
   2763                      EncodingSize size,
   2764                      Register rd,
   2765                      Register rm,
   2766                      const Operand& operand) {
   2767   VIXL_ASSERT(AllowAssembler());
   2768   CheckIT(cond);
   2769   if (operand.IsImmediate()) {
   2770     uint32_t imm = operand.GetImmediate();
   2771     if (IsUsingT32()) {
   2772       // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   2773       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   2774           (imm >= 1) && (imm <= 32)) {
   2775         uint32_t amount_ = imm % 32;
   2776         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
   2777                    (amount_ << 6));
   2778         AdvanceIT();
   2779         return;
   2780       }
   2781       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   2782       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
   2783         uint32_t amount_ = imm % 32;
   2784         EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
   2785                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2786         AdvanceIT();
   2787         return;
   2788       }
   2789     } else {
   2790       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   2791       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   2792         uint32_t amount_ = imm % 32;
   2793         EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
   2794                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   2795         return;
   2796       }
   2797     }
   2798   }
   2799   if (operand.IsPlainRegister()) {
   2800     Register rs = operand.GetBaseRegister();
   2801     if (IsUsingT32()) {
   2802       // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   2803       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   2804           rs.IsLow()) {
   2805         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   2806         AdvanceIT();
   2807         return;
   2808       }
   2809       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   2810       if (!size.IsNarrow()) {
   2811         EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   2812                    rs.GetCode());
   2813         AdvanceIT();
   2814         return;
   2815       }
   2816     } else {
   2817       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   2818       if (cond.IsNotNever()) {
   2819         EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
   2820                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   2821         return;
   2822       }
   2823     }
   2824   }
   2825   Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
   2826 }
   2827 
   2828 void Assembler::b(Condition cond, EncodingSize size, Label* label) {
   2829   VIXL_ASSERT(AllowAssembler());
   2830   Label::Offset offset =
   2831       label->IsBound()
   2832           ? label->GetLocation() -
   2833                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   2834           : 0;
   2835   if (IsUsingT32()) {
   2836     // B<c>{<q>} <label> ; T1
   2837     if (OutsideITBlock() && !size.IsWide() &&
   2838         ((label->IsBound() && (offset >= -256) && (offset <= 254) &&
   2839           ((offset & 0x1) == 0)) ||
   2840          (!label->IsBound() && size.IsNarrow())) &&
   2841         !cond.Is(al) && cond.IsNotNever()) {
   2842       static class EmitOp : public Label::LabelEmitOperator {
   2843        public:
   2844         EmitOp() : Label::LabelEmitOperator(-256, 254) {}
   2845         virtual uint32_t Encode(uint32_t instr,
   2846                                 Label::Offset pc,
   2847                                 const Label* label) const VIXL_OVERRIDE {
   2848           Label::Offset offset = label->GetLocation() - pc;
   2849           VIXL_ASSERT((offset >= -256) && (offset <= 254) &&
   2850                       ((offset & 0x1) == 0));
   2851           const int32_t target = offset >> 1;
   2852           return instr | (target & 0xff);
   2853         }
   2854       } immop;
   2855       EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8), label, immop));
   2856       AdvanceIT();
   2857       return;
   2858     }
   2859     // B{<c>}{<q>} <label> ; T2
   2860     if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
   2861         ((label->IsBound() && (offset >= -2048) && (offset <= 2046) &&
   2862           ((offset & 0x1) == 0)) ||
   2863          (!label->IsBound() && size.IsNarrow()))) {
   2864       CheckIT(cond);
   2865       static class EmitOp : public Label::LabelEmitOperator {
   2866        public:
   2867         EmitOp() : Label::LabelEmitOperator(-2048, 2046) {}
   2868         virtual uint32_t Encode(uint32_t instr,
   2869                                 Label::Offset pc,
   2870                                 const Label* label) const VIXL_OVERRIDE {
   2871           Label::Offset offset = label->GetLocation() - pc;
   2872           VIXL_ASSERT((offset >= -2048) && (offset <= 2046) &&
   2873                       ((offset & 0x1) == 0));
   2874           const int32_t target = offset >> 1;
   2875           return instr | (target & 0x7ff);
   2876         }
   2877       } immop;
   2878       EmitT32_16(Link(0xe000, label, immop));
   2879       AdvanceIT();
   2880       return;
   2881     }
   2882     // B<c>{<q>} <label> ; T3
   2883     if (OutsideITBlock() && !size.IsNarrow() &&
   2884         ((label->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
   2885           ((offset & 0x1) == 0)) ||
   2886          !label->IsBound()) &&
   2887         !cond.Is(al) && cond.IsNotNever()) {
   2888       static class EmitOp : public Label::LabelEmitOperator {
   2889        public:
   2890         EmitOp() : Label::LabelEmitOperator(-1048576, 1048574) {}
   2891         virtual uint32_t Encode(uint32_t instr,
   2892                                 Label::Offset pc,
   2893                                 const Label* label) const VIXL_OVERRIDE {
   2894           Label::Offset offset = label->GetLocation() - pc;
   2895           VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) &&
   2896                       ((offset & 0x1) == 0));
   2897           const int32_t target = offset >> 1;
   2898           return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
   2899                  ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
   2900                  ((target & 0x80000) << 7);
   2901         }
   2902       } immop;
   2903       EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22), label, immop));
   2904       AdvanceIT();
   2905       return;
   2906     }
   2907     // B{<c>}{<q>} <label> ; T4
   2908     if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
   2909         ((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
   2910           ((offset & 0x1) == 0)) ||
   2911          !label->IsBound())) {
   2912       CheckIT(cond);
   2913       static class EmitOp : public Label::LabelEmitOperator {
   2914        public:
   2915         EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
   2916         virtual uint32_t Encode(uint32_t instr,
   2917                                 Label::Offset pc,
   2918                                 const Label* label) const VIXL_OVERRIDE {
   2919           Label::Offset offset = label->GetLocation() - pc;
   2920           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
   2921                       ((offset & 0x1) == 0));
   2922           int32_t target = offset >> 1;
   2923           uint32_t S = target & (1 << 23);
   2924           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
   2925           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
   2926                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
   2927                  ((target & 0x800000) << 3);
   2928         }
   2929       } immop;
   2930       EmitT32_32(Link(0xf0009000U, label, immop));
   2931       AdvanceIT();
   2932       return;
   2933     }
   2934   } else {
   2935     // B{<c>}{<q>} <label> ; A1
   2936     if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
   2937           ((offset & 0x3) == 0)) ||
   2938          !label->IsBound()) &&
   2939         cond.IsNotNever()) {
   2940       static class EmitOp : public Label::LabelEmitOperator {
   2941        public:
   2942         EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
   2943         virtual uint32_t Encode(uint32_t instr,
   2944                                 Label::Offset pc,
   2945                                 const Label* label) const VIXL_OVERRIDE {
   2946           Label::Offset offset = label->GetLocation() - pc;
   2947           VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
   2948                       ((offset & 0x3) == 0));
   2949           const int32_t target = offset >> 2;
   2950           return instr | (target & 0xffffff);
   2951         }
   2952       } immop;
   2953       EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28), label, immop));
   2954       return;
   2955     }
   2956   }
   2957   Delegate(kB, &Assembler::b, cond, size, label);
   2958 }
   2959 
   2960 void Assembler::bfc(Condition cond,
   2961                     Register rd,
   2962                     uint32_t lsb,
   2963                     const Operand& operand) {
   2964   VIXL_ASSERT(AllowAssembler());
   2965   CheckIT(cond);
   2966   if (operand.IsImmediate()) {
   2967     uint32_t width = operand.GetImmediate();
   2968     if (IsUsingT32()) {
   2969       // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
   2970       if ((lsb <= 31) &&
   2971           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
   2972         uint32_t msb = lsb + width - 1;
   2973         EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
   2974                    ((lsb & 0x1c) << 10) | msb);
   2975         AdvanceIT();
   2976         return;
   2977       }
   2978     } else {
   2979       // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
   2980       if ((lsb <= 31) && cond.IsNotNever() &&
   2981           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
   2982         uint32_t msb = lsb + width - 1;
   2983         EmitA32(0x07c0001fU | (cond.GetCondition() << 28) |
   2984                 (rd.GetCode() << 12) | (lsb << 7) | (msb << 16));
   2985         return;
   2986       }
   2987     }
   2988   }
   2989   Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, operand);
   2990 }
   2991 
   2992 void Assembler::bfi(Condition cond,
   2993                     Register rd,
   2994                     Register rn,
   2995                     uint32_t lsb,
   2996                     const Operand& operand) {
   2997   VIXL_ASSERT(AllowAssembler());
   2998   CheckIT(cond);
   2999   if (operand.IsImmediate()) {
   3000     uint32_t width = operand.GetImmediate();
   3001     if (IsUsingT32()) {
   3002       // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
   3003       if ((lsb <= 31) && !rn.Is(pc) &&
   3004           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
   3005         uint32_t msb = lsb + width - 1;
   3006         EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3007                    ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
   3008         AdvanceIT();
   3009         return;
   3010       }
   3011     } else {
   3012       // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
   3013       if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
   3014           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
   3015         uint32_t msb = lsb + width - 1;
   3016         EmitA32(0x07c00010U | (cond.GetCondition() << 28) |
   3017                 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) | (msb << 16));
   3018         return;
   3019       }
   3020     }
   3021   }
   3022   Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, operand);
   3023 }
   3024 
   3025 void Assembler::bic(Condition cond,
   3026                     EncodingSize size,
   3027                     Register rd,
   3028                     Register rn,
   3029                     const Operand& operand) {
   3030   VIXL_ASSERT(AllowAssembler());
   3031   CheckIT(cond);
   3032   if (operand.IsImmediate()) {
   3033     uint32_t imm = operand.GetImmediate();
   3034     if (IsUsingT32()) {
   3035       ImmediateT32 immediate_t32(imm);
   3036       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   3037       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   3038         EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3039                    (immediate_t32.GetEncodingValue() & 0xff) |
   3040                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3041                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3042         AdvanceIT();
   3043         return;
   3044       }
   3045     } else {
   3046       ImmediateA32 immediate_a32(imm);
   3047       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   3048       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3049         EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
   3050                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   3051                 immediate_a32.GetEncodingValue());
   3052         return;
   3053       }
   3054     }
   3055   }
   3056   if (operand.IsImmediateShiftedRegister()) {
   3057     Register rm = operand.GetBaseRegister();
   3058     if (operand.IsPlainRegister()) {
   3059       if (IsUsingT32()) {
   3060         // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   3061         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   3062             rm.IsLow()) {
   3063           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
   3064           AdvanceIT();
   3065           return;
   3066         }
   3067       }
   3068     }
   3069     Shift shift = operand.GetShift();
   3070     uint32_t amount = operand.GetShiftAmount();
   3071     if (IsUsingT32()) {
   3072       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3073       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   3074         uint32_t amount_ = amount % 32;
   3075         EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3076                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   3077                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3078         AdvanceIT();
   3079         return;
   3080       }
   3081     } else {
   3082       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3083       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3084         uint32_t amount_ = amount % 32;
   3085         EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
   3086                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3087                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3088         return;
   3089       }
   3090     }
   3091   }
   3092   if (operand.IsRegisterShiftedRegister()) {
   3093     Register rm = operand.GetBaseRegister();
   3094     Shift shift = operand.GetShift();
   3095     if (IsUsingA32()) {
   3096       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   3097       if (cond.IsNotNever()) {
   3098         EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
   3099                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3100                 (shift.GetType() << 5) |
   3101                 (operand.GetShiftRegister().GetCode() << 8));
   3102         return;
   3103       }
   3104     }
   3105   }
   3106   Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
   3107 }
   3108 
   3109 void Assembler::bics(Condition cond,
   3110                      EncodingSize size,
   3111                      Register rd,
   3112                      Register rn,
   3113                      const Operand& operand) {
   3114   VIXL_ASSERT(AllowAssembler());
   3115   CheckIT(cond);
   3116   if (operand.IsImmediate()) {
   3117     uint32_t imm = operand.GetImmediate();
   3118     if (IsUsingT32()) {
   3119       ImmediateT32 immediate_t32(imm);
   3120       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   3121       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   3122         EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3123                    (immediate_t32.GetEncodingValue() & 0xff) |
   3124                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3125                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3126         AdvanceIT();
   3127         return;
   3128       }
   3129     } else {
   3130       ImmediateA32 immediate_a32(imm);
   3131       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   3132       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3133         EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
   3134                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   3135                 immediate_a32.GetEncodingValue());
   3136         return;
   3137       }
   3138     }
   3139   }
   3140   if (operand.IsImmediateShiftedRegister()) {
   3141     Register rm = operand.GetBaseRegister();
   3142     if (operand.IsPlainRegister()) {
   3143       if (IsUsingT32()) {
   3144         // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   3145         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   3146             rm.IsLow()) {
   3147           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
   3148           AdvanceIT();
   3149           return;
   3150         }
   3151       }
   3152     }
   3153     Shift shift = operand.GetShift();
   3154     uint32_t amount = operand.GetShiftAmount();
   3155     if (IsUsingT32()) {
   3156       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3157       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   3158         uint32_t amount_ = amount % 32;
   3159         EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3160                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   3161                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3162         AdvanceIT();
   3163         return;
   3164       }
   3165     } else {
   3166       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3167       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3168         uint32_t amount_ = amount % 32;
   3169         EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
   3170                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3171                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3172         return;
   3173       }
   3174     }
   3175   }
   3176   if (operand.IsRegisterShiftedRegister()) {
   3177     Register rm = operand.GetBaseRegister();
   3178     Shift shift = operand.GetShift();
   3179     if (IsUsingA32()) {
   3180       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   3181       if (cond.IsNotNever()) {
   3182         EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
   3183                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3184                 (shift.GetType() << 5) |
   3185                 (operand.GetShiftRegister().GetCode() << 8));
   3186         return;
   3187       }
   3188     }
   3189   }
   3190   Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
   3191 }
   3192 
   3193 void Assembler::bkpt(Condition cond, uint32_t imm) {
   3194   VIXL_ASSERT(AllowAssembler());
   3195   CheckIT(cond);
   3196   if (IsUsingT32()) {
   3197     // BKPT{<q>} {#}<imm> ; T1
   3198     if ((imm <= 255)) {
   3199       EmitT32_16(0xbe00 | imm);
   3200       AdvanceIT();
   3201       return;
   3202     }
   3203   } else {
   3204     // BKPT{<q>} {#}<imm> ; A1
   3205     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   3206       EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   3207               ((imm & 0xfff0) << 4));
   3208       return;
   3209     }
   3210   }
   3211   Delegate(kBkpt, &Assembler::bkpt, cond, imm);
   3212 }
   3213 
   3214 void Assembler::bl(Condition cond, Label* label) {
   3215   VIXL_ASSERT(AllowAssembler());
   3216   CheckIT(cond);
   3217   Label::Offset offset =
   3218       label->IsBound()
   3219           ? label->GetLocation() -
   3220                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3221           : 0;
   3222   if (IsUsingT32()) {
   3223     // BL{<c>}{<q>} <label> ; T1
   3224     if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
   3225           ((offset & 0x1) == 0)) ||
   3226          !label->IsBound())) {
   3227       static class EmitOp : public Label::LabelEmitOperator {
   3228        public:
   3229         EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
   3230         virtual uint32_t Encode(uint32_t instr,
   3231                                 Label::Offset pc,
   3232                                 const Label* label) const VIXL_OVERRIDE {
   3233           Label::Offset offset = label->GetLocation() - pc;
   3234           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
   3235                       ((offset & 0x1) == 0));
   3236           int32_t target = offset >> 1;
   3237           uint32_t S = target & (1 << 23);
   3238           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
   3239           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
   3240                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
   3241                  ((target & 0x800000) << 3);
   3242         }
   3243       } immop;
   3244       EmitT32_32(Link(0xf000d000U, label, immop));
   3245       AdvanceIT();
   3246       return;
   3247     }
   3248   } else {
   3249     // BL{<c>}{<q>} <label> ; A1
   3250     if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
   3251           ((offset & 0x3) == 0)) ||
   3252          !label->IsBound()) &&
   3253         cond.IsNotNever()) {
   3254       static class EmitOp : public Label::LabelEmitOperator {
   3255        public:
   3256         EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
   3257         virtual uint32_t Encode(uint32_t instr,
   3258                                 Label::Offset pc,
   3259                                 const Label* label) const VIXL_OVERRIDE {
   3260           Label::Offset offset = label->GetLocation() - pc;
   3261           VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
   3262                       ((offset & 0x3) == 0));
   3263           const int32_t target = offset >> 2;
   3264           return instr | (target & 0xffffff);
   3265         }
   3266       } immop;
   3267       EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28), label, immop));
   3268       return;
   3269     }
   3270   }
   3271   Delegate(kBl, &Assembler::bl, cond, label);
   3272 }
   3273 
   3274 void Assembler::blx(Condition cond, Label* label) {
   3275   VIXL_ASSERT(AllowAssembler());
   3276   CheckIT(cond);
   3277   Label::Offset offset =
   3278       label->IsBound()
   3279           ? label->GetLocation() -
   3280                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   3281           : 0;
   3282   if (IsUsingT32()) {
   3283     // BLX{<c>}{<q>} <label> ; T2
   3284     if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777212) &&
   3285           ((offset & 0x3) == 0)) ||
   3286          !label->IsBound())) {
   3287       static class EmitOp : public Label::LabelEmitOperator {
   3288        public:
   3289         EmitOp() : Label::LabelEmitOperator(-16777216, 16777212) {}
   3290         virtual uint32_t Encode(uint32_t instr,
   3291                                 Label::Offset pc,
   3292                                 const Label* label) const VIXL_OVERRIDE {
   3293           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   3294           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) &&
   3295                       ((offset & 0x3) == 0));
   3296           int32_t target = offset >> 2;
   3297           uint32_t S = target & (1 << 22);
   3298           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
   3299           return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
   3300                  ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
   3301                  ((target & 0x400000) << 4);
   3302         }
   3303       } immop;
   3304       EmitT32_32(Link(0xf000c000U, label, immop));
   3305       AdvanceIT();
   3306       return;
   3307     }
   3308   } else {
   3309     // BLX{<c>}{<q>} <label> ; A2
   3310     if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554430) &&
   3311           ((offset & 0x1) == 0)) ||
   3312          !label->IsBound())) {
   3313       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   3314         static class EmitOp : public Label::LabelEmitOperator {
   3315          public:
   3316           EmitOp() : Label::LabelEmitOperator(-33554432, 33554430) {}
   3317           virtual uint32_t Encode(uint32_t instr,
   3318                                   Label::Offset pc,
   3319                                   const Label* label) const VIXL_OVERRIDE {
   3320             Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   3321             VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) &&
   3322                         ((offset & 0x1) == 0));
   3323             const int32_t target = offset >> 1;
   3324             return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
   3325           }
   3326         } immop;
   3327         EmitA32(Link(0xfa000000U, label, immop));
   3328         return;
   3329       }
   3330     }
   3331   }
   3332   Delegate(kBlx, &Assembler::blx, cond, label);
   3333 }
   3334 
   3335 void Assembler::blx(Condition cond, Register rm) {
   3336   VIXL_ASSERT(AllowAssembler());
   3337   CheckIT(cond);
   3338   if (IsUsingT32()) {
   3339     // BLX{<c>}{<q>} <Rm> ; T1
   3340     EmitT32_16(0x4780 | (rm.GetCode() << 3));
   3341     AdvanceIT();
   3342     return;
   3343   } else {
   3344     // BLX{<c>}{<q>} <Rm> ; A1
   3345     if (cond.IsNotNever()) {
   3346       EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
   3347       return;
   3348     }
   3349   }
   3350   Delegate(kBlx, &Assembler::blx, cond, rm);
   3351 }
   3352 
   3353 void Assembler::bx(Condition cond, Register rm) {
   3354   VIXL_ASSERT(AllowAssembler());
   3355   CheckIT(cond);
   3356   if (IsUsingT32()) {
   3357     // BX{<c>}{<q>} <Rm> ; T1
   3358     EmitT32_16(0x4700 | (rm.GetCode() << 3));
   3359     AdvanceIT();
   3360     return;
   3361   } else {
   3362     // BX{<c>}{<q>} <Rm> ; A1
   3363     if (cond.IsNotNever()) {
   3364       EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
   3365       return;
   3366     }
   3367   }
   3368   Delegate(kBx, &Assembler::bx, cond, rm);
   3369 }
   3370 
   3371 void Assembler::bxj(Condition cond, Register rm) {
   3372   VIXL_ASSERT(AllowAssembler());
   3373   CheckIT(cond);
   3374   if (IsUsingT32()) {
   3375     // BXJ{<c>}{<q>} <Rm> ; T1
   3376     EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
   3377     AdvanceIT();
   3378     return;
   3379   } else {
   3380     // BXJ{<c>}{<q>} <Rm> ; A1
   3381     if (cond.IsNotNever()) {
   3382       EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
   3383       return;
   3384     }
   3385   }
   3386   Delegate(kBxj, &Assembler::bxj, cond, rm);
   3387 }
   3388 
   3389 void Assembler::cbnz(Register rn, Label* label) {
   3390   VIXL_ASSERT(AllowAssembler());
   3391   CheckIT(al);
   3392   Label::Offset offset =
   3393       label->IsBound()
   3394           ? label->GetLocation() -
   3395                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3396           : 0;
   3397   if (IsUsingT32()) {
   3398     // CBNZ{<q>} <Rn>, <label> ; T1
   3399     if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
   3400                         ((offset & 0x1) == 0)) ||
   3401                        !label->IsBound())) {
   3402       static class EmitOp : public Label::LabelEmitOperator {
   3403        public:
   3404         EmitOp() : Label::LabelEmitOperator(0, 126) {}
   3405         virtual uint32_t Encode(uint32_t instr,
   3406                                 Label::Offset pc,
   3407                                 const Label* label) const VIXL_OVERRIDE {
   3408           Label::Offset offset = label->GetLocation() - pc;
   3409           VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
   3410                       ((offset & 0x1) == 0));
   3411           const int32_t target = offset >> 1;
   3412           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
   3413         }
   3414       } immop;
   3415       EmitT32_16(Link(0xb900 | rn.GetCode(), label, immop));
   3416       AdvanceIT();
   3417       return;
   3418     }
   3419   }
   3420   Delegate(kCbnz, &Assembler::cbnz, rn, label);
   3421 }
   3422 
   3423 void Assembler::cbz(Register rn, Label* label) {
   3424   VIXL_ASSERT(AllowAssembler());
   3425   CheckIT(al);
   3426   Label::Offset offset =
   3427       label->IsBound()
   3428           ? label->GetLocation() -
   3429                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3430           : 0;
   3431   if (IsUsingT32()) {
   3432     // CBZ{<q>} <Rn>, <label> ; T1
   3433     if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
   3434                         ((offset & 0x1) == 0)) ||
   3435                        !label->IsBound())) {
   3436       static class EmitOp : public Label::LabelEmitOperator {
   3437        public:
   3438         EmitOp() : Label::LabelEmitOperator(0, 126) {}
   3439         virtual uint32_t Encode(uint32_t instr,
   3440                                 Label::Offset pc,
   3441                                 const Label* label) const VIXL_OVERRIDE {
   3442           Label::Offset offset = label->GetLocation() - pc;
   3443           VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
   3444                       ((offset & 0x1) == 0));
   3445           const int32_t target = offset >> 1;
   3446           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
   3447         }
   3448       } immop;
   3449       EmitT32_16(Link(0xb100 | rn.GetCode(), label, immop));
   3450       AdvanceIT();
   3451       return;
   3452     }
   3453   }
   3454   Delegate(kCbz, &Assembler::cbz, rn, label);
   3455 }
   3456 
   3457 void Assembler::clrex(Condition cond) {
   3458   VIXL_ASSERT(AllowAssembler());
   3459   CheckIT(cond);
   3460   if (IsUsingT32()) {
   3461     // CLREX{<c>}{<q>} ; T1
   3462     EmitT32_32(0xf3bf8f2fU);
   3463     AdvanceIT();
   3464     return;
   3465   } else {
   3466     // CLREX{<c>}{<q>} ; A1
   3467     if (cond.Is(al)) {
   3468       EmitA32(0xf57ff01fU);
   3469       return;
   3470     }
   3471   }
   3472   Delegate(kClrex, &Assembler::clrex, cond);
   3473 }
   3474 
   3475 void Assembler::clz(Condition cond, Register rd, Register rm) {
   3476   VIXL_ASSERT(AllowAssembler());
   3477   CheckIT(cond);
   3478   if (IsUsingT32()) {
   3479     // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
   3480     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3481       EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
   3482                  (rm.GetCode() << 16));
   3483       AdvanceIT();
   3484       return;
   3485     }
   3486   } else {
   3487     // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
   3488     if (cond.IsNotNever() &&
   3489         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3490       EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3491               rm.GetCode());
   3492       return;
   3493     }
   3494   }
   3495   Delegate(kClz, &Assembler::clz, cond, rd, rm);
   3496 }
   3497 
   3498 void Assembler::cmn(Condition cond,
   3499                     EncodingSize size,
   3500                     Register rn,
   3501                     const Operand& operand) {
   3502   VIXL_ASSERT(AllowAssembler());
   3503   CheckIT(cond);
   3504   if (operand.IsImmediate()) {
   3505     uint32_t imm = operand.GetImmediate();
   3506     if (IsUsingT32()) {
   3507       ImmediateT32 immediate_t32(imm);
   3508       // CMN{<c>}{<q>} <Rn>, #<const> ; T1
   3509       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   3510         EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
   3511                    (immediate_t32.GetEncodingValue() & 0xff) |
   3512                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3513                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3514         AdvanceIT();
   3515         return;
   3516       }
   3517     } else {
   3518       ImmediateA32 immediate_a32(imm);
   3519       // CMN{<c>}{<q>} <Rn>, #<const> ; A1
   3520       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3521         EmitA32(0x03700000U | (cond.GetCondition() << 28) |
   3522                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   3523         return;
   3524       }
   3525     }
   3526   }
   3527   if (operand.IsImmediateShiftedRegister()) {
   3528     Register rm = operand.GetBaseRegister();
   3529     if (operand.IsPlainRegister()) {
   3530       if (IsUsingT32()) {
   3531         // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
   3532         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
   3533           EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
   3534           AdvanceIT();
   3535           return;
   3536         }
   3537       }
   3538     }
   3539     Shift shift = operand.GetShift();
   3540     uint32_t amount = operand.GetShiftAmount();
   3541     if (IsUsingT32()) {
   3542       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3543       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   3544         uint32_t amount_ = amount % 32;
   3545         EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
   3546                    (operand.GetTypeEncodingValue() << 4) |
   3547                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3548         AdvanceIT();
   3549         return;
   3550       }
   3551     } else {
   3552       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3553       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3554         uint32_t amount_ = amount % 32;
   3555         EmitA32(0x01700000U | (cond.GetCondition() << 28) |
   3556                 (rn.GetCode() << 16) | rm.GetCode() |
   3557                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3558         return;
   3559       }
   3560     }
   3561   }
   3562   if (operand.IsRegisterShiftedRegister()) {
   3563     Register rm = operand.GetBaseRegister();
   3564     Shift shift = operand.GetShift();
   3565     if (IsUsingA32()) {
   3566       // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   3567       if (cond.IsNotNever()) {
   3568         EmitA32(0x01700010U | (cond.GetCondition() << 28) |
   3569                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   3570                 (operand.GetShiftRegister().GetCode() << 8));
   3571         return;
   3572       }
   3573     }
   3574   }
   3575   Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
   3576 }
   3577 
   3578 void Assembler::cmp(Condition cond,
   3579                     EncodingSize size,
   3580                     Register rn,
   3581                     const Operand& operand) {
   3582   VIXL_ASSERT(AllowAssembler());
   3583   CheckIT(cond);
   3584   if (operand.IsImmediate()) {
   3585     uint32_t imm = operand.GetImmediate();
   3586     if (IsUsingT32()) {
   3587       ImmediateT32 immediate_t32(imm);
   3588       // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
   3589       if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
   3590         EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
   3591         AdvanceIT();
   3592         return;
   3593       }
   3594       // CMP{<c>}{<q>} <Rn>, #<const> ; T2
   3595       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   3596         EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
   3597                    (immediate_t32.GetEncodingValue() & 0xff) |
   3598                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3599                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3600         AdvanceIT();
   3601         return;
   3602       }
   3603     } else {
   3604       ImmediateA32 immediate_a32(imm);
   3605       // CMP{<c>}{<q>} <Rn>, #<const> ; A1
   3606       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3607         EmitA32(0x03500000U | (cond.GetCondition() << 28) |
   3608                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   3609         return;
   3610       }
   3611     }
   3612   }
   3613   if (operand.IsImmediateShiftedRegister()) {
   3614     Register rm = operand.GetBaseRegister();
   3615     if (operand.IsPlainRegister()) {
   3616       if (IsUsingT32()) {
   3617         // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
   3618         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
   3619           EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
   3620           AdvanceIT();
   3621           return;
   3622         }
   3623         // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
   3624         if (!size.IsWide()) {
   3625           EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
   3626                      ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   3627           AdvanceIT();
   3628           return;
   3629         }
   3630       }
   3631     }
   3632     Shift shift = operand.GetShift();
   3633     uint32_t amount = operand.GetShiftAmount();
   3634     if (IsUsingT32()) {
   3635       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
   3636       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   3637         uint32_t amount_ = amount % 32;
   3638         EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
   3639                    (operand.GetTypeEncodingValue() << 4) |
   3640                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3641         AdvanceIT();
   3642         return;
   3643       }
   3644     } else {
   3645       // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3646       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3647         uint32_t amount_ = amount % 32;
   3648         EmitA32(0x01500000U | (cond.GetCondition() << 28) |
   3649                 (rn.GetCode() << 16) | rm.GetCode() |
   3650                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3651         return;
   3652       }
   3653     }
   3654   }
   3655   if (operand.IsRegisterShiftedRegister()) {
   3656     Register rm = operand.GetBaseRegister();
   3657     Shift shift = operand.GetShift();
   3658     if (IsUsingA32()) {
   3659       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   3660       if (cond.IsNotNever()) {
   3661         EmitA32(0x01500010U | (cond.GetCondition() << 28) |
   3662                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   3663                 (operand.GetShiftRegister().GetCode() << 8));
   3664         return;
   3665       }
   3666     }
   3667   }
   3668   Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
   3669 }
   3670 
   3671 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
   3672   VIXL_ASSERT(AllowAssembler());
   3673   CheckIT(cond);
   3674   if (IsUsingT32()) {
   3675     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
   3676     EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3677                rm.GetCode());
   3678     AdvanceIT();
   3679     return;
   3680   } else {
   3681     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
   3682     if ((cond.Is(al) || AllowUnpredictable())) {
   3683       EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3684               (rn.GetCode() << 16) | rm.GetCode());
   3685       return;
   3686     }
   3687   }
   3688   Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
   3689 }
   3690 
   3691 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
   3692   VIXL_ASSERT(AllowAssembler());
   3693   CheckIT(cond);
   3694   if (IsUsingT32()) {
   3695     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
   3696     EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3697                rm.GetCode());
   3698     AdvanceIT();
   3699     return;
   3700   } else {
   3701     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
   3702     if ((cond.Is(al) || AllowUnpredictable())) {
   3703       EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3704               (rn.GetCode() << 16) | rm.GetCode());
   3705       return;
   3706     }
   3707   }
   3708   Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
   3709 }
   3710 
   3711 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
   3712   VIXL_ASSERT(AllowAssembler());
   3713   CheckIT(cond);
   3714   if (IsUsingT32()) {
   3715     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
   3716     EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3717                rm.GetCode());
   3718     AdvanceIT();
   3719     return;
   3720   } else {
   3721     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
   3722     if ((cond.Is(al) || AllowUnpredictable())) {
   3723       EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3724               (rn.GetCode() << 16) | rm.GetCode());
   3725       return;
   3726     }
   3727   }
   3728   Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
   3729 }
   3730 
   3731 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
   3732   VIXL_ASSERT(AllowAssembler());
   3733   CheckIT(cond);
   3734   if (IsUsingT32()) {
   3735     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
   3736     EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3737                rm.GetCode());
   3738     AdvanceIT();
   3739     return;
   3740   } else {
   3741     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
   3742     if ((cond.Is(al) || AllowUnpredictable())) {
   3743       EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3744               (rn.GetCode() << 16) | rm.GetCode());
   3745       return;
   3746     }
   3747   }
   3748   Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
   3749 }
   3750 
   3751 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
   3752   VIXL_ASSERT(AllowAssembler());
   3753   CheckIT(cond);
   3754   if (IsUsingT32()) {
   3755     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
   3756     EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3757                rm.GetCode());
   3758     AdvanceIT();
   3759     return;
   3760   } else {
   3761     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
   3762     if ((cond.Is(al) || AllowUnpredictable())) {
   3763       EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3764               (rn.GetCode() << 16) | rm.GetCode());
   3765       return;
   3766     }
   3767   }
   3768   Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
   3769 }
   3770 
   3771 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
   3772   VIXL_ASSERT(AllowAssembler());
   3773   CheckIT(cond);
   3774   if (IsUsingT32()) {
   3775     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
   3776     EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3777                rm.GetCode());
   3778     AdvanceIT();
   3779     return;
   3780   } else {
   3781     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
   3782     if ((cond.Is(al) || AllowUnpredictable())) {
   3783       EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3784               (rn.GetCode() << 16) | rm.GetCode());
   3785       return;
   3786     }
   3787   }
   3788   Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
   3789 }
   3790 
   3791 void Assembler::dmb(Condition cond, MemoryBarrier option) {
   3792   VIXL_ASSERT(AllowAssembler());
   3793   CheckIT(cond);
   3794   if (IsUsingT32()) {
   3795     // DMB{<c>}{<q>} {<option>} ; T1
   3796     EmitT32_32(0xf3bf8f50U | option.GetType());
   3797     AdvanceIT();
   3798     return;
   3799   } else {
   3800     // DMB{<c>}{<q>} {<option>} ; A1
   3801     if (cond.Is(al)) {
   3802       EmitA32(0xf57ff050U | option.GetType());
   3803       return;
   3804     }
   3805   }
   3806   Delegate(kDmb, &Assembler::dmb, cond, option);
   3807 }
   3808 
   3809 void Assembler::dsb(Condition cond, MemoryBarrier option) {
   3810   VIXL_ASSERT(AllowAssembler());
   3811   CheckIT(cond);
   3812   if (IsUsingT32()) {
   3813     // DSB{<c>}{<q>} {<option>} ; T1
   3814     EmitT32_32(0xf3bf8f40U | option.GetType());
   3815     AdvanceIT();
   3816     return;
   3817   } else {
   3818     // DSB{<c>}{<q>} {<option>} ; A1
   3819     if (cond.Is(al)) {
   3820       EmitA32(0xf57ff040U | option.GetType());
   3821       return;
   3822     }
   3823   }
   3824   Delegate(kDsb, &Assembler::dsb, cond, option);
   3825 }
   3826 
   3827 void Assembler::eor(Condition cond,
   3828                     EncodingSize size,
   3829                     Register rd,
   3830                     Register rn,
   3831                     const Operand& operand) {
   3832   VIXL_ASSERT(AllowAssembler());
   3833   CheckIT(cond);
   3834   if (operand.IsImmediate()) {
   3835     uint32_t imm = operand.GetImmediate();
   3836     if (IsUsingT32()) {
   3837       ImmediateT32 immediate_t32(imm);
   3838       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   3839       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   3840         EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3841                    (immediate_t32.GetEncodingValue() & 0xff) |
   3842                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3843                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3844         AdvanceIT();
   3845         return;
   3846       }
   3847     } else {
   3848       ImmediateA32 immediate_a32(imm);
   3849       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   3850       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3851         EmitA32(0x02200000U | (cond.GetCondition() << 28) |
   3852                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   3853                 immediate_a32.GetEncodingValue());
   3854         return;
   3855       }
   3856     }
   3857   }
   3858   if (operand.IsImmediateShiftedRegister()) {
   3859     Register rm = operand.GetBaseRegister();
   3860     if (operand.IsPlainRegister()) {
   3861       if (IsUsingT32()) {
   3862         // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   3863         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   3864             rm.IsLow()) {
   3865           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
   3866           AdvanceIT();
   3867           return;
   3868         }
   3869       }
   3870     }
   3871     Shift shift = operand.GetShift();
   3872     uint32_t amount = operand.GetShiftAmount();
   3873     if (IsUsingT32()) {
   3874       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3875       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   3876         uint32_t amount_ = amount % 32;
   3877         EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3878                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   3879                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3880         AdvanceIT();
   3881         return;
   3882       }
   3883     } else {
   3884       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3885       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3886         uint32_t amount_ = amount % 32;
   3887         EmitA32(0x00200000U | (cond.GetCondition() << 28) |
   3888                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3889                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3890         return;
   3891       }
   3892     }
   3893   }
   3894   if (operand.IsRegisterShiftedRegister()) {
   3895     Register rm = operand.GetBaseRegister();
   3896     Shift shift = operand.GetShift();
   3897     if (IsUsingA32()) {
   3898       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   3899       if (cond.IsNotNever()) {
   3900         EmitA32(0x00200010U | (cond.GetCondition() << 28) |
   3901                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3902                 (shift.GetType() << 5) |
   3903                 (operand.GetShiftRegister().GetCode() << 8));
   3904         return;
   3905       }
   3906     }
   3907   }
   3908   Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
   3909 }
   3910 
   3911 void Assembler::eors(Condition cond,
   3912                      EncodingSize size,
   3913                      Register rd,
   3914                      Register rn,
   3915                      const Operand& operand) {
   3916   VIXL_ASSERT(AllowAssembler());
   3917   CheckIT(cond);
   3918   if (operand.IsImmediate()) {
   3919     uint32_t imm = operand.GetImmediate();
   3920     if (IsUsingT32()) {
   3921       ImmediateT32 immediate_t32(imm);
   3922       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   3923       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
   3924         EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3925                    (immediate_t32.GetEncodingValue() & 0xff) |
   3926                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3927                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3928         AdvanceIT();
   3929         return;
   3930       }
   3931     } else {
   3932       ImmediateA32 immediate_a32(imm);
   3933       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   3934       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3935         EmitA32(0x02300000U | (cond.GetCondition() << 28) |
   3936                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   3937                 immediate_a32.GetEncodingValue());
   3938         return;
   3939       }
   3940     }
   3941   }
   3942   if (operand.IsImmediateShiftedRegister()) {
   3943     Register rm = operand.GetBaseRegister();
   3944     if (operand.IsPlainRegister()) {
   3945       if (IsUsingT32()) {
   3946         // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   3947         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   3948             rm.IsLow()) {
   3949           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
   3950           AdvanceIT();
   3951           return;
   3952         }
   3953       }
   3954     }
   3955     Shift shift = operand.GetShift();
   3956     uint32_t amount = operand.GetShiftAmount();
   3957     if (IsUsingT32()) {
   3958       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3959       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
   3960         uint32_t amount_ = amount % 32;
   3961         EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3962                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   3963                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3964         AdvanceIT();
   3965         return;
   3966       }
   3967     } else {
   3968       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3969       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3970         uint32_t amount_ = amount % 32;
   3971         EmitA32(0x00300000U | (cond.GetCondition() << 28) |
   3972                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3973                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3974         return;
   3975       }
   3976     }
   3977   }
   3978   if (operand.IsRegisterShiftedRegister()) {
   3979     Register rm = operand.GetBaseRegister();
   3980     Shift shift = operand.GetShift();
   3981     if (IsUsingA32()) {
   3982       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   3983       if (cond.IsNotNever()) {
   3984         EmitA32(0x00300010U | (cond.GetCondition() << 28) |
   3985                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3986                 (shift.GetType() << 5) |
   3987                 (operand.GetShiftRegister().GetCode() << 8));
   3988         return;
   3989       }
   3990     }
   3991   }
   3992   Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
   3993 }
   3994 
   3995 void Assembler::fldmdbx(Condition cond,
   3996                         Register rn,
   3997                         WriteBack write_back,
   3998                         DRegisterList dreglist) {
   3999   VIXL_ASSERT(AllowAssembler());
   4000   CheckIT(cond);
   4001   if (IsUsingT32()) {
   4002     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
   4003     if (write_back.DoesWriteBack() &&
   4004         (((dreglist.GetLength() <= 16) &&
   4005           (dreglist.GetLastDRegister().GetCode() < 16)) ||
   4006          AllowUnpredictable())) {
   4007       const DRegister& dreg = dreglist.GetFirstDRegister();
   4008       unsigned len = dreglist.GetLength() * 2;
   4009       EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   4010                  (len & 0xff));
   4011       AdvanceIT();
   4012       return;
   4013     }
   4014   } else {
   4015     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
   4016     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   4017         (((dreglist.GetLength() <= 16) &&
   4018           (dreglist.GetLastDRegister().GetCode() < 16)) ||
   4019          AllowUnpredictable())) {
   4020       const DRegister& dreg = dreglist.GetFirstDRegister();
   4021       unsigned len = dreglist.GetLength() * 2;
   4022       EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4023               dreg.Encode(22, 12) | (len & 0xff));
   4024       return;
   4025     }
   4026   }
   4027   Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
   4028 }
   4029 
   4030 void Assembler::fldmiax(Condition cond,
   4031                         Register rn,
   4032                         WriteBack write_back,
   4033                         DRegisterList dreglist) {
   4034   VIXL_ASSERT(AllowAssembler());
   4035   CheckIT(cond);
   4036   if (IsUsingT32()) {
   4037     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
   4038     if ((((dreglist.GetLength() <= 16) &&
   4039           (dreglist.GetLastDRegister().GetCode() < 16)) ||
   4040          AllowUnpredictable())) {
   4041       const DRegister& dreg = dreglist.GetFirstDRegister();
   4042       unsigned len = dreglist.GetLength() * 2;
   4043       EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
   4044                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4045                  (len & 0xff));
   4046       AdvanceIT();
   4047       return;
   4048     }
   4049   } else {
   4050     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
   4051     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   4052                                (dreglist.GetLastDRegister().GetCode() < 16)) ||
   4053                               AllowUnpredictable())) {
   4054       const DRegister& dreg = dreglist.GetFirstDRegister();
   4055       unsigned len = dreglist.GetLength() * 2;
   4056       EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4057               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4058               (len & 0xff));
   4059       return;
   4060     }
   4061   }
   4062   Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
   4063 }
   4064 
   4065 void Assembler::fstmdbx(Condition cond,
   4066                         Register rn,
   4067                         WriteBack write_back,
   4068                         DRegisterList dreglist) {
   4069   VIXL_ASSERT(AllowAssembler());
   4070   CheckIT(cond);
   4071   if (IsUsingT32()) {
   4072     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
   4073     if (write_back.DoesWriteBack() &&
   4074         (((dreglist.GetLength() <= 16) &&
   4075           (dreglist.GetLastDRegister().GetCode() < 16)) ||
   4076          AllowUnpredictable())) {
   4077       const DRegister& dreg = dreglist.GetFirstDRegister();
   4078       unsigned len = dreglist.GetLength() * 2;
   4079       EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   4080                  (len & 0xff));
   4081       AdvanceIT();
   4082       return;
   4083     }
   4084   } else {
   4085     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
   4086     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   4087         (((dreglist.GetLength() <= 16) &&
   4088           (dreglist.GetLastDRegister().GetCode() < 16)) ||
   4089          AllowUnpredictable())) {
   4090       const DRegister& dreg = dreglist.GetFirstDRegister();
   4091       unsigned len = dreglist.GetLength() * 2;
   4092       EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4093               dreg.Encode(22, 12) | (len & 0xff));
   4094       return;
   4095     }
   4096   }
   4097   Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
   4098 }
   4099 
   4100 void Assembler::fstmiax(Condition cond,
   4101                         Register rn,
   4102                         WriteBack write_back,
   4103                         DRegisterList dreglist) {
   4104   VIXL_ASSERT(AllowAssembler());
   4105   CheckIT(cond);
   4106   if (IsUsingT32()) {
   4107     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
   4108     if ((((dreglist.GetLength() <= 16) &&
   4109           (dreglist.GetLastDRegister().GetCode() < 16)) ||
   4110          AllowUnpredictable())) {
   4111       const DRegister& dreg = dreglist.GetFirstDRegister();
   4112       unsigned len = dreglist.GetLength() * 2;
   4113       EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
   4114                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4115                  (len & 0xff));
   4116       AdvanceIT();
   4117       return;
   4118     }
   4119   } else {
   4120     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
   4121     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   4122                                (dreglist.GetLastDRegister().GetCode() < 16)) ||
   4123                               AllowUnpredictable())) {
   4124       const DRegister& dreg = dreglist.GetFirstDRegister();
   4125       unsigned len = dreglist.GetLength() * 2;
   4126       EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4127               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4128               (len & 0xff));
   4129       return;
   4130     }
   4131   }
   4132   Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
   4133 }
   4134 
   4135 void Assembler::hlt(Condition cond, uint32_t imm) {
   4136   VIXL_ASSERT(AllowAssembler());
   4137   CheckIT(cond);
   4138   if (IsUsingT32()) {
   4139     // HLT{<q>} {#}<imm> ; T1
   4140     if ((imm <= 63)) {
   4141       EmitT32_16(0xba80 | imm);
   4142       AdvanceIT();
   4143       return;
   4144     }
   4145   } else {
   4146     // HLT{<q>} {#}<imm> ; A1
   4147     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   4148       EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   4149               ((imm & 0xfff0) << 4));
   4150       return;
   4151     }
   4152   }
   4153   Delegate(kHlt, &Assembler::hlt, cond, imm);
   4154 }
   4155 
   4156 void Assembler::hvc(Condition cond, uint32_t imm) {
   4157   VIXL_ASSERT(AllowAssembler());
   4158   CheckIT(cond);
   4159   if (IsUsingT32()) {
   4160     // HVC{<q>} {#}<imm16> ; T1
   4161     if ((imm <= 65535)) {
   4162       EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
   4163       AdvanceIT();
   4164       return;
   4165     }
   4166   } else {
   4167     // HVC{<q>} {#}<imm16> ; A1
   4168     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   4169       EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   4170               ((imm & 0xfff0) << 4));
   4171       return;
   4172     }
   4173   }
   4174   Delegate(kHvc, &Assembler::hvc, cond, imm);
   4175 }
   4176 
   4177 void Assembler::isb(Condition cond, MemoryBarrier option) {
   4178   VIXL_ASSERT(AllowAssembler());
   4179   CheckIT(cond);
   4180   if (IsUsingT32()) {
   4181     // ISB{<c>}{<q>} {<option>} ; T1
   4182     EmitT32_32(0xf3bf8f60U | option.GetType());
   4183     AdvanceIT();
   4184     return;
   4185   } else {
   4186     // ISB{<c>}{<q>} {<option>} ; A1
   4187     if (cond.Is(al)) {
   4188       EmitA32(0xf57ff060U | option.GetType());
   4189       return;
   4190     }
   4191   }
   4192   Delegate(kIsb, &Assembler::isb, cond, option);
   4193 }
   4194 
   4195 void Assembler::it(Condition cond, uint16_t mask) {
   4196   VIXL_ASSERT(AllowAssembler());
   4197   CheckNotIT();
   4198   if (mask != 0) {
   4199     if ((cond.GetCondition() & 0x1) != 0) {
   4200       if ((mask & 0x1) != 0) {
   4201         mask ^= 0xE;
   4202       } else if ((mask & 0x2) != 0) {
   4203         mask ^= 0xC;
   4204       } else if ((mask & 0x4) != 0) {
   4205         mask ^= 0x8;
   4206       }
   4207     }
   4208     if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
   4209     SetIT(cond, mask);
   4210     return;
   4211   }
   4212   DelegateIt(cond, mask);
   4213 }
   4214 
   4215 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
   4216   VIXL_ASSERT(AllowAssembler());
   4217   CheckIT(cond);
   4218   if (operand.IsImmediateZero()) {
   4219     Register rn = operand.GetBaseRegister();
   4220     if (IsUsingT32()) {
   4221       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4222       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   4223         EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4224         AdvanceIT();
   4225         return;
   4226       }
   4227     } else {
   4228       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4229       if (operand.IsOffset() && cond.IsNotNever() &&
   4230           (!rn.IsPC() || AllowUnpredictable())) {
   4231         EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
   4232                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4233         return;
   4234       }
   4235     }
   4236   }
   4237   Delegate(kLda, &Assembler::lda, cond, rt, operand);
   4238 }
   4239 
   4240 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
   4241   VIXL_ASSERT(AllowAssembler());
   4242   CheckIT(cond);
   4243   if (operand.IsImmediateZero()) {
   4244     Register rn = operand.GetBaseRegister();
   4245     if (IsUsingT32()) {
   4246       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4247       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   4248         EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4249         AdvanceIT();
   4250         return;
   4251       }
   4252     } else {
   4253       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4254       if (operand.IsOffset() && cond.IsNotNever() &&
   4255           (!rn.IsPC() || AllowUnpredictable())) {
   4256         EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
   4257                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4258         return;
   4259       }
   4260     }
   4261   }
   4262   Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
   4263 }
   4264 
   4265 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
   4266   VIXL_ASSERT(AllowAssembler());
   4267   CheckIT(cond);
   4268   if (operand.IsImmediateZero()) {
   4269     Register rn = operand.GetBaseRegister();
   4270     if (IsUsingT32()) {
   4271       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4272       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   4273         EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4274         AdvanceIT();
   4275         return;
   4276       }
   4277     } else {
   4278       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4279       if (operand.IsOffset() && cond.IsNotNever() &&
   4280           (!rn.IsPC() || AllowUnpredictable())) {
   4281         EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
   4282                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4283         return;
   4284       }
   4285     }
   4286   }
   4287   Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
   4288 }
   4289 
   4290 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
   4291   VIXL_ASSERT(AllowAssembler());
   4292   CheckIT(cond);
   4293   if (operand.IsImmediateZero()) {
   4294     Register rn = operand.GetBaseRegister();
   4295     if (IsUsingT32()) {
   4296       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4297       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   4298         EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4299         AdvanceIT();
   4300         return;
   4301       }
   4302     } else {
   4303       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4304       if (operand.IsOffset() && cond.IsNotNever() &&
   4305           (!rn.IsPC() || AllowUnpredictable())) {
   4306         EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
   4307                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4308         return;
   4309       }
   4310     }
   4311   }
   4312   Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
   4313 }
   4314 
   4315 void Assembler::ldaexd(Condition cond,
   4316                        Register rt,
   4317                        Register rt2,
   4318                        const MemOperand& operand) {
   4319   VIXL_ASSERT(AllowAssembler());
   4320   CheckIT(cond);
   4321   if (operand.IsImmediateZero()) {
   4322     Register rn = operand.GetBaseRegister();
   4323     if (IsUsingT32()) {
   4324       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
   4325       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   4326         EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   4327                    (rn.GetCode() << 16));
   4328         AdvanceIT();
   4329         return;
   4330       }
   4331     } else {
   4332       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
   4333       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   4334           operand.IsOffset() && cond.IsNotNever() &&
   4335           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
   4336            AllowUnpredictable())) {
   4337         EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
   4338                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4339         return;
   4340       }
   4341     }
   4342   }
   4343   Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
   4344 }
   4345 
   4346 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
   4347   VIXL_ASSERT(AllowAssembler());
   4348   CheckIT(cond);
   4349   if (operand.IsImmediateZero()) {
   4350     Register rn = operand.GetBaseRegister();
   4351     if (IsUsingT32()) {
   4352       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4353       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   4354         EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4355         AdvanceIT();
   4356         return;
   4357       }
   4358     } else {
   4359       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4360       if (operand.IsOffset() && cond.IsNotNever() &&
   4361           (!rn.IsPC() || AllowUnpredictable())) {
   4362         EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
   4363                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4364         return;
   4365       }
   4366     }
   4367   }
   4368   Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
   4369 }
   4370 
   4371 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
   4372   VIXL_ASSERT(AllowAssembler());
   4373   CheckIT(cond);
   4374   if (operand.IsImmediateZero()) {
   4375     Register rn = operand.GetBaseRegister();
   4376     if (IsUsingT32()) {
   4377       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4378       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   4379         EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4380         AdvanceIT();
   4381         return;
   4382       }
   4383     } else {
   4384       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4385       if (operand.IsOffset() && cond.IsNotNever() &&
   4386           (!rn.IsPC() || AllowUnpredictable())) {
   4387         EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
   4388                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4389         return;
   4390       }
   4391     }
   4392   }
   4393   Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
   4394 }
   4395 
   4396 void Assembler::ldm(Condition cond,
   4397                     EncodingSize size,
   4398                     Register rn,
   4399                     WriteBack write_back,
   4400                     RegisterList registers) {
   4401   VIXL_ASSERT(AllowAssembler());
   4402   CheckIT(cond);
   4403   if (IsUsingT32()) {
   4404     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4405     if (!size.IsWide() && rn.IsLow() &&
   4406         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
   4407          write_back.DoesWriteBack()) &&
   4408         ((registers.GetList() & ~0xff) == 0)) {
   4409       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
   4410                  GetRegisterListEncoding(registers, 0, 8));
   4411       AdvanceIT();
   4412       return;
   4413     }
   4414     // LDM{<c>}{<q>} SP!, <registers> ; T1
   4415     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
   4416         ((registers.GetList() & ~0x80ff) == 0)) {
   4417       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
   4418                  GetRegisterListEncoding(registers, 0, 8));
   4419       AdvanceIT();
   4420       return;
   4421     }
   4422     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
   4423     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
   4424       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
   4425                  (write_back.GetWriteBackUint32() << 21) |
   4426                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4427                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4428                  GetRegisterListEncoding(registers, 0, 13));
   4429       AdvanceIT();
   4430       return;
   4431     }
   4432   } else {
   4433     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4434     if (cond.IsNotNever()) {
   4435       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4436               (write_back.GetWriteBackUint32() << 21) |
   4437               GetRegisterListEncoding(registers, 0, 16));
   4438       return;
   4439     }
   4440   }
   4441   Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
   4442 }
   4443 
   4444 void Assembler::ldmda(Condition cond,
   4445                       Register rn,
   4446                       WriteBack write_back,
   4447                       RegisterList registers) {
   4448   VIXL_ASSERT(AllowAssembler());
   4449   CheckIT(cond);
   4450   if (IsUsingA32()) {
   4451     // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4452     if (cond.IsNotNever()) {
   4453       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4454               (write_back.GetWriteBackUint32() << 21) |
   4455               GetRegisterListEncoding(registers, 0, 16));
   4456       return;
   4457     }
   4458   }
   4459   Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
   4460 }
   4461 
   4462 void Assembler::ldmdb(Condition cond,
   4463                       Register rn,
   4464                       WriteBack write_back,
   4465                       RegisterList registers) {
   4466   VIXL_ASSERT(AllowAssembler());
   4467   CheckIT(cond);
   4468   if (IsUsingT32()) {
   4469     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4470     if (((registers.GetList() & ~0xdfff) == 0)) {
   4471       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
   4472                  (write_back.GetWriteBackUint32() << 21) |
   4473                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4474                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4475                  GetRegisterListEncoding(registers, 0, 13));
   4476       AdvanceIT();
   4477       return;
   4478     }
   4479   } else {
   4480     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4481     if (cond.IsNotNever()) {
   4482       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4483               (write_back.GetWriteBackUint32() << 21) |
   4484               GetRegisterListEncoding(registers, 0, 16));
   4485       return;
   4486     }
   4487   }
   4488   Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
   4489 }
   4490 
   4491 void Assembler::ldmea(Condition cond,
   4492                       Register rn,
   4493                       WriteBack write_back,
   4494                       RegisterList registers) {
   4495   VIXL_ASSERT(AllowAssembler());
   4496   CheckIT(cond);
   4497   if (IsUsingT32()) {
   4498     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4499     if (((registers.GetList() & ~0xdfff) == 0)) {
   4500       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
   4501                  (write_back.GetWriteBackUint32() << 21) |
   4502                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4503                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4504                  GetRegisterListEncoding(registers, 0, 13));
   4505       AdvanceIT();
   4506       return;
   4507     }
   4508   } else {
   4509     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4510     if (cond.IsNotNever()) {
   4511       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4512               (write_back.GetWriteBackUint32() << 21) |
   4513               GetRegisterListEncoding(registers, 0, 16));
   4514       return;
   4515     }
   4516   }
   4517   Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
   4518 }
   4519 
   4520 void Assembler::ldmed(Condition cond,
   4521                       Register rn,
   4522                       WriteBack write_back,
   4523                       RegisterList registers) {
   4524   VIXL_ASSERT(AllowAssembler());
   4525   CheckIT(cond);
   4526   if (IsUsingA32()) {
   4527     // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4528     if (cond.IsNotNever()) {
   4529       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4530               (write_back.GetWriteBackUint32() << 21) |
   4531               GetRegisterListEncoding(registers, 0, 16));
   4532       return;
   4533     }
   4534   }
   4535   Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
   4536 }
   4537 
   4538 void Assembler::ldmfa(Condition cond,
   4539                       Register rn,
   4540                       WriteBack write_back,
   4541                       RegisterList registers) {
   4542   VIXL_ASSERT(AllowAssembler());
   4543   CheckIT(cond);
   4544   if (IsUsingA32()) {
   4545     // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4546     if (cond.IsNotNever()) {
   4547       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4548               (write_back.GetWriteBackUint32() << 21) |
   4549               GetRegisterListEncoding(registers, 0, 16));
   4550       return;
   4551     }
   4552   }
   4553   Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
   4554 }
   4555 
   4556 void Assembler::ldmfd(Condition cond,
   4557                       EncodingSize size,
   4558                       Register rn,
   4559                       WriteBack write_back,
   4560                       RegisterList registers) {
   4561   VIXL_ASSERT(AllowAssembler());
   4562   CheckIT(cond);
   4563   if (IsUsingT32()) {
   4564     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4565     if (!size.IsWide() && rn.IsLow() &&
   4566         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
   4567          write_back.DoesWriteBack()) &&
   4568         ((registers.GetList() & ~0xff) == 0)) {
   4569       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
   4570                  GetRegisterListEncoding(registers, 0, 8));
   4571       AdvanceIT();
   4572       return;
   4573     }
   4574     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
   4575     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
   4576       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
   4577                  (write_back.GetWriteBackUint32() << 21) |
   4578                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4579                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4580                  GetRegisterListEncoding(registers, 0, 13));
   4581       AdvanceIT();
   4582       return;
   4583     }
   4584   } else {
   4585     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4586     if (cond.IsNotNever()) {
   4587       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4588               (write_back.GetWriteBackUint32() << 21) |
   4589               GetRegisterListEncoding(registers, 0, 16));
   4590       return;
   4591     }
   4592   }
   4593   Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
   4594 }
   4595 
   4596 void Assembler::ldmib(Condition cond,
   4597                       Register rn,
   4598                       WriteBack write_back,
   4599                       RegisterList registers) {
   4600   VIXL_ASSERT(AllowAssembler());
   4601   CheckIT(cond);
   4602   if (IsUsingA32()) {
   4603     // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4604     if (cond.IsNotNever()) {
   4605       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4606               (write_back.GetWriteBackUint32() << 21) |
   4607               GetRegisterListEncoding(registers, 0, 16));
   4608       return;
   4609     }
   4610   }
   4611   Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
   4612 }
   4613 
   4614 void Assembler::ldr(Condition cond,
   4615                     EncodingSize size,
   4616                     Register rt,
   4617                     const MemOperand& operand) {
   4618   VIXL_ASSERT(AllowAssembler());
   4619   CheckIT(cond);
   4620   if (operand.IsImmediate()) {
   4621     Register rn = operand.GetBaseRegister();
   4622     int32_t offset = operand.GetOffsetImmediate();
   4623     if (IsUsingT32()) {
   4624       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   4625       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   4626           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
   4627         int32_t offset_ = offset >> 2;
   4628         EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
   4629                    ((offset_ & 0x1f) << 6));
   4630         AdvanceIT();
   4631         return;
   4632       }
   4633       // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
   4634       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
   4635           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
   4636         int32_t offset_ = offset >> 2;
   4637         EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
   4638         AdvanceIT();
   4639         return;
   4640       }
   4641       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
   4642       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   4643           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   4644         EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4645                    (offset & 0xfff));
   4646         AdvanceIT();
   4647         return;
   4648       }
   4649       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
   4650       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   4651           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   4652         EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4653                    (-offset & 0xff));
   4654         AdvanceIT();
   4655         return;
   4656       }
   4657       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
   4658       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   4659           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   4660         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4661         uint32_t offset_ = abs(offset);
   4662         EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4663                    offset_ | (sign << 9));
   4664         AdvanceIT();
   4665         return;
   4666       }
   4667       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
   4668       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   4669           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   4670         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4671         uint32_t offset_ = abs(offset);
   4672         EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4673                    offset_ | (sign << 9));
   4674         AdvanceIT();
   4675         return;
   4676       }
   4677       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
   4678       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   4679           rn.Is(pc) && operand.IsOffset()) {
   4680         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4681         uint32_t offset_ = abs(offset);
   4682         EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   4683         AdvanceIT();
   4684         return;
   4685       }
   4686     } else {
   4687       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   4688       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   4689           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   4690         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4691         uint32_t offset_ = abs(offset);
   4692         EmitA32(0x05100000U | (cond.GetCondition() << 28) |
   4693                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   4694                 (sign << 23));
   4695         return;
   4696       }
   4697       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   4698       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   4699           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   4700         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4701         uint32_t offset_ = abs(offset);
   4702         EmitA32(0x04100000U | (cond.GetCondition() << 28) |
   4703                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   4704                 (sign << 23));
   4705         return;
   4706       }
   4707       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   4708       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   4709           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   4710         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4711         uint32_t offset_ = abs(offset);
   4712         EmitA32(0x05300000U | (cond.GetCondition() << 28) |
   4713                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   4714                 (sign << 23));
   4715         return;
   4716       }
   4717       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   4718       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   4719           operand.IsOffset() && cond.IsNotNever()) {
   4720         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4721         uint32_t offset_ = abs(offset);
   4722         EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
   4723                 (rt.GetCode() << 12) | offset_ | (sign << 23));
   4724         return;
   4725       }
   4726     }
   4727   }
   4728   if (operand.IsPlainRegister()) {
   4729     Register rn = operand.GetBaseRegister();
   4730     Sign sign = operand.GetSign();
   4731     Register rm = operand.GetOffsetRegister();
   4732     if (IsUsingT32()) {
   4733       // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   4734       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   4735           sign.IsPlus() && operand.IsOffset()) {
   4736         EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
   4737                    (rm.GetCode() << 6));
   4738         AdvanceIT();
   4739         return;
   4740       }
   4741     }
   4742   }
   4743   if (operand.IsShiftedRegister()) {
   4744     Register rn = operand.GetBaseRegister();
   4745     Sign sign = operand.GetSign();
   4746     Register rm = operand.GetOffsetRegister();
   4747     Shift shift = operand.GetShift();
   4748     uint32_t amount = operand.GetShiftAmount();
   4749     if (IsUsingT32()) {
   4750       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   4751       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   4752           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   4753         EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4754                    rm.GetCode() | (amount << 4));
   4755         AdvanceIT();
   4756         return;
   4757       }
   4758     } else {
   4759       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   4760       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
   4761         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   4762         uint32_t shift_ = TypeEncodingValue(shift);
   4763         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   4764         EmitA32(0x07100000U | (cond.GetCondition() << 28) |
   4765                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4766                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   4767         return;
   4768       }
   4769       // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   4770       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   4771           cond.IsNotNever()) {
   4772         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   4773         uint32_t shift_ = TypeEncodingValue(shift);
   4774         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   4775         EmitA32(0x06100000U | (cond.GetCondition() << 28) |
   4776                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4777                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   4778         return;
   4779       }
   4780       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   4781       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
   4782         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   4783         uint32_t shift_ = TypeEncodingValue(shift);
   4784         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   4785         EmitA32(0x07300000U | (cond.GetCondition() << 28) |
   4786                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4787                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   4788         return;
   4789       }
   4790     }
   4791   }
   4792   Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
   4793 }
   4794 
   4795 void Assembler::ldr(Condition cond,
   4796                     EncodingSize size,
   4797                     Register rt,
   4798                     Label* label) {
   4799   VIXL_ASSERT(AllowAssembler());
   4800   CheckIT(cond);
   4801   Label::Offset offset =
   4802       label->IsBound()
   4803           ? label->GetLocation() -
   4804                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   4805           : 0;
   4806   if (IsUsingT32()) {
   4807     // LDR{<c>}{<q>} <Rt>, <label> ; T1
   4808     if (!size.IsWide() && rt.IsLow() &&
   4809         ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
   4810           ((offset & 0x3) == 0)) ||
   4811          (!label->IsBound() && size.IsNarrow()))) {
   4812       static class EmitOp : public Label::LabelEmitOperator {
   4813        public:
   4814         EmitOp() : Label::LabelEmitOperator(0, 1020) {}
   4815         virtual uint32_t Encode(uint32_t instr,
   4816                                 Label::Offset pc,
   4817                                 const Label* label) const VIXL_OVERRIDE {
   4818           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   4819           VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
   4820                       ((offset & 0x3) == 0));
   4821           const int32_t target = offset >> 2;
   4822           return instr | (target & 0xff);
   4823         }
   4824       } immop;
   4825       EmitT32_16(Link(0x4800 | (rt.GetCode() << 8), label, immop));
   4826       AdvanceIT();
   4827       return;
   4828     }
   4829     // LDR{<c>}{<q>} <Rt>, <label> ; T2
   4830     if (!size.IsNarrow() &&
   4831         ((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   4832          !label->IsBound())) {
   4833       static class EmitOp : public Label::LabelEmitOperator {
   4834        public:
   4835         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   4836         virtual uint32_t Encode(uint32_t instr,
   4837                                 Label::Offset pc,
   4838                                 const Label* label) const VIXL_OVERRIDE {
   4839           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   4840           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   4841           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   4842           int32_t target = abs(offset) | (U << 12);
   4843           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   4844         }
   4845       } immop;
   4846       EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12), label, immop));
   4847       AdvanceIT();
   4848       return;
   4849     }
   4850   } else {
   4851     // LDR{<c>}{<q>} <Rt>, <label> ; A1
   4852     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   4853          !label->IsBound()) &&
   4854         cond.IsNotNever()) {
   4855       static class EmitOp : public Label::LabelEmitOperator {
   4856        public:
   4857         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   4858         virtual uint32_t Encode(uint32_t instr,
   4859                                 Label::Offset pc,
   4860                                 const Label* label) const VIXL_OVERRIDE {
   4861           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   4862           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   4863           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   4864           int32_t target = abs(offset) | (U << 12);
   4865           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   4866         }
   4867       } immop;
   4868       EmitA32(
   4869           Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   4870                label,
   4871                immop));
   4872       return;
   4873     }
   4874   }
   4875   Delegate(kLdr, &Assembler::ldr, cond, size, rt, label);
   4876 }
   4877 
   4878 void Assembler::ldrb(Condition cond,
   4879                      EncodingSize size,
   4880                      Register rt,
   4881                      const MemOperand& operand) {
   4882   VIXL_ASSERT(AllowAssembler());
   4883   CheckIT(cond);
   4884   if (operand.IsImmediate()) {
   4885     Register rn = operand.GetBaseRegister();
   4886     int32_t offset = operand.GetOffsetImmediate();
   4887     if (IsUsingT32()) {
   4888       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   4889       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   4890           (offset <= 31) && operand.IsOffset()) {
   4891         EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
   4892                    ((offset & 0x1f) << 6));
   4893         AdvanceIT();
   4894         return;
   4895       }
   4896       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   4897       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   4898           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   4899         EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4900                    (offset & 0xfff));
   4901         AdvanceIT();
   4902         return;
   4903       }
   4904       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   4905       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   4906           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   4907         EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4908                    (-offset & 0xff));
   4909         AdvanceIT();
   4910         return;
   4911       }
   4912       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   4913       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   4914           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   4915         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4916         uint32_t offset_ = abs(offset);
   4917         EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4918                    offset_ | (sign << 9));
   4919         AdvanceIT();
   4920         return;
   4921       }
   4922       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   4923       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   4924           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   4925         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4926         uint32_t offset_ = abs(offset);
   4927         EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   4928                    offset_ | (sign << 9));
   4929         AdvanceIT();
   4930         return;
   4931       }
   4932       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   4933       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   4934           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   4935         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4936         uint32_t offset_ = abs(offset);
   4937         EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   4938         AdvanceIT();
   4939         return;
   4940       }
   4941     } else {
   4942       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   4943       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   4944           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   4945         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4946         uint32_t offset_ = abs(offset);
   4947         EmitA32(0x05500000U | (cond.GetCondition() << 28) |
   4948                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   4949                 (sign << 23));
   4950         return;
   4951       }
   4952       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   4953       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   4954           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   4955         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4956         uint32_t offset_ = abs(offset);
   4957         EmitA32(0x04500000U | (cond.GetCondition() << 28) |
   4958                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   4959                 (sign << 23));
   4960         return;
   4961       }
   4962       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   4963       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   4964           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   4965         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4966         uint32_t offset_ = abs(offset);
   4967         EmitA32(0x05700000U | (cond.GetCondition() << 28) |
   4968                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   4969                 (sign << 23));
   4970         return;
   4971       }
   4972       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   4973       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   4974           operand.IsOffset() && cond.IsNotNever()) {
   4975         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   4976         uint32_t offset_ = abs(offset);
   4977         EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
   4978                 (rt.GetCode() << 12) | offset_ | (sign << 23));
   4979         return;
   4980       }
   4981     }
   4982   }
   4983   if (operand.IsPlainRegister()) {
   4984     Register rn = operand.GetBaseRegister();
   4985     Sign sign = operand.GetSign();
   4986     Register rm = operand.GetOffsetRegister();
   4987     if (IsUsingT32()) {
   4988       // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   4989       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   4990           sign.IsPlus() && operand.IsOffset()) {
   4991         EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
   4992                    (rm.GetCode() << 6));
   4993         AdvanceIT();
   4994         return;
   4995       }
   4996     }
   4997   }
   4998   if (operand.IsShiftedRegister()) {
   4999     Register rn = operand.GetBaseRegister();
   5000     Sign sign = operand.GetSign();
   5001     Register rm = operand.GetOffsetRegister();
   5002     Shift shift = operand.GetShift();
   5003     uint32_t amount = operand.GetShiftAmount();
   5004     if (IsUsingT32()) {
   5005       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   5006       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   5007           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5008         EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5009                    rm.GetCode() | (amount << 4));
   5010         AdvanceIT();
   5011         return;
   5012       }
   5013     } else {
   5014       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   5015       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
   5016         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5017         uint32_t shift_ = TypeEncodingValue(shift);
   5018         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5019         EmitA32(0x07500000U | (cond.GetCondition() << 28) |
   5020                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5021                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5022         return;
   5023       }
   5024       // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   5025       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   5026           cond.IsNotNever()) {
   5027         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5028         uint32_t shift_ = TypeEncodingValue(shift);
   5029         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5030         EmitA32(0x06500000U | (cond.GetCondition() << 28) |
   5031                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5032                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5033         return;
   5034       }
   5035       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   5036       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
   5037         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5038         uint32_t shift_ = TypeEncodingValue(shift);
   5039         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5040         EmitA32(0x07700000U | (cond.GetCondition() << 28) |
   5041                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5042                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5043         return;
   5044       }
   5045     }
   5046   }
   5047   Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
   5048 }
   5049 
   5050 void Assembler::ldrb(Condition cond, Register rt, Label* label) {
   5051   VIXL_ASSERT(AllowAssembler());
   5052   CheckIT(cond);
   5053   Label::Offset offset =
   5054       label->IsBound()
   5055           ? label->GetLocation() -
   5056                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5057           : 0;
   5058   if (IsUsingT32()) {
   5059     // LDRB{<c>}{<q>} <Rt>, <label> ; T1
   5060     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5061          !label->IsBound()) &&
   5062         !rt.Is(pc)) {
   5063       static class EmitOp : public Label::LabelEmitOperator {
   5064        public:
   5065         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   5066         virtual uint32_t Encode(uint32_t instr,
   5067                                 Label::Offset pc,
   5068                                 const Label* label) const VIXL_OVERRIDE {
   5069           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   5070           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   5071           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   5072           int32_t target = abs(offset) | (U << 12);
   5073           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5074         }
   5075       } immop;
   5076       EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12), label, immop));
   5077       AdvanceIT();
   5078       return;
   5079     }
   5080   } else {
   5081     // LDRB{<c>}{<q>} <Rt>, <label> ; A1
   5082     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5083          !label->IsBound()) &&
   5084         cond.IsNotNever()) {
   5085       static class EmitOp : public Label::LabelEmitOperator {
   5086        public:
   5087         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   5088         virtual uint32_t Encode(uint32_t instr,
   5089                                 Label::Offset pc,
   5090                                 const Label* label) const VIXL_OVERRIDE {
   5091           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   5092           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   5093           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   5094           int32_t target = abs(offset) | (U << 12);
   5095           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5096         }
   5097       } immop;
   5098       EmitA32(
   5099           Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5100                label,
   5101                immop));
   5102       return;
   5103     }
   5104   }
   5105   Delegate(kLdrb, &Assembler::ldrb, cond, rt, label);
   5106 }
   5107 
   5108 void Assembler::ldrd(Condition cond,
   5109                      Register rt,
   5110                      Register rt2,
   5111                      const MemOperand& operand) {
   5112   VIXL_ASSERT(AllowAssembler());
   5113   CheckIT(cond);
   5114   if (operand.IsImmediate()) {
   5115     Register rn = operand.GetBaseRegister();
   5116     int32_t offset = operand.GetOffsetImmediate();
   5117     if (IsUsingT32()) {
   5118       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
   5119       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5120           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   5121         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5122         uint32_t offset_ = abs(offset) >> 2;
   5123         EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5124                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5125         AdvanceIT();
   5126         return;
   5127       }
   5128       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
   5129       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5130           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5131         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5132         uint32_t offset_ = abs(offset) >> 2;
   5133         EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5134                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5135         AdvanceIT();
   5136         return;
   5137       }
   5138       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
   5139       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5140           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5141         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5142         uint32_t offset_ = abs(offset) >> 2;
   5143         EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5144                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5145         AdvanceIT();
   5146         return;
   5147       }
   5148       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
   5149       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5150           operand.IsOffset()) {
   5151         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5152         uint32_t offset_ = abs(offset);
   5153         EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5154                    offset_ | (sign << 23));
   5155         AdvanceIT();
   5156         return;
   5157       }
   5158     } else {
   5159       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
   5160       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5161           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   5162           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5163           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   5164         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5165         uint32_t offset_ = abs(offset);
   5166         EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
   5167                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5168                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5169         return;
   5170       }
   5171       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
   5172       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5173           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   5174           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5175           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   5176         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5177         uint32_t offset_ = abs(offset);
   5178         EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
   5179                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5180                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5181         return;
   5182       }
   5183       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
   5184       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5185           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   5186           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5187           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   5188         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5189         uint32_t offset_ = abs(offset);
   5190         EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
   5191                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5192                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5193         return;
   5194       }
   5195       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
   5196       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5197           (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5198           operand.IsOffset() && cond.IsNotNever() &&
   5199           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   5200         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5201         uint32_t offset_ = abs(offset);
   5202         EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
   5203                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   5204                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5205         return;
   5206       }
   5207     }
   5208   }
   5209   if (operand.IsPlainRegister()) {
   5210     Register rn = operand.GetBaseRegister();
   5211     Sign sign = operand.GetSign();
   5212     Register rm = operand.GetOffsetRegister();
   5213     if (IsUsingA32()) {
   5214       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
   5215       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5216           operand.IsOffset() && cond.IsNotNever() &&
   5217           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   5218         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5219         EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
   5220                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5221                 (sign_ << 23));
   5222         return;
   5223       }
   5224       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
   5225       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5226           operand.IsPostIndex() && cond.IsNotNever() &&
   5227           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   5228         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5229         EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
   5230                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5231                 (sign_ << 23));
   5232         return;
   5233       }
   5234       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
   5235       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5236           operand.IsPreIndex() && cond.IsNotNever() &&
   5237           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   5238         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5239         EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
   5240                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5241                 (sign_ << 23));
   5242         return;
   5243       }
   5244     }
   5245   }
   5246   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
   5247 }
   5248 
   5249 void Assembler::ldrd(Condition cond, Register rt, Register rt2, Label* label) {
   5250   VIXL_ASSERT(AllowAssembler());
   5251   CheckIT(cond);
   5252   Label::Offset offset =
   5253       label->IsBound()
   5254           ? label->GetLocation() -
   5255                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5256           : 0;
   5257   if (IsUsingT32()) {
   5258     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
   5259     if (((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   5260           ((offset & 0x3) == 0)) ||
   5261          !label->IsBound())) {
   5262       static class EmitOp : public Label::LabelEmitOperator {
   5263        public:
   5264         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
   5265         virtual uint32_t Encode(uint32_t instr,
   5266                                 Label::Offset pc,
   5267                                 const Label* label) const VIXL_OVERRIDE {
   5268           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   5269           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   5270                       ((offset & 0x3) == 0));
   5271           int32_t target = offset >> 2;
   5272           uint32_t U = (target >= 0) && !label->IsMinusZero();
   5273           target = abs(target) | (U << 8);
   5274           return instr | (target & 0xff) | ((target & 0x100) << 15);
   5275         }
   5276       } immop;
   5277       EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
   5278                       label,
   5279                       immop));
   5280       AdvanceIT();
   5281       return;
   5282     }
   5283   } else {
   5284     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
   5285     if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5286         ((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
   5287          !label->IsBound()) &&
   5288         cond.IsNotNever() &&
   5289         ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   5290       static class EmitOp : public Label::LabelEmitOperator {
   5291        public:
   5292         EmitOp() : Label::LabelEmitOperator(-255, 255) {}
   5293         virtual uint32_t Encode(uint32_t instr,
   5294                                 Label::Offset pc,
   5295                                 const Label* label) const VIXL_OVERRIDE {
   5296           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   5297           VIXL_ASSERT((offset >= -255) && (offset <= 255));
   5298           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   5299           int32_t target = abs(offset) | (U << 8);
   5300           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   5301                  ((target & 0x100) << 15);
   5302         }
   5303       } immop;
   5304       EmitA32(
   5305           Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5306                label,
   5307                immop));
   5308       return;
   5309     }
   5310   }
   5311   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, label);
   5312 }
   5313 
   5314 void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) {
   5315   VIXL_ASSERT(AllowAssembler());
   5316   CheckIT(cond);
   5317   if (operand.IsImmediate()) {
   5318     Register rn = operand.GetBaseRegister();
   5319     int32_t offset = operand.GetOffsetImmediate();
   5320     if (IsUsingT32()) {
   5321       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
   5322       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
   5323           operand.IsOffset()) {
   5324         int32_t offset_ = offset >> 2;
   5325         EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5326                    (offset_ & 0xff));
   5327         AdvanceIT();
   5328         return;
   5329       }
   5330     } else {
   5331       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
   5332       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) {
   5333         EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
   5334                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5335         return;
   5336       }
   5337     }
   5338   }
   5339   Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
   5340 }
   5341 
   5342 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
   5343   VIXL_ASSERT(AllowAssembler());
   5344   CheckIT(cond);
   5345   if (operand.IsImmediateZero()) {
   5346     Register rn = operand.GetBaseRegister();
   5347     if (IsUsingT32()) {
   5348       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   5349       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   5350         EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5351         AdvanceIT();
   5352         return;
   5353       }
   5354     } else {
   5355       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   5356       if (operand.IsOffset() && cond.IsNotNever() &&
   5357           (!rn.IsPC() || AllowUnpredictable())) {
   5358         EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
   5359                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5360         return;
   5361       }
   5362     }
   5363   }
   5364   Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
   5365 }
   5366 
   5367 void Assembler::ldrexd(Condition cond,
   5368                        Register rt,
   5369                        Register rt2,
   5370                        const MemOperand& operand) {
   5371   VIXL_ASSERT(AllowAssembler());
   5372   CheckIT(cond);
   5373   if (operand.IsImmediateZero()) {
   5374     Register rn = operand.GetBaseRegister();
   5375     if (IsUsingT32()) {
   5376       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
   5377       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   5378         EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5379                    (rn.GetCode() << 16));
   5380         AdvanceIT();
   5381         return;
   5382       }
   5383     } else {
   5384       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
   5385       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5386           operand.IsOffset() && cond.IsNotNever() &&
   5387           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
   5388            AllowUnpredictable())) {
   5389         EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
   5390                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5391         return;
   5392       }
   5393     }
   5394   }
   5395   Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
   5396 }
   5397 
   5398 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
   5399   VIXL_ASSERT(AllowAssembler());
   5400   CheckIT(cond);
   5401   if (operand.IsImmediateZero()) {
   5402     Register rn = operand.GetBaseRegister();
   5403     if (IsUsingT32()) {
   5404       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   5405       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   5406         EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5407         AdvanceIT();
   5408         return;
   5409       }
   5410     } else {
   5411       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   5412       if (operand.IsOffset() && cond.IsNotNever() &&
   5413           (!rn.IsPC() || AllowUnpredictable())) {
   5414         EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
   5415                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5416         return;
   5417       }
   5418     }
   5419   }
   5420   Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
   5421 }
   5422 
   5423 void Assembler::ldrh(Condition cond,
   5424                      EncodingSize size,
   5425                      Register rt,
   5426                      const MemOperand& operand) {
   5427   VIXL_ASSERT(AllowAssembler());
   5428   CheckIT(cond);
   5429   if (operand.IsImmediate()) {
   5430     Register rn = operand.GetBaseRegister();
   5431     int32_t offset = operand.GetOffsetImmediate();
   5432     if (IsUsingT32()) {
   5433       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   5434       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   5435           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
   5436         int32_t offset_ = offset >> 1;
   5437         EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
   5438                    ((offset_ & 0x1f) << 6));
   5439         AdvanceIT();
   5440         return;
   5441       }
   5442       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   5443       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5444           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5445         EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5446                    (offset & 0xfff));
   5447         AdvanceIT();
   5448         return;
   5449       }
   5450       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   5451       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5452           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5453         EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5454                    (-offset & 0xff));
   5455         AdvanceIT();
   5456         return;
   5457       }
   5458       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   5459       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5460           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5461         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5462         uint32_t offset_ = abs(offset);
   5463         EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5464                    offset_ | (sign << 9));
   5465         AdvanceIT();
   5466         return;
   5467       }
   5468       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   5469       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5470           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5471         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5472         uint32_t offset_ = abs(offset);
   5473         EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5474                    offset_ | (sign << 9));
   5475         AdvanceIT();
   5476         return;
   5477       }
   5478       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   5479       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   5480           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   5481         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5482         uint32_t offset_ = abs(offset);
   5483         EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   5484         AdvanceIT();
   5485         return;
   5486       }
   5487     } else {
   5488       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   5489       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   5490           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5491         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5492         uint32_t offset_ = abs(offset);
   5493         EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
   5494                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5495                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5496         return;
   5497       }
   5498       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   5499       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   5500           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5501         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5502         uint32_t offset_ = abs(offset);
   5503         EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
   5504                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5505                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5506         return;
   5507       }
   5508       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   5509       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   5510           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5511         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5512         uint32_t offset_ = abs(offset);
   5513         EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
   5514                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5515                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5516         return;
   5517       }
   5518       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   5519       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5520           operand.IsOffset() && cond.IsNotNever()) {
   5521         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5522         uint32_t offset_ = abs(offset);
   5523         EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
   5524                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   5525                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5526         return;
   5527       }
   5528     }
   5529   }
   5530   if (operand.IsPlainRegister()) {
   5531     Register rn = operand.GetBaseRegister();
   5532     Sign sign = operand.GetSign();
   5533     Register rm = operand.GetOffsetRegister();
   5534     if (IsUsingT32()) {
   5535       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   5536       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   5537           sign.IsPlus() && operand.IsOffset()) {
   5538         EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
   5539                    (rm.GetCode() << 6));
   5540         AdvanceIT();
   5541         return;
   5542       }
   5543     } else {
   5544       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   5545       if (operand.IsOffset() && cond.IsNotNever()) {
   5546         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5547         EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
   5548                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5549                 (sign_ << 23));
   5550         return;
   5551       }
   5552       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   5553       if (operand.IsPostIndex() && cond.IsNotNever()) {
   5554         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5555         EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
   5556                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5557                 (sign_ << 23));
   5558         return;
   5559       }
   5560       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   5561       if (operand.IsPreIndex() && cond.IsNotNever()) {
   5562         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5563         EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
   5564                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5565                 (sign_ << 23));
   5566         return;
   5567       }
   5568     }
   5569   }
   5570   if (operand.IsShiftedRegister()) {
   5571     Register rn = operand.GetBaseRegister();
   5572     Sign sign = operand.GetSign();
   5573     Register rm = operand.GetOffsetRegister();
   5574     Shift shift = operand.GetShift();
   5575     uint32_t amount = operand.GetShiftAmount();
   5576     if (IsUsingT32()) {
   5577       // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   5578       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   5579           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5580         EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5581                    rm.GetCode() | (amount << 4));
   5582         AdvanceIT();
   5583         return;
   5584       }
   5585     }
   5586   }
   5587   Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
   5588 }
   5589 
   5590 void Assembler::ldrh(Condition cond, Register rt, Label* label) {
   5591   VIXL_ASSERT(AllowAssembler());
   5592   CheckIT(cond);
   5593   Label::Offset offset =
   5594       label->IsBound()
   5595           ? label->GetLocation() -
   5596                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5597           : 0;
   5598   if (IsUsingT32()) {
   5599     // LDRH{<c>}{<q>} <Rt>, <label> ; T1
   5600     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5601          !label->IsBound()) &&
   5602         !rt.Is(pc)) {
   5603       static class EmitOp : public Label::LabelEmitOperator {
   5604        public:
   5605         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   5606         virtual uint32_t Encode(uint32_t instr,
   5607                                 Label::Offset pc,
   5608                                 const Label* label) const VIXL_OVERRIDE {
   5609           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   5610           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   5611           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   5612           int32_t target = abs(offset) | (U << 12);
   5613           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5614         }
   5615       } immop;
   5616       EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12), label, immop));
   5617       AdvanceIT();
   5618       return;
   5619     }
   5620   } else {
   5621     // LDRH{<c>}{<q>} <Rt>, <label> ; A1
   5622     if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
   5623          !label->IsBound()) &&
   5624         cond.IsNotNever()) {
   5625       static class EmitOp : public Label::LabelEmitOperator {
   5626        public:
   5627         EmitOp() : Label::LabelEmitOperator(-255, 255) {}
   5628         virtual uint32_t Encode(uint32_t instr,
   5629                                 Label::Offset pc,
   5630                                 const Label* label) const VIXL_OVERRIDE {
   5631           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   5632           VIXL_ASSERT((offset >= -255) && (offset <= 255));
   5633           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   5634           int32_t target = abs(offset) | (U << 8);
   5635           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   5636                  ((target & 0x100) << 15);
   5637         }
   5638       } immop;
   5639       EmitA32(
   5640           Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5641                label,
   5642                immop));
   5643       return;
   5644     }
   5645   }
   5646   Delegate(kLdrh, &Assembler::ldrh, cond, rt, label);
   5647 }
   5648 
   5649 void Assembler::ldrsb(Condition cond,
   5650                       EncodingSize size,
   5651                       Register rt,
   5652                       const MemOperand& operand) {
   5653   VIXL_ASSERT(AllowAssembler());
   5654   CheckIT(cond);
   5655   if (operand.IsImmediate()) {
   5656     Register rn = operand.GetBaseRegister();
   5657     int32_t offset = operand.GetOffsetImmediate();
   5658     if (IsUsingT32()) {
   5659       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   5660       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5661           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5662         EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5663                    (offset & 0xfff));
   5664         AdvanceIT();
   5665         return;
   5666       }
   5667       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
   5668       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5669           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5670         EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5671                    (-offset & 0xff));
   5672         AdvanceIT();
   5673         return;
   5674       }
   5675       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
   5676       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5677           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5678         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5679         uint32_t offset_ = abs(offset);
   5680         EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5681                    offset_ | (sign << 9));
   5682         AdvanceIT();
   5683         return;
   5684       }
   5685       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
   5686       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5687           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5688         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5689         uint32_t offset_ = abs(offset);
   5690         EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5691                    offset_ | (sign << 9));
   5692         AdvanceIT();
   5693         return;
   5694       }
   5695       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   5696       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   5697           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   5698         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5699         uint32_t offset_ = abs(offset);
   5700         EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   5701         AdvanceIT();
   5702         return;
   5703       }
   5704     } else {
   5705       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
   5706       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   5707           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5708         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5709         uint32_t offset_ = abs(offset);
   5710         EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
   5711                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5712                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5713         return;
   5714       }
   5715       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
   5716       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   5717           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5718         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5719         uint32_t offset_ = abs(offset);
   5720         EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
   5721                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5722                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5723         return;
   5724       }
   5725       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
   5726       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   5727           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5728         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5729         uint32_t offset_ = abs(offset);
   5730         EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
   5731                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5732                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5733         return;
   5734       }
   5735       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   5736       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5737           operand.IsOffset() && cond.IsNotNever()) {
   5738         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5739         uint32_t offset_ = abs(offset);
   5740         EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
   5741                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   5742                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5743         return;
   5744       }
   5745     }
   5746   }
   5747   if (operand.IsPlainRegister()) {
   5748     Register rn = operand.GetBaseRegister();
   5749     Sign sign = operand.GetSign();
   5750     Register rm = operand.GetOffsetRegister();
   5751     if (IsUsingT32()) {
   5752       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   5753       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   5754           sign.IsPlus() && operand.IsOffset()) {
   5755         EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
   5756                    (rm.GetCode() << 6));
   5757         AdvanceIT();
   5758         return;
   5759       }
   5760     } else {
   5761       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   5762       if (operand.IsOffset() && cond.IsNotNever()) {
   5763         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5764         EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
   5765                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5766                 (sign_ << 23));
   5767         return;
   5768       }
   5769       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   5770       if (operand.IsPostIndex() && cond.IsNotNever()) {
   5771         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5772         EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
   5773                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5774                 (sign_ << 23));
   5775         return;
   5776       }
   5777       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   5778       if (operand.IsPreIndex() && cond.IsNotNever()) {
   5779         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5780         EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
   5781                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5782                 (sign_ << 23));
   5783         return;
   5784       }
   5785     }
   5786   }
   5787   if (operand.IsShiftedRegister()) {
   5788     Register rn = operand.GetBaseRegister();
   5789     Sign sign = operand.GetSign();
   5790     Register rm = operand.GetOffsetRegister();
   5791     Shift shift = operand.GetShift();
   5792     uint32_t amount = operand.GetShiftAmount();
   5793     if (IsUsingT32()) {
   5794       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   5795       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   5796           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5797         EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5798                    rm.GetCode() | (amount << 4));
   5799         AdvanceIT();
   5800         return;
   5801       }
   5802     }
   5803   }
   5804   Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
   5805 }
   5806 
   5807 void Assembler::ldrsb(Condition cond, Register rt, Label* label) {
   5808   VIXL_ASSERT(AllowAssembler());
   5809   CheckIT(cond);
   5810   Label::Offset offset =
   5811       label->IsBound()
   5812           ? label->GetLocation() -
   5813                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5814           : 0;
   5815   if (IsUsingT32()) {
   5816     // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
   5817     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5818          !label->IsBound()) &&
   5819         !rt.Is(pc)) {
   5820       static class EmitOp : public Label::LabelEmitOperator {
   5821        public:
   5822         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   5823         virtual uint32_t Encode(uint32_t instr,
   5824                                 Label::Offset pc,
   5825                                 const Label* label) const VIXL_OVERRIDE {
   5826           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   5827           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   5828           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   5829           int32_t target = abs(offset) | (U << 12);
   5830           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5831         }
   5832       } immop;
   5833       EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12), label, immop));
   5834       AdvanceIT();
   5835       return;
   5836     }
   5837   } else {
   5838     // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
   5839     if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
   5840          !label->IsBound()) &&
   5841         cond.IsNotNever()) {
   5842       static class EmitOp : public Label::LabelEmitOperator {
   5843        public:
   5844         EmitOp() : Label::LabelEmitOperator(-255, 255) {}
   5845         virtual uint32_t Encode(uint32_t instr,
   5846                                 Label::Offset pc,
   5847                                 const Label* label) const VIXL_OVERRIDE {
   5848           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   5849           VIXL_ASSERT((offset >= -255) && (offset <= 255));
   5850           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   5851           int32_t target = abs(offset) | (U << 8);
   5852           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   5853                  ((target & 0x100) << 15);
   5854         }
   5855       } immop;
   5856       EmitA32(
   5857           Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5858                label,
   5859                immop));
   5860       return;
   5861     }
   5862   }
   5863   Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, label);
   5864 }
   5865 
   5866 void Assembler::ldrsh(Condition cond,
   5867                       EncodingSize size,
   5868                       Register rt,
   5869                       const MemOperand& operand) {
   5870   VIXL_ASSERT(AllowAssembler());
   5871   CheckIT(cond);
   5872   if (operand.IsImmediate()) {
   5873     Register rn = operand.GetBaseRegister();
   5874     int32_t offset = operand.GetOffsetImmediate();
   5875     if (IsUsingT32()) {
   5876       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   5877       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5878           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5879         EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5880                    (offset & 0xfff));
   5881         AdvanceIT();
   5882         return;
   5883       }
   5884       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
   5885       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5886           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5887         EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5888                    (-offset & 0xff));
   5889         AdvanceIT();
   5890         return;
   5891       }
   5892       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
   5893       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5894           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5895         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5896         uint32_t offset_ = abs(offset);
   5897         EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5898                    offset_ | (sign << 9));
   5899         AdvanceIT();
   5900         return;
   5901       }
   5902       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
   5903       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5904           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5905         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5906         uint32_t offset_ = abs(offset);
   5907         EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5908                    offset_ | (sign << 9));
   5909         AdvanceIT();
   5910         return;
   5911       }
   5912       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   5913       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   5914           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   5915         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5916         uint32_t offset_ = abs(offset);
   5917         EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   5918         AdvanceIT();
   5919         return;
   5920       }
   5921     } else {
   5922       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
   5923       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   5924           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5925         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5926         uint32_t offset_ = abs(offset);
   5927         EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
   5928                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5929                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5930         return;
   5931       }
   5932       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
   5933       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   5934           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5935         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5936         uint32_t offset_ = abs(offset);
   5937         EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
   5938                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5939                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5940         return;
   5941       }
   5942       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
   5943       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   5944           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5945         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5946         uint32_t offset_ = abs(offset);
   5947         EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
   5948                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5949                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5950         return;
   5951       }
   5952       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   5953       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5954           operand.IsOffset() && cond.IsNotNever()) {
   5955         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5956         uint32_t offset_ = abs(offset);
   5957         EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
   5958                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   5959                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5960         return;
   5961       }
   5962     }
   5963   }
   5964   if (operand.IsPlainRegister()) {
   5965     Register rn = operand.GetBaseRegister();
   5966     Sign sign = operand.GetSign();
   5967     Register rm = operand.GetOffsetRegister();
   5968     if (IsUsingT32()) {
   5969       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   5970       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   5971           sign.IsPlus() && operand.IsOffset()) {
   5972         EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
   5973                    (rm.GetCode() << 6));
   5974         AdvanceIT();
   5975         return;
   5976       }
   5977     } else {
   5978       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   5979       if (operand.IsOffset() && cond.IsNotNever()) {
   5980         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5981         EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
   5982                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5983                 (sign_ << 23));
   5984         return;
   5985       }
   5986       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   5987       if (operand.IsPostIndex() && cond.IsNotNever()) {
   5988         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5989         EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
   5990                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5991                 (sign_ << 23));
   5992         return;
   5993       }
   5994       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   5995       if (operand.IsPreIndex() && cond.IsNotNever()) {
   5996         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5997         EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
   5998                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5999                 (sign_ << 23));
   6000         return;
   6001       }
   6002     }
   6003   }
   6004   if (operand.IsShiftedRegister()) {
   6005     Register rn = operand.GetBaseRegister();
   6006     Sign sign = operand.GetSign();
   6007     Register rm = operand.GetOffsetRegister();
   6008     Shift shift = operand.GetShift();
   6009     uint32_t amount = operand.GetShiftAmount();
   6010     if (IsUsingT32()) {
   6011       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   6012       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   6013           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6014         EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6015                    rm.GetCode() | (amount << 4));
   6016         AdvanceIT();
   6017         return;
   6018       }
   6019     }
   6020   }
   6021   Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
   6022 }
   6023 
   6024 void Assembler::ldrsh(Condition cond, Register rt, Label* label) {
   6025   VIXL_ASSERT(AllowAssembler());
   6026   CheckIT(cond);
   6027   Label::Offset offset =
   6028       label->IsBound()
   6029           ? label->GetLocation() -
   6030                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   6031           : 0;
   6032   if (IsUsingT32()) {
   6033     // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
   6034     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   6035          !label->IsBound()) &&
   6036         !rt.Is(pc)) {
   6037       static class EmitOp : public Label::LabelEmitOperator {
   6038        public:
   6039         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   6040         virtual uint32_t Encode(uint32_t instr,
   6041                                 Label::Offset pc,
   6042                                 const Label* label) const VIXL_OVERRIDE {
   6043           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   6044           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   6045           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   6046           int32_t target = abs(offset) | (U << 12);
   6047           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   6048         }
   6049       } immop;
   6050       EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12), label, immop));
   6051       AdvanceIT();
   6052       return;
   6053     }
   6054   } else {
   6055     // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
   6056     if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
   6057          !label->IsBound()) &&
   6058         cond.IsNotNever()) {
   6059       static class EmitOp : public Label::LabelEmitOperator {
   6060        public:
   6061         EmitOp() : Label::LabelEmitOperator(-255, 255) {}
   6062         virtual uint32_t Encode(uint32_t instr,
   6063                                 Label::Offset pc,
   6064                                 const Label* label) const VIXL_OVERRIDE {
   6065           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   6066           VIXL_ASSERT((offset >= -255) && (offset <= 255));
   6067           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   6068           int32_t target = abs(offset) | (U << 8);
   6069           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   6070                  ((target & 0x100) << 15);
   6071         }
   6072       } immop;
   6073       EmitA32(
   6074           Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   6075                label,
   6076                immop));
   6077       return;
   6078     }
   6079   }
   6080   Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, label);
   6081 }
   6082 
   6083 void Assembler::lsl(Condition cond,
   6084                     EncodingSize size,
   6085                     Register rd,
   6086                     Register rm,
   6087                     const Operand& operand) {
   6088   VIXL_ASSERT(AllowAssembler());
   6089   CheckIT(cond);
   6090   if (operand.IsImmediate()) {
   6091     uint32_t imm = operand.GetImmediate();
   6092     if (IsUsingT32()) {
   6093       // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6094       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6095           (imm >= 1) && (imm <= 31)) {
   6096         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
   6097         AdvanceIT();
   6098         return;
   6099       }
   6100       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6101       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
   6102         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6103                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   6104         AdvanceIT();
   6105         return;
   6106       }
   6107     } else {
   6108       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6109       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   6110         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
   6111                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   6112         return;
   6113       }
   6114     }
   6115   }
   6116   if (operand.IsPlainRegister()) {
   6117     Register rs = operand.GetBaseRegister();
   6118     if (IsUsingT32()) {
   6119       // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6120       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6121           rs.IsLow()) {
   6122         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   6123         AdvanceIT();
   6124         return;
   6125       }
   6126       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6127       if (!size.IsNarrow()) {
   6128         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6129                    rs.GetCode());
   6130         AdvanceIT();
   6131         return;
   6132       }
   6133     } else {
   6134       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6135       if (cond.IsNotNever()) {
   6136         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
   6137                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6138         return;
   6139       }
   6140     }
   6141   }
   6142   Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
   6143 }
   6144 
   6145 void Assembler::lsls(Condition cond,
   6146                      EncodingSize size,
   6147                      Register rd,
   6148                      Register rm,
   6149                      const Operand& operand) {
   6150   VIXL_ASSERT(AllowAssembler());
   6151   CheckIT(cond);
   6152   if (operand.IsImmediate()) {
   6153     uint32_t imm = operand.GetImmediate();
   6154     if (IsUsingT32()) {
   6155       // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6156       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6157           (imm >= 1) && (imm <= 31)) {
   6158         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
   6159         AdvanceIT();
   6160         return;
   6161       }
   6162       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6163       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
   6164         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6165                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   6166         AdvanceIT();
   6167         return;
   6168       }
   6169     } else {
   6170       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6171       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   6172         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
   6173                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   6174         return;
   6175       }
   6176     }
   6177   }
   6178   if (operand.IsPlainRegister()) {
   6179     Register rs = operand.GetBaseRegister();
   6180     if (IsUsingT32()) {
   6181       // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6182       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6183           rs.IsLow()) {
   6184         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   6185         AdvanceIT();
   6186         return;
   6187       }
   6188       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6189       if (!size.IsNarrow()) {
   6190         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6191                    rs.GetCode());
   6192         AdvanceIT();
   6193         return;
   6194       }
   6195     } else {
   6196       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6197       if (cond.IsNotNever()) {
   6198         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
   6199                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6200         return;
   6201       }
   6202     }
   6203   }
   6204   Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
   6205 }
   6206 
   6207 void Assembler::lsr(Condition cond,
   6208                     EncodingSize size,
   6209                     Register rd,
   6210                     Register rm,
   6211                     const Operand& operand) {
   6212   VIXL_ASSERT(AllowAssembler());
   6213   CheckIT(cond);
   6214   if (operand.IsImmediate()) {
   6215     uint32_t imm = operand.GetImmediate();
   6216     if (IsUsingT32()) {
   6217       // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6218       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6219           (imm >= 1) && (imm <= 32)) {
   6220         uint32_t amount_ = imm % 32;
   6221         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
   6222                    (amount_ << 6));
   6223         AdvanceIT();
   6224         return;
   6225       }
   6226       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6227       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
   6228         uint32_t amount_ = imm % 32;
   6229         EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
   6230                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6231         AdvanceIT();
   6232         return;
   6233       }
   6234     } else {
   6235       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6236       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   6237         uint32_t amount_ = imm % 32;
   6238         EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
   6239                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   6240         return;
   6241       }
   6242     }
   6243   }
   6244   if (operand.IsPlainRegister()) {
   6245     Register rs = operand.GetBaseRegister();
   6246     if (IsUsingT32()) {
   6247       // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6248       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6249           rs.IsLow()) {
   6250         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   6251         AdvanceIT();
   6252         return;
   6253       }
   6254       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6255       if (!size.IsNarrow()) {
   6256         EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6257                    rs.GetCode());
   6258         AdvanceIT();
   6259         return;
   6260       }
   6261     } else {
   6262       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6263       if (cond.IsNotNever()) {
   6264         EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
   6265                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6266         return;
   6267       }
   6268     }
   6269   }
   6270   Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
   6271 }
   6272 
   6273 void Assembler::lsrs(Condition cond,
   6274                      EncodingSize size,
   6275                      Register rd,
   6276                      Register rm,
   6277                      const Operand& operand) {
   6278   VIXL_ASSERT(AllowAssembler());
   6279   CheckIT(cond);
   6280   if (operand.IsImmediate()) {
   6281     uint32_t imm = operand.GetImmediate();
   6282     if (IsUsingT32()) {
   6283       // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6284       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6285           (imm >= 1) && (imm <= 32)) {
   6286         uint32_t amount_ = imm % 32;
   6287         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
   6288                    (amount_ << 6));
   6289         AdvanceIT();
   6290         return;
   6291       }
   6292       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6293       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
   6294         uint32_t amount_ = imm % 32;
   6295         EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
   6296                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6297         AdvanceIT();
   6298         return;
   6299       }
   6300     } else {
   6301       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6302       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   6303         uint32_t amount_ = imm % 32;
   6304         EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
   6305                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   6306         return;
   6307       }
   6308     }
   6309   }
   6310   if (operand.IsPlainRegister()) {
   6311     Register rs = operand.GetBaseRegister();
   6312     if (IsUsingT32()) {
   6313       // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6314       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6315           rs.IsLow()) {
   6316         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   6317         AdvanceIT();
   6318         return;
   6319       }
   6320       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6321       if (!size.IsNarrow()) {
   6322         EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6323                    rs.GetCode());
   6324         AdvanceIT();
   6325         return;
   6326       }
   6327     } else {
   6328       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6329       if (cond.IsNotNever()) {
   6330         EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
   6331                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6332         return;
   6333       }
   6334     }
   6335   }
   6336   Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
   6337 }
   6338 
   6339 void Assembler::mla(
   6340     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   6341   VIXL_ASSERT(AllowAssembler());
   6342   CheckIT(cond);
   6343   if (IsUsingT32()) {
   6344     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   6345     if (!ra.Is(pc)) {
   6346       EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   6347                  rm.GetCode() | (ra.GetCode() << 12));
   6348       AdvanceIT();
   6349       return;
   6350     }
   6351   } else {
   6352     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   6353     if (cond.IsNotNever()) {
   6354       EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   6355               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   6356       return;
   6357     }
   6358   }
   6359   Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
   6360 }
   6361 
   6362 void Assembler::mlas(
   6363     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   6364   VIXL_ASSERT(AllowAssembler());
   6365   CheckIT(cond);
   6366   if (IsUsingA32()) {
   6367     // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   6368     if (cond.IsNotNever()) {
   6369       EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   6370               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   6371       return;
   6372     }
   6373   }
   6374   Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
   6375 }
   6376 
   6377 void Assembler::mls(
   6378     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   6379   VIXL_ASSERT(AllowAssembler());
   6380   CheckIT(cond);
   6381   if (IsUsingT32()) {
   6382     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   6383     EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   6384                rm.GetCode() | (ra.GetCode() << 12));
   6385     AdvanceIT();
   6386     return;
   6387   } else {
   6388     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   6389     if (cond.IsNotNever()) {
   6390       EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   6391               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   6392       return;
   6393     }
   6394   }
   6395   Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
   6396 }
   6397 
   6398 void Assembler::mov(Condition cond,
   6399                     EncodingSize size,
   6400                     Register rd,
   6401                     const Operand& operand) {
   6402   VIXL_ASSERT(AllowAssembler());
   6403   CheckIT(cond);
   6404   if (operand.IsImmediateShiftedRegister()) {
   6405     Register rm = operand.GetBaseRegister();
   6406     if (operand.IsPlainRegister()) {
   6407       if (IsUsingT32()) {
   6408         // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
   6409         if (!size.IsWide() &&
   6410             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   6411              AllowUnpredictable())) {
   6412           EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
   6413                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   6414           AdvanceIT();
   6415           return;
   6416         }
   6417       }
   6418     }
   6419     Shift shift = operand.GetShift();
   6420     uint32_t amount = operand.GetShiftAmount();
   6421     if (IsUsingT32()) {
   6422       // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   6423       if (InITBlock() && !size.IsWide() && rd.IsLow() &&
   6424           shift.IsValidAmount(amount) && rm.IsLow() &&
   6425           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) &&
   6426           ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) {
   6427         uint32_t amount_ = amount % 32;
   6428         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
   6429                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
   6430         AdvanceIT();
   6431         return;
   6432       }
   6433       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
   6434       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   6435           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6436         uint32_t amount_ = amount % 32;
   6437         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6438                    (operand.GetTypeEncodingValue() << 4) |
   6439                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6440         AdvanceIT();
   6441         return;
   6442       }
   6443     } else {
   6444       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   6445       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   6446         uint32_t amount_ = amount % 32;
   6447         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
   6448                 (rd.GetCode() << 12) | rm.GetCode() |
   6449                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   6450         return;
   6451       }
   6452     }
   6453   }
   6454   if (operand.IsRegisterShiftedRegister()) {
   6455     Register rm = operand.GetBaseRegister();
   6456     Shift shift = operand.GetShift();
   6457     if (IsUsingT32()) {
   6458       // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
   6459       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6460           shift.IsASR() && operand.GetShiftRegister().IsLow()) {
   6461         EmitT32_16(0x4100 | rd.GetCode() |
   6462                    (operand.GetShiftRegister().GetCode() << 3));
   6463         AdvanceIT();
   6464         return;
   6465       }
   6466       // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
   6467       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6468           shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
   6469         EmitT32_16(0x4080 | rd.GetCode() |
   6470                    (operand.GetShiftRegister().GetCode() << 3));
   6471         AdvanceIT();
   6472         return;
   6473       }
   6474       // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
   6475       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6476           shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
   6477         EmitT32_16(0x40c0 | rd.GetCode() |
   6478                    (operand.GetShiftRegister().GetCode() << 3));
   6479         AdvanceIT();
   6480         return;
   6481       }
   6482       // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
   6483       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6484           shift.IsROR() && operand.GetShiftRegister().IsLow()) {
   6485         EmitT32_16(0x41c0 | rd.GetCode() |
   6486                    (operand.GetShiftRegister().GetCode() << 3));
   6487         AdvanceIT();
   6488         return;
   6489       }
   6490       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
   6491       if (!size.IsNarrow() &&
   6492           ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
   6493            AllowUnpredictable())) {
   6494         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6495                    (shift.GetType() << 21) |
   6496                    operand.GetShiftRegister().GetCode());
   6497         AdvanceIT();
   6498         return;
   6499       }
   6500     } else {
   6501       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   6502       if (cond.IsNotNever() &&
   6503           ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
   6504            AllowUnpredictable())) {
   6505         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
   6506                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   6507                 (operand.GetShiftRegister().GetCode() << 8));
   6508         return;
   6509       }
   6510     }
   6511   }
   6512   if (operand.IsImmediate()) {
   6513     uint32_t imm = operand.GetImmediate();
   6514     if (IsUsingT32()) {
   6515       ImmediateT32 immediate_t32(imm);
   6516       // MOV<c>{<q>} <Rd>, #<imm8> ; T1
   6517       if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
   6518         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
   6519         AdvanceIT();
   6520         return;
   6521       }
   6522       // MOV{<c>}{<q>} <Rd>, #<const> ; T2
   6523       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   6524           (!rd.IsPC() || AllowUnpredictable())) {
   6525         EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
   6526                    (immediate_t32.GetEncodingValue() & 0xff) |
   6527                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   6528                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   6529         AdvanceIT();
   6530         return;
   6531       }
   6532       // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
   6533       if (!size.IsNarrow() && (imm <= 65535) &&
   6534           (!rd.IsPC() || AllowUnpredictable())) {
   6535         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
   6536                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   6537                    ((imm & 0xf000) << 4));
   6538         AdvanceIT();
   6539         return;
   6540       }
   6541     } else {
   6542       ImmediateA32 immediate_a32(imm);
   6543       // MOV{<c>}{<q>} <Rd>, #<const> ; A1
   6544       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   6545         EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
   6546                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   6547         return;
   6548       }
   6549       // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
   6550       if ((imm <= 65535) && cond.IsNotNever() &&
   6551           (!rd.IsPC() || AllowUnpredictable())) {
   6552         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
   6553                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   6554         return;
   6555       }
   6556     }
   6557   }
   6558   Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
   6559 }
   6560 
   6561 void Assembler::movs(Condition cond,
   6562                      EncodingSize size,
   6563                      Register rd,
   6564                      const Operand& operand) {
   6565   VIXL_ASSERT(AllowAssembler());
   6566   CheckIT(cond);
   6567   if (operand.IsImmediateShiftedRegister()) {
   6568     Register rm = operand.GetBaseRegister();
   6569     Shift shift = operand.GetShift();
   6570     uint32_t amount = operand.GetShiftAmount();
   6571     if (IsUsingT32()) {
   6572       // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   6573       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
   6574           shift.IsValidAmount(amount) && rm.IsLow() &&
   6575           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
   6576         uint32_t amount_ = amount % 32;
   6577         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
   6578                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
   6579         AdvanceIT();
   6580         return;
   6581       }
   6582       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
   6583       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   6584           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6585         uint32_t amount_ = amount % 32;
   6586         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6587                    (operand.GetTypeEncodingValue() << 4) |
   6588                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6589         AdvanceIT();
   6590         return;
   6591       }
   6592     } else {
   6593       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   6594       if (shift.IsValidAmount(amount) && cond.IsNotNever() &&
   6595           (!rd.IsPC() || AllowUnpredictable())) {
   6596         uint32_t amount_ = amount % 32;
   6597         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
   6598                 (rd.GetCode() << 12) | rm.GetCode() |
   6599                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   6600         return;
   6601       }
   6602     }
   6603   }
   6604   if (operand.IsRegisterShiftedRegister()) {
   6605     Register rm = operand.GetBaseRegister();
   6606     Shift shift = operand.GetShift();
   6607     if (IsUsingT32()) {
   6608       // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
   6609       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6610           shift.IsASR() && operand.GetShiftRegister().IsLow()) {
   6611         EmitT32_16(0x4100 | rd.GetCode() |
   6612                    (operand.GetShiftRegister().GetCode() << 3));
   6613         AdvanceIT();
   6614         return;
   6615       }
   6616       // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
   6617       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6618           shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
   6619         EmitT32_16(0x4080 | rd.GetCode() |
   6620                    (operand.GetShiftRegister().GetCode() << 3));
   6621         AdvanceIT();
   6622         return;
   6623       }
   6624       // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
   6625       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6626           shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
   6627         EmitT32_16(0x40c0 | rd.GetCode() |
   6628                    (operand.GetShiftRegister().GetCode() << 3));
   6629         AdvanceIT();
   6630         return;
   6631       }
   6632       // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
   6633       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6634           shift.IsROR() && operand.GetShiftRegister().IsLow()) {
   6635         EmitT32_16(0x41c0 | rd.GetCode() |
   6636                    (operand.GetShiftRegister().GetCode() << 3));
   6637         AdvanceIT();
   6638         return;
   6639       }
   6640       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
   6641       if (!size.IsNarrow() &&
   6642           ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
   6643            AllowUnpredictable())) {
   6644         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6645                    (shift.GetType() << 21) |
   6646                    operand.GetShiftRegister().GetCode());
   6647         AdvanceIT();
   6648         return;
   6649       }
   6650     } else {
   6651       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   6652       if (cond.IsNotNever() &&
   6653           ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
   6654            AllowUnpredictable())) {
   6655         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
   6656                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   6657                 (operand.GetShiftRegister().GetCode() << 8));
   6658         return;
   6659       }
   6660     }
   6661   }
   6662   if (operand.IsImmediate()) {
   6663     uint32_t imm = operand.GetImmediate();
   6664     if (IsUsingT32()) {
   6665       ImmediateT32 immediate_t32(imm);
   6666       // MOVS{<q>} <Rd>, #<imm8> ; T1
   6667       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
   6668         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
   6669         AdvanceIT();
   6670         return;
   6671       }
   6672       // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
   6673       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   6674           (!rd.IsPC() || AllowUnpredictable())) {
   6675         EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
   6676                    (immediate_t32.GetEncodingValue() & 0xff) |
   6677                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   6678                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   6679         AdvanceIT();
   6680         return;
   6681       }
   6682     } else {
   6683       ImmediateA32 immediate_a32(imm);
   6684       // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
   6685       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   6686         EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
   6687                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   6688         return;
   6689       }
   6690     }
   6691   }
   6692   Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
   6693 }
   6694 
   6695 void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
   6696   VIXL_ASSERT(AllowAssembler());
   6697   CheckIT(cond);
   6698   if (operand.IsImmediate()) {
   6699     uint32_t imm = operand.GetImmediate();
   6700     if (IsUsingT32()) {
   6701       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
   6702       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
   6703         EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
   6704                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   6705                    ((imm & 0xf000) << 4));
   6706         AdvanceIT();
   6707         return;
   6708       }
   6709     } else {
   6710       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
   6711       if ((imm <= 65535) && cond.IsNotNever() &&
   6712           (!rd.IsPC() || AllowUnpredictable())) {
   6713         EmitA32(0x03400000U | (cond.GetCondition() << 28) |
   6714                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   6715         return;
   6716       }
   6717     }
   6718   }
   6719   Delegate(kMovt, &Assembler::movt, cond, rd, operand);
   6720 }
   6721 
   6722 void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
   6723   VIXL_ASSERT(AllowAssembler());
   6724   CheckIT(cond);
   6725   if (operand.IsImmediate()) {
   6726     uint32_t imm = operand.GetImmediate();
   6727     if (IsUsingT32()) {
   6728       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
   6729       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
   6730         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
   6731                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   6732                    ((imm & 0xf000) << 4));
   6733         AdvanceIT();
   6734         return;
   6735       }
   6736     } else {
   6737       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
   6738       if ((imm <= 65535) && cond.IsNotNever() &&
   6739           (!rd.IsPC() || AllowUnpredictable())) {
   6740         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
   6741                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   6742         return;
   6743       }
   6744     }
   6745   }
   6746   Delegate(kMovw, &Assembler::movw, cond, rd, operand);
   6747 }
   6748 
   6749 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
   6750   VIXL_ASSERT(AllowAssembler());
   6751   CheckIT(cond);
   6752   if (IsUsingT32()) {
   6753     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
   6754     EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
   6755     AdvanceIT();
   6756     return;
   6757   } else {
   6758     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
   6759     if (cond.IsNotNever()) {
   6760       EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   6761               (spec_reg.GetReg() << 22));
   6762       return;
   6763     }
   6764   }
   6765   Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
   6766 }
   6767 
   6768 void Assembler::msr(Condition cond,
   6769                     MaskedSpecialRegister spec_reg,
   6770                     const Operand& operand) {
   6771   VIXL_ASSERT(AllowAssembler());
   6772   CheckIT(cond);
   6773   if (operand.IsImmediate()) {
   6774     uint32_t imm = operand.GetImmediate();
   6775     if (IsUsingA32()) {
   6776       ImmediateA32 immediate_a32(imm);
   6777       // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
   6778       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   6779         EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
   6780                 ((spec_reg.GetReg() & 0xf) << 16) |
   6781                 ((spec_reg.GetReg() & 0x10) << 18) |
   6782                 immediate_a32.GetEncodingValue());
   6783         return;
   6784       }
   6785     }
   6786   }
   6787   if (operand.IsPlainRegister()) {
   6788     Register rn = operand.GetBaseRegister();
   6789     if (IsUsingT32()) {
   6790       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
   6791       EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
   6792                  ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
   6793       AdvanceIT();
   6794       return;
   6795     } else {
   6796       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
   6797       if (cond.IsNotNever()) {
   6798         EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
   6799                 ((spec_reg.GetReg() & 0xf) << 16) |
   6800                 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
   6801         return;
   6802       }
   6803     }
   6804   }
   6805   Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
   6806 }
   6807 
   6808 void Assembler::mul(
   6809     Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
   6810   VIXL_ASSERT(AllowAssembler());
   6811   CheckIT(cond);
   6812   if (IsUsingT32()) {
   6813     // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
   6814     if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
   6815         rm.IsLow()) {
   6816       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
   6817       AdvanceIT();
   6818       return;
   6819     }
   6820     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
   6821     if (!size.IsNarrow()) {
   6822       EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   6823                  rm.GetCode());
   6824       AdvanceIT();
   6825       return;
   6826     }
   6827   } else {
   6828     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
   6829     if (cond.IsNotNever()) {
   6830       EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   6831               rn.GetCode() | (rm.GetCode() << 8));
   6832       return;
   6833     }
   6834   }
   6835   Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
   6836 }
   6837 
   6838 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
   6839   VIXL_ASSERT(AllowAssembler());
   6840   CheckIT(cond);
   6841   if (IsUsingT32()) {
   6842     // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
   6843     if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
   6844       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
   6845       AdvanceIT();
   6846       return;
   6847     }
   6848   } else {
   6849     // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
   6850     if (cond.IsNotNever()) {
   6851       EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   6852               rn.GetCode() | (rm.GetCode() << 8));
   6853       return;
   6854     }
   6855   }
   6856   Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
   6857 }
   6858 
   6859 void Assembler::mvn(Condition cond,
   6860                     EncodingSize size,
   6861                     Register rd,
   6862                     const Operand& operand) {
   6863   VIXL_ASSERT(AllowAssembler());
   6864   CheckIT(cond);
   6865   if (operand.IsImmediate()) {
   6866     uint32_t imm = operand.GetImmediate();
   6867     if (IsUsingT32()) {
   6868       ImmediateT32 immediate_t32(imm);
   6869       // MVN{<c>}{<q>} <Rd>, #<const> ; T1
   6870       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   6871         EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
   6872                    (immediate_t32.GetEncodingValue() & 0xff) |
   6873                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   6874                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   6875         AdvanceIT();
   6876         return;
   6877       }
   6878     } else {
   6879       ImmediateA32 immediate_a32(imm);
   6880       // MVN{<c>}{<q>} <Rd>, #<const> ; A1
   6881       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   6882         EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
   6883                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   6884         return;
   6885       }
   6886     }
   6887   }
   6888   if (operand.IsImmediateShiftedRegister()) {
   6889     Register rm = operand.GetBaseRegister();
   6890     if (operand.IsPlainRegister()) {
   6891       if (IsUsingT32()) {
   6892         // MVN<c>{<q>} <Rd>, <Rm> ; T1
   6893         if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
   6894           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
   6895           AdvanceIT();
   6896           return;
   6897         }
   6898       }
   6899     }
   6900     Shift shift = operand.GetShift();
   6901     uint32_t amount = operand.GetShiftAmount();
   6902     if (IsUsingT32()) {
   6903       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   6904       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   6905         uint32_t amount_ = amount % 32;
   6906         EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6907                    (operand.GetTypeEncodingValue() << 4) |
   6908                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6909         AdvanceIT();
   6910         return;
   6911       }
   6912     } else {
   6913       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   6914       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   6915         uint32_t amount_ = amount % 32;
   6916         EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
   6917                 (rd.GetCode() << 12) | rm.GetCode() |
   6918                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   6919         return;
   6920       }
   6921     }
   6922   }
   6923   if (operand.IsRegisterShiftedRegister()) {
   6924     Register rm = operand.GetBaseRegister();
   6925     Shift shift = operand.GetShift();
   6926     if (IsUsingA32()) {
   6927       // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   6928       if (cond.IsNotNever()) {
   6929         EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
   6930                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   6931                 (operand.GetShiftRegister().GetCode() << 8));
   6932         return;
   6933       }
   6934     }
   6935   }
   6936   Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
   6937 }
   6938 
   6939 void Assembler::mvns(Condition cond,
   6940                      EncodingSize size,
   6941                      Register rd,
   6942                      const Operand& operand) {
   6943   VIXL_ASSERT(AllowAssembler());
   6944   CheckIT(cond);
   6945   if (operand.IsImmediate()) {
   6946     uint32_t imm = operand.GetImmediate();
   6947     if (IsUsingT32()) {
   6948       ImmediateT32 immediate_t32(imm);
   6949       // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
   6950       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   6951         EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
   6952                    (immediate_t32.GetEncodingValue() & 0xff) |
   6953                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   6954                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   6955         AdvanceIT();
   6956         return;
   6957       }
   6958     } else {
   6959       ImmediateA32 immediate_a32(imm);
   6960       // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
   6961       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   6962         EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
   6963                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   6964         return;
   6965       }
   6966     }
   6967   }
   6968   if (operand.IsImmediateShiftedRegister()) {
   6969     Register rm = operand.GetBaseRegister();
   6970     if (operand.IsPlainRegister()) {
   6971       if (IsUsingT32()) {
   6972         // MVNS{<q>} <Rd>, <Rm> ; T1
   6973         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
   6974           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
   6975           AdvanceIT();
   6976           return;
   6977         }
   6978       }
   6979     }
   6980     Shift shift = operand.GetShift();
   6981     uint32_t amount = operand.GetShiftAmount();
   6982     if (IsUsingT32()) {
   6983       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   6984       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   6985         uint32_t amount_ = amount % 32;
   6986         EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6987                    (operand.GetTypeEncodingValue() << 4) |
   6988                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6989         AdvanceIT();
   6990         return;
   6991       }
   6992     } else {
   6993       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   6994       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   6995         uint32_t amount_ = amount % 32;
   6996         EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
   6997                 (rd.GetCode() << 12) | rm.GetCode() |
   6998                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   6999         return;
   7000       }
   7001     }
   7002   }
   7003   if (operand.IsRegisterShiftedRegister()) {
   7004     Register rm = operand.GetBaseRegister();
   7005     Shift shift = operand.GetShift();
   7006     if (IsUsingA32()) {
   7007       // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7008       if (cond.IsNotNever()) {
   7009         EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
   7010                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7011                 (operand.GetShiftRegister().GetCode() << 8));
   7012         return;
   7013       }
   7014     }
   7015   }
   7016   Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
   7017 }
   7018 
   7019 void Assembler::nop(Condition cond, EncodingSize size) {
   7020   VIXL_ASSERT(AllowAssembler());
   7021   CheckIT(cond);
   7022   if (IsUsingT32()) {
   7023     // NOP{<c>}{<q>} ; T1
   7024     if (!size.IsWide()) {
   7025       EmitT32_16(0xbf00);
   7026       AdvanceIT();
   7027       return;
   7028     }
   7029     // NOP{<c>}.W ; T2
   7030     if (!size.IsNarrow()) {
   7031       EmitT32_32(0xf3af8000U);
   7032       AdvanceIT();
   7033       return;
   7034     }
   7035   } else {
   7036     // NOP{<c>}{<q>} ; A1
   7037     if (cond.IsNotNever()) {
   7038       EmitA32(0x0320f000U | (cond.GetCondition() << 28));
   7039       return;
   7040     }
   7041   }
   7042   Delegate(kNop, &Assembler::nop, cond, size);
   7043 }
   7044 
   7045 void Assembler::orn(Condition cond,
   7046                     Register rd,
   7047                     Register rn,
   7048                     const Operand& operand) {
   7049   VIXL_ASSERT(AllowAssembler());
   7050   CheckIT(cond);
   7051   if (operand.IsImmediate()) {
   7052     uint32_t imm = operand.GetImmediate();
   7053     if (IsUsingT32()) {
   7054       ImmediateT32 immediate_t32(imm);
   7055       // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7056       if (immediate_t32.IsValid() && !rn.Is(pc)) {
   7057         EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7058                    (immediate_t32.GetEncodingValue() & 0xff) |
   7059                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7060                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7061         AdvanceIT();
   7062         return;
   7063       }
   7064     }
   7065   }
   7066   if (operand.IsImmediateShiftedRegister()) {
   7067     Register rm = operand.GetBaseRegister();
   7068     Shift shift = operand.GetShift();
   7069     uint32_t amount = operand.GetShiftAmount();
   7070     if (IsUsingT32()) {
   7071       // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   7072       if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
   7073         uint32_t amount_ = amount % 32;
   7074         EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7075                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7076                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7077         AdvanceIT();
   7078         return;
   7079       }
   7080     }
   7081   }
   7082   Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
   7083 }
   7084 
   7085 void Assembler::orns(Condition cond,
   7086                      Register rd,
   7087                      Register rn,
   7088                      const Operand& operand) {
   7089   VIXL_ASSERT(AllowAssembler());
   7090   CheckIT(cond);
   7091   if (operand.IsImmediate()) {
   7092     uint32_t imm = operand.GetImmediate();
   7093     if (IsUsingT32()) {
   7094       ImmediateT32 immediate_t32(imm);
   7095       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7096       if (immediate_t32.IsValid() && !rn.Is(pc)) {
   7097         EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7098                    (immediate_t32.GetEncodingValue() & 0xff) |
   7099                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7100                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7101         AdvanceIT();
   7102         return;
   7103       }
   7104     }
   7105   }
   7106   if (operand.IsImmediateShiftedRegister()) {
   7107     Register rm = operand.GetBaseRegister();
   7108     Shift shift = operand.GetShift();
   7109     uint32_t amount = operand.GetShiftAmount();
   7110     if (IsUsingT32()) {
   7111       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   7112       if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
   7113         uint32_t amount_ = amount % 32;
   7114         EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7115                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7116                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7117         AdvanceIT();
   7118         return;
   7119       }
   7120     }
   7121   }
   7122   Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
   7123 }
   7124 
   7125 void Assembler::orr(Condition cond,
   7126                     EncodingSize size,
   7127                     Register rd,
   7128                     Register rn,
   7129                     const Operand& operand) {
   7130   VIXL_ASSERT(AllowAssembler());
   7131   CheckIT(cond);
   7132   if (operand.IsImmediate()) {
   7133     uint32_t imm = operand.GetImmediate();
   7134     if (IsUsingT32()) {
   7135       ImmediateT32 immediate_t32(imm);
   7136       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7137       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
   7138         EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7139                    (immediate_t32.GetEncodingValue() & 0xff) |
   7140                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7141                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7142         AdvanceIT();
   7143         return;
   7144       }
   7145     } else {
   7146       ImmediateA32 immediate_a32(imm);
   7147       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   7148       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7149         EmitA32(0x03800000U | (cond.GetCondition() << 28) |
   7150                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   7151                 immediate_a32.GetEncodingValue());
   7152         return;
   7153       }
   7154     }
   7155   }
   7156   if (operand.IsImmediateShiftedRegister()) {
   7157     Register rm = operand.GetBaseRegister();
   7158     if (operand.IsPlainRegister()) {
   7159       if (IsUsingT32()) {
   7160         // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   7161         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   7162             rm.IsLow()) {
   7163           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
   7164           AdvanceIT();
   7165           return;
   7166         }
   7167       }
   7168     }
   7169     Shift shift = operand.GetShift();
   7170     uint32_t amount = operand.GetShiftAmount();
   7171     if (IsUsingT32()) {
   7172       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   7173       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
   7174         uint32_t amount_ = amount % 32;
   7175         EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7176                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7177                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7178         AdvanceIT();
   7179         return;
   7180       }
   7181     } else {
   7182       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   7183       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7184         uint32_t amount_ = amount % 32;
   7185         EmitA32(0x01800000U | (cond.GetCondition() << 28) |
   7186                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7187                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7188         return;
   7189       }
   7190     }
   7191   }
   7192   if (operand.IsRegisterShiftedRegister()) {
   7193     Register rm = operand.GetBaseRegister();
   7194     Shift shift = operand.GetShift();
   7195     if (IsUsingA32()) {
   7196       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   7197       if (cond.IsNotNever()) {
   7198         EmitA32(0x01800010U | (cond.GetCondition() << 28) |
   7199                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7200                 (shift.GetType() << 5) |
   7201                 (operand.GetShiftRegister().GetCode() << 8));
   7202         return;
   7203       }
   7204     }
   7205   }
   7206   Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
   7207 }
   7208 
   7209 void Assembler::orrs(Condition cond,
   7210                      EncodingSize size,
   7211                      Register rd,
   7212                      Register rn,
   7213                      const Operand& operand) {
   7214   VIXL_ASSERT(AllowAssembler());
   7215   CheckIT(cond);
   7216   if (operand.IsImmediate()) {
   7217     uint32_t imm = operand.GetImmediate();
   7218     if (IsUsingT32()) {
   7219       ImmediateT32 immediate_t32(imm);
   7220       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7221       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
   7222         EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7223                    (immediate_t32.GetEncodingValue() & 0xff) |
   7224                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7225                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7226         AdvanceIT();
   7227         return;
   7228       }
   7229     } else {
   7230       ImmediateA32 immediate_a32(imm);
   7231       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   7232       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7233         EmitA32(0x03900000U | (cond.GetCondition() << 28) |
   7234                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   7235                 immediate_a32.GetEncodingValue());
   7236         return;
   7237       }
   7238     }
   7239   }
   7240   if (operand.IsImmediateShiftedRegister()) {
   7241     Register rm = operand.GetBaseRegister();
   7242     if (operand.IsPlainRegister()) {
   7243       if (IsUsingT32()) {
   7244         // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   7245         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   7246             rm.IsLow()) {
   7247           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
   7248           AdvanceIT();
   7249           return;
   7250         }
   7251       }
   7252     }
   7253     Shift shift = operand.GetShift();
   7254     uint32_t amount = operand.GetShiftAmount();
   7255     if (IsUsingT32()) {
   7256       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   7257       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
   7258         uint32_t amount_ = amount % 32;
   7259         EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7260                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7261                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7262         AdvanceIT();
   7263         return;
   7264       }
   7265     } else {
   7266       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   7267       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7268         uint32_t amount_ = amount % 32;
   7269         EmitA32(0x01900000U | (cond.GetCondition() << 28) |
   7270                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7271                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7272         return;
   7273       }
   7274     }
   7275   }
   7276   if (operand.IsRegisterShiftedRegister()) {
   7277     Register rm = operand.GetBaseRegister();
   7278     Shift shift = operand.GetShift();
   7279     if (IsUsingA32()) {
   7280       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   7281       if (cond.IsNotNever()) {
   7282         EmitA32(0x01900010U | (cond.GetCondition() << 28) |
   7283                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7284                 (shift.GetType() << 5) |
   7285                 (operand.GetShiftRegister().GetCode() << 8));
   7286         return;
   7287       }
   7288     }
   7289   }
   7290   Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
   7291 }
   7292 
   7293 void Assembler::pkhbt(Condition cond,
   7294                       Register rd,
   7295                       Register rn,
   7296                       const Operand& operand) {
   7297   VIXL_ASSERT(AllowAssembler());
   7298   CheckIT(cond);
   7299   if (operand.IsImmediateShiftedRegister()) {
   7300     Register rm = operand.GetBaseRegister();
   7301     Shift shift = operand.GetShift();
   7302     uint32_t amount = operand.GetShiftAmount();
   7303     if (IsUsingT32()) {
   7304       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
   7305       if (shift.IsLSL() && shift.IsValidAmount(amount)) {
   7306         EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7307                    rm.GetCode() | ((amount & 0x3) << 6) |
   7308                    ((amount & 0x1c) << 10));
   7309         AdvanceIT();
   7310         return;
   7311       }
   7312     } else {
   7313       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
   7314       if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7315         EmitA32(0x06800010U | (cond.GetCondition() << 28) |
   7316                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7317                 (amount << 7));
   7318         return;
   7319       }
   7320     }
   7321   }
   7322   Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
   7323 }
   7324 
   7325 void Assembler::pkhtb(Condition cond,
   7326                       Register rd,
   7327                       Register rn,
   7328                       const Operand& operand) {
   7329   VIXL_ASSERT(AllowAssembler());
   7330   CheckIT(cond);
   7331   if (operand.IsImmediateShiftedRegister()) {
   7332     Register rm = operand.GetBaseRegister();
   7333     Shift shift = operand.GetShift();
   7334     uint32_t amount = operand.GetShiftAmount();
   7335     if (IsUsingT32()) {
   7336       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
   7337       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount)) {
   7338         uint32_t amount_ = amount % 32;
   7339         EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7340                    rm.GetCode() | ((amount_ & 0x3) << 6) |
   7341                    ((amount_ & 0x1c) << 10));
   7342         AdvanceIT();
   7343         return;
   7344       }
   7345     } else {
   7346       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
   7347       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
   7348           cond.IsNotNever()) {
   7349         uint32_t amount_ = amount % 32;
   7350         EmitA32(0x06800050U | (cond.GetCondition() << 28) |
   7351                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7352                 (amount_ << 7));
   7353         return;
   7354       }
   7355     }
   7356   }
   7357   Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
   7358 }
   7359 
   7360 void Assembler::pld(Condition cond, Label* label) {
   7361   VIXL_ASSERT(AllowAssembler());
   7362   CheckIT(cond);
   7363   Label::Offset offset =
   7364       label->IsBound()
   7365           ? label->GetLocation() -
   7366                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   7367           : 0;
   7368   if (IsUsingT32()) {
   7369     // PLD{<c>}{<q>} <label> ; T1
   7370     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   7371          !label->IsBound())) {
   7372       static class EmitOp : public Label::LabelEmitOperator {
   7373        public:
   7374         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   7375         virtual uint32_t Encode(uint32_t instr,
   7376                                 Label::Offset pc,
   7377                                 const Label* label) const VIXL_OVERRIDE {
   7378           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   7379           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   7380           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   7381           int32_t target = abs(offset) | (U << 12);
   7382           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   7383         }
   7384       } immop;
   7385       EmitT32_32(Link(0xf81ff000U, label, immop));
   7386       AdvanceIT();
   7387       return;
   7388     }
   7389   } else {
   7390     // PLD{<c>}{<q>} <label> ; A1
   7391     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   7392          !label->IsBound())) {
   7393       if (cond.Is(al)) {
   7394         static class EmitOp : public Label::LabelEmitOperator {
   7395          public:
   7396           EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   7397           virtual uint32_t Encode(uint32_t instr,
   7398                                   Label::Offset pc,
   7399                                   const Label* label) const VIXL_OVERRIDE {
   7400             Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   7401             VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   7402             uint32_t U = (offset >= 0) && !label->IsMinusZero();
   7403             int32_t target = abs(offset) | (U << 12);
   7404             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   7405           }
   7406         } immop;
   7407         EmitA32(Link(0xf55ff000U, label, immop));
   7408         return;
   7409       }
   7410     }
   7411   }
   7412   Delegate(kPld, &Assembler::pld, cond, label);
   7413 }
   7414 
   7415 void Assembler::pld(Condition cond, const MemOperand& operand) {
   7416   VIXL_ASSERT(AllowAssembler());
   7417   CheckIT(cond);
   7418   if (operand.IsImmediate()) {
   7419     Register rn = operand.GetBaseRegister();
   7420     int32_t offset = operand.GetOffsetImmediate();
   7421     if (IsUsingT32()) {
   7422       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
   7423       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   7424           operand.IsOffset()) {
   7425         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   7426         uint32_t offset_ = abs(offset);
   7427         EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
   7428         AdvanceIT();
   7429         return;
   7430       }
   7431     } else {
   7432       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
   7433       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   7434           operand.IsOffset()) {
   7435         if (cond.Is(al)) {
   7436           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   7437           uint32_t offset_ = abs(offset);
   7438           EmitA32(0xf55ff000U | offset_ | (sign << 23));
   7439           return;
   7440         }
   7441       }
   7442     }
   7443   }
   7444   if (operand.IsImmediate()) {
   7445     Register rn = operand.GetBaseRegister();
   7446     int32_t offset = operand.GetOffsetImmediate();
   7447     if (IsUsingT32()) {
   7448       // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   7449       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   7450           ((rn.GetCode() & 0xf) != 0xf)) {
   7451         EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   7452         AdvanceIT();
   7453         return;
   7454       }
   7455       // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   7456       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   7457           ((rn.GetCode() & 0xf) != 0xf)) {
   7458         EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   7459         AdvanceIT();
   7460         return;
   7461       }
   7462     } else {
   7463       // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
   7464       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   7465           ((rn.GetCode() & 0xf) != 0xf)) {
   7466         if (cond.Is(al)) {
   7467           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   7468           uint32_t offset_ = abs(offset);
   7469           EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   7470           return;
   7471         }
   7472       }
   7473     }
   7474   }
   7475   if (operand.IsShiftedRegister()) {
   7476     Register rn = operand.GetBaseRegister();
   7477     Sign sign = operand.GetSign();
   7478     Register rm = operand.GetOffsetRegister();
   7479     Shift shift = operand.GetShift();
   7480     uint32_t amount = operand.GetShiftAmount();
   7481     if (IsUsingT32()) {
   7482       // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   7483       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   7484           ((rn.GetCode() & 0xf) != 0xf)) {
   7485         EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
   7486                    (amount << 4));
   7487         AdvanceIT();
   7488         return;
   7489       }
   7490     } else {
   7491       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   7492       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
   7493         if (cond.Is(al)) {
   7494           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   7495           uint32_t amount_ = amount % 32;
   7496           EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
   7497                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   7498           return;
   7499         }
   7500       }
   7501       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   7502       if (shift.IsRRX() && operand.IsOffset()) {
   7503         if (cond.Is(al)) {
   7504           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   7505           EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
   7506                   (sign_ << 23));
   7507           return;
   7508         }
   7509       }
   7510     }
   7511   }
   7512   Delegate(kPld, &Assembler::pld, cond, operand);
   7513 }
   7514 
   7515 void Assembler::pldw(Condition cond, const MemOperand& operand) {
   7516   VIXL_ASSERT(AllowAssembler());
   7517   CheckIT(cond);
   7518   if (operand.IsImmediate()) {
   7519     Register rn = operand.GetBaseRegister();
   7520     int32_t offset = operand.GetOffsetImmediate();
   7521     if (IsUsingT32()) {
   7522       // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   7523       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   7524           ((rn.GetCode() & 0xf) != 0xf)) {
   7525         EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   7526         AdvanceIT();
   7527         return;
   7528       }
   7529       // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   7530       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   7531           ((rn.GetCode() & 0xf) != 0xf)) {
   7532         EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   7533         AdvanceIT();
   7534         return;
   7535       }
   7536     } else {
   7537       // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
   7538       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   7539           ((rn.GetCode() & 0xf) != 0xf)) {
   7540         if (cond.Is(al)) {
   7541           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   7542           uint32_t offset_ = abs(offset);
   7543           EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   7544           return;
   7545         }
   7546       }
   7547     }
   7548   }
   7549   if (operand.IsShiftedRegister()) {
   7550     Register rn = operand.GetBaseRegister();
   7551     Sign sign = operand.GetSign();
   7552     Register rm = operand.GetOffsetRegister();
   7553     Shift shift = operand.GetShift();
   7554     uint32_t amount = operand.GetShiftAmount();
   7555     if (IsUsingT32()) {
   7556       // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   7557       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   7558           ((rn.GetCode() & 0xf) != 0xf)) {
   7559         EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
   7560                    (amount << 4));
   7561         AdvanceIT();
   7562         return;
   7563       }
   7564     } else {
   7565       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   7566       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
   7567         if (cond.Is(al)) {
   7568           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   7569           uint32_t amount_ = amount % 32;
   7570           EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
   7571                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   7572           return;
   7573         }
   7574       }
   7575       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   7576       if (shift.IsRRX() && operand.IsOffset()) {
   7577         if (cond.Is(al)) {
   7578           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   7579           EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
   7580                   (sign_ << 23));
   7581           return;
   7582         }
   7583       }
   7584     }
   7585   }
   7586   Delegate(kPldw, &Assembler::pldw, cond, operand);
   7587 }
   7588 
   7589 void Assembler::pli(Condition cond, const MemOperand& operand) {
   7590   VIXL_ASSERT(AllowAssembler());
   7591   CheckIT(cond);
   7592   if (operand.IsImmediate()) {
   7593     Register rn = operand.GetBaseRegister();
   7594     int32_t offset = operand.GetOffsetImmediate();
   7595     if (IsUsingT32()) {
   7596       // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   7597       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   7598           ((rn.GetCode() & 0xf) != 0xf)) {
   7599         EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   7600         AdvanceIT();
   7601         return;
   7602       }
   7603       // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   7604       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   7605           ((rn.GetCode() & 0xf) != 0xf)) {
   7606         EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   7607         AdvanceIT();
   7608         return;
   7609       }
   7610     } else {
   7611       // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
   7612       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   7613           ((rn.GetCode() & 0xf) != 0xf)) {
   7614         if (cond.Is(al)) {
   7615           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   7616           uint32_t offset_ = abs(offset);
   7617           EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   7618           return;
   7619         }
   7620       }
   7621     }
   7622   }
   7623   if (operand.IsImmediate()) {
   7624     Register rn = operand.GetBaseRegister();
   7625     int32_t offset = operand.GetOffsetImmediate();
   7626     if (IsUsingT32()) {
   7627       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
   7628       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   7629           operand.IsOffset()) {
   7630         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   7631         uint32_t offset_ = abs(offset);
   7632         EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
   7633         AdvanceIT();
   7634         return;
   7635       }
   7636     } else {
   7637       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
   7638       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   7639           operand.IsOffset()) {
   7640         if (cond.Is(al)) {
   7641           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   7642           uint32_t offset_ = abs(offset);
   7643           EmitA32(0xf45ff000U | offset_ | (sign << 23));
   7644           return;
   7645         }
   7646       }
   7647     }
   7648   }
   7649   if (operand.IsShiftedRegister()) {
   7650     Register rn = operand.GetBaseRegister();
   7651     Sign sign = operand.GetSign();
   7652     Register rm = operand.GetOffsetRegister();
   7653     Shift shift = operand.GetShift();
   7654     uint32_t amount = operand.GetShiftAmount();
   7655     if (IsUsingT32()) {
   7656       // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   7657       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   7658           ((rn.GetCode() & 0xf) != 0xf)) {
   7659         EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
   7660                    (amount << 4));
   7661         AdvanceIT();
   7662         return;
   7663       }
   7664     } else {
   7665       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   7666       if (shift.IsRRX() && operand.IsOffset()) {
   7667         if (cond.Is(al)) {
   7668           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   7669           EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
   7670                   (sign_ << 23));
   7671           return;
   7672         }
   7673       }
   7674       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   7675       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
   7676         if (cond.Is(al)) {
   7677           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   7678           uint32_t amount_ = amount % 32;
   7679           EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
   7680                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   7681           return;
   7682         }
   7683       }
   7684     }
   7685   }
   7686   Delegate(kPli, &Assembler::pli, cond, operand);
   7687 }
   7688 
   7689 void Assembler::pli(Condition cond, Label* label) {
   7690   VIXL_ASSERT(AllowAssembler());
   7691   CheckIT(cond);
   7692   Label::Offset offset =
   7693       label->IsBound()
   7694           ? label->GetLocation() -
   7695                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   7696           : 0;
   7697   if (IsUsingT32()) {
   7698     // PLI{<c>}{<q>} <label> ; T3
   7699     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   7700          !label->IsBound())) {
   7701       static class EmitOp : public Label::LabelEmitOperator {
   7702        public:
   7703         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   7704         virtual uint32_t Encode(uint32_t instr,
   7705                                 Label::Offset pc,
   7706                                 const Label* label) const VIXL_OVERRIDE {
   7707           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   7708           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   7709           uint32_t U = (offset >= 0) && !label->IsMinusZero();
   7710           int32_t target = abs(offset) | (U << 12);
   7711           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   7712         }
   7713       } immop;
   7714       EmitT32_32(Link(0xf91ff000U, label, immop));
   7715       AdvanceIT();
   7716       return;
   7717     }
   7718   } else {
   7719     // PLI{<c>}{<q>} <label> ; A1
   7720     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   7721          !label->IsBound())) {
   7722       if (cond.Is(al)) {
   7723         static class EmitOp : public Label::LabelEmitOperator {
   7724          public:
   7725           EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
   7726           virtual uint32_t Encode(uint32_t instr,
   7727                                   Label::Offset pc,
   7728                                   const Label* label) const VIXL_OVERRIDE {
   7729             Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   7730             VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   7731             uint32_t U = (offset >= 0) && !label->IsMinusZero();
   7732             int32_t target = abs(offset) | (U << 12);
   7733             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   7734           }
   7735         } immop;
   7736         EmitA32(Link(0xf45ff000U, label, immop));
   7737         return;
   7738       }
   7739     }
   7740   }
   7741   Delegate(kPli, &Assembler::pli, cond, label);
   7742 }
   7743 
   7744 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
   7745   VIXL_ASSERT(AllowAssembler());
   7746   CheckIT(cond);
   7747   if (IsUsingT32()) {
   7748     // POP{<c>}{<q>} <registers> ; T1
   7749     if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) {
   7750       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
   7751                  GetRegisterListEncoding(registers, 0, 8));
   7752       AdvanceIT();
   7753       return;
   7754     }
   7755     // POP{<c>}{<q>} <registers> ; T2
   7756     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
   7757       EmitT32_32(0xe8bd0000U |
   7758                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   7759                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   7760                  GetRegisterListEncoding(registers, 0, 13));
   7761       AdvanceIT();
   7762       return;
   7763     }
   7764   } else {
   7765     // POP{<c>}{<q>} <registers> ; A1
   7766     if (cond.IsNotNever()) {
   7767       EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
   7768               GetRegisterListEncoding(registers, 0, 16));
   7769       return;
   7770     }
   7771   }
   7772   Delegate(kPop, &Assembler::pop, cond, size, registers);
   7773 }
   7774 
   7775 void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
   7776   VIXL_ASSERT(AllowAssembler());
   7777   CheckIT(cond);
   7778   if (IsUsingT32()) {
   7779     // POP{<c>}{<q>} <single_register_list> ; T4
   7780     if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) {
   7781       EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
   7782       AdvanceIT();
   7783       return;
   7784     }
   7785   } else {
   7786     // POP{<c>}{<q>} <single_register_list> ; A1
   7787     if (cond.IsNotNever()) {
   7788       EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
   7789       return;
   7790     }
   7791   }
   7792   Delegate(kPop, &Assembler::pop, cond, size, rt);
   7793 }
   7794 
   7795 void Assembler::push(Condition cond,
   7796                      EncodingSize size,
   7797                      RegisterList registers) {
   7798   VIXL_ASSERT(AllowAssembler());
   7799   CheckIT(cond);
   7800   if (IsUsingT32()) {
   7801     // PUSH{<c>}{<q>} <registers> ; T1
   7802     if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) {
   7803       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
   7804                  GetRegisterListEncoding(registers, 0, 8));
   7805       AdvanceIT();
   7806       return;
   7807     }
   7808     // PUSH{<c>}{<q>} <registers> ; T1
   7809     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
   7810       EmitT32_32(0xe92d0000U |
   7811                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   7812                  GetRegisterListEncoding(registers, 0, 13));
   7813       AdvanceIT();
   7814       return;
   7815     }
   7816   } else {
   7817     // PUSH{<c>}{<q>} <registers> ; A1
   7818     if (cond.IsNotNever()) {
   7819       EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
   7820               GetRegisterListEncoding(registers, 0, 16));
   7821       return;
   7822     }
   7823   }
   7824   Delegate(kPush, &Assembler::push, cond, size, registers);
   7825 }
   7826 
   7827 void Assembler::push(Condition cond, EncodingSize size, Register rt) {
   7828   VIXL_ASSERT(AllowAssembler());
   7829   CheckIT(cond);
   7830   if (IsUsingT32()) {
   7831     // PUSH{<c>}{<q>} <single_register_list> ; T4
   7832     if (!size.IsNarrow()) {
   7833       EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
   7834       AdvanceIT();
   7835       return;
   7836     }
   7837   } else {
   7838     // PUSH{<c>}{<q>} <single_register_list> ; A1
   7839     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   7840       EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
   7841       return;
   7842     }
   7843   }
   7844   Delegate(kPush, &Assembler::push, cond, size, rt);
   7845 }
   7846 
   7847 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
   7848   VIXL_ASSERT(AllowAssembler());
   7849   CheckIT(cond);
   7850   if (IsUsingT32()) {
   7851     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   7852     EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
   7853                (rn.GetCode() << 16));
   7854     AdvanceIT();
   7855     return;
   7856   } else {
   7857     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   7858     if (cond.IsNotNever()) {
   7859       EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7860               rm.GetCode() | (rn.GetCode() << 16));
   7861       return;
   7862     }
   7863   }
   7864   Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
   7865 }
   7866 
   7867 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
   7868   VIXL_ASSERT(AllowAssembler());
   7869   CheckIT(cond);
   7870   if (IsUsingT32()) {
   7871     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   7872     EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7873                rm.GetCode());
   7874     AdvanceIT();
   7875     return;
   7876   } else {
   7877     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   7878     if (cond.IsNotNever()) {
   7879       EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7880               (rn.GetCode() << 16) | rm.GetCode());
   7881       return;
   7882     }
   7883   }
   7884   Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
   7885 }
   7886 
   7887 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
   7888   VIXL_ASSERT(AllowAssembler());
   7889   CheckIT(cond);
   7890   if (IsUsingT32()) {
   7891     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   7892     EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7893                rm.GetCode());
   7894     AdvanceIT();
   7895     return;
   7896   } else {
   7897     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   7898     if (cond.IsNotNever()) {
   7899       EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7900               (rn.GetCode() << 16) | rm.GetCode());
   7901       return;
   7902     }
   7903   }
   7904   Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
   7905 }
   7906 
   7907 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
   7908   VIXL_ASSERT(AllowAssembler());
   7909   CheckIT(cond);
   7910   if (IsUsingT32()) {
   7911     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   7912     EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7913                rm.GetCode());
   7914     AdvanceIT();
   7915     return;
   7916   } else {
   7917     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   7918     if (cond.IsNotNever()) {
   7919       EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7920               (rn.GetCode() << 16) | rm.GetCode());
   7921       return;
   7922     }
   7923   }
   7924   Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
   7925 }
   7926 
   7927 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
   7928   VIXL_ASSERT(AllowAssembler());
   7929   CheckIT(cond);
   7930   if (IsUsingT32()) {
   7931     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   7932     EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
   7933                (rn.GetCode() << 16));
   7934     AdvanceIT();
   7935     return;
   7936   } else {
   7937     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   7938     if (cond.IsNotNever()) {
   7939       EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7940               rm.GetCode() | (rn.GetCode() << 16));
   7941       return;
   7942     }
   7943   }
   7944   Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
   7945 }
   7946 
   7947 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
   7948   VIXL_ASSERT(AllowAssembler());
   7949   CheckIT(cond);
   7950   if (IsUsingT32()) {
   7951     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   7952     EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
   7953                (rn.GetCode() << 16));
   7954     AdvanceIT();
   7955     return;
   7956   } else {
   7957     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   7958     if (cond.IsNotNever()) {
   7959       EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7960               rm.GetCode() | (rn.GetCode() << 16));
   7961       return;
   7962     }
   7963   }
   7964   Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
   7965 }
   7966 
   7967 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
   7968   VIXL_ASSERT(AllowAssembler());
   7969   CheckIT(cond);
   7970   if (IsUsingT32()) {
   7971     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   7972     EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7973                rm.GetCode());
   7974     AdvanceIT();
   7975     return;
   7976   } else {
   7977     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   7978     if (cond.IsNotNever()) {
   7979       EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7980               (rn.GetCode() << 16) | rm.GetCode());
   7981       return;
   7982     }
   7983   }
   7984   Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
   7985 }
   7986 
   7987 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
   7988   VIXL_ASSERT(AllowAssembler());
   7989   CheckIT(cond);
   7990   if (IsUsingT32()) {
   7991     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   7992     EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
   7993                (rn.GetCode() << 16));
   7994     AdvanceIT();
   7995     return;
   7996   } else {
   7997     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   7998     if (cond.IsNotNever()) {
   7999       EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8000               rm.GetCode() | (rn.GetCode() << 16));
   8001       return;
   8002     }
   8003   }
   8004   Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
   8005 }
   8006 
   8007 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
   8008   VIXL_ASSERT(AllowAssembler());
   8009   CheckIT(cond);
   8010   if (IsUsingT32()) {
   8011     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8012     EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8013                rm.GetCode());
   8014     AdvanceIT();
   8015     return;
   8016   } else {
   8017     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8018     if (cond.IsNotNever()) {
   8019       EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8020               (rn.GetCode() << 16) | rm.GetCode());
   8021       return;
   8022     }
   8023   }
   8024   Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
   8025 }
   8026 
   8027 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
   8028   VIXL_ASSERT(AllowAssembler());
   8029   CheckIT(cond);
   8030   if (IsUsingT32()) {
   8031     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8032     EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8033                rm.GetCode());
   8034     AdvanceIT();
   8035     return;
   8036   } else {
   8037     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8038     if (cond.IsNotNever()) {
   8039       EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8040               (rn.GetCode() << 16) | rm.GetCode());
   8041       return;
   8042     }
   8043   }
   8044   Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
   8045 }
   8046 
   8047 void Assembler::rbit(Condition cond, Register rd, Register rm) {
   8048   VIXL_ASSERT(AllowAssembler());
   8049   CheckIT(cond);
   8050   if (IsUsingT32()) {
   8051     // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
   8052     EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
   8053                (rm.GetCode() << 16));
   8054     AdvanceIT();
   8055     return;
   8056   } else {
   8057     // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
   8058     if (cond.IsNotNever()) {
   8059       EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8060               rm.GetCode());
   8061       return;
   8062     }
   8063   }
   8064   Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
   8065 }
   8066 
   8067 void Assembler::rev(Condition cond,
   8068                     EncodingSize size,
   8069                     Register rd,
   8070                     Register rm) {
   8071   VIXL_ASSERT(AllowAssembler());
   8072   CheckIT(cond);
   8073   if (IsUsingT32()) {
   8074     // REV{<c>}{<q>} <Rd>, <Rm> ; T1
   8075     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8076       EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
   8077       AdvanceIT();
   8078       return;
   8079     }
   8080     // REV{<c>}{<q>} <Rd>, <Rm> ; T2
   8081     if (!size.IsNarrow()) {
   8082       EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
   8083                  (rm.GetCode() << 16));
   8084       AdvanceIT();
   8085       return;
   8086     }
   8087   } else {
   8088     // REV{<c>}{<q>} <Rd>, <Rm> ; A1
   8089     if (cond.IsNotNever()) {
   8090       EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8091               rm.GetCode());
   8092       return;
   8093     }
   8094   }
   8095   Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
   8096 }
   8097 
   8098 void Assembler::rev16(Condition cond,
   8099                       EncodingSize size,
   8100                       Register rd,
   8101                       Register rm) {
   8102   VIXL_ASSERT(AllowAssembler());
   8103   CheckIT(cond);
   8104   if (IsUsingT32()) {
   8105     // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
   8106     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8107       EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
   8108       AdvanceIT();
   8109       return;
   8110     }
   8111     // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
   8112     if (!size.IsNarrow()) {
   8113       EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
   8114                  (rm.GetCode() << 16));
   8115       AdvanceIT();
   8116       return;
   8117     }
   8118   } else {
   8119     // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
   8120     if (cond.IsNotNever()) {
   8121       EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8122               rm.GetCode());
   8123       return;
   8124     }
   8125   }
   8126   Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
   8127 }
   8128 
   8129 void Assembler::revsh(Condition cond,
   8130                       EncodingSize size,
   8131                       Register rd,
   8132                       Register rm) {
   8133   VIXL_ASSERT(AllowAssembler());
   8134   CheckIT(cond);
   8135   if (IsUsingT32()) {
   8136     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
   8137     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8138       EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
   8139       AdvanceIT();
   8140       return;
   8141     }
   8142     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
   8143     if (!size.IsNarrow()) {
   8144       EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
   8145                  (rm.GetCode() << 16));
   8146       AdvanceIT();
   8147       return;
   8148     }
   8149   } else {
   8150     // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
   8151     if (cond.IsNotNever()) {
   8152       EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8153               rm.GetCode());
   8154       return;
   8155     }
   8156   }
   8157   Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
   8158 }
   8159 
   8160 void Assembler::ror(Condition cond,
   8161                     EncodingSize size,
   8162                     Register rd,
   8163                     Register rm,
   8164                     const Operand& operand) {
   8165   VIXL_ASSERT(AllowAssembler());
   8166   CheckIT(cond);
   8167   if (operand.IsImmediate()) {
   8168     uint32_t imm = operand.GetImmediate();
   8169     if (IsUsingT32()) {
   8170       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   8171       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
   8172         EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
   8173                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   8174         AdvanceIT();
   8175         return;
   8176       }
   8177     } else {
   8178       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   8179       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   8180         EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
   8181                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   8182         return;
   8183       }
   8184     }
   8185   }
   8186   if (operand.IsPlainRegister()) {
   8187     Register rs = operand.GetBaseRegister();
   8188     if (IsUsingT32()) {
   8189       // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   8190       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   8191           rs.IsLow()) {
   8192         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   8193         AdvanceIT();
   8194         return;
   8195       }
   8196       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   8197       if (!size.IsNarrow()) {
   8198         EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   8199                    rs.GetCode());
   8200         AdvanceIT();
   8201         return;
   8202       }
   8203     } else {
   8204       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   8205       if (cond.IsNotNever()) {
   8206         EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
   8207                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   8208         return;
   8209       }
   8210     }
   8211   }
   8212   Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
   8213 }
   8214 
   8215 void Assembler::rors(Condition cond,
   8216                      EncodingSize size,
   8217                      Register rd,
   8218                      Register rm,
   8219                      const Operand& operand) {
   8220   VIXL_ASSERT(AllowAssembler());
   8221   CheckIT(cond);
   8222   if (operand.IsImmediate()) {
   8223     uint32_t imm = operand.GetImmediate();
   8224     if (IsUsingT32()) {
   8225       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   8226       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
   8227         EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
   8228                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   8229         AdvanceIT();
   8230         return;
   8231       }
   8232     } else {
   8233       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   8234       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   8235         EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
   8236                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   8237         return;
   8238       }
   8239     }
   8240   }
   8241   if (operand.IsPlainRegister()) {
   8242     Register rs = operand.GetBaseRegister();
   8243     if (IsUsingT32()) {
   8244       // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   8245       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   8246           rs.IsLow()) {
   8247         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   8248         AdvanceIT();
   8249         return;
   8250       }
   8251       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   8252       if (!size.IsNarrow()) {
   8253         EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   8254                    rs.GetCode());
   8255         AdvanceIT();
   8256         return;
   8257       }
   8258     } else {
   8259       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   8260       if (cond.IsNotNever()) {
   8261         EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
   8262                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   8263         return;
   8264       }
   8265     }
   8266   }
   8267   Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
   8268 }
   8269 
   8270 void Assembler::rrx(Condition cond, Register rd, Register rm) {
   8271   VIXL_ASSERT(AllowAssembler());
   8272   CheckIT(cond);
   8273   if (IsUsingT32()) {
   8274     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
   8275     EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
   8276     AdvanceIT();
   8277     return;
   8278   } else {
   8279     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
   8280     if (cond.IsNotNever()) {
   8281       EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8282               rm.GetCode());
   8283       return;
   8284     }
   8285   }
   8286   Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
   8287 }
   8288 
   8289 void Assembler::rrxs(Condition cond, Register rd, Register rm) {
   8290   VIXL_ASSERT(AllowAssembler());
   8291   CheckIT(cond);
   8292   if (IsUsingT32()) {
   8293     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
   8294     EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
   8295     AdvanceIT();
   8296     return;
   8297   } else {
   8298     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
   8299     if (cond.IsNotNever()) {
   8300       EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8301               rm.GetCode());
   8302       return;
   8303     }
   8304   }
   8305   Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
   8306 }
   8307 
   8308 void Assembler::rsb(Condition cond,
   8309                     EncodingSize size,
   8310                     Register rd,
   8311                     Register rn,
   8312                     const Operand& operand) {
   8313   VIXL_ASSERT(AllowAssembler());
   8314   CheckIT(cond);
   8315   if (operand.IsImmediate()) {
   8316     uint32_t imm = operand.GetImmediate();
   8317     if (IsUsingT32()) {
   8318       ImmediateT32 immediate_t32(imm);
   8319       // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
   8320       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   8321           (imm == 0)) {
   8322         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
   8323         AdvanceIT();
   8324         return;
   8325       }
   8326       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
   8327       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   8328         EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8329                    (immediate_t32.GetEncodingValue() & 0xff) |
   8330                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   8331                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   8332         AdvanceIT();
   8333         return;
   8334       }
   8335     } else {
   8336       ImmediateA32 immediate_a32(imm);
   8337       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   8338       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   8339         EmitA32(0x02600000U | (cond.GetCondition() << 28) |
   8340                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   8341                 immediate_a32.GetEncodingValue());
   8342         return;
   8343       }
   8344     }
   8345   }
   8346   if (operand.IsImmediateShiftedRegister()) {
   8347     Register rm = operand.GetBaseRegister();
   8348     Shift shift = operand.GetShift();
   8349     uint32_t amount = operand.GetShiftAmount();
   8350     if (IsUsingT32()) {
   8351       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   8352       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   8353         uint32_t amount_ = amount % 32;
   8354         EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8355                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   8356                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   8357         AdvanceIT();
   8358         return;
   8359       }
   8360     } else {
   8361       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   8362       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   8363         uint32_t amount_ = amount % 32;
   8364         EmitA32(0x00600000U | (cond.GetCondition() << 28) |
   8365                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8366                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   8367         return;
   8368       }
   8369     }
   8370   }
   8371   if (operand.IsRegisterShiftedRegister()) {
   8372     Register rm = operand.GetBaseRegister();
   8373     Shift shift = operand.GetShift();
   8374     if (IsUsingA32()) {
   8375       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   8376       if (cond.IsNotNever()) {
   8377         EmitA32(0x00600010U | (cond.GetCondition() << 28) |
   8378                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8379                 (shift.GetType() << 5) |
   8380                 (operand.GetShiftRegister().GetCode() << 8));
   8381         return;
   8382       }
   8383     }
   8384   }
   8385   Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
   8386 }
   8387 
   8388 void Assembler::rsbs(Condition cond,
   8389                      EncodingSize size,
   8390                      Register rd,
   8391                      Register rn,
   8392                      const Operand& operand) {
   8393   VIXL_ASSERT(AllowAssembler());
   8394   CheckIT(cond);
   8395   if (operand.IsImmediate()) {
   8396     uint32_t imm = operand.GetImmediate();
   8397     if (IsUsingT32()) {
   8398       ImmediateT32 immediate_t32(imm);
   8399       // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
   8400       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   8401           (imm == 0)) {
   8402         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
   8403         AdvanceIT();
   8404         return;
   8405       }
   8406       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
   8407       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   8408         EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8409                    (immediate_t32.GetEncodingValue() & 0xff) |
   8410                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   8411                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   8412         AdvanceIT();
   8413         return;
   8414       }
   8415     } else {
   8416       ImmediateA32 immediate_a32(imm);
   8417       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   8418       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   8419         EmitA32(0x02700000U | (cond.GetCondition() << 28) |
   8420                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   8421                 immediate_a32.GetEncodingValue());
   8422         return;
   8423       }
   8424     }
   8425   }
   8426   if (operand.IsImmediateShiftedRegister()) {
   8427     Register rm = operand.GetBaseRegister();
   8428     Shift shift = operand.GetShift();
   8429     uint32_t amount = operand.GetShiftAmount();
   8430     if (IsUsingT32()) {
   8431       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   8432       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   8433         uint32_t amount_ = amount % 32;
   8434         EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8435                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   8436                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   8437         AdvanceIT();
   8438         return;
   8439       }
   8440     } else {
   8441       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   8442       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   8443         uint32_t amount_ = amount % 32;
   8444         EmitA32(0x00700000U | (cond.GetCondition() << 28) |
   8445                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8446                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   8447         return;
   8448       }
   8449     }
   8450   }
   8451   if (operand.IsRegisterShiftedRegister()) {
   8452     Register rm = operand.GetBaseRegister();
   8453     Shift shift = operand.GetShift();
   8454     if (IsUsingA32()) {
   8455       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   8456       if (cond.IsNotNever()) {
   8457         EmitA32(0x00700010U | (cond.GetCondition() << 28) |
   8458                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8459                 (shift.GetType() << 5) |
   8460                 (operand.GetShiftRegister().GetCode() << 8));
   8461         return;
   8462       }
   8463     }
   8464   }
   8465   Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
   8466 }
   8467 
   8468 void Assembler::rsc(Condition cond,
   8469                     Register rd,
   8470                     Register rn,
   8471                     const Operand& operand) {
   8472   VIXL_ASSERT(AllowAssembler());
   8473   CheckIT(cond);
   8474   if (operand.IsImmediate()) {
   8475     uint32_t imm = operand.GetImmediate();
   8476     if (IsUsingA32()) {
   8477       ImmediateA32 immediate_a32(imm);
   8478       // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   8479       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   8480         EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
   8481                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   8482                 immediate_a32.GetEncodingValue());
   8483         return;
   8484       }
   8485     }
   8486   }
   8487   if (operand.IsImmediateShiftedRegister()) {
   8488     Register rm = operand.GetBaseRegister();
   8489     Shift shift = operand.GetShift();
   8490     uint32_t amount = operand.GetShiftAmount();
   8491     if (IsUsingA32()) {
   8492       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   8493       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   8494         uint32_t amount_ = amount % 32;
   8495         EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
   8496                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8497                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   8498         return;
   8499       }
   8500     }
   8501   }
   8502   if (operand.IsRegisterShiftedRegister()) {
   8503     Register rm = operand.GetBaseRegister();
   8504     Shift shift = operand.GetShift();
   8505     if (IsUsingA32()) {
   8506       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   8507       if (cond.IsNotNever()) {
   8508         EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
   8509                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8510                 (shift.GetType() << 5) |
   8511                 (operand.GetShiftRegister().GetCode() << 8));
   8512         return;
   8513       }
   8514     }
   8515   }
   8516   Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
   8517 }
   8518 
   8519 void Assembler::rscs(Condition cond,
   8520                      Register rd,
   8521                      Register rn,
   8522                      const Operand& operand) {
   8523   VIXL_ASSERT(AllowAssembler());
   8524   CheckIT(cond);
   8525   if (operand.IsImmediate()) {
   8526     uint32_t imm = operand.GetImmediate();
   8527     if (IsUsingA32()) {
   8528       ImmediateA32 immediate_a32(imm);
   8529       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   8530       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   8531         EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
   8532                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   8533                 immediate_a32.GetEncodingValue());
   8534         return;
   8535       }
   8536     }
   8537   }
   8538   if (operand.IsImmediateShiftedRegister()) {
   8539     Register rm = operand.GetBaseRegister();
   8540     Shift shift = operand.GetShift();
   8541     uint32_t amount = operand.GetShiftAmount();
   8542     if (IsUsingA32()) {
   8543       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   8544       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   8545         uint32_t amount_ = amount % 32;
   8546         EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
   8547                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8548                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   8549         return;
   8550       }
   8551     }
   8552   }
   8553   if (operand.IsRegisterShiftedRegister()) {
   8554     Register rm = operand.GetBaseRegister();
   8555     Shift shift = operand.GetShift();
   8556     if (IsUsingA32()) {
   8557       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   8558       if (cond.IsNotNever()) {
   8559         EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
   8560                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8561                 (shift.GetType() << 5) |
   8562                 (operand.GetShiftRegister().GetCode() << 8));
   8563         return;
   8564       }
   8565     }
   8566   }
   8567   Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
   8568 }
   8569 
   8570 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
   8571   VIXL_ASSERT(AllowAssembler());
   8572   CheckIT(cond);
   8573   if (IsUsingT32()) {
   8574     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8575     EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8576                rm.GetCode());
   8577     AdvanceIT();
   8578     return;
   8579   } else {
   8580     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8581     if (cond.IsNotNever()) {
   8582       EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8583               (rn.GetCode() << 16) | rm.GetCode());
   8584       return;
   8585     }
   8586   }
   8587   Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
   8588 }
   8589 
   8590 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
   8591   VIXL_ASSERT(AllowAssembler());
   8592   CheckIT(cond);
   8593   if (IsUsingT32()) {
   8594     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8595     EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8596                rm.GetCode());
   8597     AdvanceIT();
   8598     return;
   8599   } else {
   8600     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8601     if (cond.IsNotNever()) {
   8602       EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8603               (rn.GetCode() << 16) | rm.GetCode());
   8604       return;
   8605     }
   8606   }
   8607   Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
   8608 }
   8609 
   8610 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
   8611   VIXL_ASSERT(AllowAssembler());
   8612   CheckIT(cond);
   8613   if (IsUsingT32()) {
   8614     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8615     EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8616                rm.GetCode());
   8617     AdvanceIT();
   8618     return;
   8619   } else {
   8620     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8621     if (cond.IsNotNever()) {
   8622       EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8623               (rn.GetCode() << 16) | rm.GetCode());
   8624       return;
   8625     }
   8626   }
   8627   Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
   8628 }
   8629 
   8630 void Assembler::sbc(Condition cond,
   8631                     EncodingSize size,
   8632                     Register rd,
   8633                     Register rn,
   8634                     const Operand& operand) {
   8635   VIXL_ASSERT(AllowAssembler());
   8636   CheckIT(cond);
   8637   if (operand.IsImmediate()) {
   8638     uint32_t imm = operand.GetImmediate();
   8639     if (IsUsingT32()) {
   8640       ImmediateT32 immediate_t32(imm);
   8641       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   8642       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   8643         EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8644                    (immediate_t32.GetEncodingValue() & 0xff) |
   8645                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   8646                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   8647         AdvanceIT();
   8648         return;
   8649       }
   8650     } else {
   8651       ImmediateA32 immediate_a32(imm);
   8652       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   8653       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   8654         EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
   8655                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   8656                 immediate_a32.GetEncodingValue());
   8657         return;
   8658       }
   8659     }
   8660   }
   8661   if (operand.IsImmediateShiftedRegister()) {
   8662     Register rm = operand.GetBaseRegister();
   8663     if (operand.IsPlainRegister()) {
   8664       if (IsUsingT32()) {
   8665         // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   8666         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   8667             rm.IsLow()) {
   8668           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
   8669           AdvanceIT();
   8670           return;
   8671         }
   8672       }
   8673     }
   8674     Shift shift = operand.GetShift();
   8675     uint32_t amount = operand.GetShiftAmount();
   8676     if (IsUsingT32()) {
   8677       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   8678       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   8679         uint32_t amount_ = amount % 32;
   8680         EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8681                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   8682                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   8683         AdvanceIT();
   8684         return;
   8685       }
   8686     } else {
   8687       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   8688       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   8689         uint32_t amount_ = amount % 32;
   8690         EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
   8691                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8692                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   8693         return;
   8694       }
   8695     }
   8696   }
   8697   if (operand.IsRegisterShiftedRegister()) {
   8698     Register rm = operand.GetBaseRegister();
   8699     Shift shift = operand.GetShift();
   8700     if (IsUsingA32()) {
   8701       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   8702       if (cond.IsNotNever()) {
   8703         EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
   8704                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8705                 (shift.GetType() << 5) |
   8706                 (operand.GetShiftRegister().GetCode() << 8));
   8707         return;
   8708       }
   8709     }
   8710   }
   8711   Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
   8712 }
   8713 
   8714 void Assembler::sbcs(Condition cond,
   8715                      EncodingSize size,
   8716                      Register rd,
   8717                      Register rn,
   8718                      const Operand& operand) {
   8719   VIXL_ASSERT(AllowAssembler());
   8720   CheckIT(cond);
   8721   if (operand.IsImmediate()) {
   8722     uint32_t imm = operand.GetImmediate();
   8723     if (IsUsingT32()) {
   8724       ImmediateT32 immediate_t32(imm);
   8725       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   8726       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   8727         EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8728                    (immediate_t32.GetEncodingValue() & 0xff) |
   8729                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   8730                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   8731         AdvanceIT();
   8732         return;
   8733       }
   8734     } else {
   8735       ImmediateA32 immediate_a32(imm);
   8736       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   8737       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   8738         EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
   8739                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   8740                 immediate_a32.GetEncodingValue());
   8741         return;
   8742       }
   8743     }
   8744   }
   8745   if (operand.IsImmediateShiftedRegister()) {
   8746     Register rm = operand.GetBaseRegister();
   8747     if (operand.IsPlainRegister()) {
   8748       if (IsUsingT32()) {
   8749         // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   8750         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   8751             rm.IsLow()) {
   8752           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
   8753           AdvanceIT();
   8754           return;
   8755         }
   8756       }
   8757     }
   8758     Shift shift = operand.GetShift();
   8759     uint32_t amount = operand.GetShiftAmount();
   8760     if (IsUsingT32()) {
   8761       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   8762       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   8763         uint32_t amount_ = amount % 32;
   8764         EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8765                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   8766                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   8767         AdvanceIT();
   8768         return;
   8769       }
   8770     } else {
   8771       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   8772       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   8773         uint32_t amount_ = amount % 32;
   8774         EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
   8775                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8776                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   8777         return;
   8778       }
   8779     }
   8780   }
   8781   if (operand.IsRegisterShiftedRegister()) {
   8782     Register rm = operand.GetBaseRegister();
   8783     Shift shift = operand.GetShift();
   8784     if (IsUsingA32()) {
   8785       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   8786       if (cond.IsNotNever()) {
   8787         EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
   8788                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8789                 (shift.GetType() << 5) |
   8790                 (operand.GetShiftRegister().GetCode() << 8));
   8791         return;
   8792       }
   8793     }
   8794   }
   8795   Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
   8796 }
   8797 
   8798 void Assembler::sbfx(Condition cond,
   8799                      Register rd,
   8800                      Register rn,
   8801                      uint32_t lsb,
   8802                      const Operand& operand) {
   8803   VIXL_ASSERT(AllowAssembler());
   8804   CheckIT(cond);
   8805   if (operand.IsImmediate()) {
   8806     uint32_t width = operand.GetImmediate();
   8807     if (IsUsingT32()) {
   8808       // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
   8809       if ((lsb <= 31) &&
   8810           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
   8811         uint32_t widthm1 = width - 1;
   8812         EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8813                    ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
   8814         AdvanceIT();
   8815         return;
   8816       }
   8817     } else {
   8818       // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
   8819       if ((lsb <= 31) && cond.IsNotNever() &&
   8820           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
   8821         uint32_t widthm1 = width - 1;
   8822         EmitA32(0x07a00050U | (cond.GetCondition() << 28) |
   8823                 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
   8824                 (widthm1 << 16));
   8825         return;
   8826       }
   8827     }
   8828   }
   8829   Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, operand);
   8830 }
   8831 
   8832 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
   8833   VIXL_ASSERT(AllowAssembler());
   8834   CheckIT(cond);
   8835   if (IsUsingT32()) {
   8836     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8837     EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8838                rm.GetCode());
   8839     AdvanceIT();
   8840     return;
   8841   } else {
   8842     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8843     if (cond.IsNotNever()) {
   8844       EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   8845               rn.GetCode() | (rm.GetCode() << 8));
   8846       return;
   8847     }
   8848   }
   8849   Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
   8850 }
   8851 
   8852 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
   8853   VIXL_ASSERT(AllowAssembler());
   8854   CheckIT(cond);
   8855   if (IsUsingT32()) {
   8856     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8857     EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8858                rm.GetCode());
   8859     AdvanceIT();
   8860     return;
   8861   } else {
   8862     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8863     if (cond.IsNotNever()) {
   8864       EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8865               (rn.GetCode() << 16) | rm.GetCode());
   8866       return;
   8867     }
   8868   }
   8869   Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
   8870 }
   8871 
   8872 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
   8873   VIXL_ASSERT(AllowAssembler());
   8874   CheckIT(cond);
   8875   if (IsUsingT32()) {
   8876     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8877     EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8878                rm.GetCode());
   8879     AdvanceIT();
   8880     return;
   8881   } else {
   8882     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8883     if (cond.IsNotNever()) {
   8884       EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8885               (rn.GetCode() << 16) | rm.GetCode());
   8886       return;
   8887     }
   8888   }
   8889   Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
   8890 }
   8891 
   8892 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
   8893   VIXL_ASSERT(AllowAssembler());
   8894   CheckIT(cond);
   8895   if (IsUsingT32()) {
   8896     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8897     EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8898                rm.GetCode());
   8899     AdvanceIT();
   8900     return;
   8901   } else {
   8902     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8903     if (cond.IsNotNever()) {
   8904       EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8905               (rn.GetCode() << 16) | rm.GetCode());
   8906       return;
   8907     }
   8908   }
   8909   Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
   8910 }
   8911 
   8912 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
   8913   VIXL_ASSERT(AllowAssembler());
   8914   CheckIT(cond);
   8915   if (IsUsingT32()) {
   8916     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8917     EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8918                rm.GetCode());
   8919     AdvanceIT();
   8920     return;
   8921   } else {
   8922     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8923     if (cond.IsNotNever()) {
   8924       EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8925               (rn.GetCode() << 16) | rm.GetCode());
   8926       return;
   8927     }
   8928   }
   8929   Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
   8930 }
   8931 
   8932 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
   8933   VIXL_ASSERT(AllowAssembler());
   8934   CheckIT(cond);
   8935   if (IsUsingT32()) {
   8936     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8937     EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8938                rm.GetCode());
   8939     AdvanceIT();
   8940     return;
   8941   } else {
   8942     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8943     if (cond.IsNotNever()) {
   8944       EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8945               (rn.GetCode() << 16) | rm.GetCode());
   8946       return;
   8947     }
   8948   }
   8949   Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
   8950 }
   8951 
   8952 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
   8953   VIXL_ASSERT(AllowAssembler());
   8954   CheckIT(cond);
   8955   if (IsUsingT32()) {
   8956     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8957     EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8958                rm.GetCode());
   8959     AdvanceIT();
   8960     return;
   8961   } else {
   8962     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8963     if (cond.IsNotNever()) {
   8964       EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8965               (rn.GetCode() << 16) | rm.GetCode());
   8966       return;
   8967     }
   8968   }
   8969   Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
   8970 }
   8971 
   8972 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
   8973   VIXL_ASSERT(AllowAssembler());
   8974   CheckIT(cond);
   8975   if (IsUsingT32()) {
   8976     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8977     EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8978                rm.GetCode());
   8979     AdvanceIT();
   8980     return;
   8981   } else {
   8982     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8983     if (cond.IsNotNever()) {
   8984       EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8985               (rn.GetCode() << 16) | rm.GetCode());
   8986       return;
   8987     }
   8988   }
   8989   Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
   8990 }
   8991 
   8992 void Assembler::smlabb(
   8993     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   8994   VIXL_ASSERT(AllowAssembler());
   8995   CheckIT(cond);
   8996   if (IsUsingT32()) {
   8997     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   8998     if (!ra.Is(pc)) {
   8999       EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9000                  rm.GetCode() | (ra.GetCode() << 12));
   9001       AdvanceIT();
   9002       return;
   9003     }
   9004   } else {
   9005     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9006     if (cond.IsNotNever()) {
   9007       EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9008               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9009       return;
   9010     }
   9011   }
   9012   Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
   9013 }
   9014 
   9015 void Assembler::smlabt(
   9016     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9017   VIXL_ASSERT(AllowAssembler());
   9018   CheckIT(cond);
   9019   if (IsUsingT32()) {
   9020     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9021     if (!ra.Is(pc)) {
   9022       EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9023                  rm.GetCode() | (ra.GetCode() << 12));
   9024       AdvanceIT();
   9025       return;
   9026     }
   9027   } else {
   9028     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9029     if (cond.IsNotNever()) {
   9030       EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9031               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9032       return;
   9033     }
   9034   }
   9035   Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
   9036 }
   9037 
   9038 void Assembler::smlad(
   9039     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9040   VIXL_ASSERT(AllowAssembler());
   9041   CheckIT(cond);
   9042   if (IsUsingT32()) {
   9043     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9044     if (!ra.Is(pc)) {
   9045       EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9046                  rm.GetCode() | (ra.GetCode() << 12));
   9047       AdvanceIT();
   9048       return;
   9049     }
   9050   } else {
   9051     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9052     if (cond.IsNotNever() && !ra.Is(pc)) {
   9053       EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9054               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9055       return;
   9056     }
   9057   }
   9058   Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
   9059 }
   9060 
   9061 void Assembler::smladx(
   9062     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9063   VIXL_ASSERT(AllowAssembler());
   9064   CheckIT(cond);
   9065   if (IsUsingT32()) {
   9066     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9067     if (!ra.Is(pc)) {
   9068       EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9069                  rm.GetCode() | (ra.GetCode() << 12));
   9070       AdvanceIT();
   9071       return;
   9072     }
   9073   } else {
   9074     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9075     if (cond.IsNotNever() && !ra.Is(pc)) {
   9076       EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9077               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9078       return;
   9079     }
   9080   }
   9081   Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
   9082 }
   9083 
   9084 void Assembler::smlal(
   9085     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9086   VIXL_ASSERT(AllowAssembler());
   9087   CheckIT(cond);
   9088   if (IsUsingT32()) {
   9089     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9090     EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9091                (rn.GetCode() << 16) | rm.GetCode());
   9092     AdvanceIT();
   9093     return;
   9094   } else {
   9095     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9096     if (cond.IsNotNever()) {
   9097       EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
   9098               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9099               (rm.GetCode() << 8));
   9100       return;
   9101     }
   9102   }
   9103   Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
   9104 }
   9105 
   9106 void Assembler::smlalbb(
   9107     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9108   VIXL_ASSERT(AllowAssembler());
   9109   CheckIT(cond);
   9110   if (IsUsingT32()) {
   9111     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9112     EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9113                (rn.GetCode() << 16) | rm.GetCode());
   9114     AdvanceIT();
   9115     return;
   9116   } else {
   9117     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9118     if (cond.IsNotNever()) {
   9119       EmitA32(0x01400080U | (cond.GetCondition() << 28) |
   9120               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9121               (rm.GetCode() << 8));
   9122       return;
   9123     }
   9124   }
   9125   Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
   9126 }
   9127 
   9128 void Assembler::smlalbt(
   9129     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9130   VIXL_ASSERT(AllowAssembler());
   9131   CheckIT(cond);
   9132   if (IsUsingT32()) {
   9133     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9134     EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9135                (rn.GetCode() << 16) | rm.GetCode());
   9136     AdvanceIT();
   9137     return;
   9138   } else {
   9139     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9140     if (cond.IsNotNever()) {
   9141       EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
   9142               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9143               (rm.GetCode() << 8));
   9144       return;
   9145     }
   9146   }
   9147   Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
   9148 }
   9149 
   9150 void Assembler::smlald(
   9151     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9152   VIXL_ASSERT(AllowAssembler());
   9153   CheckIT(cond);
   9154   if (IsUsingT32()) {
   9155     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9156     EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9157                (rn.GetCode() << 16) | rm.GetCode());
   9158     AdvanceIT();
   9159     return;
   9160   } else {
   9161     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9162     if (cond.IsNotNever()) {
   9163       EmitA32(0x07400010U | (cond.GetCondition() << 28) |
   9164               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9165               (rm.GetCode() << 8));
   9166       return;
   9167     }
   9168   }
   9169   Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
   9170 }
   9171 
   9172 void Assembler::smlaldx(
   9173     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9174   VIXL_ASSERT(AllowAssembler());
   9175   CheckIT(cond);
   9176   if (IsUsingT32()) {
   9177     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9178     EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9179                (rn.GetCode() << 16) | rm.GetCode());
   9180     AdvanceIT();
   9181     return;
   9182   } else {
   9183     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9184     if (cond.IsNotNever()) {
   9185       EmitA32(0x07400030U | (cond.GetCondition() << 28) |
   9186               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9187               (rm.GetCode() << 8));
   9188       return;
   9189     }
   9190   }
   9191   Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
   9192 }
   9193 
   9194 void Assembler::smlals(
   9195     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9196   VIXL_ASSERT(AllowAssembler());
   9197   CheckIT(cond);
   9198   if (IsUsingA32()) {
   9199     // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9200     if (cond.IsNotNever()) {
   9201       EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
   9202               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9203               (rm.GetCode() << 8));
   9204       return;
   9205     }
   9206   }
   9207   Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
   9208 }
   9209 
   9210 void Assembler::smlaltb(
   9211     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9212   VIXL_ASSERT(AllowAssembler());
   9213   CheckIT(cond);
   9214   if (IsUsingT32()) {
   9215     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9216     EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9217                (rn.GetCode() << 16) | rm.GetCode());
   9218     AdvanceIT();
   9219     return;
   9220   } else {
   9221     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9222     if (cond.IsNotNever()) {
   9223       EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
   9224               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9225               (rm.GetCode() << 8));
   9226       return;
   9227     }
   9228   }
   9229   Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
   9230 }
   9231 
   9232 void Assembler::smlaltt(
   9233     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9234   VIXL_ASSERT(AllowAssembler());
   9235   CheckIT(cond);
   9236   if (IsUsingT32()) {
   9237     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9238     EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9239                (rn.GetCode() << 16) | rm.GetCode());
   9240     AdvanceIT();
   9241     return;
   9242   } else {
   9243     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9244     if (cond.IsNotNever()) {
   9245       EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
   9246               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9247               (rm.GetCode() << 8));
   9248       return;
   9249     }
   9250   }
   9251   Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
   9252 }
   9253 
   9254 void Assembler::smlatb(
   9255     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9256   VIXL_ASSERT(AllowAssembler());
   9257   CheckIT(cond);
   9258   if (IsUsingT32()) {
   9259     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9260     if (!ra.Is(pc)) {
   9261       EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9262                  rm.GetCode() | (ra.GetCode() << 12));
   9263       AdvanceIT();
   9264       return;
   9265     }
   9266   } else {
   9267     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9268     if (cond.IsNotNever()) {
   9269       EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9270               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9271       return;
   9272     }
   9273   }
   9274   Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
   9275 }
   9276 
   9277 void Assembler::smlatt(
   9278     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9279   VIXL_ASSERT(AllowAssembler());
   9280   CheckIT(cond);
   9281   if (IsUsingT32()) {
   9282     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9283     if (!ra.Is(pc)) {
   9284       EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9285                  rm.GetCode() | (ra.GetCode() << 12));
   9286       AdvanceIT();
   9287       return;
   9288     }
   9289   } else {
   9290     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9291     if (cond.IsNotNever()) {
   9292       EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9293               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9294       return;
   9295     }
   9296   }
   9297   Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
   9298 }
   9299 
   9300 void Assembler::smlawb(
   9301     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9302   VIXL_ASSERT(AllowAssembler());
   9303   CheckIT(cond);
   9304   if (IsUsingT32()) {
   9305     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9306     if (!ra.Is(pc)) {
   9307       EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9308                  rm.GetCode() | (ra.GetCode() << 12));
   9309       AdvanceIT();
   9310       return;
   9311     }
   9312   } else {
   9313     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9314     if (cond.IsNotNever()) {
   9315       EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9316               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9317       return;
   9318     }
   9319   }
   9320   Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
   9321 }
   9322 
   9323 void Assembler::smlawt(
   9324     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9325   VIXL_ASSERT(AllowAssembler());
   9326   CheckIT(cond);
   9327   if (IsUsingT32()) {
   9328     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9329     if (!ra.Is(pc)) {
   9330       EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9331                  rm.GetCode() | (ra.GetCode() << 12));
   9332       AdvanceIT();
   9333       return;
   9334     }
   9335   } else {
   9336     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9337     if (cond.IsNotNever()) {
   9338       EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9339               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9340       return;
   9341     }
   9342   }
   9343   Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
   9344 }
   9345 
   9346 void Assembler::smlsd(
   9347     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9348   VIXL_ASSERT(AllowAssembler());
   9349   CheckIT(cond);
   9350   if (IsUsingT32()) {
   9351     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9352     if (!ra.Is(pc)) {
   9353       EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9354                  rm.GetCode() | (ra.GetCode() << 12));
   9355       AdvanceIT();
   9356       return;
   9357     }
   9358   } else {
   9359     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9360     if (cond.IsNotNever() && !ra.Is(pc)) {
   9361       EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9362               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9363       return;
   9364     }
   9365   }
   9366   Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
   9367 }
   9368 
   9369 void Assembler::smlsdx(
   9370     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9371   VIXL_ASSERT(AllowAssembler());
   9372   CheckIT(cond);
   9373   if (IsUsingT32()) {
   9374     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9375     if (!ra.Is(pc)) {
   9376       EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9377                  rm.GetCode() | (ra.GetCode() << 12));
   9378       AdvanceIT();
   9379       return;
   9380     }
   9381   } else {
   9382     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9383     if (cond.IsNotNever() && !ra.Is(pc)) {
   9384       EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9385               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9386       return;
   9387     }
   9388   }
   9389   Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
   9390 }
   9391 
   9392 void Assembler::smlsld(
   9393     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9394   VIXL_ASSERT(AllowAssembler());
   9395   CheckIT(cond);
   9396   if (IsUsingT32()) {
   9397     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9398     EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9399                (rn.GetCode() << 16) | rm.GetCode());
   9400     AdvanceIT();
   9401     return;
   9402   } else {
   9403     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9404     if (cond.IsNotNever()) {
   9405       EmitA32(0x07400050U | (cond.GetCondition() << 28) |
   9406               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9407               (rm.GetCode() << 8));
   9408       return;
   9409     }
   9410   }
   9411   Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
   9412 }
   9413 
   9414 void Assembler::smlsldx(
   9415     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9416   VIXL_ASSERT(AllowAssembler());
   9417   CheckIT(cond);
   9418   if (IsUsingT32()) {
   9419     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9420     EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9421                (rn.GetCode() << 16) | rm.GetCode());
   9422     AdvanceIT();
   9423     return;
   9424   } else {
   9425     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9426     if (cond.IsNotNever()) {
   9427       EmitA32(0x07400070U | (cond.GetCondition() << 28) |
   9428               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9429               (rm.GetCode() << 8));
   9430       return;
   9431     }
   9432   }
   9433   Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
   9434 }
   9435 
   9436 void Assembler::smmla(
   9437     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9438   VIXL_ASSERT(AllowAssembler());
   9439   CheckIT(cond);
   9440   if (IsUsingT32()) {
   9441     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9442     if (!ra.Is(pc)) {
   9443       EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9444                  rm.GetCode() | (ra.GetCode() << 12));
   9445       AdvanceIT();
   9446       return;
   9447     }
   9448   } else {
   9449     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9450     if (cond.IsNotNever() && !ra.Is(pc)) {
   9451       EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9452               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9453       return;
   9454     }
   9455   }
   9456   Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
   9457 }
   9458 
   9459 void Assembler::smmlar(
   9460     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9461   VIXL_ASSERT(AllowAssembler());
   9462   CheckIT(cond);
   9463   if (IsUsingT32()) {
   9464     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9465     if (!ra.Is(pc)) {
   9466       EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9467                  rm.GetCode() | (ra.GetCode() << 12));
   9468       AdvanceIT();
   9469       return;
   9470     }
   9471   } else {
   9472     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9473     if (cond.IsNotNever() && !ra.Is(pc)) {
   9474       EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9475               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9476       return;
   9477     }
   9478   }
   9479   Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
   9480 }
   9481 
   9482 void Assembler::smmls(
   9483     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9484   VIXL_ASSERT(AllowAssembler());
   9485   CheckIT(cond);
   9486   if (IsUsingT32()) {
   9487     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9488     EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9489                rm.GetCode() | (ra.GetCode() << 12));
   9490     AdvanceIT();
   9491     return;
   9492   } else {
   9493     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9494     if (cond.IsNotNever()) {
   9495       EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9496               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9497       return;
   9498     }
   9499   }
   9500   Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
   9501 }
   9502 
   9503 void Assembler::smmlsr(
   9504     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9505   VIXL_ASSERT(AllowAssembler());
   9506   CheckIT(cond);
   9507   if (IsUsingT32()) {
   9508     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9509     EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9510                rm.GetCode() | (ra.GetCode() << 12));
   9511     AdvanceIT();
   9512     return;
   9513   } else {
   9514     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9515     if (cond.IsNotNever()) {
   9516       EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9517               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9518       return;
   9519     }
   9520   }
   9521   Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
   9522 }
   9523 
   9524 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
   9525   VIXL_ASSERT(AllowAssembler());
   9526   CheckIT(cond);
   9527   if (IsUsingT32()) {
   9528     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9529     EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9530                rm.GetCode());
   9531     AdvanceIT();
   9532     return;
   9533   } else {
   9534     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9535     if (cond.IsNotNever()) {
   9536       EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9537               rn.GetCode() | (rm.GetCode() << 8));
   9538       return;
   9539     }
   9540   }
   9541   Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
   9542 }
   9543 
   9544 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
   9545   VIXL_ASSERT(AllowAssembler());
   9546   CheckIT(cond);
   9547   if (IsUsingT32()) {
   9548     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9549     EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9550                rm.GetCode());
   9551     AdvanceIT();
   9552     return;
   9553   } else {
   9554     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9555     if (cond.IsNotNever()) {
   9556       EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9557               rn.GetCode() | (rm.GetCode() << 8));
   9558       return;
   9559     }
   9560   }
   9561   Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
   9562 }
   9563 
   9564 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
   9565   VIXL_ASSERT(AllowAssembler());
   9566   CheckIT(cond);
   9567   if (IsUsingT32()) {
   9568     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9569     EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9570                rm.GetCode());
   9571     AdvanceIT();
   9572     return;
   9573   } else {
   9574     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9575     if (cond.IsNotNever()) {
   9576       EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9577               rn.GetCode() | (rm.GetCode() << 8));
   9578       return;
   9579     }
   9580   }
   9581   Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
   9582 }
   9583 
   9584 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
   9585   VIXL_ASSERT(AllowAssembler());
   9586   CheckIT(cond);
   9587   if (IsUsingT32()) {
   9588     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9589     EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9590                rm.GetCode());
   9591     AdvanceIT();
   9592     return;
   9593   } else {
   9594     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9595     if (cond.IsNotNever()) {
   9596       EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9597               rn.GetCode() | (rm.GetCode() << 8));
   9598       return;
   9599     }
   9600   }
   9601   Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
   9602 }
   9603 
   9604 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
   9605   VIXL_ASSERT(AllowAssembler());
   9606   CheckIT(cond);
   9607   if (IsUsingT32()) {
   9608     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9609     EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9610                rm.GetCode());
   9611     AdvanceIT();
   9612     return;
   9613   } else {
   9614     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9615     if (cond.IsNotNever()) {
   9616       EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9617               rn.GetCode() | (rm.GetCode() << 8));
   9618       return;
   9619     }
   9620   }
   9621   Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
   9622 }
   9623 
   9624 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
   9625   VIXL_ASSERT(AllowAssembler());
   9626   CheckIT(cond);
   9627   if (IsUsingT32()) {
   9628     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9629     EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9630                rm.GetCode());
   9631     AdvanceIT();
   9632     return;
   9633   } else {
   9634     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9635     if (cond.IsNotNever()) {
   9636       EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9637               rn.GetCode() | (rm.GetCode() << 8));
   9638       return;
   9639     }
   9640   }
   9641   Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
   9642 }
   9643 
   9644 void Assembler::smull(
   9645     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9646   VIXL_ASSERT(AllowAssembler());
   9647   CheckIT(cond);
   9648   if (IsUsingT32()) {
   9649     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9650     EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9651                (rn.GetCode() << 16) | rm.GetCode());
   9652     AdvanceIT();
   9653     return;
   9654   } else {
   9655     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9656     if (cond.IsNotNever()) {
   9657       EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
   9658               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9659               (rm.GetCode() << 8));
   9660       return;
   9661     }
   9662   }
   9663   Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
   9664 }
   9665 
   9666 void Assembler::smulls(
   9667     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9668   VIXL_ASSERT(AllowAssembler());
   9669   CheckIT(cond);
   9670   if (IsUsingA32()) {
   9671     // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9672     if (cond.IsNotNever()) {
   9673       EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
   9674               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9675               (rm.GetCode() << 8));
   9676       return;
   9677     }
   9678   }
   9679   Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
   9680 }
   9681 
   9682 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
   9683   VIXL_ASSERT(AllowAssembler());
   9684   CheckIT(cond);
   9685   if (IsUsingT32()) {
   9686     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9687     EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9688                rm.GetCode());
   9689     AdvanceIT();
   9690     return;
   9691   } else {
   9692     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9693     if (cond.IsNotNever()) {
   9694       EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9695               rn.GetCode() | (rm.GetCode() << 8));
   9696       return;
   9697     }
   9698   }
   9699   Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
   9700 }
   9701 
   9702 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
   9703   VIXL_ASSERT(AllowAssembler());
   9704   CheckIT(cond);
   9705   if (IsUsingT32()) {
   9706     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9707     EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9708                rm.GetCode());
   9709     AdvanceIT();
   9710     return;
   9711   } else {
   9712     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9713     if (cond.IsNotNever()) {
   9714       EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9715               rn.GetCode() | (rm.GetCode() << 8));
   9716       return;
   9717     }
   9718   }
   9719   Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
   9720 }
   9721 
   9722 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
   9723   VIXL_ASSERT(AllowAssembler());
   9724   CheckIT(cond);
   9725   if (IsUsingT32()) {
   9726     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9727     EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9728                rm.GetCode());
   9729     AdvanceIT();
   9730     return;
   9731   } else {
   9732     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9733     if (cond.IsNotNever()) {
   9734       EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9735               rn.GetCode() | (rm.GetCode() << 8));
   9736       return;
   9737     }
   9738   }
   9739   Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
   9740 }
   9741 
   9742 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
   9743   VIXL_ASSERT(AllowAssembler());
   9744   CheckIT(cond);
   9745   if (IsUsingT32()) {
   9746     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9747     EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9748                rm.GetCode());
   9749     AdvanceIT();
   9750     return;
   9751   } else {
   9752     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9753     if (cond.IsNotNever()) {
   9754       EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9755               rn.GetCode() | (rm.GetCode() << 8));
   9756       return;
   9757     }
   9758   }
   9759   Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
   9760 }
   9761 
   9762 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
   9763   VIXL_ASSERT(AllowAssembler());
   9764   CheckIT(cond);
   9765   if (IsUsingT32()) {
   9766     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9767     EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9768                rm.GetCode());
   9769     AdvanceIT();
   9770     return;
   9771   } else {
   9772     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9773     if (cond.IsNotNever()) {
   9774       EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9775               rn.GetCode() | (rm.GetCode() << 8));
   9776       return;
   9777     }
   9778   }
   9779   Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
   9780 }
   9781 
   9782 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
   9783   VIXL_ASSERT(AllowAssembler());
   9784   CheckIT(cond);
   9785   if (IsUsingT32()) {
   9786     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9787     EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9788                rm.GetCode());
   9789     AdvanceIT();
   9790     return;
   9791   } else {
   9792     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9793     if (cond.IsNotNever()) {
   9794       EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9795               rn.GetCode() | (rm.GetCode() << 8));
   9796       return;
   9797     }
   9798   }
   9799   Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
   9800 }
   9801 
   9802 void Assembler::ssat(Condition cond,
   9803                      Register rd,
   9804                      uint32_t imm,
   9805                      const Operand& operand) {
   9806   VIXL_ASSERT(AllowAssembler());
   9807   CheckIT(cond);
   9808   if (operand.IsImmediateShiftedRegister()) {
   9809     Register rn = operand.GetBaseRegister();
   9810     Shift shift = operand.GetShift();
   9811     uint32_t amount = operand.GetShiftAmount();
   9812     if (IsUsingT32()) {
   9813       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
   9814       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
   9815           (amount <= 31)) {
   9816         uint32_t imm_ = imm - 1;
   9817         EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
   9818                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
   9819                    ((amount & 0x1c) << 10));
   9820         AdvanceIT();
   9821         return;
   9822       }
   9823       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
   9824       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31)) {
   9825         uint32_t imm_ = imm - 1;
   9826         EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
   9827                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
   9828                    ((amount & 0x1c) << 10));
   9829         AdvanceIT();
   9830         return;
   9831       }
   9832     } else {
   9833       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
   9834       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
   9835           (amount <= 32) && cond.IsNotNever()) {
   9836         uint32_t imm_ = imm - 1;
   9837         uint32_t amount_ = amount % 32;
   9838         EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
   9839                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
   9840                 (amount_ << 7));
   9841         return;
   9842       }
   9843       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
   9844       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
   9845           cond.IsNotNever()) {
   9846         uint32_t imm_ = imm - 1;
   9847         EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
   9848                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
   9849                 (amount << 7));
   9850         return;
   9851       }
   9852     }
   9853   }
   9854   Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
   9855 }
   9856 
   9857 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
   9858   VIXL_ASSERT(AllowAssembler());
   9859   CheckIT(cond);
   9860   if (IsUsingT32()) {
   9861     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
   9862     if ((imm >= 1) && (imm <= 16)) {
   9863       uint32_t imm_ = imm - 1;
   9864       EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
   9865                  (rn.GetCode() << 16));
   9866       AdvanceIT();
   9867       return;
   9868     }
   9869   } else {
   9870     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
   9871     if ((imm >= 1) && (imm <= 16) && cond.IsNotNever()) {
   9872       uint32_t imm_ = imm - 1;
   9873       EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9874               (imm_ << 16) | rn.GetCode());
   9875       return;
   9876     }
   9877   }
   9878   Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
   9879 }
   9880 
   9881 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
   9882   VIXL_ASSERT(AllowAssembler());
   9883   CheckIT(cond);
   9884   if (IsUsingT32()) {
   9885     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9886     EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9887                rm.GetCode());
   9888     AdvanceIT();
   9889     return;
   9890   } else {
   9891     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9892     if (cond.IsNotNever()) {
   9893       EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9894               (rn.GetCode() << 16) | rm.GetCode());
   9895       return;
   9896     }
   9897   }
   9898   Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
   9899 }
   9900 
   9901 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
   9902   VIXL_ASSERT(AllowAssembler());
   9903   CheckIT(cond);
   9904   if (IsUsingT32()) {
   9905     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9906     EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9907                rm.GetCode());
   9908     AdvanceIT();
   9909     return;
   9910   } else {
   9911     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9912     if (cond.IsNotNever()) {
   9913       EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9914               (rn.GetCode() << 16) | rm.GetCode());
   9915       return;
   9916     }
   9917   }
   9918   Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
   9919 }
   9920 
   9921 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
   9922   VIXL_ASSERT(AllowAssembler());
   9923   CheckIT(cond);
   9924   if (IsUsingT32()) {
   9925     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9926     EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9927                rm.GetCode());
   9928     AdvanceIT();
   9929     return;
   9930   } else {
   9931     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9932     if (cond.IsNotNever()) {
   9933       EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9934               (rn.GetCode() << 16) | rm.GetCode());
   9935       return;
   9936     }
   9937   }
   9938   Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
   9939 }
   9940 
   9941 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
   9942   VIXL_ASSERT(AllowAssembler());
   9943   CheckIT(cond);
   9944   if (operand.IsImmediateZero()) {
   9945     Register rn = operand.GetBaseRegister();
   9946     if (IsUsingT32()) {
   9947       // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
   9948       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   9949         EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   9950         AdvanceIT();
   9951         return;
   9952       }
   9953     } else {
   9954       // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
   9955       if (operand.IsOffset() && cond.IsNotNever() &&
   9956           (!rn.IsPC() || AllowUnpredictable())) {
   9957         EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
   9958                 (rn.GetCode() << 16));
   9959         return;
   9960       }
   9961     }
   9962   }
   9963   Delegate(kStl, &Assembler::stl, cond, rt, operand);
   9964 }
   9965 
   9966 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
   9967   VIXL_ASSERT(AllowAssembler());
   9968   CheckIT(cond);
   9969   if (operand.IsImmediateZero()) {
   9970     Register rn = operand.GetBaseRegister();
   9971     if (IsUsingT32()) {
   9972       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   9973       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   9974         EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   9975         AdvanceIT();
   9976         return;
   9977       }
   9978     } else {
   9979       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   9980       if (operand.IsOffset() && cond.IsNotNever() &&
   9981           (!rn.IsPC() || AllowUnpredictable())) {
   9982         EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
   9983                 (rn.GetCode() << 16));
   9984         return;
   9985       }
   9986     }
   9987   }
   9988   Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
   9989 }
   9990 
   9991 void Assembler::stlex(Condition cond,
   9992                       Register rd,
   9993                       Register rt,
   9994                       const MemOperand& operand) {
   9995   VIXL_ASSERT(AllowAssembler());
   9996   CheckIT(cond);
   9997   if (operand.IsImmediateZero()) {
   9998     Register rn = operand.GetBaseRegister();
   9999     if (IsUsingT32()) {
   10000       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   10001       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   10002         EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
   10003                    (rn.GetCode() << 16));
   10004         AdvanceIT();
   10005         return;
   10006       }
   10007     } else {
   10008       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   10009       if (operand.IsOffset() && cond.IsNotNever() &&
   10010           (!rn.IsPC() || AllowUnpredictable())) {
   10011         EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
   10012                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10013         return;
   10014       }
   10015     }
   10016   }
   10017   Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
   10018 }
   10019 
   10020 void Assembler::stlexb(Condition cond,
   10021                        Register rd,
   10022                        Register rt,
   10023                        const MemOperand& operand) {
   10024   VIXL_ASSERT(AllowAssembler());
   10025   CheckIT(cond);
   10026   if (operand.IsImmediateZero()) {
   10027     Register rn = operand.GetBaseRegister();
   10028     if (IsUsingT32()) {
   10029       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   10030       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   10031         EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
   10032                    (rn.GetCode() << 16));
   10033         AdvanceIT();
   10034         return;
   10035       }
   10036     } else {
   10037       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   10038       if (operand.IsOffset() && cond.IsNotNever() &&
   10039           (!rn.IsPC() || AllowUnpredictable())) {
   10040         EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
   10041                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10042         return;
   10043       }
   10044     }
   10045   }
   10046   Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
   10047 }
   10048 
   10049 void Assembler::stlexd(Condition cond,
   10050                        Register rd,
   10051                        Register rt,
   10052                        Register rt2,
   10053                        const MemOperand& operand) {
   10054   VIXL_ASSERT(AllowAssembler());
   10055   CheckIT(cond);
   10056   if (operand.IsImmediateZero()) {
   10057     Register rn = operand.GetBaseRegister();
   10058     if (IsUsingT32()) {
   10059       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
   10060       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   10061         EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
   10062                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
   10063         AdvanceIT();
   10064         return;
   10065       }
   10066     } else {
   10067       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
   10068       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   10069           operand.IsOffset() && cond.IsNotNever() &&
   10070           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
   10071            AllowUnpredictable())) {
   10072         EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
   10073                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10074         return;
   10075       }
   10076     }
   10077   }
   10078   Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
   10079 }
   10080 
   10081 void Assembler::stlexh(Condition cond,
   10082                        Register rd,
   10083                        Register rt,
   10084                        const MemOperand& operand) {
   10085   VIXL_ASSERT(AllowAssembler());
   10086   CheckIT(cond);
   10087   if (operand.IsImmediateZero()) {
   10088     Register rn = operand.GetBaseRegister();
   10089     if (IsUsingT32()) {
   10090       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   10091       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   10092         EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
   10093                    (rn.GetCode() << 16));
   10094         AdvanceIT();
   10095         return;
   10096       }
   10097     } else {
   10098       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   10099       if (operand.IsOffset() && cond.IsNotNever() &&
   10100           (!rn.IsPC() || AllowUnpredictable())) {
   10101         EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
   10102                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10103         return;
   10104       }
   10105     }
   10106   }
   10107   Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
   10108 }
   10109 
   10110 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
   10111   VIXL_ASSERT(AllowAssembler());
   10112   CheckIT(cond);
   10113   if (operand.IsImmediateZero()) {
   10114     Register rn = operand.GetBaseRegister();
   10115     if (IsUsingT32()) {
   10116       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   10117       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   10118         EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   10119         AdvanceIT();
   10120         return;
   10121       }
   10122     } else {
   10123       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   10124       if (operand.IsOffset() && cond.IsNotNever() &&
   10125           (!rn.IsPC() || AllowUnpredictable())) {
   10126         EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
   10127                 (rn.GetCode() << 16));
   10128         return;
   10129       }
   10130     }
   10131   }
   10132   Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
   10133 }
   10134 
   10135 void Assembler::stm(Condition cond,
   10136                     EncodingSize size,
   10137                     Register rn,
   10138                     WriteBack write_back,
   10139                     RegisterList registers) {
   10140   VIXL_ASSERT(AllowAssembler());
   10141   CheckIT(cond);
   10142   if (IsUsingT32()) {
   10143     // STM{<c>}{<q>} <Rn>!, <registers> ; T1
   10144     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
   10145         ((registers.GetList() & ~0xff) == 0)) {
   10146       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
   10147                  GetRegisterListEncoding(registers, 0, 8));
   10148       AdvanceIT();
   10149       return;
   10150     }
   10151     // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
   10152     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
   10153       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
   10154                  (write_back.GetWriteBackUint32() << 21) |
   10155                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   10156                  GetRegisterListEncoding(registers, 0, 13));
   10157       AdvanceIT();
   10158       return;
   10159     }
   10160   } else {
   10161     // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
   10162     if (cond.IsNotNever()) {
   10163       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   10164               (write_back.GetWriteBackUint32() << 21) |
   10165               GetRegisterListEncoding(registers, 0, 16));
   10166       return;
   10167     }
   10168   }
   10169   Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
   10170 }
   10171 
   10172 void Assembler::stmda(Condition cond,
   10173                       Register rn,
   10174                       WriteBack write_back,
   10175                       RegisterList registers) {
   10176   VIXL_ASSERT(AllowAssembler());
   10177   CheckIT(cond);
   10178   if (IsUsingA32()) {
   10179     // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   10180     if (cond.IsNotNever()) {
   10181       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   10182               (write_back.GetWriteBackUint32() << 21) |
   10183               GetRegisterListEncoding(registers, 0, 16));
   10184       return;
   10185     }
   10186   }
   10187   Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
   10188 }
   10189 
   10190 void Assembler::stmdb(Condition cond,
   10191                       EncodingSize size,
   10192                       Register rn,
   10193                       WriteBack write_back,
   10194                       RegisterList registers) {
   10195   VIXL_ASSERT(AllowAssembler());
   10196   CheckIT(cond);
   10197   if (IsUsingT32()) {
   10198     // STMDB{<c>}{<q>} SP!, <registers> ; T1
   10199     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
   10200         ((registers.GetList() & ~0x40ff) == 0)) {
   10201       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
   10202                  GetRegisterListEncoding(registers, 0, 8));
   10203       AdvanceIT();
   10204       return;
   10205     }
   10206     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
   10207     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
   10208       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
   10209                  (write_back.GetWriteBackUint32() << 21) |
   10210                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   10211                  GetRegisterListEncoding(registers, 0, 13));
   10212       AdvanceIT();
   10213       return;
   10214     }
   10215   } else {
   10216     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   10217     if (cond.IsNotNever()) {
   10218       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   10219               (write_back.GetWriteBackUint32() << 21) |
   10220               GetRegisterListEncoding(registers, 0, 16));
   10221       return;
   10222     }
   10223   }
   10224   Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
   10225 }
   10226 
   10227 void Assembler::stmea(Condition cond,
   10228                       EncodingSize size,
   10229                       Register rn,
   10230                       WriteBack write_back,
   10231                       RegisterList registers) {
   10232   VIXL_ASSERT(AllowAssembler());
   10233   CheckIT(cond);
   10234   if (IsUsingT32()) {
   10235     // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
   10236     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
   10237         ((registers.GetList() & ~0xff) == 0)) {
   10238       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
   10239                  GetRegisterListEncoding(registers, 0, 8));
   10240       AdvanceIT();
   10241       return;
   10242     }
   10243     // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
   10244     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
   10245       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
   10246                  (write_back.GetWriteBackUint32() << 21) |
   10247                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   10248                  GetRegisterListEncoding(registers, 0, 13));
   10249       AdvanceIT();
   10250       return;
   10251     }
   10252     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
   10253     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
   10254       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
   10255                  (write_back.GetWriteBackUint32() << 21) |
   10256                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   10257                  GetRegisterListEncoding(registers, 0, 13));
   10258       AdvanceIT();
   10259       return;
   10260     }
   10261   } else {
   10262     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   10263     if (cond.IsNotNever()) {
   10264       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   10265               (write_back.GetWriteBackUint32() << 21) |
   10266               GetRegisterListEncoding(registers, 0, 16));
   10267       return;
   10268     }
   10269   }
   10270   Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
   10271 }
   10272 
   10273 void Assembler::stmed(Condition cond,
   10274                       Register rn,
   10275                       WriteBack write_back,
   10276                       RegisterList registers) {
   10277   VIXL_ASSERT(AllowAssembler());
   10278   CheckIT(cond);
   10279   if (IsUsingA32()) {
   10280     // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
   10281     if (cond.IsNotNever()) {
   10282       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   10283               (write_back.GetWriteBackUint32() << 21) |
   10284               GetRegisterListEncoding(registers, 0, 16));
   10285       return;
   10286     }
   10287   }
   10288   Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
   10289 }
   10290 
   10291 void Assembler::stmfa(Condition cond,
   10292                       Register rn,
   10293                       WriteBack write_back,
   10294                       RegisterList registers) {
   10295   VIXL_ASSERT(AllowAssembler());
   10296   CheckIT(cond);
   10297   if (IsUsingA32()) {
   10298     // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   10299     if (cond.IsNotNever()) {
   10300       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   10301               (write_back.GetWriteBackUint32() << 21) |
   10302               GetRegisterListEncoding(registers, 0, 16));
   10303       return;
   10304     }
   10305   }
   10306   Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
   10307 }
   10308 
   10309 void Assembler::stmfd(Condition cond,
   10310                       Register rn,
   10311                       WriteBack write_back,
   10312                       RegisterList registers) {
   10313   VIXL_ASSERT(AllowAssembler());
   10314   CheckIT(cond);
   10315   if (IsUsingT32()) {
   10316     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
   10317     if (((registers.GetList() & ~0x5fff) == 0)) {
   10318       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
   10319                  (write_back.GetWriteBackUint32() << 21) |
   10320                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   10321                  GetRegisterListEncoding(registers, 0, 13));
   10322       AdvanceIT();
   10323       return;
   10324     }
   10325   } else {
   10326     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
   10327     if (cond.IsNotNever()) {
   10328       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   10329               (write_back.GetWriteBackUint32() << 21) |
   10330               GetRegisterListEncoding(registers, 0, 16));
   10331       return;
   10332     }
   10333   }
   10334   Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
   10335 }
   10336 
   10337 void Assembler::stmib(Condition cond,
   10338                       Register rn,
   10339                       WriteBack write_back,
   10340                       RegisterList registers) {
   10341   VIXL_ASSERT(AllowAssembler());
   10342   CheckIT(cond);
   10343   if (IsUsingA32()) {
   10344     // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   10345     if (cond.IsNotNever()) {
   10346       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   10347               (write_back.GetWriteBackUint32() << 21) |
   10348               GetRegisterListEncoding(registers, 0, 16));
   10349       return;
   10350     }
   10351   }
   10352   Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
   10353 }
   10354 
   10355 void Assembler::str(Condition cond,
   10356                     EncodingSize size,
   10357                     Register rt,
   10358                     const MemOperand& operand) {
   10359   VIXL_ASSERT(AllowAssembler());
   10360   CheckIT(cond);
   10361   if (operand.IsImmediate()) {
   10362     Register rn = operand.GetBaseRegister();
   10363     int32_t offset = operand.GetOffsetImmediate();
   10364     if (IsUsingT32()) {
   10365       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   10366       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   10367           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
   10368         int32_t offset_ = offset >> 2;
   10369         EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
   10370                    ((offset_ & 0x1f) << 6));
   10371         AdvanceIT();
   10372         return;
   10373       }
   10374       // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
   10375       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
   10376           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
   10377         int32_t offset_ = offset >> 2;
   10378         EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
   10379         AdvanceIT();
   10380         return;
   10381       }
   10382       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
   10383       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   10384           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10385         EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10386                    (offset & 0xfff));
   10387         AdvanceIT();
   10388         return;
   10389       }
   10390       // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
   10391       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   10392           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10393         EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10394                    (-offset & 0xff));
   10395         AdvanceIT();
   10396         return;
   10397       }
   10398       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
   10399       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   10400           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   10401         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10402         uint32_t offset_ = abs(offset);
   10403         EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10404                    offset_ | (sign << 9));
   10405         AdvanceIT();
   10406         return;
   10407       }
   10408       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
   10409       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   10410           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   10411         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10412         uint32_t offset_ = abs(offset);
   10413         EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10414                    offset_ | (sign << 9));
   10415         AdvanceIT();
   10416         return;
   10417       }
   10418     } else {
   10419       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   10420       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   10421           cond.IsNotNever()) {
   10422         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10423         uint32_t offset_ = abs(offset);
   10424         EmitA32(0x05000000U | (cond.GetCondition() << 28) |
   10425                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   10426                 (sign << 23));
   10427         return;
   10428       }
   10429       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   10430       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   10431           cond.IsNotNever()) {
   10432         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10433         uint32_t offset_ = abs(offset);
   10434         EmitA32(0x04000000U | (cond.GetCondition() << 28) |
   10435                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   10436                 (sign << 23));
   10437         return;
   10438       }
   10439       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   10440       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   10441           cond.IsNotNever()) {
   10442         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10443         uint32_t offset_ = abs(offset);
   10444         EmitA32(0x05200000U | (cond.GetCondition() << 28) |
   10445                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   10446                 (sign << 23));
   10447         return;
   10448       }
   10449     }
   10450   }
   10451   if (operand.IsPlainRegister()) {
   10452     Register rn = operand.GetBaseRegister();
   10453     Sign sign = operand.GetSign();
   10454     Register rm = operand.GetOffsetRegister();
   10455     if (IsUsingT32()) {
   10456       // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   10457       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   10458           sign.IsPlus() && operand.IsOffset()) {
   10459         EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
   10460                    (rm.GetCode() << 6));
   10461         AdvanceIT();
   10462         return;
   10463       }
   10464     }
   10465   }
   10466   if (operand.IsShiftedRegister()) {
   10467     Register rn = operand.GetBaseRegister();
   10468     Sign sign = operand.GetSign();
   10469     Register rm = operand.GetOffsetRegister();
   10470     Shift shift = operand.GetShift();
   10471     uint32_t amount = operand.GetShiftAmount();
   10472     if (IsUsingT32()) {
   10473       // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   10474       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   10475           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10476         EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10477                    rm.GetCode() | (amount << 4));
   10478         AdvanceIT();
   10479         return;
   10480       }
   10481     } else {
   10482       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   10483       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
   10484         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10485         uint32_t shift_ = TypeEncodingValue(shift);
   10486         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   10487         EmitA32(0x07000000U | (cond.GetCondition() << 28) |
   10488                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10489                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   10490         return;
   10491       }
   10492       // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   10493       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   10494           cond.IsNotNever()) {
   10495         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10496         uint32_t shift_ = TypeEncodingValue(shift);
   10497         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   10498         EmitA32(0x06000000U | (cond.GetCondition() << 28) |
   10499                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10500                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   10501         return;
   10502       }
   10503       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   10504       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
   10505         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10506         uint32_t shift_ = TypeEncodingValue(shift);
   10507         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   10508         EmitA32(0x07200000U | (cond.GetCondition() << 28) |
   10509                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10510                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   10511         return;
   10512       }
   10513     }
   10514   }
   10515   Delegate(kStr, &Assembler::str, cond, size, rt, operand);
   10516 }
   10517 
   10518 void Assembler::strb(Condition cond,
   10519                      EncodingSize size,
   10520                      Register rt,
   10521                      const MemOperand& operand) {
   10522   VIXL_ASSERT(AllowAssembler());
   10523   CheckIT(cond);
   10524   if (operand.IsImmediate()) {
   10525     Register rn = operand.GetBaseRegister();
   10526     int32_t offset = operand.GetOffsetImmediate();
   10527     if (IsUsingT32()) {
   10528       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   10529       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   10530           (offset <= 31) && operand.IsOffset()) {
   10531         EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
   10532                    ((offset & 0x1f) << 6));
   10533         AdvanceIT();
   10534         return;
   10535       }
   10536       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   10537       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   10538           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10539         EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10540                    (offset & 0xfff));
   10541         AdvanceIT();
   10542         return;
   10543       }
   10544       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   10545       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   10546           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10547         EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10548                    (-offset & 0xff));
   10549         AdvanceIT();
   10550         return;
   10551       }
   10552       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   10553       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   10554           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   10555         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10556         uint32_t offset_ = abs(offset);
   10557         EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10558                    offset_ | (sign << 9));
   10559         AdvanceIT();
   10560         return;
   10561       }
   10562       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   10563       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   10564           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   10565         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10566         uint32_t offset_ = abs(offset);
   10567         EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10568                    offset_ | (sign << 9));
   10569         AdvanceIT();
   10570         return;
   10571       }
   10572     } else {
   10573       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   10574       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   10575           cond.IsNotNever()) {
   10576         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10577         uint32_t offset_ = abs(offset);
   10578         EmitA32(0x05400000U | (cond.GetCondition() << 28) |
   10579                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   10580                 (sign << 23));
   10581         return;
   10582       }
   10583       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   10584       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   10585           cond.IsNotNever()) {
   10586         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10587         uint32_t offset_ = abs(offset);
   10588         EmitA32(0x04400000U | (cond.GetCondition() << 28) |
   10589                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   10590                 (sign << 23));
   10591         return;
   10592       }
   10593       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   10594       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   10595           cond.IsNotNever()) {
   10596         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10597         uint32_t offset_ = abs(offset);
   10598         EmitA32(0x05600000U | (cond.GetCondition() << 28) |
   10599                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   10600                 (sign << 23));
   10601         return;
   10602       }
   10603     }
   10604   }
   10605   if (operand.IsPlainRegister()) {
   10606     Register rn = operand.GetBaseRegister();
   10607     Sign sign = operand.GetSign();
   10608     Register rm = operand.GetOffsetRegister();
   10609     if (IsUsingT32()) {
   10610       // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   10611       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   10612           sign.IsPlus() && operand.IsOffset()) {
   10613         EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
   10614                    (rm.GetCode() << 6));
   10615         AdvanceIT();
   10616         return;
   10617       }
   10618     }
   10619   }
   10620   if (operand.IsShiftedRegister()) {
   10621     Register rn = operand.GetBaseRegister();
   10622     Sign sign = operand.GetSign();
   10623     Register rm = operand.GetOffsetRegister();
   10624     Shift shift = operand.GetShift();
   10625     uint32_t amount = operand.GetShiftAmount();
   10626     if (IsUsingT32()) {
   10627       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   10628       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   10629           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10630         EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10631                    rm.GetCode() | (amount << 4));
   10632         AdvanceIT();
   10633         return;
   10634       }
   10635     } else {
   10636       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   10637       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
   10638         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10639         uint32_t shift_ = TypeEncodingValue(shift);
   10640         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   10641         EmitA32(0x07400000U | (cond.GetCondition() << 28) |
   10642                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10643                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   10644         return;
   10645       }
   10646       // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   10647       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   10648           cond.IsNotNever()) {
   10649         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10650         uint32_t shift_ = TypeEncodingValue(shift);
   10651         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   10652         EmitA32(0x06400000U | (cond.GetCondition() << 28) |
   10653                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10654                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   10655         return;
   10656       }
   10657       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   10658       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
   10659         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10660         uint32_t shift_ = TypeEncodingValue(shift);
   10661         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   10662         EmitA32(0x07600000U | (cond.GetCondition() << 28) |
   10663                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10664                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   10665         return;
   10666       }
   10667     }
   10668   }
   10669   Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
   10670 }
   10671 
   10672 void Assembler::strd(Condition cond,
   10673                      Register rt,
   10674                      Register rt2,
   10675                      const MemOperand& operand) {
   10676   VIXL_ASSERT(AllowAssembler());
   10677   CheckIT(cond);
   10678   if (operand.IsImmediate()) {
   10679     Register rn = operand.GetBaseRegister();
   10680     int32_t offset = operand.GetOffsetImmediate();
   10681     if (IsUsingT32()) {
   10682       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
   10683       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   10684           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10685         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10686         uint32_t offset_ = abs(offset) >> 2;
   10687         EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   10688                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   10689         AdvanceIT();
   10690         return;
   10691       }
   10692       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
   10693       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   10694           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   10695         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10696         uint32_t offset_ = abs(offset) >> 2;
   10697         EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   10698                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   10699         AdvanceIT();
   10700         return;
   10701       }
   10702       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
   10703       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   10704           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   10705         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10706         uint32_t offset_ = abs(offset) >> 2;
   10707         EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   10708                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   10709         AdvanceIT();
   10710         return;
   10711       }
   10712     } else {
   10713       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
   10714       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   10715           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   10716           cond.IsNotNever() &&
   10717           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   10718         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10719         uint32_t offset_ = abs(offset);
   10720         EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
   10721                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   10722                 ((offset_ & 0xf0) << 4) | (sign << 23));
   10723         return;
   10724       }
   10725       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
   10726       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   10727           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   10728           cond.IsNotNever() &&
   10729           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   10730         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10731         uint32_t offset_ = abs(offset);
   10732         EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
   10733                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   10734                 ((offset_ & 0xf0) << 4) | (sign << 23));
   10735         return;
   10736       }
   10737       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
   10738       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   10739           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   10740           cond.IsNotNever() &&
   10741           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   10742         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10743         uint32_t offset_ = abs(offset);
   10744         EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
   10745                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   10746                 ((offset_ & 0xf0) << 4) | (sign << 23));
   10747         return;
   10748       }
   10749     }
   10750   }
   10751   if (operand.IsPlainRegister()) {
   10752     Register rn = operand.GetBaseRegister();
   10753     Sign sign = operand.GetSign();
   10754     Register rm = operand.GetOffsetRegister();
   10755     if (IsUsingA32()) {
   10756       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
   10757       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   10758           operand.IsOffset() && cond.IsNotNever() &&
   10759           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   10760         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10761         EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
   10762                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10763                 (sign_ << 23));
   10764         return;
   10765       }
   10766       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
   10767       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   10768           operand.IsPostIndex() && cond.IsNotNever() &&
   10769           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   10770         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10771         EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
   10772                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10773                 (sign_ << 23));
   10774         return;
   10775       }
   10776       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
   10777       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   10778           operand.IsPreIndex() && cond.IsNotNever() &&
   10779           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
   10780         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   10781         EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
   10782                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   10783                 (sign_ << 23));
   10784         return;
   10785       }
   10786     }
   10787   }
   10788   Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
   10789 }
   10790 
   10791 void Assembler::strex(Condition cond,
   10792                       Register rd,
   10793                       Register rt,
   10794                       const MemOperand& operand) {
   10795   VIXL_ASSERT(AllowAssembler());
   10796   CheckIT(cond);
   10797   if (operand.IsImmediate()) {
   10798     Register rn = operand.GetBaseRegister();
   10799     int32_t offset = operand.GetOffsetImmediate();
   10800     if (IsUsingT32()) {
   10801       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
   10802       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
   10803           operand.IsOffset()) {
   10804         int32_t offset_ = offset >> 2;
   10805         EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
   10806                    (rn.GetCode() << 16) | (offset_ & 0xff));
   10807         AdvanceIT();
   10808         return;
   10809       }
   10810     } else {
   10811       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
   10812       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) {
   10813         EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
   10814                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10815         return;
   10816       }
   10817     }
   10818   }
   10819   Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
   10820 }
   10821 
   10822 void Assembler::strexb(Condition cond,
   10823                        Register rd,
   10824                        Register rt,
   10825                        const MemOperand& operand) {
   10826   VIXL_ASSERT(AllowAssembler());
   10827   CheckIT(cond);
   10828   if (operand.IsImmediateZero()) {
   10829     Register rn = operand.GetBaseRegister();
   10830     if (IsUsingT32()) {
   10831       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   10832       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   10833         EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
   10834                    (rn.GetCode() << 16));
   10835         AdvanceIT();
   10836         return;
   10837       }
   10838     } else {
   10839       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   10840       if (operand.IsOffset() && cond.IsNotNever() &&
   10841           (!rn.IsPC() || AllowUnpredictable())) {
   10842         EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
   10843                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10844         return;
   10845       }
   10846     }
   10847   }
   10848   Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
   10849 }
   10850 
   10851 void Assembler::strexd(Condition cond,
   10852                        Register rd,
   10853                        Register rt,
   10854                        Register rt2,
   10855                        const MemOperand& operand) {
   10856   VIXL_ASSERT(AllowAssembler());
   10857   CheckIT(cond);
   10858   if (operand.IsImmediateZero()) {
   10859     Register rn = operand.GetBaseRegister();
   10860     if (IsUsingT32()) {
   10861       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
   10862       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   10863         EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
   10864                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
   10865         AdvanceIT();
   10866         return;
   10867       }
   10868     } else {
   10869       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
   10870       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   10871           operand.IsOffset() && cond.IsNotNever() &&
   10872           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
   10873            AllowUnpredictable())) {
   10874         EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
   10875                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10876         return;
   10877       }
   10878     }
   10879   }
   10880   Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
   10881 }
   10882 
   10883 void Assembler::strexh(Condition cond,
   10884                        Register rd,
   10885                        Register rt,
   10886                        const MemOperand& operand) {
   10887   VIXL_ASSERT(AllowAssembler());
   10888   CheckIT(cond);
   10889   if (operand.IsImmediateZero()) {
   10890     Register rn = operand.GetBaseRegister();
   10891     if (IsUsingT32()) {
   10892       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   10893       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   10894         EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
   10895                    (rn.GetCode() << 16));
   10896         AdvanceIT();
   10897         return;
   10898       }
   10899     } else {
   10900       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   10901       if (operand.IsOffset() && cond.IsNotNever() &&
   10902           (!rn.IsPC() || AllowUnpredictable())) {
   10903         EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
   10904                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10905         return;
   10906       }
   10907     }
   10908   }
   10909   Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
   10910 }
   10911 
   10912 void Assembler::strh(Condition cond,
   10913                      EncodingSize size,
   10914                      Register rt,
   10915                      const MemOperand& operand) {
   10916   VIXL_ASSERT(AllowAssembler());
   10917   CheckIT(cond);
   10918   if (operand.IsImmediate()) {
   10919     Register rn = operand.GetBaseRegister();
   10920     int32_t offset = operand.GetOffsetImmediate();
   10921     if (IsUsingT32()) {
   10922       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   10923       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   10924           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
   10925         int32_t offset_ = offset >> 1;
   10926         EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
   10927                    ((offset_ & 0x1f) << 6));
   10928         AdvanceIT();
   10929         return;
   10930       }
   10931       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   10932       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   10933           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10934         EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10935                    (offset & 0xfff));
   10936         AdvanceIT();
   10937         return;
   10938       }
   10939       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   10940       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   10941           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   10942         EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10943                    (-offset & 0xff));
   10944         AdvanceIT();
   10945         return;
   10946       }
   10947       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   10948       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   10949           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   10950         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10951         uint32_t offset_ = abs(offset);
   10952         EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10953                    offset_ | (sign << 9));
   10954         AdvanceIT();
   10955         return;
   10956       }
   10957       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   10958       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   10959           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   10960         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10961         uint32_t offset_ = abs(offset);
   10962         EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   10963                    offset_ | (sign << 9));
   10964         AdvanceIT();
   10965         return;
   10966       }
   10967     } else {
   10968       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   10969       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   10970           cond.IsNotNever()) {
   10971         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10972         uint32_t offset_ = abs(offset);
   10973         EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
   10974                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   10975                 ((offset_ & 0xf0) << 4) | (sign << 23));
   10976         return;
   10977       }
   10978       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   10979       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   10980           cond.IsNotNever()) {
   10981         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10982         uint32_t offset_ = abs(offset);
   10983         EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
   10984                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   10985                 ((offset_ & 0xf0) << 4) | (sign << 23));
   10986         return;
   10987       }
   10988       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   10989       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   10990           cond.IsNotNever()) {
   10991         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   10992         uint32_t offset_ = abs(offset);
   10993         EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
   10994                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   10995                 ((offset_ & 0xf0) << 4) | (sign << 23));
   10996         return;
   10997       }
   10998     }
   10999   }
   11000   if (operand.IsPlainRegister()) {
   11001     Register rn = operand.GetBaseRegister();
   11002     Sign sign = operand.GetSign();
   11003     Register rm = operand.GetOffsetRegister();
   11004     if (IsUsingT32()) {
   11005       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   11006       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   11007           sign.IsPlus() && operand.IsOffset()) {
   11008         EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
   11009                    (rm.GetCode() << 6));
   11010         AdvanceIT();
   11011         return;
   11012       }
   11013     } else {
   11014       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   11015       if (operand.IsOffset() && cond.IsNotNever()) {
   11016         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11017         EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
   11018                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11019                 (sign_ << 23));
   11020         return;
   11021       }
   11022       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   11023       if (operand.IsPostIndex() && cond.IsNotNever()) {
   11024         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11025         EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
   11026                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11027                 (sign_ << 23));
   11028         return;
   11029       }
   11030       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   11031       if (operand.IsPreIndex() && cond.IsNotNever()) {
   11032         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11033         EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
   11034                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11035                 (sign_ << 23));
   11036         return;
   11037       }
   11038     }
   11039   }
   11040   if (operand.IsShiftedRegister()) {
   11041     Register rn = operand.GetBaseRegister();
   11042     Sign sign = operand.GetSign();
   11043     Register rm = operand.GetOffsetRegister();
   11044     Shift shift = operand.GetShift();
   11045     uint32_t amount = operand.GetShiftAmount();
   11046     if (IsUsingT32()) {
   11047       // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   11048       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   11049           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
   11050         EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11051                    rm.GetCode() | (amount << 4));
   11052         AdvanceIT();
   11053         return;
   11054       }
   11055     }
   11056   }
   11057   Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
   11058 }
   11059 
   11060 void Assembler::sub(Condition cond,
   11061                     EncodingSize size,
   11062                     Register rd,
   11063                     Register rn,
   11064                     const Operand& operand) {
   11065   VIXL_ASSERT(AllowAssembler());
   11066   CheckIT(cond);
   11067   if (operand.IsImmediate()) {
   11068     uint32_t imm = operand.GetImmediate();
   11069     if (IsUsingT32()) {
   11070       ImmediateT32 immediate_t32(imm);
   11071       // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
   11072       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   11073           (imm <= 7)) {
   11074         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   11075         AdvanceIT();
   11076         return;
   11077       }
   11078       // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   11079       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   11080           (imm <= 255)) {
   11081         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
   11082         AdvanceIT();
   11083         return;
   11084       }
   11085       // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
   11086       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
   11087           ((imm % 4) == 0)) {
   11088         uint32_t imm_ = imm >> 2;
   11089         EmitT32_16(0xb080 | imm_);
   11090         AdvanceIT();
   11091         return;
   11092       }
   11093       // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
   11094       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) {
   11095         EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   11096                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   11097         AdvanceIT();
   11098         return;
   11099       }
   11100       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   11101       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) {
   11102         EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11103                    (immediate_t32.GetEncodingValue() & 0xff) |
   11104                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   11105                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   11106         AdvanceIT();
   11107         return;
   11108       }
   11109       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   11110       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
   11111         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11112                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   11113         AdvanceIT();
   11114         return;
   11115       }
   11116       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
   11117       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) {
   11118         EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
   11119                    (immediate_t32.GetEncodingValue() & 0xff) |
   11120                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   11121                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   11122         AdvanceIT();
   11123         return;
   11124       }
   11125       // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
   11126       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) {
   11127         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   11128                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   11129         AdvanceIT();
   11130         return;
   11131       }
   11132     } else {
   11133       ImmediateA32 immediate_a32(imm);
   11134       // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
   11135       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
   11136         EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
   11137                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   11138         return;
   11139       }
   11140       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   11141       if (immediate_a32.IsValid() && cond.IsNotNever() &&
   11142           ((rn.GetCode() & 0xd) != 0xd)) {
   11143         EmitA32(0x02400000U | (cond.GetCondition() << 28) |
   11144                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   11145                 immediate_a32.GetEncodingValue());
   11146         return;
   11147       }
   11148       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   11149       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   11150         EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
   11151                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   11152         return;
   11153       }
   11154     }
   11155   }
   11156   if (operand.IsImmediateShiftedRegister()) {
   11157     Register rm = operand.GetBaseRegister();
   11158     if (operand.IsPlainRegister()) {
   11159       if (IsUsingT32()) {
   11160         // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
   11161         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   11162             rm.IsLow()) {
   11163           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
   11164                      (rm.GetCode() << 6));
   11165           AdvanceIT();
   11166           return;
   11167         }
   11168         // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
   11169         if (rn.Is(sp)) {
   11170           EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
   11171           AdvanceIT();
   11172           return;
   11173         }
   11174       }
   11175     }
   11176     Shift shift = operand.GetShift();
   11177     uint32_t amount = operand.GetShiftAmount();
   11178     if (IsUsingT32()) {
   11179       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   11180       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) {
   11181         uint32_t amount_ = amount % 32;
   11182         EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11183                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   11184                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   11185         AdvanceIT();
   11186         return;
   11187       }
   11188       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
   11189       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) {
   11190         uint32_t amount_ = amount % 32;
   11191         EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
   11192                    (operand.GetTypeEncodingValue() << 4) |
   11193                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   11194         AdvanceIT();
   11195         return;
   11196       }
   11197     } else {
   11198       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   11199       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   11200         uint32_t amount_ = amount % 32;
   11201         EmitA32(0x00400000U | (cond.GetCondition() << 28) |
   11202                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11203                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   11204         return;
   11205       }
   11206       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   11207       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   11208         uint32_t amount_ = amount % 32;
   11209         EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
   11210                 (rd.GetCode() << 12) | rm.GetCode() |
   11211                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   11212         return;
   11213       }
   11214     }
   11215   }
   11216   if (operand.IsRegisterShiftedRegister()) {
   11217     Register rm = operand.GetBaseRegister();
   11218     Shift shift = operand.GetShift();
   11219     if (IsUsingA32()) {
   11220       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   11221       if (cond.IsNotNever()) {
   11222         EmitA32(0x00400010U | (cond.GetCondition() << 28) |
   11223                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11224                 (shift.GetType() << 5) |
   11225                 (operand.GetShiftRegister().GetCode() << 8));
   11226         return;
   11227       }
   11228     }
   11229   }
   11230   Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
   11231 }
   11232 
   11233 void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
   11234   VIXL_ASSERT(AllowAssembler());
   11235   CheckIT(cond);
   11236   if (operand.IsImmediate()) {
   11237     uint32_t imm = operand.GetImmediate();
   11238     if (IsUsingT32()) {
   11239       // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
   11240       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
   11241         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
   11242         AdvanceIT();
   11243         return;
   11244       }
   11245     }
   11246   }
   11247   Delegate(kSub, &Assembler::sub, cond, rd, operand);
   11248 }
   11249 
   11250 void Assembler::subs(Condition cond,
   11251                      EncodingSize size,
   11252                      Register rd,
   11253                      Register rn,
   11254                      const Operand& operand) {
   11255   VIXL_ASSERT(AllowAssembler());
   11256   CheckIT(cond);
   11257   if (operand.IsImmediate()) {
   11258     uint32_t imm = operand.GetImmediate();
   11259     if (IsUsingT32()) {
   11260       ImmediateT32 immediate_t32(imm);
   11261       // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
   11262       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   11263           (imm <= 7)) {
   11264         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   11265         AdvanceIT();
   11266         return;
   11267       }
   11268       // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   11269       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   11270           (imm <= 255)) {
   11271         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
   11272         AdvanceIT();
   11273         return;
   11274       }
   11275       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   11276       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   11277           !rd.Is(pc)) {
   11278         EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11279                    (immediate_t32.GetEncodingValue() & 0xff) |
   11280                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   11281                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   11282         AdvanceIT();
   11283         return;
   11284       }
   11285       // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
   11286       if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255)) {
   11287         EmitT32_32(0xf3de8f00U | imm);
   11288         AdvanceIT();
   11289         return;
   11290       }
   11291       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
   11292       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   11293           !rd.Is(pc)) {
   11294         EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
   11295                    (immediate_t32.GetEncodingValue() & 0xff) |
   11296                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   11297                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   11298         AdvanceIT();
   11299         return;
   11300       }
   11301     } else {
   11302       ImmediateA32 immediate_a32(imm);
   11303       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   11304       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
   11305         EmitA32(0x02500000U | (cond.GetCondition() << 28) |
   11306                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   11307                 immediate_a32.GetEncodingValue());
   11308         return;
   11309       }
   11310       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   11311       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   11312         EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
   11313                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   11314         return;
   11315       }
   11316     }
   11317   }
   11318   if (operand.IsImmediateShiftedRegister()) {
   11319     Register rm = operand.GetBaseRegister();
   11320     if (operand.IsPlainRegister()) {
   11321       if (IsUsingT32()) {
   11322         // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   11323         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   11324             rm.IsLow()) {
   11325           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
   11326                      (rm.GetCode() << 6));
   11327           AdvanceIT();
   11328           return;
   11329         }
   11330       }
   11331     }
   11332     Shift shift = operand.GetShift();
   11333     uint32_t amount = operand.GetShiftAmount();
   11334     if (IsUsingT32()) {
   11335       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   11336       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   11337           !rd.Is(pc)) {
   11338         uint32_t amount_ = amount % 32;
   11339         EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11340                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   11341                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   11342         AdvanceIT();
   11343         return;
   11344       }
   11345       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
   11346       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   11347           !rd.Is(pc)) {
   11348         uint32_t amount_ = amount % 32;
   11349         EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
   11350                    (operand.GetTypeEncodingValue() << 4) |
   11351                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   11352         AdvanceIT();
   11353         return;
   11354       }
   11355     } else {
   11356       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   11357       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   11358         uint32_t amount_ = amount % 32;
   11359         EmitA32(0x00500000U | (cond.GetCondition() << 28) |
   11360                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11361                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   11362         return;
   11363       }
   11364       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   11365       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   11366         uint32_t amount_ = amount % 32;
   11367         EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
   11368                 (rd.GetCode() << 12) | rm.GetCode() |
   11369                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   11370         return;
   11371       }
   11372     }
   11373   }
   11374   if (operand.IsRegisterShiftedRegister()) {
   11375     Register rm = operand.GetBaseRegister();
   11376     Shift shift = operand.GetShift();
   11377     if (IsUsingA32()) {
   11378       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   11379       if (cond.IsNotNever()) {
   11380         EmitA32(0x00500010U | (cond.GetCondition() << 28) |
   11381                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11382                 (shift.GetType() << 5) |
   11383                 (operand.GetShiftRegister().GetCode() << 8));
   11384         return;
   11385       }
   11386     }
   11387   }
   11388   Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
   11389 }
   11390 
   11391 void Assembler::subs(Register rd, const Operand& operand) {
   11392   VIXL_ASSERT(AllowAssembler());
   11393   CheckIT(al);
   11394   if (operand.IsImmediate()) {
   11395     uint32_t imm = operand.GetImmediate();
   11396     if (IsUsingT32()) {
   11397       // SUBS{<q>} <Rdn>, #<imm8> ; T2
   11398       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
   11399         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
   11400         AdvanceIT();
   11401         return;
   11402       }
   11403     }
   11404   }
   11405   Delegate(kSubs, &Assembler::subs, rd, operand);
   11406 }
   11407 
   11408 void Assembler::subw(Condition cond,
   11409                      Register rd,
   11410                      Register rn,
   11411                      const Operand& operand) {
   11412   VIXL_ASSERT(AllowAssembler());
   11413   CheckIT(cond);
   11414   if (operand.IsImmediate()) {
   11415     uint32_t imm = operand.GetImmediate();
   11416     if (IsUsingT32()) {
   11417       // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   11418       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
   11419         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11420                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   11421         AdvanceIT();
   11422         return;
   11423       }
   11424       // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
   11425       if (rn.Is(sp) && (imm <= 4095)) {
   11426         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   11427                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   11428         AdvanceIT();
   11429         return;
   11430       }
   11431     }
   11432   }
   11433   Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
   11434 }
   11435 
   11436 void Assembler::svc(Condition cond, uint32_t imm) {
   11437   VIXL_ASSERT(AllowAssembler());
   11438   CheckIT(cond);
   11439   if (IsUsingT32()) {
   11440     // SVC{<c>}{<q>} {#}<imm> ; T1
   11441     if ((imm <= 255)) {
   11442       EmitT32_16(0xdf00 | imm);
   11443       AdvanceIT();
   11444       return;
   11445     }
   11446   } else {
   11447     // SVC{<c>}{<q>} {#}<imm> ; A1
   11448     if ((imm <= 16777215) && cond.IsNotNever()) {
   11449       EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
   11450       return;
   11451     }
   11452   }
   11453   Delegate(kSvc, &Assembler::svc, cond, imm);
   11454 }
   11455 
   11456 void Assembler::sxtab(Condition cond,
   11457                       Register rd,
   11458                       Register rn,
   11459                       const Operand& operand) {
   11460   VIXL_ASSERT(AllowAssembler());
   11461   CheckIT(cond);
   11462   if (operand.IsImmediateShiftedRegister()) {
   11463     Register rm = operand.GetBaseRegister();
   11464     Shift shift = operand.GetShift();
   11465     uint32_t amount = operand.GetShiftAmount();
   11466     if (IsUsingT32()) {
   11467       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   11468       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11469           ((amount % 8) == 0) && !rn.Is(pc)) {
   11470         uint32_t amount_ = amount / 8;
   11471         EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11472                    rm.GetCode() | (amount_ << 4));
   11473         AdvanceIT();
   11474         return;
   11475       }
   11476     } else {
   11477       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   11478       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11479           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
   11480         uint32_t amount_ = amount / 8;
   11481         EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
   11482                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11483                 (amount_ << 10));
   11484         return;
   11485       }
   11486     }
   11487   }
   11488   Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
   11489 }
   11490 
   11491 void Assembler::sxtab16(Condition cond,
   11492                         Register rd,
   11493                         Register rn,
   11494                         const Operand& operand) {
   11495   VIXL_ASSERT(AllowAssembler());
   11496   CheckIT(cond);
   11497   if (operand.IsImmediateShiftedRegister()) {
   11498     Register rm = operand.GetBaseRegister();
   11499     Shift shift = operand.GetShift();
   11500     uint32_t amount = operand.GetShiftAmount();
   11501     if (IsUsingT32()) {
   11502       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   11503       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11504           ((amount % 8) == 0) && !rn.Is(pc)) {
   11505         uint32_t amount_ = amount / 8;
   11506         EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11507                    rm.GetCode() | (amount_ << 4));
   11508         AdvanceIT();
   11509         return;
   11510       }
   11511     } else {
   11512       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   11513       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11514           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
   11515         uint32_t amount_ = amount / 8;
   11516         EmitA32(0x06800070U | (cond.GetCondition() << 28) |
   11517                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11518                 (amount_ << 10));
   11519         return;
   11520       }
   11521     }
   11522   }
   11523   Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
   11524 }
   11525 
   11526 void Assembler::sxtah(Condition cond,
   11527                       Register rd,
   11528                       Register rn,
   11529                       const Operand& operand) {
   11530   VIXL_ASSERT(AllowAssembler());
   11531   CheckIT(cond);
   11532   if (operand.IsImmediateShiftedRegister()) {
   11533     Register rm = operand.GetBaseRegister();
   11534     Shift shift = operand.GetShift();
   11535     uint32_t amount = operand.GetShiftAmount();
   11536     if (IsUsingT32()) {
   11537       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   11538       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11539           ((amount % 8) == 0) && !rn.Is(pc)) {
   11540         uint32_t amount_ = amount / 8;
   11541         EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11542                    rm.GetCode() | (amount_ << 4));
   11543         AdvanceIT();
   11544         return;
   11545       }
   11546     } else {
   11547       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   11548       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11549           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
   11550         uint32_t amount_ = amount / 8;
   11551         EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
   11552                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11553                 (amount_ << 10));
   11554         return;
   11555       }
   11556     }
   11557   }
   11558   Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
   11559 }
   11560 
   11561 void Assembler::sxtb(Condition cond,
   11562                      EncodingSize size,
   11563                      Register rd,
   11564                      const Operand& operand) {
   11565   VIXL_ASSERT(AllowAssembler());
   11566   CheckIT(cond);
   11567   if (operand.IsImmediateShiftedRegister()) {
   11568     Register rm = operand.GetBaseRegister();
   11569     if (operand.IsPlainRegister()) {
   11570       if (IsUsingT32()) {
   11571         // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
   11572         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   11573           EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
   11574           AdvanceIT();
   11575           return;
   11576         }
   11577       }
   11578     }
   11579     Shift shift = operand.GetShift();
   11580     uint32_t amount = operand.GetShiftAmount();
   11581     if (IsUsingT32()) {
   11582       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
   11583       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
   11584           (amount <= 24) && ((amount % 8) == 0)) {
   11585         uint32_t amount_ = amount / 8;
   11586         EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   11587                    (amount_ << 4));
   11588         AdvanceIT();
   11589         return;
   11590       }
   11591     } else {
   11592       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   11593       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11594           ((amount % 8) == 0) && cond.IsNotNever()) {
   11595         uint32_t amount_ = amount / 8;
   11596         EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
   11597                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   11598         return;
   11599       }
   11600     }
   11601   }
   11602   Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
   11603 }
   11604 
   11605 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
   11606   VIXL_ASSERT(AllowAssembler());
   11607   CheckIT(cond);
   11608   if (operand.IsImmediateShiftedRegister()) {
   11609     Register rm = operand.GetBaseRegister();
   11610     Shift shift = operand.GetShift();
   11611     uint32_t amount = operand.GetShiftAmount();
   11612     if (IsUsingT32()) {
   11613       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
   11614       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11615           ((amount % 8) == 0)) {
   11616         uint32_t amount_ = amount / 8;
   11617         EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   11618                    (amount_ << 4));
   11619         AdvanceIT();
   11620         return;
   11621       }
   11622     } else {
   11623       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   11624       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11625           ((amount % 8) == 0) && cond.IsNotNever()) {
   11626         uint32_t amount_ = amount / 8;
   11627         EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
   11628                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   11629         return;
   11630       }
   11631     }
   11632   }
   11633   Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
   11634 }
   11635 
   11636 void Assembler::sxth(Condition cond,
   11637                      EncodingSize size,
   11638                      Register rd,
   11639                      const Operand& operand) {
   11640   VIXL_ASSERT(AllowAssembler());
   11641   CheckIT(cond);
   11642   if (operand.IsImmediateShiftedRegister()) {
   11643     Register rm = operand.GetBaseRegister();
   11644     if (operand.IsPlainRegister()) {
   11645       if (IsUsingT32()) {
   11646         // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
   11647         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   11648           EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
   11649           AdvanceIT();
   11650           return;
   11651         }
   11652       }
   11653     }
   11654     Shift shift = operand.GetShift();
   11655     uint32_t amount = operand.GetShiftAmount();
   11656     if (IsUsingT32()) {
   11657       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
   11658       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
   11659           (amount <= 24) && ((amount % 8) == 0)) {
   11660         uint32_t amount_ = amount / 8;
   11661         EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   11662                    (amount_ << 4));
   11663         AdvanceIT();
   11664         return;
   11665       }
   11666     } else {
   11667       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   11668       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   11669           ((amount % 8) == 0) && cond.IsNotNever()) {
   11670         uint32_t amount_ = amount / 8;
   11671         EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
   11672                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   11673         return;
   11674       }
   11675     }
   11676   }
   11677   Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
   11678 }
   11679 
   11680 void Assembler::tbb(Condition cond, Register rn, Register rm) {
   11681   VIXL_ASSERT(AllowAssembler());
   11682   CheckIT(cond);
   11683   if (IsUsingT32()) {
   11684     // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
   11685     if (OutsideITBlockAndAlOrLast(cond) &&
   11686         (!rm.IsPC() || AllowUnpredictable())) {
   11687       EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
   11688       AdvanceIT();
   11689       return;
   11690     }
   11691   }
   11692   Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
   11693 }
   11694 
   11695 void Assembler::tbh(Condition cond, Register rn, Register rm) {
   11696   VIXL_ASSERT(AllowAssembler());
   11697   CheckIT(cond);
   11698   if (IsUsingT32()) {
   11699     // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
   11700     if (OutsideITBlockAndAlOrLast(cond) &&
   11701         (!rm.IsPC() || AllowUnpredictable())) {
   11702       EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
   11703       AdvanceIT();
   11704       return;
   11705     }
   11706   }
   11707   Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
   11708 }
   11709 
   11710 void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
   11711   VIXL_ASSERT(AllowAssembler());
   11712   CheckIT(cond);
   11713   if (operand.IsImmediate()) {
   11714     uint32_t imm = operand.GetImmediate();
   11715     if (IsUsingT32()) {
   11716       ImmediateT32 immediate_t32(imm);
   11717       // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
   11718       if (immediate_t32.IsValid()) {
   11719         EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
   11720                    (immediate_t32.GetEncodingValue() & 0xff) |
   11721                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   11722                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   11723         AdvanceIT();
   11724         return;
   11725       }
   11726     } else {
   11727       ImmediateA32 immediate_a32(imm);
   11728       // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
   11729       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   11730         EmitA32(0x03300000U | (cond.GetCondition() << 28) |
   11731                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   11732         return;
   11733       }
   11734     }
   11735   }
   11736   if (operand.IsImmediateShiftedRegister()) {
   11737     Register rm = operand.GetBaseRegister();
   11738     Shift shift = operand.GetShift();
   11739     uint32_t amount = operand.GetShiftAmount();
   11740     if (IsUsingT32()) {
   11741       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
   11742       if (shift.IsValidAmount(amount)) {
   11743         uint32_t amount_ = amount % 32;
   11744         EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
   11745                    (operand.GetTypeEncodingValue() << 4) |
   11746                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   11747         AdvanceIT();
   11748         return;
   11749       }
   11750     } else {
   11751       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   11752       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   11753         uint32_t amount_ = amount % 32;
   11754         EmitA32(0x01300000U | (cond.GetCondition() << 28) |
   11755                 (rn.GetCode() << 16) | rm.GetCode() |
   11756                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   11757         return;
   11758       }
   11759     }
   11760   }
   11761   if (operand.IsRegisterShiftedRegister()) {
   11762     Register rm = operand.GetBaseRegister();
   11763     Shift shift = operand.GetShift();
   11764     if (IsUsingA32()) {
   11765       // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   11766       if (cond.IsNotNever()) {
   11767         EmitA32(0x01300010U | (cond.GetCondition() << 28) |
   11768                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   11769                 (operand.GetShiftRegister().GetCode() << 8));
   11770         return;
   11771       }
   11772     }
   11773   }
   11774   Delegate(kTeq, &Assembler::teq, cond, rn, operand);
   11775 }
   11776 
   11777 void Assembler::tst(Condition cond,
   11778                     EncodingSize size,
   11779                     Register rn,
   11780                     const Operand& operand) {
   11781   VIXL_ASSERT(AllowAssembler());
   11782   CheckIT(cond);
   11783   if (operand.IsImmediate()) {
   11784     uint32_t imm = operand.GetImmediate();
   11785     if (IsUsingT32()) {
   11786       ImmediateT32 immediate_t32(imm);
   11787       // TST{<c>}{<q>} <Rn>, #<const> ; T1
   11788       if (!size.IsNarrow() && immediate_t32.IsValid()) {
   11789         EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
   11790                    (immediate_t32.GetEncodingValue() & 0xff) |
   11791                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   11792                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   11793         AdvanceIT();
   11794         return;
   11795       }
   11796     } else {
   11797       ImmediateA32 immediate_a32(imm);
   11798       // TST{<c>}{<q>} <Rn>, #<const> ; A1
   11799       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   11800         EmitA32(0x03100000U | (cond.GetCondition() << 28) |
   11801                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   11802         return;
   11803       }
   11804     }
   11805   }
   11806   if (operand.IsImmediateShiftedRegister()) {
   11807     Register rm = operand.GetBaseRegister();
   11808     if (operand.IsPlainRegister()) {
   11809       if (IsUsingT32()) {
   11810         // TST{<c>}{<q>} <Rn>, <Rm> ; T1
   11811         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
   11812           EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
   11813           AdvanceIT();
   11814           return;
   11815         }
   11816       }
   11817     }
   11818     Shift shift = operand.GetShift();
   11819     uint32_t amount = operand.GetShiftAmount();
   11820     if (IsUsingT32()) {
   11821       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
   11822       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
   11823         uint32_t amount_ = amount % 32;
   11824         EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
   11825                    (operand.GetTypeEncodingValue() << 4) |
   11826                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   11827         AdvanceIT();
   11828         return;
   11829       }
   11830     } else {
   11831       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   11832       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   11833         uint32_t amount_ = amount % 32;
   11834         EmitA32(0x01100000U | (cond.GetCondition() << 28) |
   11835                 (rn.GetCode() << 16) | rm.GetCode() |
   11836                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   11837         return;
   11838       }
   11839     }
   11840   }
   11841   if (operand.IsRegisterShiftedRegister()) {
   11842     Register rm = operand.GetBaseRegister();
   11843     Shift shift = operand.GetShift();
   11844     if (IsUsingA32()) {
   11845       // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   11846       if (cond.IsNotNever()) {
   11847         EmitA32(0x01100010U | (cond.GetCondition() << 28) |
   11848                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   11849                 (operand.GetShiftRegister().GetCode() << 8));
   11850         return;
   11851       }
   11852     }
   11853   }
   11854   Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
   11855 }
   11856 
   11857 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
   11858   VIXL_ASSERT(AllowAssembler());
   11859   CheckIT(cond);
   11860   if (IsUsingT32()) {
   11861     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   11862     EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11863                rm.GetCode());
   11864     AdvanceIT();
   11865     return;
   11866   } else {
   11867     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   11868     if (cond.IsNotNever()) {
   11869       EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   11870               (rn.GetCode() << 16) | rm.GetCode());
   11871       return;
   11872     }
   11873   }
   11874   Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
   11875 }
   11876 
   11877 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
   11878   VIXL_ASSERT(AllowAssembler());
   11879   CheckIT(cond);
   11880   if (IsUsingT32()) {
   11881     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   11882     EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11883                rm.GetCode());
   11884     AdvanceIT();
   11885     return;
   11886   } else {
   11887     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   11888     if (cond.IsNotNever()) {
   11889       EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   11890               (rn.GetCode() << 16) | rm.GetCode());
   11891       return;
   11892     }
   11893   }
   11894   Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
   11895 }
   11896 
   11897 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
   11898   VIXL_ASSERT(AllowAssembler());
   11899   CheckIT(cond);
   11900   if (IsUsingT32()) {
   11901     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   11902     EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11903                rm.GetCode());
   11904     AdvanceIT();
   11905     return;
   11906   } else {
   11907     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   11908     if (cond.IsNotNever()) {
   11909       EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   11910               (rn.GetCode() << 16) | rm.GetCode());
   11911       return;
   11912     }
   11913   }
   11914   Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
   11915 }
   11916 
   11917 void Assembler::ubfx(Condition cond,
   11918                      Register rd,
   11919                      Register rn,
   11920                      uint32_t lsb,
   11921                      const Operand& operand) {
   11922   VIXL_ASSERT(AllowAssembler());
   11923   CheckIT(cond);
   11924   if (operand.IsImmediate()) {
   11925     uint32_t width = operand.GetImmediate();
   11926     if (IsUsingT32()) {
   11927       // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
   11928       if ((lsb <= 31) &&
   11929           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
   11930         uint32_t widthm1 = width - 1;
   11931         EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11932                    ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
   11933         AdvanceIT();
   11934         return;
   11935       }
   11936     } else {
   11937       // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
   11938       if ((lsb <= 31) && cond.IsNotNever() &&
   11939           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
   11940         uint32_t widthm1 = width - 1;
   11941         EmitA32(0x07e00050U | (cond.GetCondition() << 28) |
   11942                 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
   11943                 (widthm1 << 16));
   11944         return;
   11945       }
   11946     }
   11947   }
   11948   Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, operand);
   11949 }
   11950 
   11951 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
   11952   VIXL_ASSERT(AllowAssembler());
   11953   CheckIT(cond);
   11954   if (IsUsingT32()) {
   11955     // UDF{<c>}{<q>} {#}<imm> ; T1
   11956     if (!size.IsWide() && (imm <= 255)) {
   11957       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   11958         EmitT32_16(0xde00 | imm);
   11959         AdvanceIT();
   11960         return;
   11961       }
   11962     }
   11963     // UDF{<c>}{<q>} {#}<imm> ; T2
   11964     if (!size.IsNarrow() && (imm <= 65535)) {
   11965       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   11966         EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
   11967         AdvanceIT();
   11968         return;
   11969       }
   11970     }
   11971   } else {
   11972     // UDF{<c>}{<q>} {#}<imm> ; A1
   11973     if ((imm <= 65535)) {
   11974       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   11975         EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
   11976         return;
   11977       }
   11978     }
   11979   }
   11980   Delegate(kUdf, &Assembler::udf, cond, size, imm);
   11981 }
   11982 
   11983 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
   11984   VIXL_ASSERT(AllowAssembler());
   11985   CheckIT(cond);
   11986   if (IsUsingT32()) {
   11987     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   11988     EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   11989                rm.GetCode());
   11990     AdvanceIT();
   11991     return;
   11992   } else {
   11993     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   11994     if (cond.IsNotNever()) {
   11995       EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   11996               rn.GetCode() | (rm.GetCode() << 8));
   11997       return;
   11998     }
   11999   }
   12000   Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
   12001 }
   12002 
   12003 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
   12004   VIXL_ASSERT(AllowAssembler());
   12005   CheckIT(cond);
   12006   if (IsUsingT32()) {
   12007     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12008     EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12009                rm.GetCode());
   12010     AdvanceIT();
   12011     return;
   12012   } else {
   12013     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12014     if (cond.IsNotNever()) {
   12015       EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12016               (rn.GetCode() << 16) | rm.GetCode());
   12017       return;
   12018     }
   12019   }
   12020   Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
   12021 }
   12022 
   12023 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
   12024   VIXL_ASSERT(AllowAssembler());
   12025   CheckIT(cond);
   12026   if (IsUsingT32()) {
   12027     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12028     EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12029                rm.GetCode());
   12030     AdvanceIT();
   12031     return;
   12032   } else {
   12033     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12034     if (cond.IsNotNever()) {
   12035       EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12036               (rn.GetCode() << 16) | rm.GetCode());
   12037       return;
   12038     }
   12039   }
   12040   Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
   12041 }
   12042 
   12043 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
   12044   VIXL_ASSERT(AllowAssembler());
   12045   CheckIT(cond);
   12046   if (IsUsingT32()) {
   12047     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12048     EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12049                rm.GetCode());
   12050     AdvanceIT();
   12051     return;
   12052   } else {
   12053     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12054     if (cond.IsNotNever()) {
   12055       EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12056               (rn.GetCode() << 16) | rm.GetCode());
   12057       return;
   12058     }
   12059   }
   12060   Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
   12061 }
   12062 
   12063 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
   12064   VIXL_ASSERT(AllowAssembler());
   12065   CheckIT(cond);
   12066   if (IsUsingT32()) {
   12067     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12068     EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12069                rm.GetCode());
   12070     AdvanceIT();
   12071     return;
   12072   } else {
   12073     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12074     if (cond.IsNotNever()) {
   12075       EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12076               (rn.GetCode() << 16) | rm.GetCode());
   12077       return;
   12078     }
   12079   }
   12080   Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
   12081 }
   12082 
   12083 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
   12084   VIXL_ASSERT(AllowAssembler());
   12085   CheckIT(cond);
   12086   if (IsUsingT32()) {
   12087     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12088     EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12089                rm.GetCode());
   12090     AdvanceIT();
   12091     return;
   12092   } else {
   12093     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12094     if (cond.IsNotNever()) {
   12095       EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12096               (rn.GetCode() << 16) | rm.GetCode());
   12097       return;
   12098     }
   12099   }
   12100   Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
   12101 }
   12102 
   12103 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
   12104   VIXL_ASSERT(AllowAssembler());
   12105   CheckIT(cond);
   12106   if (IsUsingT32()) {
   12107     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12108     EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12109                rm.GetCode());
   12110     AdvanceIT();
   12111     return;
   12112   } else {
   12113     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12114     if (cond.IsNotNever()) {
   12115       EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12116               (rn.GetCode() << 16) | rm.GetCode());
   12117       return;
   12118     }
   12119   }
   12120   Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
   12121 }
   12122 
   12123 void Assembler::umaal(
   12124     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   12125   VIXL_ASSERT(AllowAssembler());
   12126   CheckIT(cond);
   12127   if (IsUsingT32()) {
   12128     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   12129     EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   12130                (rn.GetCode() << 16) | rm.GetCode());
   12131     AdvanceIT();
   12132     return;
   12133   } else {
   12134     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   12135     if (cond.IsNotNever()) {
   12136       EmitA32(0x00400090U | (cond.GetCondition() << 28) |
   12137               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   12138               (rm.GetCode() << 8));
   12139       return;
   12140     }
   12141   }
   12142   Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
   12143 }
   12144 
   12145 void Assembler::umlal(
   12146     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   12147   VIXL_ASSERT(AllowAssembler());
   12148   CheckIT(cond);
   12149   if (IsUsingT32()) {
   12150     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   12151     EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   12152                (rn.GetCode() << 16) | rm.GetCode());
   12153     AdvanceIT();
   12154     return;
   12155   } else {
   12156     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   12157     if (cond.IsNotNever()) {
   12158       EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
   12159               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   12160               (rm.GetCode() << 8));
   12161       return;
   12162     }
   12163   }
   12164   Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
   12165 }
   12166 
   12167 void Assembler::umlals(
   12168     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   12169   VIXL_ASSERT(AllowAssembler());
   12170   CheckIT(cond);
   12171   if (IsUsingA32()) {
   12172     // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   12173     if (cond.IsNotNever()) {
   12174       EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
   12175               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   12176               (rm.GetCode() << 8));
   12177       return;
   12178     }
   12179   }
   12180   Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
   12181 }
   12182 
   12183 void Assembler::umull(
   12184     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   12185   VIXL_ASSERT(AllowAssembler());
   12186   CheckIT(cond);
   12187   if (IsUsingT32()) {
   12188     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   12189     EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   12190                (rn.GetCode() << 16) | rm.GetCode());
   12191     AdvanceIT();
   12192     return;
   12193   } else {
   12194     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   12195     if (cond.IsNotNever()) {
   12196       EmitA32(0x00800090U | (cond.GetCondition() << 28) |
   12197               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   12198               (rm.GetCode() << 8));
   12199       return;
   12200     }
   12201   }
   12202   Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
   12203 }
   12204 
   12205 void Assembler::umulls(
   12206     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   12207   VIXL_ASSERT(AllowAssembler());
   12208   CheckIT(cond);
   12209   if (IsUsingA32()) {
   12210     // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   12211     if (cond.IsNotNever()) {
   12212       EmitA32(0x00900090U | (cond.GetCondition() << 28) |
   12213               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   12214               (rm.GetCode() << 8));
   12215       return;
   12216     }
   12217   }
   12218   Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
   12219 }
   12220 
   12221 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
   12222   VIXL_ASSERT(AllowAssembler());
   12223   CheckIT(cond);
   12224   if (IsUsingT32()) {
   12225     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12226     EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12227                rm.GetCode());
   12228     AdvanceIT();
   12229     return;
   12230   } else {
   12231     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12232     if (cond.IsNotNever()) {
   12233       EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12234               (rn.GetCode() << 16) | rm.GetCode());
   12235       return;
   12236     }
   12237   }
   12238   Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
   12239 }
   12240 
   12241 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
   12242   VIXL_ASSERT(AllowAssembler());
   12243   CheckIT(cond);
   12244   if (IsUsingT32()) {
   12245     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12246     EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12247                rm.GetCode());
   12248     AdvanceIT();
   12249     return;
   12250   } else {
   12251     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12252     if (cond.IsNotNever()) {
   12253       EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12254               (rn.GetCode() << 16) | rm.GetCode());
   12255       return;
   12256     }
   12257   }
   12258   Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
   12259 }
   12260 
   12261 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
   12262   VIXL_ASSERT(AllowAssembler());
   12263   CheckIT(cond);
   12264   if (IsUsingT32()) {
   12265     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12266     EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12267                rm.GetCode());
   12268     AdvanceIT();
   12269     return;
   12270   } else {
   12271     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12272     if (cond.IsNotNever()) {
   12273       EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12274               (rn.GetCode() << 16) | rm.GetCode());
   12275       return;
   12276     }
   12277   }
   12278   Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
   12279 }
   12280 
   12281 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
   12282   VIXL_ASSERT(AllowAssembler());
   12283   CheckIT(cond);
   12284   if (IsUsingT32()) {
   12285     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12286     EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12287                rm.GetCode());
   12288     AdvanceIT();
   12289     return;
   12290   } else {
   12291     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12292     if (cond.IsNotNever()) {
   12293       EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12294               (rn.GetCode() << 16) | rm.GetCode());
   12295       return;
   12296     }
   12297   }
   12298   Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
   12299 }
   12300 
   12301 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
   12302   VIXL_ASSERT(AllowAssembler());
   12303   CheckIT(cond);
   12304   if (IsUsingT32()) {
   12305     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12306     EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12307                rm.GetCode());
   12308     AdvanceIT();
   12309     return;
   12310   } else {
   12311     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12312     if (cond.IsNotNever()) {
   12313       EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12314               (rn.GetCode() << 16) | rm.GetCode());
   12315       return;
   12316     }
   12317   }
   12318   Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
   12319 }
   12320 
   12321 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
   12322   VIXL_ASSERT(AllowAssembler());
   12323   CheckIT(cond);
   12324   if (IsUsingT32()) {
   12325     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12326     EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12327                rm.GetCode());
   12328     AdvanceIT();
   12329     return;
   12330   } else {
   12331     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12332     if (cond.IsNotNever()) {
   12333       EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12334               (rn.GetCode() << 16) | rm.GetCode());
   12335       return;
   12336     }
   12337   }
   12338   Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
   12339 }
   12340 
   12341 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
   12342   VIXL_ASSERT(AllowAssembler());
   12343   CheckIT(cond);
   12344   if (IsUsingT32()) {
   12345     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12346     EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12347                rm.GetCode());
   12348     AdvanceIT();
   12349     return;
   12350   } else {
   12351     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12352     if (cond.IsNotNever()) {
   12353       EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   12354               rn.GetCode() | (rm.GetCode() << 8));
   12355       return;
   12356     }
   12357   }
   12358   Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
   12359 }
   12360 
   12361 void Assembler::usada8(
   12362     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   12363   VIXL_ASSERT(AllowAssembler());
   12364   CheckIT(cond);
   12365   if (IsUsingT32()) {
   12366     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   12367     if (!ra.Is(pc)) {
   12368       EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12369                  rm.GetCode() | (ra.GetCode() << 12));
   12370       AdvanceIT();
   12371       return;
   12372     }
   12373   } else {
   12374     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   12375     if (cond.IsNotNever() && !ra.Is(pc)) {
   12376       EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   12377               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   12378       return;
   12379     }
   12380   }
   12381   Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
   12382 }
   12383 
   12384 void Assembler::usat(Condition cond,
   12385                      Register rd,
   12386                      uint32_t imm,
   12387                      const Operand& operand) {
   12388   VIXL_ASSERT(AllowAssembler());
   12389   CheckIT(cond);
   12390   if (operand.IsImmediateShiftedRegister()) {
   12391     Register rn = operand.GetBaseRegister();
   12392     Shift shift = operand.GetShift();
   12393     uint32_t amount = operand.GetShiftAmount();
   12394     if (IsUsingT32()) {
   12395       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
   12396       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31)) {
   12397         EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
   12398                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
   12399                    ((amount & 0x1c) << 10));
   12400         AdvanceIT();
   12401         return;
   12402       }
   12403       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
   12404       if ((imm <= 31) && shift.IsLSL() && (amount <= 31)) {
   12405         EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
   12406                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
   12407                    ((amount & 0x1c) << 10));
   12408         AdvanceIT();
   12409         return;
   12410       }
   12411     } else {
   12412       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
   12413       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
   12414           cond.IsNotNever()) {
   12415         uint32_t amount_ = amount % 32;
   12416         EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
   12417                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
   12418                 (amount_ << 7));
   12419         return;
   12420       }
   12421       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
   12422       if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever()) {
   12423         EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
   12424                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
   12425                 (amount << 7));
   12426         return;
   12427       }
   12428     }
   12429   }
   12430   Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
   12431 }
   12432 
   12433 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
   12434   VIXL_ASSERT(AllowAssembler());
   12435   CheckIT(cond);
   12436   if (IsUsingT32()) {
   12437     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
   12438     if ((imm <= 15)) {
   12439       EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
   12440                  (rn.GetCode() << 16));
   12441       AdvanceIT();
   12442       return;
   12443     }
   12444   } else {
   12445     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
   12446     if ((imm <= 15) && cond.IsNotNever()) {
   12447       EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12448               (imm << 16) | rn.GetCode());
   12449       return;
   12450     }
   12451   }
   12452   Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
   12453 }
   12454 
   12455 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
   12456   VIXL_ASSERT(AllowAssembler());
   12457   CheckIT(cond);
   12458   if (IsUsingT32()) {
   12459     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12460     EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12461                rm.GetCode());
   12462     AdvanceIT();
   12463     return;
   12464   } else {
   12465     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12466     if (cond.IsNotNever()) {
   12467       EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12468               (rn.GetCode() << 16) | rm.GetCode());
   12469       return;
   12470     }
   12471   }
   12472   Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
   12473 }
   12474 
   12475 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
   12476   VIXL_ASSERT(AllowAssembler());
   12477   CheckIT(cond);
   12478   if (IsUsingT32()) {
   12479     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12480     EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12481                rm.GetCode());
   12482     AdvanceIT();
   12483     return;
   12484   } else {
   12485     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12486     if (cond.IsNotNever()) {
   12487       EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12488               (rn.GetCode() << 16) | rm.GetCode());
   12489       return;
   12490     }
   12491   }
   12492   Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
   12493 }
   12494 
   12495 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
   12496   VIXL_ASSERT(AllowAssembler());
   12497   CheckIT(cond);
   12498   if (IsUsingT32()) {
   12499     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12500     EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12501                rm.GetCode());
   12502     AdvanceIT();
   12503     return;
   12504   } else {
   12505     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12506     if (cond.IsNotNever()) {
   12507       EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12508               (rn.GetCode() << 16) | rm.GetCode());
   12509       return;
   12510     }
   12511   }
   12512   Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
   12513 }
   12514 
   12515 void Assembler::uxtab(Condition cond,
   12516                       Register rd,
   12517                       Register rn,
   12518                       const Operand& operand) {
   12519   VIXL_ASSERT(AllowAssembler());
   12520   CheckIT(cond);
   12521   if (operand.IsImmediateShiftedRegister()) {
   12522     Register rm = operand.GetBaseRegister();
   12523     Shift shift = operand.GetShift();
   12524     uint32_t amount = operand.GetShiftAmount();
   12525     if (IsUsingT32()) {
   12526       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   12527       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12528           ((amount % 8) == 0) && !rn.Is(pc)) {
   12529         uint32_t amount_ = amount / 8;
   12530         EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12531                    rm.GetCode() | (amount_ << 4));
   12532         AdvanceIT();
   12533         return;
   12534       }
   12535     } else {
   12536       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   12537       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12538           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
   12539         uint32_t amount_ = amount / 8;
   12540         EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
   12541                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12542                 (amount_ << 10));
   12543         return;
   12544       }
   12545     }
   12546   }
   12547   Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
   12548 }
   12549 
   12550 void Assembler::uxtab16(Condition cond,
   12551                         Register rd,
   12552                         Register rn,
   12553                         const Operand& operand) {
   12554   VIXL_ASSERT(AllowAssembler());
   12555   CheckIT(cond);
   12556   if (operand.IsImmediateShiftedRegister()) {
   12557     Register rm = operand.GetBaseRegister();
   12558     Shift shift = operand.GetShift();
   12559     uint32_t amount = operand.GetShiftAmount();
   12560     if (IsUsingT32()) {
   12561       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   12562       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12563           ((amount % 8) == 0) && !rn.Is(pc)) {
   12564         uint32_t amount_ = amount / 8;
   12565         EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12566                    rm.GetCode() | (amount_ << 4));
   12567         AdvanceIT();
   12568         return;
   12569       }
   12570     } else {
   12571       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   12572       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12573           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
   12574         uint32_t amount_ = amount / 8;
   12575         EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
   12576                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12577                 (amount_ << 10));
   12578         return;
   12579       }
   12580     }
   12581   }
   12582   Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
   12583 }
   12584 
   12585 void Assembler::uxtah(Condition cond,
   12586                       Register rd,
   12587                       Register rn,
   12588                       const Operand& operand) {
   12589   VIXL_ASSERT(AllowAssembler());
   12590   CheckIT(cond);
   12591   if (operand.IsImmediateShiftedRegister()) {
   12592     Register rm = operand.GetBaseRegister();
   12593     Shift shift = operand.GetShift();
   12594     uint32_t amount = operand.GetShiftAmount();
   12595     if (IsUsingT32()) {
   12596       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   12597       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12598           ((amount % 8) == 0) && !rn.Is(pc)) {
   12599         uint32_t amount_ = amount / 8;
   12600         EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12601                    rm.GetCode() | (amount_ << 4));
   12602         AdvanceIT();
   12603         return;
   12604       }
   12605     } else {
   12606       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   12607       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12608           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
   12609         uint32_t amount_ = amount / 8;
   12610         EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
   12611                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12612                 (amount_ << 10));
   12613         return;
   12614       }
   12615     }
   12616   }
   12617   Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
   12618 }
   12619 
   12620 void Assembler::uxtb(Condition cond,
   12621                      EncodingSize size,
   12622                      Register rd,
   12623                      const Operand& operand) {
   12624   VIXL_ASSERT(AllowAssembler());
   12625   CheckIT(cond);
   12626   if (operand.IsImmediateShiftedRegister()) {
   12627     Register rm = operand.GetBaseRegister();
   12628     if (operand.IsPlainRegister()) {
   12629       if (IsUsingT32()) {
   12630         // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
   12631         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   12632           EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
   12633           AdvanceIT();
   12634           return;
   12635         }
   12636       }
   12637     }
   12638     Shift shift = operand.GetShift();
   12639     uint32_t amount = operand.GetShiftAmount();
   12640     if (IsUsingT32()) {
   12641       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
   12642       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
   12643           (amount <= 24) && ((amount % 8) == 0)) {
   12644         uint32_t amount_ = amount / 8;
   12645         EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   12646                    (amount_ << 4));
   12647         AdvanceIT();
   12648         return;
   12649       }
   12650     } else {
   12651       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   12652       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12653           ((amount % 8) == 0) && cond.IsNotNever()) {
   12654         uint32_t amount_ = amount / 8;
   12655         EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
   12656                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   12657         return;
   12658       }
   12659     }
   12660   }
   12661   Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
   12662 }
   12663 
   12664 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
   12665   VIXL_ASSERT(AllowAssembler());
   12666   CheckIT(cond);
   12667   if (operand.IsImmediateShiftedRegister()) {
   12668     Register rm = operand.GetBaseRegister();
   12669     Shift shift = operand.GetShift();
   12670     uint32_t amount = operand.GetShiftAmount();
   12671     if (IsUsingT32()) {
   12672       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
   12673       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12674           ((amount % 8) == 0)) {
   12675         uint32_t amount_ = amount / 8;
   12676         EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   12677                    (amount_ << 4));
   12678         AdvanceIT();
   12679         return;
   12680       }
   12681     } else {
   12682       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   12683       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12684           ((amount % 8) == 0) && cond.IsNotNever()) {
   12685         uint32_t amount_ = amount / 8;
   12686         EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
   12687                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   12688         return;
   12689       }
   12690     }
   12691   }
   12692   Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
   12693 }
   12694 
   12695 void Assembler::uxth(Condition cond,
   12696                      EncodingSize size,
   12697                      Register rd,
   12698                      const Operand& operand) {
   12699   VIXL_ASSERT(AllowAssembler());
   12700   CheckIT(cond);
   12701   if (operand.IsImmediateShiftedRegister()) {
   12702     Register rm = operand.GetBaseRegister();
   12703     if (operand.IsPlainRegister()) {
   12704       if (IsUsingT32()) {
   12705         // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
   12706         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   12707           EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
   12708           AdvanceIT();
   12709           return;
   12710         }
   12711       }
   12712     }
   12713     Shift shift = operand.GetShift();
   12714     uint32_t amount = operand.GetShiftAmount();
   12715     if (IsUsingT32()) {
   12716       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
   12717       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
   12718           (amount <= 24) && ((amount % 8) == 0)) {
   12719         uint32_t amount_ = amount / 8;
   12720         EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   12721                    (amount_ << 4));
   12722         AdvanceIT();
   12723         return;
   12724       }
   12725     } else {
   12726       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   12727       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12728           ((amount % 8) == 0) && cond.IsNotNever()) {
   12729         uint32_t amount_ = amount / 8;
   12730         EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
   12731                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   12732         return;
   12733       }
   12734     }
   12735   }
   12736   Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
   12737 }
   12738 
   12739 void Assembler::vaba(
   12740     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   12741   VIXL_ASSERT(AllowAssembler());
   12742   CheckIT(cond);
   12743   Dt_U_size_1 encoded_dt(dt);
   12744   if (IsUsingT32()) {
   12745     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
   12746     if (encoded_dt.IsValid()) {
   12747       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12748         EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12749                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   12750                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12751         AdvanceIT();
   12752         return;
   12753       }
   12754     }
   12755   } else {
   12756     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
   12757     if (encoded_dt.IsValid()) {
   12758       if (cond.Is(al)) {
   12759         EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12760                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   12761                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12762         return;
   12763       }
   12764     }
   12765   }
   12766   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
   12767 }
   12768 
   12769 void Assembler::vaba(
   12770     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   12771   VIXL_ASSERT(AllowAssembler());
   12772   CheckIT(cond);
   12773   Dt_U_size_1 encoded_dt(dt);
   12774   if (IsUsingT32()) {
   12775     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
   12776     if (encoded_dt.IsValid()) {
   12777       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12778         EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12779                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   12780                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12781         AdvanceIT();
   12782         return;
   12783       }
   12784     }
   12785   } else {
   12786     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
   12787     if (encoded_dt.IsValid()) {
   12788       if (cond.Is(al)) {
   12789         EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12790                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   12791                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12792         return;
   12793       }
   12794     }
   12795   }
   12796   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
   12797 }
   12798 
   12799 void Assembler::vabal(
   12800     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   12801   VIXL_ASSERT(AllowAssembler());
   12802   CheckIT(cond);
   12803   Dt_U_size_1 encoded_dt(dt);
   12804   if (IsUsingT32()) {
   12805     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   12806     if (encoded_dt.IsValid()) {
   12807       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12808         EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12809                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   12810                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12811         AdvanceIT();
   12812         return;
   12813       }
   12814     }
   12815   } else {
   12816     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   12817     if (encoded_dt.IsValid()) {
   12818       if (cond.Is(al)) {
   12819         EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12820                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   12821                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12822         return;
   12823       }
   12824     }
   12825   }
   12826   Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
   12827 }
   12828 
   12829 void Assembler::vabd(
   12830     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   12831   VIXL_ASSERT(AllowAssembler());
   12832   CheckIT(cond);
   12833   Dt_U_size_1 encoded_dt(dt);
   12834   if (IsUsingT32()) {
   12835     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   12836     if (dt.Is(F32)) {
   12837       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12838         EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   12839                    rm.Encode(5, 0));
   12840         AdvanceIT();
   12841         return;
   12842       }
   12843     }
   12844     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   12845     if (encoded_dt.IsValid()) {
   12846       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12847         EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12848                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   12849                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12850         AdvanceIT();
   12851         return;
   12852       }
   12853     }
   12854   } else {
   12855     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   12856     if (dt.Is(F32)) {
   12857       if (cond.Is(al)) {
   12858         EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   12859                 rm.Encode(5, 0));
   12860         return;
   12861       }
   12862     }
   12863     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   12864     if (encoded_dt.IsValid()) {
   12865       if (cond.Is(al)) {
   12866         EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12867                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   12868                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12869         return;
   12870       }
   12871     }
   12872   }
   12873   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
   12874 }
   12875 
   12876 void Assembler::vabd(
   12877     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   12878   VIXL_ASSERT(AllowAssembler());
   12879   CheckIT(cond);
   12880   Dt_U_size_1 encoded_dt(dt);
   12881   if (IsUsingT32()) {
   12882     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   12883     if (dt.Is(F32)) {
   12884       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12885         EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   12886                    rm.Encode(5, 0));
   12887         AdvanceIT();
   12888         return;
   12889       }
   12890     }
   12891     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   12892     if (encoded_dt.IsValid()) {
   12893       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12894         EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12895                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   12896                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12897         AdvanceIT();
   12898         return;
   12899       }
   12900     }
   12901   } else {
   12902     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   12903     if (dt.Is(F32)) {
   12904       if (cond.Is(al)) {
   12905         EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   12906                 rm.Encode(5, 0));
   12907         return;
   12908       }
   12909     }
   12910     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   12911     if (encoded_dt.IsValid()) {
   12912       if (cond.Is(al)) {
   12913         EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12914                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   12915                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12916         return;
   12917       }
   12918     }
   12919   }
   12920   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
   12921 }
   12922 
   12923 void Assembler::vabdl(
   12924     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   12925   VIXL_ASSERT(AllowAssembler());
   12926   CheckIT(cond);
   12927   Dt_U_size_1 encoded_dt(dt);
   12928   if (IsUsingT32()) {
   12929     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   12930     if (encoded_dt.IsValid()) {
   12931       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12932         EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12933                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   12934                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12935         AdvanceIT();
   12936         return;
   12937       }
   12938     }
   12939   } else {
   12940     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   12941     if (encoded_dt.IsValid()) {
   12942       if (cond.Is(al)) {
   12943         EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   12944                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   12945                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   12946         return;
   12947       }
   12948     }
   12949   }
   12950   Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
   12951 }
   12952 
   12953 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   12954   VIXL_ASSERT(AllowAssembler());
   12955   CheckIT(cond);
   12956   Dt_F_size_1 encoded_dt(dt);
   12957   if (IsUsingT32()) {
   12958     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   12959     if (encoded_dt.IsValid()) {
   12960       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12961         EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   12962                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   12963                    rd.Encode(22, 12) | rm.Encode(5, 0));
   12964         AdvanceIT();
   12965         return;
   12966       }
   12967     }
   12968     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
   12969     if (dt.Is(F64)) {
   12970       EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   12971       AdvanceIT();
   12972       return;
   12973     }
   12974   } else {
   12975     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   12976     if (encoded_dt.IsValid()) {
   12977       if (cond.Is(al)) {
   12978         EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   12979                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   12980                 rd.Encode(22, 12) | rm.Encode(5, 0));
   12981         return;
   12982       }
   12983     }
   12984     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
   12985     if (dt.Is(F64) && cond.IsNotNever()) {
   12986       EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   12987               rm.Encode(5, 0));
   12988       return;
   12989     }
   12990   }
   12991   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
   12992 }
   12993 
   12994 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   12995   VIXL_ASSERT(AllowAssembler());
   12996   CheckIT(cond);
   12997   Dt_F_size_1 encoded_dt(dt);
   12998   if (IsUsingT32()) {
   12999     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   13000     if (encoded_dt.IsValid()) {
   13001       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13002         EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   13003                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   13004                    rd.Encode(22, 12) | rm.Encode(5, 0));
   13005         AdvanceIT();
   13006         return;
   13007       }
   13008     }
   13009   } else {
   13010     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   13011     if (encoded_dt.IsValid()) {
   13012       if (cond.Is(al)) {
   13013         EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   13014                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   13015                 rd.Encode(22, 12) | rm.Encode(5, 0));
   13016         return;
   13017       }
   13018     }
   13019   }
   13020   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
   13021 }
   13022 
   13023 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
   13024   VIXL_ASSERT(AllowAssembler());
   13025   CheckIT(cond);
   13026   if (IsUsingT32()) {
   13027     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
   13028     if (dt.Is(F32)) {
   13029       EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   13030       AdvanceIT();
   13031       return;
   13032     }
   13033   } else {
   13034     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
   13035     if (dt.Is(F32) && cond.IsNotNever()) {
   13036       EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   13037               rm.Encode(5, 0));
   13038       return;
   13039     }
   13040   }
   13041   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
   13042 }
   13043 
   13044 void Assembler::vacge(
   13045     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13046   VIXL_ASSERT(AllowAssembler());
   13047   CheckIT(cond);
   13048   if (IsUsingT32()) {
   13049     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   13050     if (dt.Is(F32)) {
   13051       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13052         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13053                    rm.Encode(5, 0));
   13054         AdvanceIT();
   13055         return;
   13056       }
   13057     }
   13058   } else {
   13059     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   13060     if (dt.Is(F32)) {
   13061       if (cond.Is(al)) {
   13062         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13063                 rm.Encode(5, 0));
   13064         return;
   13065       }
   13066     }
   13067   }
   13068   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
   13069 }
   13070 
   13071 void Assembler::vacge(
   13072     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13073   VIXL_ASSERT(AllowAssembler());
   13074   CheckIT(cond);
   13075   if (IsUsingT32()) {
   13076     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   13077     if (dt.Is(F32)) {
   13078       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13079         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13080                    rm.Encode(5, 0));
   13081         AdvanceIT();
   13082         return;
   13083       }
   13084     }
   13085   } else {
   13086     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   13087     if (dt.Is(F32)) {
   13088       if (cond.Is(al)) {
   13089         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13090                 rm.Encode(5, 0));
   13091         return;
   13092       }
   13093     }
   13094   }
   13095   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
   13096 }
   13097 
   13098 void Assembler::vacgt(
   13099     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13100   VIXL_ASSERT(AllowAssembler());
   13101   CheckIT(cond);
   13102   if (IsUsingT32()) {
   13103     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   13104     if (dt.Is(F32)) {
   13105       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13106         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13107                    rm.Encode(5, 0));
   13108         AdvanceIT();
   13109         return;
   13110       }
   13111     }
   13112   } else {
   13113     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   13114     if (dt.Is(F32)) {
   13115       if (cond.Is(al)) {
   13116         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13117                 rm.Encode(5, 0));
   13118         return;
   13119       }
   13120     }
   13121   }
   13122   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
   13123 }
   13124 
   13125 void Assembler::vacgt(
   13126     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13127   VIXL_ASSERT(AllowAssembler());
   13128   CheckIT(cond);
   13129   if (IsUsingT32()) {
   13130     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   13131     if (dt.Is(F32)) {
   13132       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13133         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13134                    rm.Encode(5, 0));
   13135         AdvanceIT();
   13136         return;
   13137       }
   13138     }
   13139   } else {
   13140     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   13141     if (dt.Is(F32)) {
   13142       if (cond.Is(al)) {
   13143         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13144                 rm.Encode(5, 0));
   13145         return;
   13146       }
   13147     }
   13148   }
   13149   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
   13150 }
   13151 
   13152 void Assembler::vacle(
   13153     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13154   VIXL_ASSERT(AllowAssembler());
   13155   CheckIT(cond);
   13156   if (IsUsingT32()) {
   13157     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   13158     if (dt.Is(F32)) {
   13159       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13160         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13161                    rm.Encode(5, 0));
   13162         AdvanceIT();
   13163         return;
   13164       }
   13165     }
   13166   } else {
   13167     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   13168     if (dt.Is(F32)) {
   13169       if (cond.Is(al)) {
   13170         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13171                 rm.Encode(5, 0));
   13172         return;
   13173       }
   13174     }
   13175   }
   13176   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
   13177 }
   13178 
   13179 void Assembler::vacle(
   13180     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13181   VIXL_ASSERT(AllowAssembler());
   13182   CheckIT(cond);
   13183   if (IsUsingT32()) {
   13184     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   13185     if (dt.Is(F32)) {
   13186       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13187         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13188                    rm.Encode(5, 0));
   13189         AdvanceIT();
   13190         return;
   13191       }
   13192     }
   13193   } else {
   13194     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   13195     if (dt.Is(F32)) {
   13196       if (cond.Is(al)) {
   13197         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13198                 rm.Encode(5, 0));
   13199         return;
   13200       }
   13201     }
   13202   }
   13203   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
   13204 }
   13205 
   13206 void Assembler::vaclt(
   13207     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13208   VIXL_ASSERT(AllowAssembler());
   13209   CheckIT(cond);
   13210   if (IsUsingT32()) {
   13211     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   13212     if (dt.Is(F32)) {
   13213       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13214         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13215                    rm.Encode(5, 0));
   13216         AdvanceIT();
   13217         return;
   13218       }
   13219     }
   13220   } else {
   13221     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   13222     if (dt.Is(F32)) {
   13223       if (cond.Is(al)) {
   13224         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13225                 rm.Encode(5, 0));
   13226         return;
   13227       }
   13228     }
   13229   }
   13230   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
   13231 }
   13232 
   13233 void Assembler::vaclt(
   13234     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13235   VIXL_ASSERT(AllowAssembler());
   13236   CheckIT(cond);
   13237   if (IsUsingT32()) {
   13238     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   13239     if (dt.Is(F32)) {
   13240       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13241         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13242                    rm.Encode(5, 0));
   13243         AdvanceIT();
   13244         return;
   13245       }
   13246     }
   13247   } else {
   13248     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   13249     if (dt.Is(F32)) {
   13250       if (cond.Is(al)) {
   13251         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13252                 rm.Encode(5, 0));
   13253         return;
   13254       }
   13255     }
   13256   }
   13257   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
   13258 }
   13259 
   13260 void Assembler::vadd(
   13261     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13262   VIXL_ASSERT(AllowAssembler());
   13263   CheckIT(cond);
   13264   Dt_size_2 encoded_dt(dt);
   13265   if (IsUsingT32()) {
   13266     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   13267     if (dt.Is(F32)) {
   13268       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13269         EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13270                    rm.Encode(5, 0));
   13271         AdvanceIT();
   13272         return;
   13273       }
   13274     }
   13275     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
   13276     if (dt.Is(F64)) {
   13277       EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13278                  rm.Encode(5, 0));
   13279       AdvanceIT();
   13280       return;
   13281     }
   13282     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   13283     if (encoded_dt.IsValid()) {
   13284       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13285         EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
   13286                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13287         AdvanceIT();
   13288         return;
   13289       }
   13290     }
   13291   } else {
   13292     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   13293     if (dt.Is(F32)) {
   13294       if (cond.Is(al)) {
   13295         EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13296                 rm.Encode(5, 0));
   13297         return;
   13298       }
   13299     }
   13300     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
   13301     if (dt.Is(F64) && cond.IsNotNever()) {
   13302       EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   13303               rn.Encode(7, 16) | rm.Encode(5, 0));
   13304       return;
   13305     }
   13306     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   13307     if (encoded_dt.IsValid()) {
   13308       if (cond.Is(al)) {
   13309         EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
   13310                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13311         return;
   13312       }
   13313     }
   13314   }
   13315   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
   13316 }
   13317 
   13318 void Assembler::vadd(
   13319     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13320   VIXL_ASSERT(AllowAssembler());
   13321   CheckIT(cond);
   13322   Dt_size_2 encoded_dt(dt);
   13323   if (IsUsingT32()) {
   13324     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   13325     if (dt.Is(F32)) {
   13326       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13327         EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13328                    rm.Encode(5, 0));
   13329         AdvanceIT();
   13330         return;
   13331       }
   13332     }
   13333     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   13334     if (encoded_dt.IsValid()) {
   13335       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13336         EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
   13337                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13338         AdvanceIT();
   13339         return;
   13340       }
   13341     }
   13342   } else {
   13343     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   13344     if (dt.Is(F32)) {
   13345       if (cond.Is(al)) {
   13346         EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13347                 rm.Encode(5, 0));
   13348         return;
   13349       }
   13350     }
   13351     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   13352     if (encoded_dt.IsValid()) {
   13353       if (cond.Is(al)) {
   13354         EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
   13355                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13356         return;
   13357       }
   13358     }
   13359   }
   13360   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
   13361 }
   13362 
   13363 void Assembler::vadd(
   13364     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   13365   VIXL_ASSERT(AllowAssembler());
   13366   CheckIT(cond);
   13367   if (IsUsingT32()) {
   13368     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
   13369     if (dt.Is(F32)) {
   13370       EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13371                  rm.Encode(5, 0));
   13372       AdvanceIT();
   13373       return;
   13374     }
   13375   } else {
   13376     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
   13377     if (dt.Is(F32) && cond.IsNotNever()) {
   13378       EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   13379               rn.Encode(7, 16) | rm.Encode(5, 0));
   13380       return;
   13381     }
   13382   }
   13383   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
   13384 }
   13385 
   13386 void Assembler::vaddhn(
   13387     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
   13388   VIXL_ASSERT(AllowAssembler());
   13389   CheckIT(cond);
   13390   Dt_size_3 encoded_dt(dt);
   13391   if (IsUsingT32()) {
   13392     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
   13393     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   13394       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13395         EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
   13396                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13397         AdvanceIT();
   13398         return;
   13399       }
   13400     }
   13401   } else {
   13402     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
   13403     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   13404       if (cond.Is(al)) {
   13405         EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
   13406                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13407         return;
   13408       }
   13409     }
   13410   }
   13411   Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
   13412 }
   13413 
   13414 void Assembler::vaddl(
   13415     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   13416   VIXL_ASSERT(AllowAssembler());
   13417   CheckIT(cond);
   13418   Dt_U_size_1 encoded_dt(dt);
   13419   if (IsUsingT32()) {
   13420     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   13421     if (encoded_dt.IsValid()) {
   13422       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13423         EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13424                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   13425                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13426         AdvanceIT();
   13427         return;
   13428       }
   13429     }
   13430   } else {
   13431     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   13432     if (encoded_dt.IsValid()) {
   13433       if (cond.Is(al)) {
   13434         EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13435                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   13436                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13437         return;
   13438       }
   13439     }
   13440   }
   13441   Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
   13442 }
   13443 
   13444 void Assembler::vaddw(
   13445     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
   13446   VIXL_ASSERT(AllowAssembler());
   13447   CheckIT(cond);
   13448   Dt_U_size_1 encoded_dt(dt);
   13449   if (IsUsingT32()) {
   13450     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
   13451     if (encoded_dt.IsValid()) {
   13452       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13453         EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13454                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   13455                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13456         AdvanceIT();
   13457         return;
   13458       }
   13459     }
   13460   } else {
   13461     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
   13462     if (encoded_dt.IsValid()) {
   13463       if (cond.Is(al)) {
   13464         EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13465                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   13466                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13467         return;
   13468       }
   13469     }
   13470   }
   13471   Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
   13472 }
   13473 
   13474 void Assembler::vand(Condition cond,
   13475                      DataType dt,
   13476                      DRegister rd,
   13477                      DRegister rn,
   13478                      const DOperand& operand) {
   13479   VIXL_ASSERT(AllowAssembler());
   13480   CheckIT(cond);
   13481   if (operand.IsImmediate()) {
   13482     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
   13483     if (IsUsingT32()) {
   13484       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
   13485       if (encoded_dt.IsValid() && rd.Is(rn)) {
   13486         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13487           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
   13488                      rd.Encode(22, 12) |
   13489                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   13490                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   13491                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   13492           AdvanceIT();
   13493           return;
   13494         }
   13495       }
   13496     } else {
   13497       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
   13498       if (encoded_dt.IsValid() && rd.Is(rn)) {
   13499         if (cond.Is(al)) {
   13500           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
   13501                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   13502                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   13503                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   13504           return;
   13505         }
   13506       }
   13507     }
   13508   }
   13509   if (operand.IsRegister()) {
   13510     DRegister rm = operand.GetRegister();
   13511     USE(dt);
   13512     if (IsUsingT32()) {
   13513       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   13514       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13515         EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13516                    rm.Encode(5, 0));
   13517         AdvanceIT();
   13518         return;
   13519       }
   13520     } else {
   13521       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   13522       if (cond.Is(al)) {
   13523         EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13524                 rm.Encode(5, 0));
   13525         return;
   13526       }
   13527     }
   13528   }
   13529   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
   13530 }
   13531 
   13532 void Assembler::vand(Condition cond,
   13533                      DataType dt,
   13534                      QRegister rd,
   13535                      QRegister rn,
   13536                      const QOperand& operand) {
   13537   VIXL_ASSERT(AllowAssembler());
   13538   CheckIT(cond);
   13539   if (operand.IsImmediate()) {
   13540     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
   13541     if (IsUsingT32()) {
   13542       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
   13543       if (encoded_dt.IsValid() && rd.Is(rn)) {
   13544         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13545           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
   13546                      rd.Encode(22, 12) |
   13547                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   13548                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   13549                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   13550           AdvanceIT();
   13551           return;
   13552         }
   13553       }
   13554     } else {
   13555       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
   13556       if (encoded_dt.IsValid() && rd.Is(rn)) {
   13557         if (cond.Is(al)) {
   13558           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
   13559                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   13560                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   13561                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   13562           return;
   13563         }
   13564       }
   13565     }
   13566   }
   13567   if (operand.IsRegister()) {
   13568     QRegister rm = operand.GetRegister();
   13569     USE(dt);
   13570     if (IsUsingT32()) {
   13571       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   13572       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13573         EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13574                    rm.Encode(5, 0));
   13575         AdvanceIT();
   13576         return;
   13577       }
   13578     } else {
   13579       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   13580       if (cond.Is(al)) {
   13581         EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13582                 rm.Encode(5, 0));
   13583         return;
   13584       }
   13585     }
   13586   }
   13587   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
   13588 }
   13589 
   13590 void Assembler::vbic(Condition cond,
   13591                      DataType dt,
   13592                      DRegister rd,
   13593                      DRegister rn,
   13594                      const DOperand& operand) {
   13595   VIXL_ASSERT(AllowAssembler());
   13596   CheckIT(cond);
   13597   if (operand.IsImmediate()) {
   13598     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
   13599     if (IsUsingT32()) {
   13600       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
   13601       if (encoded_dt.IsValid() && rd.Is(rn)) {
   13602         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13603           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
   13604                      rd.Encode(22, 12) |
   13605                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   13606                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   13607                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   13608           AdvanceIT();
   13609           return;
   13610         }
   13611       }
   13612     } else {
   13613       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
   13614       if (encoded_dt.IsValid() && rd.Is(rn)) {
   13615         if (cond.Is(al)) {
   13616           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
   13617                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   13618                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   13619                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   13620           return;
   13621         }
   13622       }
   13623     }
   13624   }
   13625   if (operand.IsRegister()) {
   13626     DRegister rm = operand.GetRegister();
   13627     USE(dt);
   13628     if (IsUsingT32()) {
   13629       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   13630       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13631         EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13632                    rm.Encode(5, 0));
   13633         AdvanceIT();
   13634         return;
   13635       }
   13636     } else {
   13637       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   13638       if (cond.Is(al)) {
   13639         EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13640                 rm.Encode(5, 0));
   13641         return;
   13642       }
   13643     }
   13644   }
   13645   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
   13646 }
   13647 
   13648 void Assembler::vbic(Condition cond,
   13649                      DataType dt,
   13650                      QRegister rd,
   13651                      QRegister rn,
   13652                      const QOperand& operand) {
   13653   VIXL_ASSERT(AllowAssembler());
   13654   CheckIT(cond);
   13655   if (operand.IsImmediate()) {
   13656     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
   13657     if (IsUsingT32()) {
   13658       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
   13659       if (encoded_dt.IsValid() && rd.Is(rn)) {
   13660         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13661           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
   13662                      rd.Encode(22, 12) |
   13663                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   13664                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   13665                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   13666           AdvanceIT();
   13667           return;
   13668         }
   13669       }
   13670     } else {
   13671       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
   13672       if (encoded_dt.IsValid() && rd.Is(rn)) {
   13673         if (cond.Is(al)) {
   13674           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
   13675                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   13676                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   13677                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   13678           return;
   13679         }
   13680       }
   13681     }
   13682   }
   13683   if (operand.IsRegister()) {
   13684     QRegister rm = operand.GetRegister();
   13685     USE(dt);
   13686     if (IsUsingT32()) {
   13687       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   13688       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13689         EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13690                    rm.Encode(5, 0));
   13691         AdvanceIT();
   13692         return;
   13693       }
   13694     } else {
   13695       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   13696       if (cond.Is(al)) {
   13697         EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13698                 rm.Encode(5, 0));
   13699         return;
   13700       }
   13701     }
   13702   }
   13703   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
   13704 }
   13705 
   13706 void Assembler::vbif(
   13707     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13708   VIXL_ASSERT(AllowAssembler());
   13709   CheckIT(cond);
   13710   USE(dt);
   13711   if (IsUsingT32()) {
   13712     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   13713     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13714       EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13715                  rm.Encode(5, 0));
   13716       AdvanceIT();
   13717       return;
   13718     }
   13719   } else {
   13720     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   13721     if (cond.Is(al)) {
   13722       EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13723               rm.Encode(5, 0));
   13724       return;
   13725     }
   13726   }
   13727   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
   13728 }
   13729 
   13730 void Assembler::vbif(
   13731     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13732   VIXL_ASSERT(AllowAssembler());
   13733   CheckIT(cond);
   13734   USE(dt);
   13735   if (IsUsingT32()) {
   13736     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   13737     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13738       EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13739                  rm.Encode(5, 0));
   13740       AdvanceIT();
   13741       return;
   13742     }
   13743   } else {
   13744     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   13745     if (cond.Is(al)) {
   13746       EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13747               rm.Encode(5, 0));
   13748       return;
   13749     }
   13750   }
   13751   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
   13752 }
   13753 
   13754 void Assembler::vbit(
   13755     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13756   VIXL_ASSERT(AllowAssembler());
   13757   CheckIT(cond);
   13758   USE(dt);
   13759   if (IsUsingT32()) {
   13760     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   13761     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13762       EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13763                  rm.Encode(5, 0));
   13764       AdvanceIT();
   13765       return;
   13766     }
   13767   } else {
   13768     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   13769     if (cond.Is(al)) {
   13770       EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13771               rm.Encode(5, 0));
   13772       return;
   13773     }
   13774   }
   13775   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
   13776 }
   13777 
   13778 void Assembler::vbit(
   13779     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13780   VIXL_ASSERT(AllowAssembler());
   13781   CheckIT(cond);
   13782   USE(dt);
   13783   if (IsUsingT32()) {
   13784     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   13785     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13786       EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13787                  rm.Encode(5, 0));
   13788       AdvanceIT();
   13789       return;
   13790     }
   13791   } else {
   13792     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   13793     if (cond.Is(al)) {
   13794       EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13795               rm.Encode(5, 0));
   13796       return;
   13797     }
   13798   }
   13799   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
   13800 }
   13801 
   13802 void Assembler::vbsl(
   13803     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13804   VIXL_ASSERT(AllowAssembler());
   13805   CheckIT(cond);
   13806   USE(dt);
   13807   if (IsUsingT32()) {
   13808     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   13809     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13810       EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13811                  rm.Encode(5, 0));
   13812       AdvanceIT();
   13813       return;
   13814     }
   13815   } else {
   13816     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   13817     if (cond.Is(al)) {
   13818       EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13819               rm.Encode(5, 0));
   13820       return;
   13821     }
   13822   }
   13823   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
   13824 }
   13825 
   13826 void Assembler::vbsl(
   13827     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13828   VIXL_ASSERT(AllowAssembler());
   13829   CheckIT(cond);
   13830   USE(dt);
   13831   if (IsUsingT32()) {
   13832     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   13833     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13834       EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13835                  rm.Encode(5, 0));
   13836       AdvanceIT();
   13837       return;
   13838     }
   13839   } else {
   13840     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   13841     if (cond.Is(al)) {
   13842       EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13843               rm.Encode(5, 0));
   13844       return;
   13845     }
   13846   }
   13847   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
   13848 }
   13849 
   13850 void Assembler::vceq(Condition cond,
   13851                      DataType dt,
   13852                      DRegister rd,
   13853                      DRegister rm,
   13854                      const DOperand& operand) {
   13855   VIXL_ASSERT(AllowAssembler());
   13856   CheckIT(cond);
   13857   if (operand.IsImmediate()) {
   13858     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   13859       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   13860       Dt_F_size_2 encoded_dt(dt);
   13861       if (IsUsingT32()) {
   13862         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   13863         if (encoded_dt.IsValid() && (imm == 0)) {
   13864           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13865             EmitT32_32(0xffb10100U |
   13866                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   13867                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   13868                        rd.Encode(22, 12) | rm.Encode(5, 0));
   13869             AdvanceIT();
   13870             return;
   13871           }
   13872         }
   13873       } else {
   13874         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   13875         if (encoded_dt.IsValid() && (imm == 0)) {
   13876           if (cond.Is(al)) {
   13877             EmitA32(0xf3b10100U |
   13878                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   13879                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   13880                     rd.Encode(22, 12) | rm.Encode(5, 0));
   13881             return;
   13882           }
   13883         }
   13884       }
   13885     }
   13886   }
   13887   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
   13888 }
   13889 
   13890 void Assembler::vceq(Condition cond,
   13891                      DataType dt,
   13892                      QRegister rd,
   13893                      QRegister rm,
   13894                      const QOperand& operand) {
   13895   VIXL_ASSERT(AllowAssembler());
   13896   CheckIT(cond);
   13897   if (operand.IsImmediate()) {
   13898     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   13899       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   13900       Dt_F_size_2 encoded_dt(dt);
   13901       if (IsUsingT32()) {
   13902         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   13903         if (encoded_dt.IsValid() && (imm == 0)) {
   13904           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13905             EmitT32_32(0xffb10140U |
   13906                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   13907                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   13908                        rd.Encode(22, 12) | rm.Encode(5, 0));
   13909             AdvanceIT();
   13910             return;
   13911           }
   13912         }
   13913       } else {
   13914         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   13915         if (encoded_dt.IsValid() && (imm == 0)) {
   13916           if (cond.Is(al)) {
   13917             EmitA32(0xf3b10140U |
   13918                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   13919                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   13920                     rd.Encode(22, 12) | rm.Encode(5, 0));
   13921             return;
   13922           }
   13923         }
   13924       }
   13925     }
   13926   }
   13927   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
   13928 }
   13929 
   13930 void Assembler::vceq(
   13931     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13932   VIXL_ASSERT(AllowAssembler());
   13933   CheckIT(cond);
   13934   Dt_size_4 encoded_dt(dt);
   13935   Dt_sz_1 encoded_dt_2(dt);
   13936   if (IsUsingT32()) {
   13937     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   13938     if (encoded_dt.IsValid()) {
   13939       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13940         EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
   13941                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13942         AdvanceIT();
   13943         return;
   13944       }
   13945     }
   13946     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
   13947     if (encoded_dt_2.IsValid()) {
   13948       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13949         EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
   13950                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13951         AdvanceIT();
   13952         return;
   13953       }
   13954     }
   13955   } else {
   13956     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   13957     if (encoded_dt.IsValid()) {
   13958       if (cond.Is(al)) {
   13959         EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
   13960                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13961         return;
   13962       }
   13963     }
   13964     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
   13965     if (encoded_dt_2.IsValid()) {
   13966       if (cond.Is(al)) {
   13967         EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
   13968                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13969         return;
   13970       }
   13971     }
   13972   }
   13973   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
   13974 }
   13975 
   13976 void Assembler::vceq(
   13977     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13978   VIXL_ASSERT(AllowAssembler());
   13979   CheckIT(cond);
   13980   Dt_size_4 encoded_dt(dt);
   13981   Dt_sz_1 encoded_dt_2(dt);
   13982   if (IsUsingT32()) {
   13983     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   13984     if (encoded_dt.IsValid()) {
   13985       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13986         EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
   13987                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13988         AdvanceIT();
   13989         return;
   13990       }
   13991     }
   13992     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
   13993     if (encoded_dt_2.IsValid()) {
   13994       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13995         EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
   13996                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13997         AdvanceIT();
   13998         return;
   13999       }
   14000     }
   14001   } else {
   14002     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   14003     if (encoded_dt.IsValid()) {
   14004       if (cond.Is(al)) {
   14005         EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
   14006                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14007         return;
   14008       }
   14009     }
   14010     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
   14011     if (encoded_dt_2.IsValid()) {
   14012       if (cond.Is(al)) {
   14013         EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
   14014                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14015         return;
   14016       }
   14017     }
   14018   }
   14019   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
   14020 }
   14021 
   14022 void Assembler::vcge(Condition cond,
   14023                      DataType dt,
   14024                      DRegister rd,
   14025                      DRegister rm,
   14026                      const DOperand& operand) {
   14027   VIXL_ASSERT(AllowAssembler());
   14028   CheckIT(cond);
   14029   if (operand.IsImmediate()) {
   14030     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14031       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14032       Dt_F_size_1 encoded_dt(dt);
   14033       if (IsUsingT32()) {
   14034         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   14035         if (encoded_dt.IsValid() && (imm == 0)) {
   14036           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14037             EmitT32_32(0xffb10080U |
   14038                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14039                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14040                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14041             AdvanceIT();
   14042             return;
   14043           }
   14044         }
   14045       } else {
   14046         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   14047         if (encoded_dt.IsValid() && (imm == 0)) {
   14048           if (cond.Is(al)) {
   14049             EmitA32(0xf3b10080U |
   14050                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14051                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14052                     rd.Encode(22, 12) | rm.Encode(5, 0));
   14053             return;
   14054           }
   14055         }
   14056       }
   14057     }
   14058   }
   14059   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
   14060 }
   14061 
   14062 void Assembler::vcge(Condition cond,
   14063                      DataType dt,
   14064                      QRegister rd,
   14065                      QRegister rm,
   14066                      const QOperand& operand) {
   14067   VIXL_ASSERT(AllowAssembler());
   14068   CheckIT(cond);
   14069   if (operand.IsImmediate()) {
   14070     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14071       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14072       Dt_F_size_1 encoded_dt(dt);
   14073       if (IsUsingT32()) {
   14074         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   14075         if (encoded_dt.IsValid() && (imm == 0)) {
   14076           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14077             EmitT32_32(0xffb100c0U |
   14078                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14079                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14080                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14081             AdvanceIT();
   14082             return;
   14083           }
   14084         }
   14085       } else {
   14086         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   14087         if (encoded_dt.IsValid() && (imm == 0)) {
   14088           if (cond.Is(al)) {
   14089             EmitA32(0xf3b100c0U |
   14090                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14091                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14092                     rd.Encode(22, 12) | rm.Encode(5, 0));
   14093             return;
   14094           }
   14095         }
   14096       }
   14097     }
   14098   }
   14099   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
   14100 }
   14101 
   14102 void Assembler::vcge(
   14103     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14104   VIXL_ASSERT(AllowAssembler());
   14105   CheckIT(cond);
   14106   Dt_U_size_1 encoded_dt(dt);
   14107   if (IsUsingT32()) {
   14108     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   14109     if (encoded_dt.IsValid()) {
   14110       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14111         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14112                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14113                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14114         AdvanceIT();
   14115         return;
   14116       }
   14117     }
   14118     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
   14119     if (dt.Is(F32)) {
   14120       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14121         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14122                    rm.Encode(5, 0));
   14123         AdvanceIT();
   14124         return;
   14125       }
   14126     }
   14127   } else {
   14128     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   14129     if (encoded_dt.IsValid()) {
   14130       if (cond.Is(al)) {
   14131         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14132                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14133                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14134         return;
   14135       }
   14136     }
   14137     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
   14138     if (dt.Is(F32)) {
   14139       if (cond.Is(al)) {
   14140         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14141                 rm.Encode(5, 0));
   14142         return;
   14143       }
   14144     }
   14145   }
   14146   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
   14147 }
   14148 
   14149 void Assembler::vcge(
   14150     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14151   VIXL_ASSERT(AllowAssembler());
   14152   CheckIT(cond);
   14153   Dt_U_size_1 encoded_dt(dt);
   14154   if (IsUsingT32()) {
   14155     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   14156     if (encoded_dt.IsValid()) {
   14157       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14158         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14159                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14160                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14161         AdvanceIT();
   14162         return;
   14163       }
   14164     }
   14165     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
   14166     if (dt.Is(F32)) {
   14167       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14168         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14169                    rm.Encode(5, 0));
   14170         AdvanceIT();
   14171         return;
   14172       }
   14173     }
   14174   } else {
   14175     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   14176     if (encoded_dt.IsValid()) {
   14177       if (cond.Is(al)) {
   14178         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14179                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14180                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14181         return;
   14182       }
   14183     }
   14184     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
   14185     if (dt.Is(F32)) {
   14186       if (cond.Is(al)) {
   14187         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14188                 rm.Encode(5, 0));
   14189         return;
   14190       }
   14191     }
   14192   }
   14193   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
   14194 }
   14195 
   14196 void Assembler::vcgt(Condition cond,
   14197                      DataType dt,
   14198                      DRegister rd,
   14199                      DRegister rm,
   14200                      const DOperand& operand) {
   14201   VIXL_ASSERT(AllowAssembler());
   14202   CheckIT(cond);
   14203   if (operand.IsImmediate()) {
   14204     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14205       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14206       Dt_F_size_1 encoded_dt(dt);
   14207       if (IsUsingT32()) {
   14208         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   14209         if (encoded_dt.IsValid() && (imm == 0)) {
   14210           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14211             EmitT32_32(0xffb10000U |
   14212                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14213                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14214                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14215             AdvanceIT();
   14216             return;
   14217           }
   14218         }
   14219       } else {
   14220         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   14221         if (encoded_dt.IsValid() && (imm == 0)) {
   14222           if (cond.Is(al)) {
   14223             EmitA32(0xf3b10000U |
   14224                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14225                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14226                     rd.Encode(22, 12) | rm.Encode(5, 0));
   14227             return;
   14228           }
   14229         }
   14230       }
   14231     }
   14232   }
   14233   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
   14234 }
   14235 
   14236 void Assembler::vcgt(Condition cond,
   14237                      DataType dt,
   14238                      QRegister rd,
   14239                      QRegister rm,
   14240                      const QOperand& operand) {
   14241   VIXL_ASSERT(AllowAssembler());
   14242   CheckIT(cond);
   14243   if (operand.IsImmediate()) {
   14244     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14245       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14246       Dt_F_size_1 encoded_dt(dt);
   14247       if (IsUsingT32()) {
   14248         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   14249         if (encoded_dt.IsValid() && (imm == 0)) {
   14250           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14251             EmitT32_32(0xffb10040U |
   14252                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14253                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14254                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14255             AdvanceIT();
   14256             return;
   14257           }
   14258         }
   14259       } else {
   14260         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   14261         if (encoded_dt.IsValid() && (imm == 0)) {
   14262           if (cond.Is(al)) {
   14263             EmitA32(0xf3b10040U |
   14264                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14265                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14266                     rd.Encode(22, 12) | rm.Encode(5, 0));
   14267             return;
   14268           }
   14269         }
   14270       }
   14271     }
   14272   }
   14273   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
   14274 }
   14275 
   14276 void Assembler::vcgt(
   14277     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14278   VIXL_ASSERT(AllowAssembler());
   14279   CheckIT(cond);
   14280   Dt_U_size_1 encoded_dt(dt);
   14281   if (IsUsingT32()) {
   14282     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   14283     if (encoded_dt.IsValid()) {
   14284       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14285         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14286                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14287                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14288         AdvanceIT();
   14289         return;
   14290       }
   14291     }
   14292     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
   14293     if (dt.Is(F32)) {
   14294       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14295         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14296                    rm.Encode(5, 0));
   14297         AdvanceIT();
   14298         return;
   14299       }
   14300     }
   14301   } else {
   14302     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   14303     if (encoded_dt.IsValid()) {
   14304       if (cond.Is(al)) {
   14305         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14306                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14307                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14308         return;
   14309       }
   14310     }
   14311     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
   14312     if (dt.Is(F32)) {
   14313       if (cond.Is(al)) {
   14314         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14315                 rm.Encode(5, 0));
   14316         return;
   14317       }
   14318     }
   14319   }
   14320   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
   14321 }
   14322 
   14323 void Assembler::vcgt(
   14324     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14325   VIXL_ASSERT(AllowAssembler());
   14326   CheckIT(cond);
   14327   Dt_U_size_1 encoded_dt(dt);
   14328   if (IsUsingT32()) {
   14329     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   14330     if (encoded_dt.IsValid()) {
   14331       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14332         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14333                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14334                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14335         AdvanceIT();
   14336         return;
   14337       }
   14338     }
   14339     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
   14340     if (dt.Is(F32)) {
   14341       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14342         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14343                    rm.Encode(5, 0));
   14344         AdvanceIT();
   14345         return;
   14346       }
   14347     }
   14348   } else {
   14349     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   14350     if (encoded_dt.IsValid()) {
   14351       if (cond.Is(al)) {
   14352         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14353                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14354                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14355         return;
   14356       }
   14357     }
   14358     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
   14359     if (dt.Is(F32)) {
   14360       if (cond.Is(al)) {
   14361         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14362                 rm.Encode(5, 0));
   14363         return;
   14364       }
   14365     }
   14366   }
   14367   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
   14368 }
   14369 
   14370 void Assembler::vcle(Condition cond,
   14371                      DataType dt,
   14372                      DRegister rd,
   14373                      DRegister rm,
   14374                      const DOperand& operand) {
   14375   VIXL_ASSERT(AllowAssembler());
   14376   CheckIT(cond);
   14377   if (operand.IsImmediate()) {
   14378     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14379       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14380       Dt_F_size_1 encoded_dt(dt);
   14381       if (IsUsingT32()) {
   14382         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   14383         if (encoded_dt.IsValid() && (imm == 0)) {
   14384           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14385             EmitT32_32(0xffb10180U |
   14386                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14387                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14388                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14389             AdvanceIT();
   14390             return;
   14391           }
   14392         }
   14393       } else {
   14394         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   14395         if (encoded_dt.IsValid() && (imm == 0)) {
   14396           if (cond.Is(al)) {
   14397             EmitA32(0xf3b10180U |
   14398                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14399                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14400                     rd.Encode(22, 12) | rm.Encode(5, 0));
   14401             return;
   14402           }
   14403         }
   14404       }
   14405     }
   14406   }
   14407   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
   14408 }
   14409 
   14410 void Assembler::vcle(Condition cond,
   14411                      DataType dt,
   14412                      QRegister rd,
   14413                      QRegister rm,
   14414                      const QOperand& operand) {
   14415   VIXL_ASSERT(AllowAssembler());
   14416   CheckIT(cond);
   14417   if (operand.IsImmediate()) {
   14418     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14419       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14420       Dt_F_size_1 encoded_dt(dt);
   14421       if (IsUsingT32()) {
   14422         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   14423         if (encoded_dt.IsValid() && (imm == 0)) {
   14424           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14425             EmitT32_32(0xffb101c0U |
   14426                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14427                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14428                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14429             AdvanceIT();
   14430             return;
   14431           }
   14432         }
   14433       } else {
   14434         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   14435         if (encoded_dt.IsValid() && (imm == 0)) {
   14436           if (cond.Is(al)) {
   14437             EmitA32(0xf3b101c0U |
   14438                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14439                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14440                     rd.Encode(22, 12) | rm.Encode(5, 0));
   14441             return;
   14442           }
   14443         }
   14444       }
   14445     }
   14446   }
   14447   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
   14448 }
   14449 
   14450 void Assembler::vcle(
   14451     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14452   VIXL_ASSERT(AllowAssembler());
   14453   CheckIT(cond);
   14454   Dt_U_size_1 encoded_dt(dt);
   14455   if (IsUsingT32()) {
   14456     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   14457     if (encoded_dt.IsValid()) {
   14458       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14459         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14460                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14461                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   14462         AdvanceIT();
   14463         return;
   14464       }
   14465     }
   14466     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
   14467     if (dt.Is(F32)) {
   14468       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14469         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   14470                    rm.Encode(7, 16));
   14471         AdvanceIT();
   14472         return;
   14473       }
   14474     }
   14475   } else {
   14476     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   14477     if (encoded_dt.IsValid()) {
   14478       if (cond.Is(al)) {
   14479         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14480                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14481                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   14482         return;
   14483       }
   14484     }
   14485     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
   14486     if (dt.Is(F32)) {
   14487       if (cond.Is(al)) {
   14488         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   14489                 rm.Encode(7, 16));
   14490         return;
   14491       }
   14492     }
   14493   }
   14494   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
   14495 }
   14496 
   14497 void Assembler::vcle(
   14498     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14499   VIXL_ASSERT(AllowAssembler());
   14500   CheckIT(cond);
   14501   Dt_U_size_1 encoded_dt(dt);
   14502   if (IsUsingT32()) {
   14503     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   14504     if (encoded_dt.IsValid()) {
   14505       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14506         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14507                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14508                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   14509         AdvanceIT();
   14510         return;
   14511       }
   14512     }
   14513     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
   14514     if (dt.Is(F32)) {
   14515       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14516         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   14517                    rm.Encode(7, 16));
   14518         AdvanceIT();
   14519         return;
   14520       }
   14521     }
   14522   } else {
   14523     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   14524     if (encoded_dt.IsValid()) {
   14525       if (cond.Is(al)) {
   14526         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14527                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14528                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   14529         return;
   14530       }
   14531     }
   14532     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
   14533     if (dt.Is(F32)) {
   14534       if (cond.Is(al)) {
   14535         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   14536                 rm.Encode(7, 16));
   14537         return;
   14538       }
   14539     }
   14540   }
   14541   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
   14542 }
   14543 
   14544 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   14545   VIXL_ASSERT(AllowAssembler());
   14546   CheckIT(cond);
   14547   Dt_size_5 encoded_dt(dt);
   14548   if (IsUsingT32()) {
   14549     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   14550     if (encoded_dt.IsValid()) {
   14551       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14552         EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
   14553                    rd.Encode(22, 12) | rm.Encode(5, 0));
   14554         AdvanceIT();
   14555         return;
   14556       }
   14557     }
   14558   } else {
   14559     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   14560     if (encoded_dt.IsValid()) {
   14561       if (cond.Is(al)) {
   14562         EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
   14563                 rd.Encode(22, 12) | rm.Encode(5, 0));
   14564         return;
   14565       }
   14566     }
   14567   }
   14568   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
   14569 }
   14570 
   14571 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   14572   VIXL_ASSERT(AllowAssembler());
   14573   CheckIT(cond);
   14574   Dt_size_5 encoded_dt(dt);
   14575   if (IsUsingT32()) {
   14576     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   14577     if (encoded_dt.IsValid()) {
   14578       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14579         EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
   14580                    rd.Encode(22, 12) | rm.Encode(5, 0));
   14581         AdvanceIT();
   14582         return;
   14583       }
   14584     }
   14585   } else {
   14586     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   14587     if (encoded_dt.IsValid()) {
   14588       if (cond.Is(al)) {
   14589         EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
   14590                 rd.Encode(22, 12) | rm.Encode(5, 0));
   14591         return;
   14592       }
   14593     }
   14594   }
   14595   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
   14596 }
   14597 
   14598 void Assembler::vclt(Condition cond,
   14599                      DataType dt,
   14600                      DRegister rd,
   14601                      DRegister rm,
   14602                      const DOperand& operand) {
   14603   VIXL_ASSERT(AllowAssembler());
   14604   CheckIT(cond);
   14605   if (operand.IsImmediate()) {
   14606     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14607       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14608       Dt_F_size_1 encoded_dt(dt);
   14609       if (IsUsingT32()) {
   14610         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   14611         if (encoded_dt.IsValid() && (imm == 0)) {
   14612           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14613             EmitT32_32(0xffb10200U |
   14614                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14615                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14616                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14617             AdvanceIT();
   14618             return;
   14619           }
   14620         }
   14621       } else {
   14622         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   14623         if (encoded_dt.IsValid() && (imm == 0)) {
   14624           if (cond.Is(al)) {
   14625             EmitA32(0xf3b10200U |
   14626                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14627                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14628                     rd.Encode(22, 12) | rm.Encode(5, 0));
   14629             return;
   14630           }
   14631         }
   14632       }
   14633     }
   14634   }
   14635   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
   14636 }
   14637 
   14638 void Assembler::vclt(Condition cond,
   14639                      DataType dt,
   14640                      QRegister rd,
   14641                      QRegister rm,
   14642                      const QOperand& operand) {
   14643   VIXL_ASSERT(AllowAssembler());
   14644   CheckIT(cond);
   14645   if (operand.IsImmediate()) {
   14646     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14647       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14648       Dt_F_size_1 encoded_dt(dt);
   14649       if (IsUsingT32()) {
   14650         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   14651         if (encoded_dt.IsValid() && (imm == 0)) {
   14652           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14653             EmitT32_32(0xffb10240U |
   14654                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14655                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14656                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14657             AdvanceIT();
   14658             return;
   14659           }
   14660         }
   14661       } else {
   14662         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   14663         if (encoded_dt.IsValid() && (imm == 0)) {
   14664           if (cond.Is(al)) {
   14665             EmitA32(0xf3b10240U |
   14666                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14667                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14668                     rd.Encode(22, 12) | rm.Encode(5, 0));
   14669             return;
   14670           }
   14671         }
   14672       }
   14673     }
   14674   }
   14675   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
   14676 }
   14677 
   14678 void Assembler::vclt(
   14679     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14680   VIXL_ASSERT(AllowAssembler());
   14681   CheckIT(cond);
   14682   Dt_U_size_1 encoded_dt(dt);
   14683   if (IsUsingT32()) {
   14684     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   14685     if (encoded_dt.IsValid()) {
   14686       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14687         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14688                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14689                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   14690         AdvanceIT();
   14691         return;
   14692       }
   14693     }
   14694     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
   14695     if (dt.Is(F32)) {
   14696       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14697         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   14698                    rm.Encode(7, 16));
   14699         AdvanceIT();
   14700         return;
   14701       }
   14702     }
   14703   } else {
   14704     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   14705     if (encoded_dt.IsValid()) {
   14706       if (cond.Is(al)) {
   14707         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14708                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14709                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   14710         return;
   14711       }
   14712     }
   14713     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
   14714     if (dt.Is(F32)) {
   14715       if (cond.Is(al)) {
   14716         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   14717                 rm.Encode(7, 16));
   14718         return;
   14719       }
   14720     }
   14721   }
   14722   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
   14723 }
   14724 
   14725 void Assembler::vclt(
   14726     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14727   VIXL_ASSERT(AllowAssembler());
   14728   CheckIT(cond);
   14729   Dt_U_size_1 encoded_dt(dt);
   14730   if (IsUsingT32()) {
   14731     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   14732     if (encoded_dt.IsValid()) {
   14733       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14734         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14735                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14736                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   14737         AdvanceIT();
   14738         return;
   14739       }
   14740     }
   14741     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
   14742     if (dt.Is(F32)) {
   14743       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14744         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   14745                    rm.Encode(7, 16));
   14746         AdvanceIT();
   14747         return;
   14748       }
   14749     }
   14750   } else {
   14751     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   14752     if (encoded_dt.IsValid()) {
   14753       if (cond.Is(al)) {
   14754         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14755                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14756                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   14757         return;
   14758       }
   14759     }
   14760     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
   14761     if (dt.Is(F32)) {
   14762       if (cond.Is(al)) {
   14763         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   14764                 rm.Encode(7, 16));
   14765         return;
   14766       }
   14767     }
   14768   }
   14769   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
   14770 }
   14771 
   14772 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   14773   VIXL_ASSERT(AllowAssembler());
   14774   CheckIT(cond);
   14775   Dt_size_4 encoded_dt(dt);
   14776   if (IsUsingT32()) {
   14777     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   14778     if (encoded_dt.IsValid()) {
   14779       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14780         EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
   14781                    rd.Encode(22, 12) | rm.Encode(5, 0));
   14782         AdvanceIT();
   14783         return;
   14784       }
   14785     }
   14786   } else {
   14787     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   14788     if (encoded_dt.IsValid()) {
   14789       if (cond.Is(al)) {
   14790         EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
   14791                 rd.Encode(22, 12) | rm.Encode(5, 0));
   14792         return;
   14793       }
   14794     }
   14795   }
   14796   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
   14797 }
   14798 
   14799 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   14800   VIXL_ASSERT(AllowAssembler());
   14801   CheckIT(cond);
   14802   Dt_size_4 encoded_dt(dt);
   14803   if (IsUsingT32()) {
   14804     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   14805     if (encoded_dt.IsValid()) {
   14806       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14807         EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
   14808                    rd.Encode(22, 12) | rm.Encode(5, 0));
   14809         AdvanceIT();
   14810         return;
   14811       }
   14812     }
   14813   } else {
   14814     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   14815     if (encoded_dt.IsValid()) {
   14816       if (cond.Is(al)) {
   14817         EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
   14818                 rd.Encode(22, 12) | rm.Encode(5, 0));
   14819         return;
   14820       }
   14821     }
   14822   }
   14823   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
   14824 }
   14825 
   14826 void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm) {
   14827   VIXL_ASSERT(AllowAssembler());
   14828   CheckIT(cond);
   14829   if (IsUsingT32()) {
   14830     // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
   14831     if (dt.Is(F32)) {
   14832       EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   14833       AdvanceIT();
   14834       return;
   14835     }
   14836   } else {
   14837     // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
   14838     if (dt.Is(F32) && cond.IsNotNever()) {
   14839       EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   14840               rm.Encode(5, 0));
   14841       return;
   14842     }
   14843   }
   14844   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
   14845 }
   14846 
   14847 void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   14848   VIXL_ASSERT(AllowAssembler());
   14849   CheckIT(cond);
   14850   if (IsUsingT32()) {
   14851     // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
   14852     if (dt.Is(F64)) {
   14853       EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   14854       AdvanceIT();
   14855       return;
   14856     }
   14857   } else {
   14858     // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
   14859     if (dt.Is(F64) && cond.IsNotNever()) {
   14860       EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   14861               rm.Encode(5, 0));
   14862       return;
   14863     }
   14864   }
   14865   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
   14866 }
   14867 
   14868 void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, double imm) {
   14869   VIXL_ASSERT(AllowAssembler());
   14870   CheckIT(cond);
   14871   if (IsUsingT32()) {
   14872     // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
   14873     if (dt.Is(F32) && (imm == 0.0)) {
   14874       EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
   14875       AdvanceIT();
   14876       return;
   14877     }
   14878   } else {
   14879     // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
   14880     if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
   14881       EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
   14882       return;
   14883     }
   14884   }
   14885   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
   14886 }
   14887 
   14888 void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, double imm) {
   14889   VIXL_ASSERT(AllowAssembler());
   14890   CheckIT(cond);
   14891   if (IsUsingT32()) {
   14892     // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
   14893     if (dt.Is(F64) && (imm == 0.0)) {
   14894       EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
   14895       AdvanceIT();
   14896       return;
   14897     }
   14898   } else {
   14899     // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
   14900     if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
   14901       EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
   14902       return;
   14903     }
   14904   }
   14905   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
   14906 }
   14907 
   14908 void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm) {
   14909   VIXL_ASSERT(AllowAssembler());
   14910   CheckIT(cond);
   14911   if (IsUsingT32()) {
   14912     // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
   14913     if (dt.Is(F32)) {
   14914       EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   14915       AdvanceIT();
   14916       return;
   14917     }
   14918   } else {
   14919     // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
   14920     if (dt.Is(F32) && cond.IsNotNever()) {
   14921       EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   14922               rm.Encode(5, 0));
   14923       return;
   14924     }
   14925   }
   14926   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
   14927 }
   14928 
   14929 void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   14930   VIXL_ASSERT(AllowAssembler());
   14931   CheckIT(cond);
   14932   if (IsUsingT32()) {
   14933     // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
   14934     if (dt.Is(F64)) {
   14935       EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   14936       AdvanceIT();
   14937       return;
   14938     }
   14939   } else {
   14940     // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
   14941     if (dt.Is(F64) && cond.IsNotNever()) {
   14942       EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   14943               rm.Encode(5, 0));
   14944       return;
   14945     }
   14946   }
   14947   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
   14948 }
   14949 
   14950 void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, double imm) {
   14951   VIXL_ASSERT(AllowAssembler());
   14952   CheckIT(cond);
   14953   if (IsUsingT32()) {
   14954     // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
   14955     if (dt.Is(F32) && (imm == 0.0)) {
   14956       EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
   14957       AdvanceIT();
   14958       return;
   14959     }
   14960   } else {
   14961     // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
   14962     if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
   14963       EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
   14964       return;
   14965     }
   14966   }
   14967   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
   14968 }
   14969 
   14970 void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, double imm) {
   14971   VIXL_ASSERT(AllowAssembler());
   14972   CheckIT(cond);
   14973   if (IsUsingT32()) {
   14974     // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
   14975     if (dt.Is(F64) && (imm == 0.0)) {
   14976       EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
   14977       AdvanceIT();
   14978       return;
   14979     }
   14980   } else {
   14981     // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
   14982     if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
   14983       EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
   14984       return;
   14985     }
   14986   }
   14987   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
   14988 }
   14989 
   14990 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   14991   VIXL_ASSERT(AllowAssembler());
   14992   CheckIT(cond);
   14993   if (IsUsingT32()) {
   14994     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
   14995     if (dt.Is(Untyped8)) {
   14996       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14997         EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
   14998         AdvanceIT();
   14999         return;
   15000       }
   15001     }
   15002   } else {
   15003     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
   15004     if (dt.Is(Untyped8)) {
   15005       if (cond.Is(al)) {
   15006         EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15007         return;
   15008       }
   15009     }
   15010   }
   15011   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
   15012 }
   15013 
   15014 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   15015   VIXL_ASSERT(AllowAssembler());
   15016   CheckIT(cond);
   15017   if (IsUsingT32()) {
   15018     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
   15019     if (dt.Is(Untyped8)) {
   15020       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15021         EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15022         AdvanceIT();
   15023         return;
   15024       }
   15025     }
   15026   } else {
   15027     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
   15028     if (dt.Is(Untyped8)) {
   15029       if (cond.Is(al)) {
   15030         EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15031         return;
   15032       }
   15033     }
   15034   }
   15035   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
   15036 }
   15037 
   15038 void Assembler::vcvt(
   15039     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
   15040   VIXL_ASSERT(AllowAssembler());
   15041   CheckIT(cond);
   15042   Dt_op_2 encoded_dt(dt2);
   15043   if (IsUsingT32()) {
   15044     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
   15045     if (dt1.Is(F64) && dt2.Is(F32)) {
   15046       EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15047       AdvanceIT();
   15048       return;
   15049     }
   15050     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
   15051     if (dt1.Is(F64) && encoded_dt.IsValid()) {
   15052       EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
   15053                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15054       AdvanceIT();
   15055       return;
   15056     }
   15057   } else {
   15058     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
   15059     if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
   15060       EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15061               rm.Encode(5, 0));
   15062       return;
   15063     }
   15064     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
   15065     if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
   15066       EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
   15067               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
   15068               rm.Encode(5, 0));
   15069       return;
   15070     }
   15071   }
   15072   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   15073 }
   15074 
   15075 void Assembler::vcvt(
   15076     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   15077   VIXL_ASSERT(AllowAssembler());
   15078   CheckIT(cond);
   15079   if (IsUsingT32()) {
   15080     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
   15081     if (dt1.Is(F32) && dt2.Is(F64)) {
   15082       EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15083       AdvanceIT();
   15084       return;
   15085     }
   15086     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
   15087     if (dt1.Is(U32) && dt2.Is(F64)) {
   15088       EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15089       AdvanceIT();
   15090       return;
   15091     }
   15092     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
   15093     if (dt1.Is(S32) && dt2.Is(F64)) {
   15094       EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15095       AdvanceIT();
   15096       return;
   15097     }
   15098   } else {
   15099     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
   15100     if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
   15101       EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15102               rm.Encode(5, 0));
   15103       return;
   15104     }
   15105     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
   15106     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
   15107       EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15108               rm.Encode(5, 0));
   15109       return;
   15110     }
   15111     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
   15112     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
   15113       EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15114               rm.Encode(5, 0));
   15115       return;
   15116     }
   15117   }
   15118   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   15119 }
   15120 
   15121 void Assembler::vcvt(Condition cond,
   15122                      DataType dt1,
   15123                      DataType dt2,
   15124                      DRegister rd,
   15125                      DRegister rm,
   15126                      int32_t fbits) {
   15127   VIXL_ASSERT(AllowAssembler());
   15128   CheckIT(cond);
   15129   Dt_op_U_1 encoded_dt(dt1, dt2);
   15130   Dt_U_sx_1 encoded_dt_2(dt2);
   15131   Dt_U_sx_1 encoded_dt_3(dt1);
   15132   if (IsUsingT32()) {
   15133     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
   15134     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
   15135       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15136         uint32_t fbits_ = 64 - fbits;
   15137         EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
   15138                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
   15139                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
   15140         AdvanceIT();
   15141         return;
   15142       }
   15143     }
   15144     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
   15145     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
   15146         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
   15147          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
   15148       unsigned offset = 32;
   15149       if (dt2.Is(S16) || dt2.Is(U16)) {
   15150         offset = 16;
   15151       }
   15152       uint32_t fbits_ = offset - fbits;
   15153       EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
   15154                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
   15155                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   15156                  ((fbits_ & 0x1e) >> 1));
   15157       AdvanceIT();
   15158       return;
   15159     }
   15160     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
   15161     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
   15162         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
   15163          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
   15164       unsigned offset = 32;
   15165       if (dt1.Is(S16) || dt1.Is(U16)) {
   15166         offset = 16;
   15167       }
   15168       uint32_t fbits_ = offset - fbits;
   15169       EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
   15170                  ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
   15171                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   15172                  ((fbits_ & 0x1e) >> 1));
   15173       AdvanceIT();
   15174       return;
   15175     }
   15176   } else {
   15177     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
   15178     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
   15179       if (cond.Is(al)) {
   15180         uint32_t fbits_ = 64 - fbits;
   15181         EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
   15182                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
   15183                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
   15184         return;
   15185       }
   15186     }
   15187     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
   15188     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
   15189         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
   15190          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
   15191         cond.IsNotNever()) {
   15192       unsigned offset = 32;
   15193       if (dt2.Is(S16) || dt2.Is(U16)) {
   15194         offset = 16;
   15195       }
   15196       uint32_t fbits_ = offset - fbits;
   15197       EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
   15198               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
   15199               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
   15200               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   15201               ((fbits_ & 0x1e) >> 1));
   15202       return;
   15203     }
   15204     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
   15205     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
   15206         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
   15207          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
   15208         cond.IsNotNever()) {
   15209       unsigned offset = 32;
   15210       if (dt1.Is(S16) || dt1.Is(U16)) {
   15211         offset = 16;
   15212       }
   15213       uint32_t fbits_ = offset - fbits;
   15214       EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
   15215               ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
   15216               ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
   15217               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   15218               ((fbits_ & 0x1e) >> 1));
   15219       return;
   15220     }
   15221   }
   15222   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
   15223 }
   15224 
   15225 void Assembler::vcvt(Condition cond,
   15226                      DataType dt1,
   15227                      DataType dt2,
   15228                      QRegister rd,
   15229                      QRegister rm,
   15230                      int32_t fbits) {
   15231   VIXL_ASSERT(AllowAssembler());
   15232   CheckIT(cond);
   15233   Dt_op_U_1 encoded_dt(dt1, dt2);
   15234   if (IsUsingT32()) {
   15235     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
   15236     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
   15237       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15238         uint32_t fbits_ = 64 - fbits;
   15239         EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
   15240                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
   15241                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
   15242         AdvanceIT();
   15243         return;
   15244       }
   15245     }
   15246   } else {
   15247     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
   15248     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
   15249       if (cond.Is(al)) {
   15250         uint32_t fbits_ = 64 - fbits;
   15251         EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
   15252                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
   15253                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
   15254         return;
   15255       }
   15256     }
   15257   }
   15258   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
   15259 }
   15260 
   15261 void Assembler::vcvt(Condition cond,
   15262                      DataType dt1,
   15263                      DataType dt2,
   15264                      SRegister rd,
   15265                      SRegister rm,
   15266                      int32_t fbits) {
   15267   VIXL_ASSERT(AllowAssembler());
   15268   CheckIT(cond);
   15269   Dt_U_sx_1 encoded_dt(dt2);
   15270   Dt_U_sx_1 encoded_dt_2(dt1);
   15271   if (IsUsingT32()) {
   15272     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
   15273     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
   15274         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
   15275          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
   15276       unsigned offset = 32;
   15277       if (dt2.Is(S16) || dt2.Is(U16)) {
   15278         offset = 16;
   15279       }
   15280       uint32_t fbits_ = offset - fbits;
   15281       EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
   15282                  ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
   15283                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   15284                  ((fbits_ & 0x1e) >> 1));
   15285       AdvanceIT();
   15286       return;
   15287     }
   15288     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
   15289     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
   15290         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
   15291          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
   15292       unsigned offset = 32;
   15293       if (dt1.Is(S16) || dt1.Is(U16)) {
   15294         offset = 16;
   15295       }
   15296       uint32_t fbits_ = offset - fbits;
   15297       EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
   15298                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
   15299                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   15300                  ((fbits_ & 0x1e) >> 1));
   15301       AdvanceIT();
   15302       return;
   15303     }
   15304   } else {
   15305     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
   15306     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
   15307         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
   15308          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
   15309         cond.IsNotNever()) {
   15310       unsigned offset = 32;
   15311       if (dt2.Is(S16) || dt2.Is(U16)) {
   15312         offset = 16;
   15313       }
   15314       uint32_t fbits_ = offset - fbits;
   15315       EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
   15316               ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
   15317               ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
   15318               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   15319               ((fbits_ & 0x1e) >> 1));
   15320       return;
   15321     }
   15322     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
   15323     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
   15324         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
   15325          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
   15326         cond.IsNotNever()) {
   15327       unsigned offset = 32;
   15328       if (dt1.Is(S16) || dt1.Is(U16)) {
   15329         offset = 16;
   15330       }
   15331       uint32_t fbits_ = offset - fbits;
   15332       EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
   15333               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
   15334               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
   15335               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   15336               ((fbits_ & 0x1e) >> 1));
   15337       return;
   15338     }
   15339   }
   15340   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
   15341 }
   15342 
   15343 void Assembler::vcvt(
   15344     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   15345   VIXL_ASSERT(AllowAssembler());
   15346   CheckIT(cond);
   15347   Dt_op_1 encoded_dt(dt1, dt2);
   15348   if (IsUsingT32()) {
   15349     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
   15350     if (encoded_dt.IsValid()) {
   15351       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15352         EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
   15353                    rd.Encode(22, 12) | rm.Encode(5, 0));
   15354         AdvanceIT();
   15355         return;
   15356       }
   15357     }
   15358   } else {
   15359     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
   15360     if (encoded_dt.IsValid()) {
   15361       if (cond.Is(al)) {
   15362         EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
   15363                 rd.Encode(22, 12) | rm.Encode(5, 0));
   15364         return;
   15365       }
   15366     }
   15367   }
   15368   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   15369 }
   15370 
   15371 void Assembler::vcvt(
   15372     Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   15373   VIXL_ASSERT(AllowAssembler());
   15374   CheckIT(cond);
   15375   Dt_op_1 encoded_dt(dt1, dt2);
   15376   if (IsUsingT32()) {
   15377     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
   15378     if (encoded_dt.IsValid()) {
   15379       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15380         EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
   15381                    rd.Encode(22, 12) | rm.Encode(5, 0));
   15382         AdvanceIT();
   15383         return;
   15384       }
   15385     }
   15386   } else {
   15387     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
   15388     if (encoded_dt.IsValid()) {
   15389       if (cond.Is(al)) {
   15390         EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
   15391                 rd.Encode(22, 12) | rm.Encode(5, 0));
   15392         return;
   15393       }
   15394     }
   15395   }
   15396   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   15397 }
   15398 
   15399 void Assembler::vcvt(
   15400     Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
   15401   VIXL_ASSERT(AllowAssembler());
   15402   CheckIT(cond);
   15403   if (IsUsingT32()) {
   15404     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
   15405     if (dt1.Is(F16) && dt2.Is(F32)) {
   15406       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15407         EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15408         AdvanceIT();
   15409         return;
   15410       }
   15411     }
   15412   } else {
   15413     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
   15414     if (dt1.Is(F16) && dt2.Is(F32)) {
   15415       if (cond.Is(al)) {
   15416         EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15417         return;
   15418       }
   15419     }
   15420   }
   15421   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   15422 }
   15423 
   15424 void Assembler::vcvt(
   15425     Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
   15426   VIXL_ASSERT(AllowAssembler());
   15427   CheckIT(cond);
   15428   if (IsUsingT32()) {
   15429     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
   15430     if (dt1.Is(F32) && dt2.Is(F16)) {
   15431       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15432         EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15433         AdvanceIT();
   15434         return;
   15435       }
   15436     }
   15437   } else {
   15438     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
   15439     if (dt1.Is(F32) && dt2.Is(F16)) {
   15440       if (cond.Is(al)) {
   15441         EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15442         return;
   15443       }
   15444     }
   15445   }
   15446   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   15447 }
   15448 
   15449 void Assembler::vcvt(
   15450     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   15451   VIXL_ASSERT(AllowAssembler());
   15452   CheckIT(cond);
   15453   Dt_op_2 encoded_dt(dt2);
   15454   if (IsUsingT32()) {
   15455     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
   15456     if (dt1.Is(U32) && dt2.Is(F32)) {
   15457       EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15458       AdvanceIT();
   15459       return;
   15460     }
   15461     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
   15462     if (dt1.Is(S32) && dt2.Is(F32)) {
   15463       EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15464       AdvanceIT();
   15465       return;
   15466     }
   15467     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
   15468     if (dt1.Is(F32) && encoded_dt.IsValid()) {
   15469       EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
   15470                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15471       AdvanceIT();
   15472       return;
   15473     }
   15474   } else {
   15475     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
   15476     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
   15477       EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15478               rm.Encode(5, 0));
   15479       return;
   15480     }
   15481     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
   15482     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
   15483       EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15484               rm.Encode(5, 0));
   15485       return;
   15486     }
   15487     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
   15488     if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
   15489       EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
   15490               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
   15491               rm.Encode(5, 0));
   15492       return;
   15493     }
   15494   }
   15495   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   15496 }
   15497 
   15498 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   15499   VIXL_ASSERT(AllowAssembler());
   15500   CheckIT(al);
   15501   Dt_op_3 encoded_dt(dt1);
   15502   if (IsUsingT32()) {
   15503     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
   15504     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15505       EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
   15506                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15507       AdvanceIT();
   15508       return;
   15509     }
   15510   } else {
   15511     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
   15512     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15513       EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
   15514               rd.Encode(22, 12) | rm.Encode(5, 0));
   15515       return;
   15516     }
   15517   }
   15518   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
   15519 }
   15520 
   15521 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   15522   VIXL_ASSERT(AllowAssembler());
   15523   CheckIT(al);
   15524   Dt_op_3 encoded_dt(dt1);
   15525   if (IsUsingT32()) {
   15526     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
   15527     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15528       EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
   15529                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15530       AdvanceIT();
   15531       return;
   15532     }
   15533   } else {
   15534     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
   15535     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15536       EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
   15537               rd.Encode(22, 12) | rm.Encode(5, 0));
   15538       return;
   15539     }
   15540   }
   15541   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
   15542 }
   15543 
   15544 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   15545   VIXL_ASSERT(AllowAssembler());
   15546   CheckIT(al);
   15547   Dt_op_2 encoded_dt(dt1);
   15548   if (IsUsingT32()) {
   15549     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
   15550     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15551       EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
   15552                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15553       AdvanceIT();
   15554       return;
   15555     }
   15556   } else {
   15557     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
   15558     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15559       EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
   15560               rd.Encode(22, 12) | rm.Encode(5, 0));
   15561       return;
   15562     }
   15563   }
   15564   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
   15565 }
   15566 
   15567 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   15568   VIXL_ASSERT(AllowAssembler());
   15569   CheckIT(al);
   15570   Dt_op_2 encoded_dt(dt1);
   15571   if (IsUsingT32()) {
   15572     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
   15573     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   15574       EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
   15575                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15576       AdvanceIT();
   15577       return;
   15578     }
   15579   } else {
   15580     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
   15581     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   15582       EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
   15583               rd.Encode(22, 12) | rm.Encode(5, 0));
   15584       return;
   15585     }
   15586   }
   15587   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
   15588 }
   15589 
   15590 void Assembler::vcvtb(
   15591     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   15592   VIXL_ASSERT(AllowAssembler());
   15593   CheckIT(cond);
   15594   if (IsUsingT32()) {
   15595     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
   15596     if (dt1.Is(F32) && dt2.Is(F16)) {
   15597       EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15598       AdvanceIT();
   15599       return;
   15600     }
   15601     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
   15602     if (dt1.Is(F16) && dt2.Is(F32)) {
   15603       EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15604       AdvanceIT();
   15605       return;
   15606     }
   15607   } else {
   15608     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
   15609     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
   15610       EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15611               rm.Encode(5, 0));
   15612       return;
   15613     }
   15614     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
   15615     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
   15616       EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15617               rm.Encode(5, 0));
   15618       return;
   15619     }
   15620   }
   15621   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
   15622 }
   15623 
   15624 void Assembler::vcvtb(
   15625     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
   15626   VIXL_ASSERT(AllowAssembler());
   15627   CheckIT(cond);
   15628   if (IsUsingT32()) {
   15629     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
   15630     if (dt1.Is(F64) && dt2.Is(F16)) {
   15631       EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15632       AdvanceIT();
   15633       return;
   15634     }
   15635   } else {
   15636     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
   15637     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
   15638       EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15639               rm.Encode(5, 0));
   15640       return;
   15641     }
   15642   }
   15643   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
   15644 }
   15645 
   15646 void Assembler::vcvtb(
   15647     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   15648   VIXL_ASSERT(AllowAssembler());
   15649   CheckIT(cond);
   15650   if (IsUsingT32()) {
   15651     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
   15652     if (dt1.Is(F16) && dt2.Is(F64)) {
   15653       EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15654       AdvanceIT();
   15655       return;
   15656     }
   15657   } else {
   15658     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
   15659     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
   15660       EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15661               rm.Encode(5, 0));
   15662       return;
   15663     }
   15664   }
   15665   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
   15666 }
   15667 
   15668 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   15669   VIXL_ASSERT(AllowAssembler());
   15670   CheckIT(al);
   15671   Dt_op_3 encoded_dt(dt1);
   15672   if (IsUsingT32()) {
   15673     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
   15674     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15675       EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
   15676                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15677       AdvanceIT();
   15678       return;
   15679     }
   15680   } else {
   15681     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
   15682     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15683       EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
   15684               rd.Encode(22, 12) | rm.Encode(5, 0));
   15685       return;
   15686     }
   15687   }
   15688   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
   15689 }
   15690 
   15691 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   15692   VIXL_ASSERT(AllowAssembler());
   15693   CheckIT(al);
   15694   Dt_op_3 encoded_dt(dt1);
   15695   if (IsUsingT32()) {
   15696     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
   15697     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15698       EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
   15699                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15700       AdvanceIT();
   15701       return;
   15702     }
   15703   } else {
   15704     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
   15705     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15706       EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
   15707               rd.Encode(22, 12) | rm.Encode(5, 0));
   15708       return;
   15709     }
   15710   }
   15711   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
   15712 }
   15713 
   15714 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   15715   VIXL_ASSERT(AllowAssembler());
   15716   CheckIT(al);
   15717   Dt_op_2 encoded_dt(dt1);
   15718   if (IsUsingT32()) {
   15719     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
   15720     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15721       EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
   15722                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15723       AdvanceIT();
   15724       return;
   15725     }
   15726   } else {
   15727     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
   15728     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15729       EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
   15730               rd.Encode(22, 12) | rm.Encode(5, 0));
   15731       return;
   15732     }
   15733   }
   15734   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
   15735 }
   15736 
   15737 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   15738   VIXL_ASSERT(AllowAssembler());
   15739   CheckIT(al);
   15740   Dt_op_2 encoded_dt(dt1);
   15741   if (IsUsingT32()) {
   15742     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
   15743     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   15744       EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
   15745                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15746       AdvanceIT();
   15747       return;
   15748     }
   15749   } else {
   15750     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
   15751     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   15752       EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
   15753               rd.Encode(22, 12) | rm.Encode(5, 0));
   15754       return;
   15755     }
   15756   }
   15757   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
   15758 }
   15759 
   15760 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   15761   VIXL_ASSERT(AllowAssembler());
   15762   CheckIT(al);
   15763   Dt_op_3 encoded_dt(dt1);
   15764   if (IsUsingT32()) {
   15765     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
   15766     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15767       EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
   15768                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15769       AdvanceIT();
   15770       return;
   15771     }
   15772   } else {
   15773     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
   15774     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15775       EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
   15776               rd.Encode(22, 12) | rm.Encode(5, 0));
   15777       return;
   15778     }
   15779   }
   15780   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
   15781 }
   15782 
   15783 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   15784   VIXL_ASSERT(AllowAssembler());
   15785   CheckIT(al);
   15786   Dt_op_3 encoded_dt(dt1);
   15787   if (IsUsingT32()) {
   15788     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
   15789     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15790       EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
   15791                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15792       AdvanceIT();
   15793       return;
   15794     }
   15795   } else {
   15796     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
   15797     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15798       EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
   15799               rd.Encode(22, 12) | rm.Encode(5, 0));
   15800       return;
   15801     }
   15802   }
   15803   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
   15804 }
   15805 
   15806 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   15807   VIXL_ASSERT(AllowAssembler());
   15808   CheckIT(al);
   15809   Dt_op_2 encoded_dt(dt1);
   15810   if (IsUsingT32()) {
   15811     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
   15812     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15813       EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
   15814                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15815       AdvanceIT();
   15816       return;
   15817     }
   15818   } else {
   15819     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
   15820     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15821       EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
   15822               rd.Encode(22, 12) | rm.Encode(5, 0));
   15823       return;
   15824     }
   15825   }
   15826   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
   15827 }
   15828 
   15829 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   15830   VIXL_ASSERT(AllowAssembler());
   15831   CheckIT(al);
   15832   Dt_op_2 encoded_dt(dt1);
   15833   if (IsUsingT32()) {
   15834     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
   15835     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   15836       EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
   15837                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15838       AdvanceIT();
   15839       return;
   15840     }
   15841   } else {
   15842     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
   15843     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   15844       EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
   15845               rd.Encode(22, 12) | rm.Encode(5, 0));
   15846       return;
   15847     }
   15848   }
   15849   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
   15850 }
   15851 
   15852 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   15853   VIXL_ASSERT(AllowAssembler());
   15854   CheckIT(al);
   15855   Dt_op_3 encoded_dt(dt1);
   15856   if (IsUsingT32()) {
   15857     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
   15858     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15859       EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
   15860                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15861       AdvanceIT();
   15862       return;
   15863     }
   15864   } else {
   15865     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
   15866     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15867       EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
   15868               rd.Encode(22, 12) | rm.Encode(5, 0));
   15869       return;
   15870     }
   15871   }
   15872   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
   15873 }
   15874 
   15875 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   15876   VIXL_ASSERT(AllowAssembler());
   15877   CheckIT(al);
   15878   Dt_op_3 encoded_dt(dt1);
   15879   if (IsUsingT32()) {
   15880     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
   15881     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15882       EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
   15883                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15884       AdvanceIT();
   15885       return;
   15886     }
   15887   } else {
   15888     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
   15889     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15890       EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
   15891               rd.Encode(22, 12) | rm.Encode(5, 0));
   15892       return;
   15893     }
   15894   }
   15895   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
   15896 }
   15897 
   15898 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   15899   VIXL_ASSERT(AllowAssembler());
   15900   CheckIT(al);
   15901   Dt_op_2 encoded_dt(dt1);
   15902   if (IsUsingT32()) {
   15903     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
   15904     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15905       EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
   15906                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15907       AdvanceIT();
   15908       return;
   15909     }
   15910   } else {
   15911     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
   15912     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   15913       EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
   15914               rd.Encode(22, 12) | rm.Encode(5, 0));
   15915       return;
   15916     }
   15917   }
   15918   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
   15919 }
   15920 
   15921 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   15922   VIXL_ASSERT(AllowAssembler());
   15923   CheckIT(al);
   15924   Dt_op_2 encoded_dt(dt1);
   15925   if (IsUsingT32()) {
   15926     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
   15927     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   15928       EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
   15929                  rd.Encode(22, 12) | rm.Encode(5, 0));
   15930       AdvanceIT();
   15931       return;
   15932     }
   15933   } else {
   15934     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
   15935     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   15936       EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
   15937               rd.Encode(22, 12) | rm.Encode(5, 0));
   15938       return;
   15939     }
   15940   }
   15941   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
   15942 }
   15943 
   15944 void Assembler::vcvtr(
   15945     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   15946   VIXL_ASSERT(AllowAssembler());
   15947   CheckIT(cond);
   15948   if (IsUsingT32()) {
   15949     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
   15950     if (dt1.Is(U32) && dt2.Is(F32)) {
   15951       EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15952       AdvanceIT();
   15953       return;
   15954     }
   15955     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
   15956     if (dt1.Is(S32) && dt2.Is(F32)) {
   15957       EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15958       AdvanceIT();
   15959       return;
   15960     }
   15961   } else {
   15962     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
   15963     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
   15964       EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15965               rm.Encode(5, 0));
   15966       return;
   15967     }
   15968     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
   15969     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
   15970       EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15971               rm.Encode(5, 0));
   15972       return;
   15973     }
   15974   }
   15975   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
   15976 }
   15977 
   15978 void Assembler::vcvtr(
   15979     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   15980   VIXL_ASSERT(AllowAssembler());
   15981   CheckIT(cond);
   15982   if (IsUsingT32()) {
   15983     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
   15984     if (dt1.Is(U32) && dt2.Is(F64)) {
   15985       EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15986       AdvanceIT();
   15987       return;
   15988     }
   15989     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
   15990     if (dt1.Is(S32) && dt2.Is(F64)) {
   15991       EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15992       AdvanceIT();
   15993       return;
   15994     }
   15995   } else {
   15996     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
   15997     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
   15998       EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15999               rm.Encode(5, 0));
   16000       return;
   16001     }
   16002     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
   16003     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
   16004       EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16005               rm.Encode(5, 0));
   16006       return;
   16007     }
   16008   }
   16009   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
   16010 }
   16011 
   16012 void Assembler::vcvtt(
   16013     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   16014   VIXL_ASSERT(AllowAssembler());
   16015   CheckIT(cond);
   16016   if (IsUsingT32()) {
   16017     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
   16018     if (dt1.Is(F32) && dt2.Is(F16)) {
   16019       EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16020       AdvanceIT();
   16021       return;
   16022     }
   16023     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
   16024     if (dt1.Is(F16) && dt2.Is(F32)) {
   16025       EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16026       AdvanceIT();
   16027       return;
   16028     }
   16029   } else {
   16030     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
   16031     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
   16032       EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16033               rm.Encode(5, 0));
   16034       return;
   16035     }
   16036     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
   16037     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
   16038       EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16039               rm.Encode(5, 0));
   16040       return;
   16041     }
   16042   }
   16043   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
   16044 }
   16045 
   16046 void Assembler::vcvtt(
   16047     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
   16048   VIXL_ASSERT(AllowAssembler());
   16049   CheckIT(cond);
   16050   if (IsUsingT32()) {
   16051     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
   16052     if (dt1.Is(F64) && dt2.Is(F16)) {
   16053       EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16054       AdvanceIT();
   16055       return;
   16056     }
   16057   } else {
   16058     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
   16059     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
   16060       EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16061               rm.Encode(5, 0));
   16062       return;
   16063     }
   16064   }
   16065   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
   16066 }
   16067 
   16068 void Assembler::vcvtt(
   16069     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   16070   VIXL_ASSERT(AllowAssembler());
   16071   CheckIT(cond);
   16072   if (IsUsingT32()) {
   16073     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
   16074     if (dt1.Is(F16) && dt2.Is(F64)) {
   16075       EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16076       AdvanceIT();
   16077       return;
   16078     }
   16079   } else {
   16080     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
   16081     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
   16082       EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16083               rm.Encode(5, 0));
   16084       return;
   16085     }
   16086   }
   16087   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
   16088 }
   16089 
   16090 void Assembler::vdiv(
   16091     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   16092   VIXL_ASSERT(AllowAssembler());
   16093   CheckIT(cond);
   16094   if (IsUsingT32()) {
   16095     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
   16096     if (dt.Is(F32)) {
   16097       EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16098                  rm.Encode(5, 0));
   16099       AdvanceIT();
   16100       return;
   16101     }
   16102   } else {
   16103     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
   16104     if (dt.Is(F32) && cond.IsNotNever()) {
   16105       EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16106               rn.Encode(7, 16) | rm.Encode(5, 0));
   16107       return;
   16108     }
   16109   }
   16110   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
   16111 }
   16112 
   16113 void Assembler::vdiv(
   16114     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   16115   VIXL_ASSERT(AllowAssembler());
   16116   CheckIT(cond);
   16117   if (IsUsingT32()) {
   16118     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
   16119     if (dt.Is(F64)) {
   16120       EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16121                  rm.Encode(5, 0));
   16122       AdvanceIT();
   16123       return;
   16124     }
   16125   } else {
   16126     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
   16127     if (dt.Is(F64) && cond.IsNotNever()) {
   16128       EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16129               rn.Encode(7, 16) | rm.Encode(5, 0));
   16130       return;
   16131     }
   16132   }
   16133   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
   16134 }
   16135 
   16136 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
   16137   VIXL_ASSERT(AllowAssembler());
   16138   CheckIT(cond);
   16139   Dt_B_E_1 encoded_dt(dt);
   16140   if (IsUsingT32()) {
   16141     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
   16142     if (encoded_dt.IsValid()) {
   16143       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16144         EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
   16145                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
   16146                    rd.Encode(7, 16) | (rt.GetCode() << 12));
   16147         AdvanceIT();
   16148         return;
   16149       }
   16150     }
   16151   } else {
   16152     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
   16153     if (encoded_dt.IsValid() && cond.IsNotNever()) {
   16154       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16155         EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
   16156                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
   16157                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
   16158                 rd.Encode(7, 16) | (rt.GetCode() << 12));
   16159         return;
   16160       }
   16161     }
   16162   }
   16163   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
   16164 }
   16165 
   16166 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
   16167   VIXL_ASSERT(AllowAssembler());
   16168   CheckIT(cond);
   16169   Dt_B_E_1 encoded_dt(dt);
   16170   if (IsUsingT32()) {
   16171     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
   16172     if (encoded_dt.IsValid()) {
   16173       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16174         EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
   16175                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
   16176                    rd.Encode(7, 16) | (rt.GetCode() << 12));
   16177         AdvanceIT();
   16178         return;
   16179       }
   16180     }
   16181   } else {
   16182     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
   16183     if (encoded_dt.IsValid() && cond.IsNotNever()) {
   16184       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16185         EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
   16186                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
   16187                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
   16188                 rd.Encode(7, 16) | (rt.GetCode() << 12));
   16189         return;
   16190       }
   16191     }
   16192   }
   16193   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
   16194 }
   16195 
   16196 void Assembler::vdup(Condition cond,
   16197                      DataType dt,
   16198                      DRegister rd,
   16199                      DRegisterLane rm) {
   16200   VIXL_ASSERT(AllowAssembler());
   16201   CheckIT(cond);
   16202   Dt_imm4_1 encoded_dt(dt, rm);
   16203   if (IsUsingT32()) {
   16204     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
   16205     if (encoded_dt.IsValid()) {
   16206       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16207         EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
   16208                    rd.Encode(22, 12) | rm.Encode(5, 0));
   16209         AdvanceIT();
   16210         return;
   16211       }
   16212     }
   16213   } else {
   16214     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
   16215     if (encoded_dt.IsValid()) {
   16216       if (cond.Is(al)) {
   16217         EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
   16218                 rd.Encode(22, 12) | rm.Encode(5, 0));
   16219         return;
   16220       }
   16221     }
   16222   }
   16223   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
   16224 }
   16225 
   16226 void Assembler::vdup(Condition cond,
   16227                      DataType dt,
   16228                      QRegister rd,
   16229                      DRegisterLane rm) {
   16230   VIXL_ASSERT(AllowAssembler());
   16231   CheckIT(cond);
   16232   Dt_imm4_1 encoded_dt(dt, rm);
   16233   if (IsUsingT32()) {
   16234     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
   16235     if (encoded_dt.IsValid()) {
   16236       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16237         EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
   16238                    rd.Encode(22, 12) | rm.Encode(5, 0));
   16239         AdvanceIT();
   16240         return;
   16241       }
   16242     }
   16243   } else {
   16244     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
   16245     if (encoded_dt.IsValid()) {
   16246       if (cond.Is(al)) {
   16247         EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
   16248                 rd.Encode(22, 12) | rm.Encode(5, 0));
   16249         return;
   16250       }
   16251     }
   16252   }
   16253   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
   16254 }
   16255 
   16256 void Assembler::veor(
   16257     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   16258   VIXL_ASSERT(AllowAssembler());
   16259   CheckIT(cond);
   16260   USE(dt);
   16261   if (IsUsingT32()) {
   16262     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   16263     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16264       EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16265                  rm.Encode(5, 0));
   16266       AdvanceIT();
   16267       return;
   16268     }
   16269   } else {
   16270     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   16271     if (cond.Is(al)) {
   16272       EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16273               rm.Encode(5, 0));
   16274       return;
   16275     }
   16276   }
   16277   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
   16278 }
   16279 
   16280 void Assembler::veor(
   16281     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   16282   VIXL_ASSERT(AllowAssembler());
   16283   CheckIT(cond);
   16284   USE(dt);
   16285   if (IsUsingT32()) {
   16286     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   16287     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16288       EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16289                  rm.Encode(5, 0));
   16290       AdvanceIT();
   16291       return;
   16292     }
   16293   } else {
   16294     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   16295     if (cond.Is(al)) {
   16296       EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16297               rm.Encode(5, 0));
   16298       return;
   16299     }
   16300   }
   16301   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
   16302 }
   16303 
   16304 void Assembler::vext(Condition cond,
   16305                      DataType dt,
   16306                      DRegister rd,
   16307                      DRegister rn,
   16308                      DRegister rm,
   16309                      const DOperand& operand) {
   16310   VIXL_ASSERT(AllowAssembler());
   16311   CheckIT(cond);
   16312   if (operand.IsImmediate()) {
   16313     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   16314       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   16315       if (IsUsingT32()) {
   16316         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
   16317         if (dt.Is(Untyped8) && (imm <= 7)) {
   16318           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16319             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16320                        rm.Encode(5, 0) | (imm << 8));
   16321             AdvanceIT();
   16322             return;
   16323           }
   16324         }
   16325         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
   16326         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
   16327             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
   16328           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16329             uint32_t imm4 = imm / dt.GetSize();
   16330             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16331                        rm.Encode(5, 0) | (imm4 << 8));
   16332             AdvanceIT();
   16333             return;
   16334           }
   16335         }
   16336       } else {
   16337         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
   16338         if (dt.Is(Untyped8) && (imm <= 7)) {
   16339           if (cond.Is(al)) {
   16340             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16341                     rm.Encode(5, 0) | (imm << 8));
   16342             return;
   16343           }
   16344         }
   16345         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
   16346         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
   16347             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
   16348           if (cond.Is(al)) {
   16349             uint32_t imm4 = imm / dt.GetSize();
   16350             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16351                     rm.Encode(5, 0) | (imm4 << 8));
   16352             return;
   16353           }
   16354         }
   16355       }
   16356     }
   16357   }
   16358   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
   16359 }
   16360 
   16361 void Assembler::vext(Condition cond,
   16362                      DataType dt,
   16363                      QRegister rd,
   16364                      QRegister rn,
   16365                      QRegister rm,
   16366                      const QOperand& operand) {
   16367   VIXL_ASSERT(AllowAssembler());
   16368   CheckIT(cond);
   16369   if (operand.IsImmediate()) {
   16370     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   16371       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   16372       if (IsUsingT32()) {
   16373         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
   16374         if (dt.Is(Untyped8) && (imm <= 15)) {
   16375           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16376             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16377                        rm.Encode(5, 0) | (imm << 8));
   16378             AdvanceIT();
   16379             return;
   16380           }
   16381         }
   16382         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
   16383         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
   16384             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
   16385           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16386             uint32_t imm4 = imm / dt.GetSize();
   16387             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16388                        rm.Encode(5, 0) | (imm4 << 8));
   16389             AdvanceIT();
   16390             return;
   16391           }
   16392         }
   16393       } else {
   16394         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
   16395         if (dt.Is(Untyped8) && (imm <= 15)) {
   16396           if (cond.Is(al)) {
   16397             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16398                     rm.Encode(5, 0) | (imm << 8));
   16399             return;
   16400           }
   16401         }
   16402         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
   16403         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
   16404             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
   16405           if (cond.Is(al)) {
   16406             uint32_t imm4 = imm / dt.GetSize();
   16407             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16408                     rm.Encode(5, 0) | (imm4 << 8));
   16409             return;
   16410           }
   16411         }
   16412       }
   16413     }
   16414   }
   16415   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
   16416 }
   16417 
   16418 void Assembler::vfma(
   16419     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   16420   VIXL_ASSERT(AllowAssembler());
   16421   CheckIT(cond);
   16422   if (IsUsingT32()) {
   16423     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   16424     if (dt.Is(F32)) {
   16425       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16426         EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16427                    rm.Encode(5, 0));
   16428         AdvanceIT();
   16429         return;
   16430       }
   16431     }
   16432     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   16433     if (dt.Is(F64)) {
   16434       EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16435                  rm.Encode(5, 0));
   16436       AdvanceIT();
   16437       return;
   16438     }
   16439   } else {
   16440     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   16441     if (dt.Is(F32)) {
   16442       if (cond.Is(al)) {
   16443         EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16444                 rm.Encode(5, 0));
   16445         return;
   16446       }
   16447     }
   16448     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   16449     if (dt.Is(F64) && cond.IsNotNever()) {
   16450       EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16451               rn.Encode(7, 16) | rm.Encode(5, 0));
   16452       return;
   16453     }
   16454   }
   16455   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
   16456 }
   16457 
   16458 void Assembler::vfma(
   16459     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   16460   VIXL_ASSERT(AllowAssembler());
   16461   CheckIT(cond);
   16462   if (IsUsingT32()) {
   16463     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   16464     if (dt.Is(F32)) {
   16465       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16466         EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16467                    rm.Encode(5, 0));
   16468         AdvanceIT();
   16469         return;
   16470       }
   16471     }
   16472   } else {
   16473     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   16474     if (dt.Is(F32)) {
   16475       if (cond.Is(al)) {
   16476         EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16477                 rm.Encode(5, 0));
   16478         return;
   16479       }
   16480     }
   16481   }
   16482   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
   16483 }
   16484 
   16485 void Assembler::vfma(
   16486     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   16487   VIXL_ASSERT(AllowAssembler());
   16488   CheckIT(cond);
   16489   if (IsUsingT32()) {
   16490     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   16491     if (dt.Is(F32)) {
   16492       EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16493                  rm.Encode(5, 0));
   16494       AdvanceIT();
   16495       return;
   16496     }
   16497   } else {
   16498     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   16499     if (dt.Is(F32) && cond.IsNotNever()) {
   16500       EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16501               rn.Encode(7, 16) | rm.Encode(5, 0));
   16502       return;
   16503     }
   16504   }
   16505   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
   16506 }
   16507 
   16508 void Assembler::vfms(
   16509     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   16510   VIXL_ASSERT(AllowAssembler());
   16511   CheckIT(cond);
   16512   if (IsUsingT32()) {
   16513     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   16514     if (dt.Is(F32)) {
   16515       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16516         EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16517                    rm.Encode(5, 0));
   16518         AdvanceIT();
   16519         return;
   16520       }
   16521     }
   16522     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   16523     if (dt.Is(F64)) {
   16524       EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16525                  rm.Encode(5, 0));
   16526       AdvanceIT();
   16527       return;
   16528     }
   16529   } else {
   16530     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   16531     if (dt.Is(F32)) {
   16532       if (cond.Is(al)) {
   16533         EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16534                 rm.Encode(5, 0));
   16535         return;
   16536       }
   16537     }
   16538     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   16539     if (dt.Is(F64) && cond.IsNotNever()) {
   16540       EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16541               rn.Encode(7, 16) | rm.Encode(5, 0));
   16542       return;
   16543     }
   16544   }
   16545   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
   16546 }
   16547 
   16548 void Assembler::vfms(
   16549     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   16550   VIXL_ASSERT(AllowAssembler());
   16551   CheckIT(cond);
   16552   if (IsUsingT32()) {
   16553     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   16554     if (dt.Is(F32)) {
   16555       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16556         EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16557                    rm.Encode(5, 0));
   16558         AdvanceIT();
   16559         return;
   16560       }
   16561     }
   16562   } else {
   16563     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   16564     if (dt.Is(F32)) {
   16565       if (cond.Is(al)) {
   16566         EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16567                 rm.Encode(5, 0));
   16568         return;
   16569       }
   16570     }
   16571   }
   16572   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
   16573 }
   16574 
   16575 void Assembler::vfms(
   16576     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   16577   VIXL_ASSERT(AllowAssembler());
   16578   CheckIT(cond);
   16579   if (IsUsingT32()) {
   16580     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   16581     if (dt.Is(F32)) {
   16582       EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16583                  rm.Encode(5, 0));
   16584       AdvanceIT();
   16585       return;
   16586     }
   16587   } else {
   16588     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   16589     if (dt.Is(F32) && cond.IsNotNever()) {
   16590       EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16591               rn.Encode(7, 16) | rm.Encode(5, 0));
   16592       return;
   16593     }
   16594   }
   16595   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
   16596 }
   16597 
   16598 void Assembler::vfnma(
   16599     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   16600   VIXL_ASSERT(AllowAssembler());
   16601   CheckIT(cond);
   16602   if (IsUsingT32()) {
   16603     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
   16604     if (dt.Is(F32)) {
   16605       EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16606                  rm.Encode(5, 0));
   16607       AdvanceIT();
   16608       return;
   16609     }
   16610   } else {
   16611     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
   16612     if (dt.Is(F32) && cond.IsNotNever()) {
   16613       EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16614               rn.Encode(7, 16) | rm.Encode(5, 0));
   16615       return;
   16616     }
   16617   }
   16618   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
   16619 }
   16620 
   16621 void Assembler::vfnma(
   16622     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   16623   VIXL_ASSERT(AllowAssembler());
   16624   CheckIT(cond);
   16625   if (IsUsingT32()) {
   16626     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
   16627     if (dt.Is(F64)) {
   16628       EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16629                  rm.Encode(5, 0));
   16630       AdvanceIT();
   16631       return;
   16632     }
   16633   } else {
   16634     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
   16635     if (dt.Is(F64) && cond.IsNotNever()) {
   16636       EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16637               rn.Encode(7, 16) | rm.Encode(5, 0));
   16638       return;
   16639     }
   16640   }
   16641   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
   16642 }
   16643 
   16644 void Assembler::vfnms(
   16645     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   16646   VIXL_ASSERT(AllowAssembler());
   16647   CheckIT(cond);
   16648   if (IsUsingT32()) {
   16649     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
   16650     if (dt.Is(F32)) {
   16651       EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16652                  rm.Encode(5, 0));
   16653       AdvanceIT();
   16654       return;
   16655     }
   16656   } else {
   16657     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
   16658     if (dt.Is(F32) && cond.IsNotNever()) {
   16659       EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16660               rn.Encode(7, 16) | rm.Encode(5, 0));
   16661       return;
   16662     }
   16663   }
   16664   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
   16665 }
   16666 
   16667 void Assembler::vfnms(
   16668     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   16669   VIXL_ASSERT(AllowAssembler());
   16670   CheckIT(cond);
   16671   if (IsUsingT32()) {
   16672     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
   16673     if (dt.Is(F64)) {
   16674       EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   16675                  rm.Encode(5, 0));
   16676       AdvanceIT();
   16677       return;
   16678     }
   16679   } else {
   16680     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
   16681     if (dt.Is(F64) && cond.IsNotNever()) {
   16682       EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16683               rn.Encode(7, 16) | rm.Encode(5, 0));
   16684       return;
   16685     }
   16686   }
   16687   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
   16688 }
   16689 
   16690 void Assembler::vhadd(
   16691     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   16692   VIXL_ASSERT(AllowAssembler());
   16693   CheckIT(cond);
   16694   Dt_U_size_1 encoded_dt(dt);
   16695   if (IsUsingT32()) {
   16696     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   16697     if (encoded_dt.IsValid()) {
   16698       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16699         EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   16700                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   16701                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   16702         AdvanceIT();
   16703         return;
   16704       }
   16705     }
   16706   } else {
   16707     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   16708     if (encoded_dt.IsValid()) {
   16709       if (cond.Is(al)) {
   16710         EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   16711                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   16712                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   16713         return;
   16714       }
   16715     }
   16716   }
   16717   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
   16718 }
   16719 
   16720 void Assembler::vhadd(
   16721     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   16722   VIXL_ASSERT(AllowAssembler());
   16723   CheckIT(cond);
   16724   Dt_U_size_1 encoded_dt(dt);
   16725   if (IsUsingT32()) {
   16726     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   16727     if (encoded_dt.IsValid()) {
   16728       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16729         EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   16730                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   16731                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   16732         AdvanceIT();
   16733         return;
   16734       }
   16735     }
   16736   } else {
   16737     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   16738     if (encoded_dt.IsValid()) {
   16739       if (cond.Is(al)) {
   16740         EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   16741                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   16742                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   16743         return;
   16744       }
   16745     }
   16746   }
   16747   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
   16748 }
   16749 
   16750 void Assembler::vhsub(
   16751     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   16752   VIXL_ASSERT(AllowAssembler());
   16753   CheckIT(cond);
   16754   Dt_U_size_1 encoded_dt(dt);
   16755   if (IsUsingT32()) {
   16756     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   16757     if (encoded_dt.IsValid()) {
   16758       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16759         EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   16760                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   16761                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   16762         AdvanceIT();
   16763         return;
   16764       }
   16765     }
   16766   } else {
   16767     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   16768     if (encoded_dt.IsValid()) {
   16769       if (cond.Is(al)) {
   16770         EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   16771                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   16772                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   16773         return;
   16774       }
   16775     }
   16776   }
   16777   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
   16778 }
   16779 
   16780 void Assembler::vhsub(
   16781     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   16782   VIXL_ASSERT(AllowAssembler());
   16783   CheckIT(cond);
   16784   Dt_U_size_1 encoded_dt(dt);
   16785   if (IsUsingT32()) {
   16786     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   16787     if (encoded_dt.IsValid()) {
   16788       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16789         EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   16790                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   16791                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   16792         AdvanceIT();
   16793         return;
   16794       }
   16795     }
   16796   } else {
   16797     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   16798     if (encoded_dt.IsValid()) {
   16799       if (cond.Is(al)) {
   16800         EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   16801                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   16802                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   16803         return;
   16804       }
   16805     }
   16806   }
   16807   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
   16808 }
   16809 
   16810 void Assembler::vld1(Condition cond,
   16811                      DataType dt,
   16812                      const NeonRegisterList& nreglist,
   16813                      const AlignedMemOperand& operand) {
   16814   VIXL_ASSERT(AllowAssembler());
   16815   CheckIT(cond);
   16816   if (operand.IsImmediateZero()) {
   16817     Register rn = operand.GetBaseRegister();
   16818     Alignment align = operand.GetAlignment();
   16819     Dt_size_6 encoded_dt(dt);
   16820     Dt_size_7 encoded_dt_2(dt);
   16821     Align_align_1 encoded_align_1(align, nreglist);
   16822     Align_a_1 encoded_align_2(align, dt);
   16823     Align_index_align_1 encoded_align_3(align, nreglist, dt);
   16824     if (IsUsingT32()) {
   16825       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   16826       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   16827           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   16828           operand.IsOffset() && encoded_align_1.IsValid() &&
   16829           (!rn.IsPC() || AllowUnpredictable())) {
   16830         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16831           const DRegister& first = nreglist.GetFirstDRegister();
   16832           uint32_t len_encoding;
   16833           switch (nreglist.GetLength()) {
   16834             default:
   16835               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   16836             case 1:
   16837               len_encoding = 0x7;
   16838               break;
   16839             case 2:
   16840               len_encoding = 0xa;
   16841               break;
   16842             case 3:
   16843               len_encoding = 0x6;
   16844               break;
   16845             case 4:
   16846               len_encoding = 0x2;
   16847               break;
   16848           }
   16849           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
   16850                      (encoded_align_1.GetEncodingValue() << 4) |
   16851                      first.Encode(22, 12) | (len_encoding << 8) |
   16852                      (rn.GetCode() << 16));
   16853           AdvanceIT();
   16854           return;
   16855         }
   16856       }
   16857       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   16858       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   16859           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   16860           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   16861           (!rn.IsPC() || AllowUnpredictable())) {
   16862         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16863           const DRegister& first = nreglist.GetFirstDRegister();
   16864           uint32_t len_encoding;
   16865           switch (nreglist.GetLength()) {
   16866             default:
   16867               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   16868             case 1:
   16869               len_encoding = 0x7;
   16870               break;
   16871             case 2:
   16872               len_encoding = 0xa;
   16873               break;
   16874             case 3:
   16875               len_encoding = 0x6;
   16876               break;
   16877             case 4:
   16878               len_encoding = 0x2;
   16879               break;
   16880           }
   16881           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
   16882                      (encoded_align_1.GetEncodingValue() << 4) |
   16883                      first.Encode(22, 12) | (len_encoding << 8) |
   16884                      (rn.GetCode() << 16));
   16885           AdvanceIT();
   16886           return;
   16887         }
   16888       }
   16889       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   16890       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   16891           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   16892           operand.IsOffset() && encoded_align_2.IsValid() &&
   16893           (!rn.IsPC() || AllowUnpredictable())) {
   16894         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16895           const DRegister& first = nreglist.GetFirstDRegister();
   16896           uint32_t len_encoding = nreglist.GetLength() - 1;
   16897           EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
   16898                      (encoded_align_2.GetEncodingValue() << 4) |
   16899                      first.Encode(22, 12) | (len_encoding << 5) |
   16900                      (rn.GetCode() << 16));
   16901           AdvanceIT();
   16902           return;
   16903         }
   16904       }
   16905       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   16906       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   16907           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   16908           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   16909           (!rn.IsPC() || AllowUnpredictable())) {
   16910         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16911           const DRegister& first = nreglist.GetFirstDRegister();
   16912           uint32_t len_encoding = nreglist.GetLength() - 1;
   16913           EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
   16914                      (encoded_align_2.GetEncodingValue() << 4) |
   16915                      first.Encode(22, 12) | (len_encoding << 5) |
   16916                      (rn.GetCode() << 16));
   16917           AdvanceIT();
   16918           return;
   16919         }
   16920       }
   16921       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   16922       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   16923           (nreglist.GetLength() == 1) && operand.IsOffset() &&
   16924           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   16925         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16926           const DRegister& first = nreglist.GetFirstDRegister();
   16927           EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
   16928                      (encoded_align_3.GetEncodingValue() << 4) |
   16929                      first.Encode(22, 12) | (rn.GetCode() << 16));
   16930           AdvanceIT();
   16931           return;
   16932         }
   16933       }
   16934       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   16935       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   16936           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
   16937           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   16938         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16939           const DRegister& first = nreglist.GetFirstDRegister();
   16940           EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
   16941                      (encoded_align_3.GetEncodingValue() << 4) |
   16942                      first.Encode(22, 12) | (rn.GetCode() << 16));
   16943           AdvanceIT();
   16944           return;
   16945         }
   16946       }
   16947     } else {
   16948       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   16949       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   16950           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   16951           operand.IsOffset() && encoded_align_1.IsValid() &&
   16952           (!rn.IsPC() || AllowUnpredictable())) {
   16953         if (cond.Is(al)) {
   16954           const DRegister& first = nreglist.GetFirstDRegister();
   16955           uint32_t len_encoding;
   16956           switch (nreglist.GetLength()) {
   16957             default:
   16958               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   16959             case 1:
   16960               len_encoding = 0x7;
   16961               break;
   16962             case 2:
   16963               len_encoding = 0xa;
   16964               break;
   16965             case 3:
   16966               len_encoding = 0x6;
   16967               break;
   16968             case 4:
   16969               len_encoding = 0x2;
   16970               break;
   16971           }
   16972           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
   16973                   (encoded_align_1.GetEncodingValue() << 4) |
   16974                   first.Encode(22, 12) | (len_encoding << 8) |
   16975                   (rn.GetCode() << 16));
   16976           return;
   16977         }
   16978       }
   16979       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   16980       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   16981           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   16982           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   16983           (!rn.IsPC() || AllowUnpredictable())) {
   16984         if (cond.Is(al)) {
   16985           const DRegister& first = nreglist.GetFirstDRegister();
   16986           uint32_t len_encoding;
   16987           switch (nreglist.GetLength()) {
   16988             default:
   16989               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   16990             case 1:
   16991               len_encoding = 0x7;
   16992               break;
   16993             case 2:
   16994               len_encoding = 0xa;
   16995               break;
   16996             case 3:
   16997               len_encoding = 0x6;
   16998               break;
   16999             case 4:
   17000               len_encoding = 0x2;
   17001               break;
   17002           }
   17003           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
   17004                   (encoded_align_1.GetEncodingValue() << 4) |
   17005                   first.Encode(22, 12) | (len_encoding << 8) |
   17006                   (rn.GetCode() << 16));
   17007           return;
   17008         }
   17009       }
   17010       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   17011       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   17012           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   17013           operand.IsOffset() && encoded_align_2.IsValid() &&
   17014           (!rn.IsPC() || AllowUnpredictable())) {
   17015         if (cond.Is(al)) {
   17016           const DRegister& first = nreglist.GetFirstDRegister();
   17017           uint32_t len_encoding = nreglist.GetLength() - 1;
   17018           EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
   17019                   (encoded_align_2.GetEncodingValue() << 4) |
   17020                   first.Encode(22, 12) | (len_encoding << 5) |
   17021                   (rn.GetCode() << 16));
   17022           return;
   17023         }
   17024       }
   17025       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   17026       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   17027           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   17028           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   17029           (!rn.IsPC() || AllowUnpredictable())) {
   17030         if (cond.Is(al)) {
   17031           const DRegister& first = nreglist.GetFirstDRegister();
   17032           uint32_t len_encoding = nreglist.GetLength() - 1;
   17033           EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
   17034                   (encoded_align_2.GetEncodingValue() << 4) |
   17035                   first.Encode(22, 12) | (len_encoding << 5) |
   17036                   (rn.GetCode() << 16));
   17037           return;
   17038         }
   17039       }
   17040       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   17041       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   17042           (nreglist.GetLength() == 1) && operand.IsOffset() &&
   17043           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   17044         if (cond.Is(al)) {
   17045           const DRegister& first = nreglist.GetFirstDRegister();
   17046           EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
   17047                   (encoded_align_3.GetEncodingValue() << 4) |
   17048                   first.Encode(22, 12) | (rn.GetCode() << 16));
   17049           return;
   17050         }
   17051       }
   17052       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   17053       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   17054           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
   17055           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   17056         if (cond.Is(al)) {
   17057           const DRegister& first = nreglist.GetFirstDRegister();
   17058           EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
   17059                   (encoded_align_3.GetEncodingValue() << 4) |
   17060                   first.Encode(22, 12) | (rn.GetCode() << 16));
   17061           return;
   17062         }
   17063       }
   17064     }
   17065   }
   17066   if (operand.IsPlainRegister()) {
   17067     Register rn = operand.GetBaseRegister();
   17068     Alignment align = operand.GetAlignment();
   17069     Register rm = operand.GetOffsetRegister();
   17070     Dt_size_6 encoded_dt(dt);
   17071     Dt_size_7 encoded_dt_2(dt);
   17072     Align_align_1 encoded_align_1(align, nreglist);
   17073     Align_a_1 encoded_align_2(align, dt);
   17074     Align_index_align_1 encoded_align_3(align, nreglist, dt);
   17075     if (IsUsingT32()) {
   17076       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   17077       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17078           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   17079           !rm.IsPC() && !rm.IsSP()) {
   17080         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17081           const DRegister& first = nreglist.GetFirstDRegister();
   17082           uint32_t len_encoding;
   17083           switch (nreglist.GetLength()) {
   17084             default:
   17085               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   17086             case 1:
   17087               len_encoding = 0x7;
   17088               break;
   17089             case 2:
   17090               len_encoding = 0xa;
   17091               break;
   17092             case 3:
   17093               len_encoding = 0x6;
   17094               break;
   17095             case 4:
   17096               len_encoding = 0x2;
   17097               break;
   17098           }
   17099           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
   17100                      (encoded_align_1.GetEncodingValue() << 4) |
   17101                      first.Encode(22, 12) | (len_encoding << 8) |
   17102                      (rn.GetCode() << 16) | rm.GetCode());
   17103           AdvanceIT();
   17104           return;
   17105         }
   17106       }
   17107       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   17108       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   17109           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   17110           !rm.IsPC() && !rm.IsSP()) {
   17111         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17112           const DRegister& first = nreglist.GetFirstDRegister();
   17113           uint32_t len_encoding = nreglist.GetLength() - 1;
   17114           EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
   17115                      (encoded_align_2.GetEncodingValue() << 4) |
   17116                      first.Encode(22, 12) | (len_encoding << 5) |
   17117                      (rn.GetCode() << 16) | rm.GetCode());
   17118           AdvanceIT();
   17119           return;
   17120         }
   17121       }
   17122       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   17123       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   17124           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
   17125         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17126           const DRegister& first = nreglist.GetFirstDRegister();
   17127           EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
   17128                      (encoded_align_3.GetEncodingValue() << 4) |
   17129                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   17130                      rm.GetCode());
   17131           AdvanceIT();
   17132           return;
   17133         }
   17134       }
   17135     } else {
   17136       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   17137       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17138           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   17139           !rm.IsPC() && !rm.IsSP()) {
   17140         if (cond.Is(al)) {
   17141           const DRegister& first = nreglist.GetFirstDRegister();
   17142           uint32_t len_encoding;
   17143           switch (nreglist.GetLength()) {
   17144             default:
   17145               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   17146             case 1:
   17147               len_encoding = 0x7;
   17148               break;
   17149             case 2:
   17150               len_encoding = 0xa;
   17151               break;
   17152             case 3:
   17153               len_encoding = 0x6;
   17154               break;
   17155             case 4:
   17156               len_encoding = 0x2;
   17157               break;
   17158           }
   17159           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
   17160                   (encoded_align_1.GetEncodingValue() << 4) |
   17161                   first.Encode(22, 12) | (len_encoding << 8) |
   17162                   (rn.GetCode() << 16) | rm.GetCode());
   17163           return;
   17164         }
   17165       }
   17166       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   17167       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   17168           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   17169           !rm.IsPC() && !rm.IsSP()) {
   17170         if (cond.Is(al)) {
   17171           const DRegister& first = nreglist.GetFirstDRegister();
   17172           uint32_t len_encoding = nreglist.GetLength() - 1;
   17173           EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
   17174                   (encoded_align_2.GetEncodingValue() << 4) |
   17175                   first.Encode(22, 12) | (len_encoding << 5) |
   17176                   (rn.GetCode() << 16) | rm.GetCode());
   17177           return;
   17178         }
   17179       }
   17180       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   17181       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   17182           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
   17183         if (cond.Is(al)) {
   17184           const DRegister& first = nreglist.GetFirstDRegister();
   17185           EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
   17186                   (encoded_align_3.GetEncodingValue() << 4) |
   17187                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   17188           return;
   17189         }
   17190       }
   17191     }
   17192   }
   17193   Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
   17194 }
   17195 
   17196 void Assembler::vld2(Condition cond,
   17197                      DataType dt,
   17198                      const NeonRegisterList& nreglist,
   17199                      const AlignedMemOperand& operand) {
   17200   VIXL_ASSERT(AllowAssembler());
   17201   CheckIT(cond);
   17202   if (operand.IsImmediateZero()) {
   17203     Register rn = operand.GetBaseRegister();
   17204     Alignment align = operand.GetAlignment();
   17205     Dt_size_7 encoded_dt(dt);
   17206     Align_align_2 encoded_align_1(align, nreglist);
   17207     Align_a_2 encoded_align_2(align, dt);
   17208     Align_index_align_2 encoded_align_3(align, nreglist, dt);
   17209     if (IsUsingT32()) {
   17210       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   17211       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17212           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17213            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   17214            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   17215           operand.IsOffset() && encoded_align_1.IsValid() &&
   17216           (!rn.IsPC() || AllowUnpredictable())) {
   17217         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17218           const DRegister& first = nreglist.GetFirstDRegister();
   17219           uint32_t len_encoding;
   17220           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   17221             len_encoding = 0x8;
   17222           }
   17223           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   17224             len_encoding = 0x9;
   17225           }
   17226           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   17227             len_encoding = 0x3;
   17228           }
   17229           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
   17230                      (encoded_align_1.GetEncodingValue() << 4) |
   17231                      first.Encode(22, 12) | (len_encoding << 8) |
   17232                      (rn.GetCode() << 16));
   17233           AdvanceIT();
   17234           return;
   17235         }
   17236       }
   17237       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   17238       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17239           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17240            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   17241            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   17242           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   17243           (!rn.IsPC() || AllowUnpredictable())) {
   17244         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17245           const DRegister& first = nreglist.GetFirstDRegister();
   17246           uint32_t len_encoding;
   17247           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   17248             len_encoding = 0x8;
   17249           }
   17250           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   17251             len_encoding = 0x9;
   17252           }
   17253           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   17254             len_encoding = 0x3;
   17255           }
   17256           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
   17257                      (encoded_align_1.GetEncodingValue() << 4) |
   17258                      first.Encode(22, 12) | (len_encoding << 8) |
   17259                      (rn.GetCode() << 16));
   17260           AdvanceIT();
   17261           return;
   17262         }
   17263       }
   17264       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   17265       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17266           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17267            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17268           operand.IsOffset() && encoded_align_2.IsValid() &&
   17269           (!rn.IsPC() || AllowUnpredictable())) {
   17270         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17271           const DRegister& first = nreglist.GetFirstDRegister();
   17272           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17273           EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
   17274                      (encoded_align_2.GetEncodingValue() << 4) |
   17275                      first.Encode(22, 12) | (len_encoding << 5) |
   17276                      (rn.GetCode() << 16));
   17277           AdvanceIT();
   17278           return;
   17279         }
   17280       }
   17281       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   17282       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17283           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17284            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17285           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   17286           (!rn.IsPC() || AllowUnpredictable())) {
   17287         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17288           const DRegister& first = nreglist.GetFirstDRegister();
   17289           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17290           EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
   17291                      (encoded_align_2.GetEncodingValue() << 4) |
   17292                      first.Encode(22, 12) | (len_encoding << 5) |
   17293                      (rn.GetCode() << 16));
   17294           AdvanceIT();
   17295           return;
   17296         }
   17297       }
   17298       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   17299       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17300           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17301            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17302           operand.IsOffset() && encoded_align_3.IsValid() &&
   17303           (!rn.IsPC() || AllowUnpredictable())) {
   17304         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17305           const DRegister& first = nreglist.GetFirstDRegister();
   17306           EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
   17307                      (encoded_align_3.GetEncodingValue() << 4) |
   17308                      first.Encode(22, 12) | (rn.GetCode() << 16));
   17309           AdvanceIT();
   17310           return;
   17311         }
   17312       }
   17313       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   17314       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17315           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17316            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17317           operand.IsPostIndex() && encoded_align_3.IsValid() &&
   17318           (!rn.IsPC() || AllowUnpredictable())) {
   17319         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17320           const DRegister& first = nreglist.GetFirstDRegister();
   17321           EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
   17322                      (encoded_align_3.GetEncodingValue() << 4) |
   17323                      first.Encode(22, 12) | (rn.GetCode() << 16));
   17324           AdvanceIT();
   17325           return;
   17326         }
   17327       }
   17328     } else {
   17329       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   17330       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17331           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17332            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   17333            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   17334           operand.IsOffset() && encoded_align_1.IsValid() &&
   17335           (!rn.IsPC() || AllowUnpredictable())) {
   17336         if (cond.Is(al)) {
   17337           const DRegister& first = nreglist.GetFirstDRegister();
   17338           uint32_t len_encoding;
   17339           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   17340             len_encoding = 0x8;
   17341           }
   17342           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   17343             len_encoding = 0x9;
   17344           }
   17345           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   17346             len_encoding = 0x3;
   17347           }
   17348           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
   17349                   (encoded_align_1.GetEncodingValue() << 4) |
   17350                   first.Encode(22, 12) | (len_encoding << 8) |
   17351                   (rn.GetCode() << 16));
   17352           return;
   17353         }
   17354       }
   17355       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   17356       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17357           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17358            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   17359            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   17360           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   17361           (!rn.IsPC() || AllowUnpredictable())) {
   17362         if (cond.Is(al)) {
   17363           const DRegister& first = nreglist.GetFirstDRegister();
   17364           uint32_t len_encoding;
   17365           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   17366             len_encoding = 0x8;
   17367           }
   17368           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   17369             len_encoding = 0x9;
   17370           }
   17371           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   17372             len_encoding = 0x3;
   17373           }
   17374           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
   17375                   (encoded_align_1.GetEncodingValue() << 4) |
   17376                   first.Encode(22, 12) | (len_encoding << 8) |
   17377                   (rn.GetCode() << 16));
   17378           return;
   17379         }
   17380       }
   17381       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   17382       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17383           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17384            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17385           operand.IsOffset() && encoded_align_2.IsValid() &&
   17386           (!rn.IsPC() || AllowUnpredictable())) {
   17387         if (cond.Is(al)) {
   17388           const DRegister& first = nreglist.GetFirstDRegister();
   17389           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17390           EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
   17391                   (encoded_align_2.GetEncodingValue() << 4) |
   17392                   first.Encode(22, 12) | (len_encoding << 5) |
   17393                   (rn.GetCode() << 16));
   17394           return;
   17395         }
   17396       }
   17397       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   17398       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17399           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17400            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17401           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   17402           (!rn.IsPC() || AllowUnpredictable())) {
   17403         if (cond.Is(al)) {
   17404           const DRegister& first = nreglist.GetFirstDRegister();
   17405           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17406           EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
   17407                   (encoded_align_2.GetEncodingValue() << 4) |
   17408                   first.Encode(22, 12) | (len_encoding << 5) |
   17409                   (rn.GetCode() << 16));
   17410           return;
   17411         }
   17412       }
   17413       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   17414       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17415           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17416            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17417           operand.IsOffset() && encoded_align_3.IsValid() &&
   17418           (!rn.IsPC() || AllowUnpredictable())) {
   17419         if (cond.Is(al)) {
   17420           const DRegister& first = nreglist.GetFirstDRegister();
   17421           EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
   17422                   (encoded_align_3.GetEncodingValue() << 4) |
   17423                   first.Encode(22, 12) | (rn.GetCode() << 16));
   17424           return;
   17425         }
   17426       }
   17427       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   17428       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17429           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17430            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17431           operand.IsPostIndex() && encoded_align_3.IsValid() &&
   17432           (!rn.IsPC() || AllowUnpredictable())) {
   17433         if (cond.Is(al)) {
   17434           const DRegister& first = nreglist.GetFirstDRegister();
   17435           EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
   17436                   (encoded_align_3.GetEncodingValue() << 4) |
   17437                   first.Encode(22, 12) | (rn.GetCode() << 16));
   17438           return;
   17439         }
   17440       }
   17441     }
   17442   }
   17443   if (operand.IsPlainRegister()) {
   17444     Register rn = operand.GetBaseRegister();
   17445     Alignment align = operand.GetAlignment();
   17446     Register rm = operand.GetOffsetRegister();
   17447     Dt_size_7 encoded_dt(dt);
   17448     Align_align_2 encoded_align_1(align, nreglist);
   17449     Align_a_2 encoded_align_2(align, dt);
   17450     Align_index_align_2 encoded_align_3(align, nreglist, dt);
   17451     if (IsUsingT32()) {
   17452       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   17453       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17454           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17455            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   17456            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   17457           !rm.IsPC() && !rm.IsSP()) {
   17458         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17459           const DRegister& first = nreglist.GetFirstDRegister();
   17460           uint32_t len_encoding;
   17461           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   17462             len_encoding = 0x8;
   17463           }
   17464           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   17465             len_encoding = 0x9;
   17466           }
   17467           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   17468             len_encoding = 0x3;
   17469           }
   17470           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
   17471                      (encoded_align_1.GetEncodingValue() << 4) |
   17472                      first.Encode(22, 12) | (len_encoding << 8) |
   17473                      (rn.GetCode() << 16) | rm.GetCode());
   17474           AdvanceIT();
   17475           return;
   17476         }
   17477       }
   17478       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   17479       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17480           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17481            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17482           !rm.IsPC() && !rm.IsSP()) {
   17483         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17484           const DRegister& first = nreglist.GetFirstDRegister();
   17485           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17486           EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
   17487                      (encoded_align_2.GetEncodingValue() << 4) |
   17488                      first.Encode(22, 12) | (len_encoding << 5) |
   17489                      (rn.GetCode() << 16) | rm.GetCode());
   17490           AdvanceIT();
   17491           return;
   17492         }
   17493       }
   17494       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   17495       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17496           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17497            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17498           !rm.IsPC() && !rm.IsSP()) {
   17499         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17500           const DRegister& first = nreglist.GetFirstDRegister();
   17501           EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
   17502                      (encoded_align_3.GetEncodingValue() << 4) |
   17503                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   17504                      rm.GetCode());
   17505           AdvanceIT();
   17506           return;
   17507         }
   17508       }
   17509     } else {
   17510       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   17511       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17512           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17513            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   17514            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   17515           !rm.IsPC() && !rm.IsSP()) {
   17516         if (cond.Is(al)) {
   17517           const DRegister& first = nreglist.GetFirstDRegister();
   17518           uint32_t len_encoding;
   17519           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   17520             len_encoding = 0x8;
   17521           }
   17522           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   17523             len_encoding = 0x9;
   17524           }
   17525           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   17526             len_encoding = 0x3;
   17527           }
   17528           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
   17529                   (encoded_align_1.GetEncodingValue() << 4) |
   17530                   first.Encode(22, 12) | (len_encoding << 8) |
   17531                   (rn.GetCode() << 16) | rm.GetCode());
   17532           return;
   17533         }
   17534       }
   17535       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   17536       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17537           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17538            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17539           !rm.IsPC() && !rm.IsSP()) {
   17540         if (cond.Is(al)) {
   17541           const DRegister& first = nreglist.GetFirstDRegister();
   17542           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17543           EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
   17544                   (encoded_align_2.GetEncodingValue() << 4) |
   17545                   first.Encode(22, 12) | (len_encoding << 5) |
   17546                   (rn.GetCode() << 16) | rm.GetCode());
   17547           return;
   17548         }
   17549       }
   17550       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   17551       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17552           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   17553            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   17554           !rm.IsPC() && !rm.IsSP()) {
   17555         if (cond.Is(al)) {
   17556           const DRegister& first = nreglist.GetFirstDRegister();
   17557           EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
   17558                   (encoded_align_3.GetEncodingValue() << 4) |
   17559                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   17560           return;
   17561         }
   17562       }
   17563     }
   17564   }
   17565   Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
   17566 }
   17567 
   17568 void Assembler::vld3(Condition cond,
   17569                      DataType dt,
   17570                      const NeonRegisterList& nreglist,
   17571                      const AlignedMemOperand& operand) {
   17572   VIXL_ASSERT(AllowAssembler());
   17573   CheckIT(cond);
   17574   if (operand.IsImmediateZero()) {
   17575     Register rn = operand.GetBaseRegister();
   17576     Alignment align = operand.GetAlignment();
   17577     Dt_size_7 encoded_dt(dt);
   17578     Align_align_3 encoded_align_1(align);
   17579     if (IsUsingT32()) {
   17580       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   17581       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17582           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17583            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17584           operand.IsOffset() && encoded_align_1.IsValid() &&
   17585           (!rn.IsPC() || AllowUnpredictable())) {
   17586         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17587           const DRegister& first = nreglist.GetFirstDRegister();
   17588           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   17589           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
   17590                      (encoded_align_1.GetEncodingValue() << 4) |
   17591                      first.Encode(22, 12) | (len_encoding << 8) |
   17592                      (rn.GetCode() << 16));
   17593           AdvanceIT();
   17594           return;
   17595         }
   17596       }
   17597       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   17598       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17599           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17600            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17601           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   17602           (!rn.IsPC() || AllowUnpredictable())) {
   17603         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17604           const DRegister& first = nreglist.GetFirstDRegister();
   17605           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   17606           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
   17607                      (encoded_align_1.GetEncodingValue() << 4) |
   17608                      first.Encode(22, 12) | (len_encoding << 8) |
   17609                      (rn.GetCode() << 16));
   17610           AdvanceIT();
   17611           return;
   17612         }
   17613       }
   17614     } else {
   17615       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   17616       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17617           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17618            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17619           operand.IsOffset() && encoded_align_1.IsValid() &&
   17620           (!rn.IsPC() || AllowUnpredictable())) {
   17621         if (cond.Is(al)) {
   17622           const DRegister& first = nreglist.GetFirstDRegister();
   17623           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   17624           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
   17625                   (encoded_align_1.GetEncodingValue() << 4) |
   17626                   first.Encode(22, 12) | (len_encoding << 8) |
   17627                   (rn.GetCode() << 16));
   17628           return;
   17629         }
   17630       }
   17631       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   17632       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17633           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17634            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17635           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   17636           (!rn.IsPC() || AllowUnpredictable())) {
   17637         if (cond.Is(al)) {
   17638           const DRegister& first = nreglist.GetFirstDRegister();
   17639           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   17640           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
   17641                   (encoded_align_1.GetEncodingValue() << 4) |
   17642                   first.Encode(22, 12) | (len_encoding << 8) |
   17643                   (rn.GetCode() << 16));
   17644           return;
   17645         }
   17646       }
   17647     }
   17648   }
   17649   if (operand.IsPlainRegister()) {
   17650     Register rn = operand.GetBaseRegister();
   17651     Alignment align = operand.GetAlignment();
   17652     Register rm = operand.GetOffsetRegister();
   17653     Dt_size_7 encoded_dt(dt);
   17654     Align_align_3 encoded_align_1(align);
   17655     if (IsUsingT32()) {
   17656       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   17657       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17658           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17659            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17660           !rm.IsPC() && !rm.IsSP()) {
   17661         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17662           const DRegister& first = nreglist.GetFirstDRegister();
   17663           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   17664           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
   17665                      (encoded_align_1.GetEncodingValue() << 4) |
   17666                      first.Encode(22, 12) | (len_encoding << 8) |
   17667                      (rn.GetCode() << 16) | rm.GetCode());
   17668           AdvanceIT();
   17669           return;
   17670         }
   17671       }
   17672     } else {
   17673       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   17674       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17675           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17676            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17677           !rm.IsPC() && !rm.IsSP()) {
   17678         if (cond.Is(al)) {
   17679           const DRegister& first = nreglist.GetFirstDRegister();
   17680           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   17681           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
   17682                   (encoded_align_1.GetEncodingValue() << 4) |
   17683                   first.Encode(22, 12) | (len_encoding << 8) |
   17684                   (rn.GetCode() << 16) | rm.GetCode());
   17685           return;
   17686         }
   17687       }
   17688     }
   17689   }
   17690   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
   17691 }
   17692 
   17693 void Assembler::vld3(Condition cond,
   17694                      DataType dt,
   17695                      const NeonRegisterList& nreglist,
   17696                      const MemOperand& operand) {
   17697   VIXL_ASSERT(AllowAssembler());
   17698   CheckIT(cond);
   17699   if (operand.IsImmediateZero()) {
   17700     Register rn = operand.GetBaseRegister();
   17701     Dt_size_7 encoded_dt(dt);
   17702     Index_1 encoded_align_1(nreglist, dt);
   17703     if (IsUsingT32()) {
   17704       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
   17705       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17706           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17707            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17708           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   17709         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17710           const DRegister& first = nreglist.GetFirstDRegister();
   17711           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17712           EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
   17713                      first.Encode(22, 12) | (len_encoding << 5) |
   17714                      (rn.GetCode() << 16));
   17715           AdvanceIT();
   17716           return;
   17717         }
   17718       }
   17719       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
   17720       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17721           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17722            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17723           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   17724         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17725           const DRegister& first = nreglist.GetFirstDRegister();
   17726           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17727           EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
   17728                      first.Encode(22, 12) | (len_encoding << 5) |
   17729                      (rn.GetCode() << 16));
   17730           AdvanceIT();
   17731           return;
   17732         }
   17733       }
   17734       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
   17735       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17736           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17737            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17738           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   17739         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17740           const DRegister& first = nreglist.GetFirstDRegister();
   17741           EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
   17742                      (encoded_align_1.GetEncodingValue() << 4) |
   17743                      first.Encode(22, 12) | (rn.GetCode() << 16));
   17744           AdvanceIT();
   17745           return;
   17746         }
   17747       }
   17748       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
   17749       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17750           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17751            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17752           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   17753         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17754           const DRegister& first = nreglist.GetFirstDRegister();
   17755           EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
   17756                      (encoded_align_1.GetEncodingValue() << 4) |
   17757                      first.Encode(22, 12) | (rn.GetCode() << 16));
   17758           AdvanceIT();
   17759           return;
   17760         }
   17761       }
   17762     } else {
   17763       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
   17764       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17765           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17766            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17767           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   17768         if (cond.Is(al)) {
   17769           const DRegister& first = nreglist.GetFirstDRegister();
   17770           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17771           EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
   17772                   first.Encode(22, 12) | (len_encoding << 5) |
   17773                   (rn.GetCode() << 16));
   17774           return;
   17775         }
   17776       }
   17777       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
   17778       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17779           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17780            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17781           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   17782         if (cond.Is(al)) {
   17783           const DRegister& first = nreglist.GetFirstDRegister();
   17784           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17785           EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
   17786                   first.Encode(22, 12) | (len_encoding << 5) |
   17787                   (rn.GetCode() << 16));
   17788           return;
   17789         }
   17790       }
   17791       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
   17792       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17793           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17794            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17795           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   17796         if (cond.Is(al)) {
   17797           const DRegister& first = nreglist.GetFirstDRegister();
   17798           EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
   17799                   (encoded_align_1.GetEncodingValue() << 4) |
   17800                   first.Encode(22, 12) | (rn.GetCode() << 16));
   17801           return;
   17802         }
   17803       }
   17804       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
   17805       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17806           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17807            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17808           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   17809         if (cond.Is(al)) {
   17810           const DRegister& first = nreglist.GetFirstDRegister();
   17811           EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
   17812                   (encoded_align_1.GetEncodingValue() << 4) |
   17813                   first.Encode(22, 12) | (rn.GetCode() << 16));
   17814           return;
   17815         }
   17816       }
   17817     }
   17818   }
   17819   if (operand.IsPlainRegister()) {
   17820     Register rn = operand.GetBaseRegister();
   17821     Sign sign = operand.GetSign();
   17822     Register rm = operand.GetOffsetRegister();
   17823     Dt_size_7 encoded_dt(dt);
   17824     Index_1 encoded_align_1(nreglist, dt);
   17825     if (IsUsingT32()) {
   17826       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
   17827       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17828           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17829            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17830           sign.IsPlus() && operand.IsPostIndex()) {
   17831         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17832           const DRegister& first = nreglist.GetFirstDRegister();
   17833           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17834           EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
   17835                      first.Encode(22, 12) | (len_encoding << 5) |
   17836                      (rn.GetCode() << 16) | rm.GetCode());
   17837           AdvanceIT();
   17838           return;
   17839         }
   17840       }
   17841       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
   17842       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17843           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17844            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17845           sign.IsPlus() && operand.IsPostIndex()) {
   17846         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17847           const DRegister& first = nreglist.GetFirstDRegister();
   17848           EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
   17849                      (encoded_align_1.GetEncodingValue() << 4) |
   17850                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   17851                      rm.GetCode());
   17852           AdvanceIT();
   17853           return;
   17854         }
   17855       }
   17856     } else {
   17857       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
   17858       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   17859           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17860            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17861           sign.IsPlus() && operand.IsPostIndex()) {
   17862         if (cond.Is(al)) {
   17863           const DRegister& first = nreglist.GetFirstDRegister();
   17864           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17865           EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
   17866                   first.Encode(22, 12) | (len_encoding << 5) |
   17867                   (rn.GetCode() << 16) | rm.GetCode());
   17868           return;
   17869         }
   17870       }
   17871       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
   17872       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17873           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   17874            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   17875           sign.IsPlus() && operand.IsPostIndex()) {
   17876         if (cond.Is(al)) {
   17877           const DRegister& first = nreglist.GetFirstDRegister();
   17878           EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
   17879                   (encoded_align_1.GetEncodingValue() << 4) |
   17880                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   17881           return;
   17882         }
   17883       }
   17884     }
   17885   }
   17886   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
   17887 }
   17888 
   17889 void Assembler::vld4(Condition cond,
   17890                      DataType dt,
   17891                      const NeonRegisterList& nreglist,
   17892                      const AlignedMemOperand& operand) {
   17893   VIXL_ASSERT(AllowAssembler());
   17894   CheckIT(cond);
   17895   if (operand.IsImmediateZero()) {
   17896     Register rn = operand.GetBaseRegister();
   17897     Alignment align = operand.GetAlignment();
   17898     Dt_size_7 encoded_dt(dt);
   17899     Dt_size_8 encoded_dt_2(dt, align);
   17900     Align_align_4 encoded_align_1(align);
   17901     Align_a_3 encoded_align_2(align, dt);
   17902     Align_index_align_3 encoded_align_3(align, nreglist, dt);
   17903     if (IsUsingT32()) {
   17904       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   17905       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17906           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   17907            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   17908           operand.IsOffset() && encoded_align_1.IsValid() &&
   17909           (!rn.IsPC() || AllowUnpredictable())) {
   17910         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17911           const DRegister& first = nreglist.GetFirstDRegister();
   17912           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17913           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
   17914                      (encoded_align_1.GetEncodingValue() << 4) |
   17915                      first.Encode(22, 12) | (len_encoding << 8) |
   17916                      (rn.GetCode() << 16));
   17917           AdvanceIT();
   17918           return;
   17919         }
   17920       }
   17921       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   17922       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17923           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   17924            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   17925           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   17926           (!rn.IsPC() || AllowUnpredictable())) {
   17927         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17928           const DRegister& first = nreglist.GetFirstDRegister();
   17929           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17930           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
   17931                      (encoded_align_1.GetEncodingValue() << 4) |
   17932                      first.Encode(22, 12) | (len_encoding << 8) |
   17933                      (rn.GetCode() << 16));
   17934           AdvanceIT();
   17935           return;
   17936         }
   17937       }
   17938       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   17939       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   17940           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   17941            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   17942           operand.IsOffset() && encoded_align_2.IsValid() &&
   17943           (!rn.IsPC() || AllowUnpredictable())) {
   17944         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17945           const DRegister& first = nreglist.GetFirstDRegister();
   17946           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17947           EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
   17948                      (encoded_align_2.GetEncodingValue() << 4) |
   17949                      first.Encode(22, 12) | (len_encoding << 5) |
   17950                      (rn.GetCode() << 16));
   17951           AdvanceIT();
   17952           return;
   17953         }
   17954       }
   17955       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   17956       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   17957           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   17958            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   17959           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   17960           (!rn.IsPC() || AllowUnpredictable())) {
   17961         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17962           const DRegister& first = nreglist.GetFirstDRegister();
   17963           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   17964           EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
   17965                      (encoded_align_2.GetEncodingValue() << 4) |
   17966                      first.Encode(22, 12) | (len_encoding << 5) |
   17967                      (rn.GetCode() << 16));
   17968           AdvanceIT();
   17969           return;
   17970         }
   17971       }
   17972       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   17973       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17974           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   17975            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   17976           operand.IsOffset() && encoded_align_3.IsValid() &&
   17977           (!rn.IsPC() || AllowUnpredictable())) {
   17978         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17979           const DRegister& first = nreglist.GetFirstDRegister();
   17980           EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
   17981                      (encoded_align_3.GetEncodingValue() << 4) |
   17982                      first.Encode(22, 12) | (rn.GetCode() << 16));
   17983           AdvanceIT();
   17984           return;
   17985         }
   17986       }
   17987       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   17988       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   17989           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   17990            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   17991           operand.IsPostIndex() && encoded_align_3.IsValid() &&
   17992           (!rn.IsPC() || AllowUnpredictable())) {
   17993         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17994           const DRegister& first = nreglist.GetFirstDRegister();
   17995           EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
   17996                      (encoded_align_3.GetEncodingValue() << 4) |
   17997                      first.Encode(22, 12) | (rn.GetCode() << 16));
   17998           AdvanceIT();
   17999           return;
   18000         }
   18001       }
   18002     } else {
   18003       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18004       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18005           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18006            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18007           operand.IsOffset() && encoded_align_1.IsValid() &&
   18008           (!rn.IsPC() || AllowUnpredictable())) {
   18009         if (cond.Is(al)) {
   18010           const DRegister& first = nreglist.GetFirstDRegister();
   18011           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18012           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
   18013                   (encoded_align_1.GetEncodingValue() << 4) |
   18014                   first.Encode(22, 12) | (len_encoding << 8) |
   18015                   (rn.GetCode() << 16));
   18016           return;
   18017         }
   18018       }
   18019       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18020       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18021           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18022            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18023           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   18024           (!rn.IsPC() || AllowUnpredictable())) {
   18025         if (cond.Is(al)) {
   18026           const DRegister& first = nreglist.GetFirstDRegister();
   18027           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18028           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
   18029                   (encoded_align_1.GetEncodingValue() << 4) |
   18030                   first.Encode(22, 12) | (len_encoding << 8) |
   18031                   (rn.GetCode() << 16));
   18032           return;
   18033         }
   18034       }
   18035       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18036       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18037           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18038            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18039           operand.IsOffset() && encoded_align_2.IsValid() &&
   18040           (!rn.IsPC() || AllowUnpredictable())) {
   18041         if (cond.Is(al)) {
   18042           const DRegister& first = nreglist.GetFirstDRegister();
   18043           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18044           EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
   18045                   (encoded_align_2.GetEncodingValue() << 4) |
   18046                   first.Encode(22, 12) | (len_encoding << 5) |
   18047                   (rn.GetCode() << 16));
   18048           return;
   18049         }
   18050       }
   18051       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18052       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18053           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18054            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18055           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   18056           (!rn.IsPC() || AllowUnpredictable())) {
   18057         if (cond.Is(al)) {
   18058           const DRegister& first = nreglist.GetFirstDRegister();
   18059           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18060           EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
   18061                   (encoded_align_2.GetEncodingValue() << 4) |
   18062                   first.Encode(22, 12) | (len_encoding << 5) |
   18063                   (rn.GetCode() << 16));
   18064           return;
   18065         }
   18066       }
   18067       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18068       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18069           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18070            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18071           operand.IsOffset() && encoded_align_3.IsValid() &&
   18072           (!rn.IsPC() || AllowUnpredictable())) {
   18073         if (cond.Is(al)) {
   18074           const DRegister& first = nreglist.GetFirstDRegister();
   18075           EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
   18076                   (encoded_align_3.GetEncodingValue() << 4) |
   18077                   first.Encode(22, 12) | (rn.GetCode() << 16));
   18078           return;
   18079         }
   18080       }
   18081       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18082       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18083           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18084            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18085           operand.IsPostIndex() && encoded_align_3.IsValid() &&
   18086           (!rn.IsPC() || AllowUnpredictable())) {
   18087         if (cond.Is(al)) {
   18088           const DRegister& first = nreglist.GetFirstDRegister();
   18089           EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
   18090                   (encoded_align_3.GetEncodingValue() << 4) |
   18091                   first.Encode(22, 12) | (rn.GetCode() << 16));
   18092           return;
   18093         }
   18094       }
   18095     }
   18096   }
   18097   if (operand.IsPlainRegister()) {
   18098     Register rn = operand.GetBaseRegister();
   18099     Alignment align = operand.GetAlignment();
   18100     Register rm = operand.GetOffsetRegister();
   18101     Dt_size_7 encoded_dt(dt);
   18102     Dt_size_8 encoded_dt_2(dt, align);
   18103     Align_align_4 encoded_align_1(align);
   18104     Align_a_3 encoded_align_2(align, dt);
   18105     Align_index_align_3 encoded_align_3(align, nreglist, dt);
   18106     if (IsUsingT32()) {
   18107       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18108       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18109           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18110            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18111           !rm.IsPC() && !rm.IsSP()) {
   18112         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18113           const DRegister& first = nreglist.GetFirstDRegister();
   18114           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18115           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
   18116                      (encoded_align_1.GetEncodingValue() << 4) |
   18117                      first.Encode(22, 12) | (len_encoding << 8) |
   18118                      (rn.GetCode() << 16) | rm.GetCode());
   18119           AdvanceIT();
   18120           return;
   18121         }
   18122       }
   18123       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18124       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18125           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18126            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18127           !rm.IsPC() && !rm.IsSP()) {
   18128         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18129           const DRegister& first = nreglist.GetFirstDRegister();
   18130           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18131           EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
   18132                      (encoded_align_2.GetEncodingValue() << 4) |
   18133                      first.Encode(22, 12) | (len_encoding << 5) |
   18134                      (rn.GetCode() << 16) | rm.GetCode());
   18135           AdvanceIT();
   18136           return;
   18137         }
   18138       }
   18139       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18140       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18141           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18142            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18143           !rm.IsPC() && !rm.IsSP()) {
   18144         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18145           const DRegister& first = nreglist.GetFirstDRegister();
   18146           EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
   18147                      (encoded_align_3.GetEncodingValue() << 4) |
   18148                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   18149                      rm.GetCode());
   18150           AdvanceIT();
   18151           return;
   18152         }
   18153       }
   18154     } else {
   18155       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18156       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18157           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18158            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18159           !rm.IsPC() && !rm.IsSP()) {
   18160         if (cond.Is(al)) {
   18161           const DRegister& first = nreglist.GetFirstDRegister();
   18162           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18163           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
   18164                   (encoded_align_1.GetEncodingValue() << 4) |
   18165                   first.Encode(22, 12) | (len_encoding << 8) |
   18166                   (rn.GetCode() << 16) | rm.GetCode());
   18167           return;
   18168         }
   18169       }
   18170       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18171       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18172           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18173            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18174           !rm.IsPC() && !rm.IsSP()) {
   18175         if (cond.Is(al)) {
   18176           const DRegister& first = nreglist.GetFirstDRegister();
   18177           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18178           EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
   18179                   (encoded_align_2.GetEncodingValue() << 4) |
   18180                   first.Encode(22, 12) | (len_encoding << 5) |
   18181                   (rn.GetCode() << 16) | rm.GetCode());
   18182           return;
   18183         }
   18184       }
   18185       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18186       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18187           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   18188            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   18189           !rm.IsPC() && !rm.IsSP()) {
   18190         if (cond.Is(al)) {
   18191           const DRegister& first = nreglist.GetFirstDRegister();
   18192           EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
   18193                   (encoded_align_3.GetEncodingValue() << 4) |
   18194                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   18195           return;
   18196         }
   18197       }
   18198     }
   18199   }
   18200   Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
   18201 }
   18202 
   18203 void Assembler::vldm(Condition cond,
   18204                      DataType dt,
   18205                      Register rn,
   18206                      WriteBack write_back,
   18207                      DRegisterList dreglist) {
   18208   VIXL_ASSERT(AllowAssembler());
   18209   CheckIT(cond);
   18210   USE(dt);
   18211   if (IsUsingT32()) {
   18212     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
   18213     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   18214       const DRegister& dreg = dreglist.GetFirstDRegister();
   18215       unsigned len = dreglist.GetLength() * 2;
   18216       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
   18217                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   18218                  (len & 0xff));
   18219       AdvanceIT();
   18220       return;
   18221     }
   18222   } else {
   18223     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
   18224     if (cond.IsNotNever() &&
   18225         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   18226       const DRegister& dreg = dreglist.GetFirstDRegister();
   18227       unsigned len = dreglist.GetLength() * 2;
   18228       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   18229               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   18230               (len & 0xff));
   18231       return;
   18232     }
   18233   }
   18234   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
   18235 }
   18236 
   18237 void Assembler::vldm(Condition cond,
   18238                      DataType dt,
   18239                      Register rn,
   18240                      WriteBack write_back,
   18241                      SRegisterList sreglist) {
   18242   VIXL_ASSERT(AllowAssembler());
   18243   CheckIT(cond);
   18244   USE(dt);
   18245   if (IsUsingT32()) {
   18246     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
   18247     const SRegister& sreg = sreglist.GetFirstSRegister();
   18248     unsigned len = sreglist.GetLength();
   18249     EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
   18250                (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   18251                (len & 0xff));
   18252     AdvanceIT();
   18253     return;
   18254   } else {
   18255     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
   18256     if (cond.IsNotNever()) {
   18257       const SRegister& sreg = sreglist.GetFirstSRegister();
   18258       unsigned len = sreglist.GetLength();
   18259       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   18260               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   18261               (len & 0xff));
   18262       return;
   18263     }
   18264   }
   18265   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
   18266 }
   18267 
   18268 void Assembler::vldmdb(Condition cond,
   18269                        DataType dt,
   18270                        Register rn,
   18271                        WriteBack write_back,
   18272                        DRegisterList dreglist) {
   18273   VIXL_ASSERT(AllowAssembler());
   18274   CheckIT(cond);
   18275   USE(dt);
   18276   if (IsUsingT32()) {
   18277     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
   18278     if (write_back.DoesWriteBack() &&
   18279         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   18280       const DRegister& dreg = dreglist.GetFirstDRegister();
   18281       unsigned len = dreglist.GetLength() * 2;
   18282       EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   18283                  (len & 0xff));
   18284       AdvanceIT();
   18285       return;
   18286     }
   18287   } else {
   18288     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
   18289     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   18290         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   18291       const DRegister& dreg = dreglist.GetFirstDRegister();
   18292       unsigned len = dreglist.GetLength() * 2;
   18293       EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   18294               dreg.Encode(22, 12) | (len & 0xff));
   18295       return;
   18296     }
   18297   }
   18298   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
   18299 }
   18300 
   18301 void Assembler::vldmdb(Condition cond,
   18302                        DataType dt,
   18303                        Register rn,
   18304                        WriteBack write_back,
   18305                        SRegisterList sreglist) {
   18306   VIXL_ASSERT(AllowAssembler());
   18307   CheckIT(cond);
   18308   USE(dt);
   18309   if (IsUsingT32()) {
   18310     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
   18311     if (write_back.DoesWriteBack()) {
   18312       const SRegister& sreg = sreglist.GetFirstSRegister();
   18313       unsigned len = sreglist.GetLength();
   18314       EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
   18315                  (len & 0xff));
   18316       AdvanceIT();
   18317       return;
   18318     }
   18319   } else {
   18320     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
   18321     if (write_back.DoesWriteBack() && cond.IsNotNever()) {
   18322       const SRegister& sreg = sreglist.GetFirstSRegister();
   18323       unsigned len = sreglist.GetLength();
   18324       EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   18325               sreg.Encode(22, 12) | (len & 0xff));
   18326       return;
   18327     }
   18328   }
   18329   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
   18330 }
   18331 
   18332 void Assembler::vldmia(Condition cond,
   18333                        DataType dt,
   18334                        Register rn,
   18335                        WriteBack write_back,
   18336                        DRegisterList dreglist) {
   18337   VIXL_ASSERT(AllowAssembler());
   18338   CheckIT(cond);
   18339   USE(dt);
   18340   if (IsUsingT32()) {
   18341     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
   18342     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   18343       const DRegister& dreg = dreglist.GetFirstDRegister();
   18344       unsigned len = dreglist.GetLength() * 2;
   18345       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
   18346                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   18347                  (len & 0xff));
   18348       AdvanceIT();
   18349       return;
   18350     }
   18351   } else {
   18352     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
   18353     if (cond.IsNotNever() &&
   18354         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   18355       const DRegister& dreg = dreglist.GetFirstDRegister();
   18356       unsigned len = dreglist.GetLength() * 2;
   18357       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   18358               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   18359               (len & 0xff));
   18360       return;
   18361     }
   18362   }
   18363   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
   18364 }
   18365 
   18366 void Assembler::vldmia(Condition cond,
   18367                        DataType dt,
   18368                        Register rn,
   18369                        WriteBack write_back,
   18370                        SRegisterList sreglist) {
   18371   VIXL_ASSERT(AllowAssembler());
   18372   CheckIT(cond);
   18373   USE(dt);
   18374   if (IsUsingT32()) {
   18375     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
   18376     const SRegister& sreg = sreglist.GetFirstSRegister();
   18377     unsigned len = sreglist.GetLength();
   18378     EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
   18379                (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   18380                (len & 0xff));
   18381     AdvanceIT();
   18382     return;
   18383   } else {
   18384     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
   18385     if (cond.IsNotNever()) {
   18386       const SRegister& sreg = sreglist.GetFirstSRegister();
   18387       unsigned len = sreglist.GetLength();
   18388       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   18389               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   18390               (len & 0xff));
   18391       return;
   18392     }
   18393   }
   18394   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
   18395 }
   18396 
   18397 void Assembler::vldr(Condition cond, DataType dt, DRegister rd, Label* label) {
   18398   VIXL_ASSERT(AllowAssembler());
   18399   CheckIT(cond);
   18400   Label::Offset offset =
   18401       label->IsBound()
   18402           ? label->GetLocation() -
   18403                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   18404           : 0;
   18405   if (IsUsingT32()) {
   18406     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
   18407     if (dt.IsNoneOr(Untyped64) &&
   18408         ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   18409           ((offset & 0x3) == 0)) ||
   18410          !label->IsBound())) {
   18411       static class EmitOp : public Label::LabelEmitOperator {
   18412        public:
   18413         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
   18414         virtual uint32_t Encode(uint32_t instr,
   18415                                 Label::Offset pc,
   18416                                 const Label* label) const VIXL_OVERRIDE {
   18417           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   18418           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   18419                       ((offset & 0x3) == 0));
   18420           int32_t target = offset >> 2;
   18421           uint32_t U = (target >= 0) && !label->IsMinusZero();
   18422           target = abs(target) | (U << 8);
   18423           return instr | (target & 0xff) | ((target & 0x100) << 15);
   18424         }
   18425       } immop;
   18426       EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12), label, immop));
   18427       AdvanceIT();
   18428       return;
   18429     }
   18430   } else {
   18431     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
   18432     if (dt.IsNoneOr(Untyped64) &&
   18433         ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   18434           ((offset & 0x3) == 0)) ||
   18435          !label->IsBound()) &&
   18436         cond.IsNotNever()) {
   18437       static class EmitOp : public Label::LabelEmitOperator {
   18438        public:
   18439         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
   18440         virtual uint32_t Encode(uint32_t instr,
   18441                                 Label::Offset pc,
   18442                                 const Label* label) const VIXL_OVERRIDE {
   18443           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   18444           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   18445                       ((offset & 0x3) == 0));
   18446           int32_t target = offset >> 2;
   18447           uint32_t U = (target >= 0) && !label->IsMinusZero();
   18448           target = abs(target) | (U << 8);
   18449           return instr | (target & 0xff) | ((target & 0x100) << 15);
   18450         }
   18451       } immop;
   18452       EmitA32(
   18453           Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
   18454                label,
   18455                immop));
   18456       return;
   18457     }
   18458   }
   18459   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
   18460 }
   18461 
   18462 void Assembler::vldr(Condition cond,
   18463                      DataType dt,
   18464                      DRegister rd,
   18465                      const MemOperand& operand) {
   18466   VIXL_ASSERT(AllowAssembler());
   18467   CheckIT(cond);
   18468   if (operand.IsImmediate()) {
   18469     Register rn = operand.GetBaseRegister();
   18470     int32_t offset = operand.GetOffsetImmediate();
   18471     if (IsUsingT32()) {
   18472       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
   18473       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   18474           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
   18475         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   18476         uint32_t offset_ = abs(offset) >> 2;
   18477         EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
   18478         AdvanceIT();
   18479         return;
   18480       }
   18481       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
   18482       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   18483           ((offset % 4) == 0) && operand.IsOffset() &&
   18484           ((rn.GetCode() & 0xf) != 0xf)) {
   18485         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   18486         uint32_t offset_ = abs(offset) >> 2;
   18487         EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
   18488                    offset_ | (sign << 23));
   18489         AdvanceIT();
   18490         return;
   18491       }
   18492     } else {
   18493       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
   18494       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   18495           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
   18496           cond.IsNotNever()) {
   18497         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   18498         uint32_t offset_ = abs(offset) >> 2;
   18499         EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   18500                 offset_ | (sign << 23));
   18501         return;
   18502       }
   18503       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
   18504       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   18505           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
   18506           ((rn.GetCode() & 0xf) != 0xf)) {
   18507         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   18508         uint32_t offset_ = abs(offset) >> 2;
   18509         EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   18510                 (rn.GetCode() << 16) | offset_ | (sign << 23));
   18511         return;
   18512       }
   18513     }
   18514   }
   18515   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
   18516 }
   18517 
   18518 void Assembler::vldr(Condition cond, DataType dt, SRegister rd, Label* label) {
   18519   VIXL_ASSERT(AllowAssembler());
   18520   CheckIT(cond);
   18521   Label::Offset offset =
   18522       label->IsBound()
   18523           ? label->GetLocation() -
   18524                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   18525           : 0;
   18526   if (IsUsingT32()) {
   18527     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
   18528     if (dt.IsNoneOr(Untyped32) &&
   18529         ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   18530           ((offset & 0x3) == 0)) ||
   18531          !label->IsBound())) {
   18532       static class EmitOp : public Label::LabelEmitOperator {
   18533        public:
   18534         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
   18535         virtual uint32_t Encode(uint32_t instr,
   18536                                 Label::Offset pc,
   18537                                 const Label* label) const VIXL_OVERRIDE {
   18538           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   18539           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   18540                       ((offset & 0x3) == 0));
   18541           int32_t target = offset >> 2;
   18542           uint32_t U = (target >= 0) && !label->IsMinusZero();
   18543           target = abs(target) | (U << 8);
   18544           return instr | (target & 0xff) | ((target & 0x100) << 15);
   18545         }
   18546       } immop;
   18547       EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12), label, immop));
   18548       AdvanceIT();
   18549       return;
   18550     }
   18551   } else {
   18552     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
   18553     if (dt.IsNoneOr(Untyped32) &&
   18554         ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   18555           ((offset & 0x3) == 0)) ||
   18556          !label->IsBound()) &&
   18557         cond.IsNotNever()) {
   18558       static class EmitOp : public Label::LabelEmitOperator {
   18559        public:
   18560         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
   18561         virtual uint32_t Encode(uint32_t instr,
   18562                                 Label::Offset pc,
   18563                                 const Label* label) const VIXL_OVERRIDE {
   18564           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
   18565           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   18566                       ((offset & 0x3) == 0));
   18567           int32_t target = offset >> 2;
   18568           uint32_t U = (target >= 0) && !label->IsMinusZero();
   18569           target = abs(target) | (U << 8);
   18570           return instr | (target & 0xff) | ((target & 0x100) << 15);
   18571         }
   18572       } immop;
   18573       EmitA32(
   18574           Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
   18575                label,
   18576                immop));
   18577       return;
   18578     }
   18579   }
   18580   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
   18581 }
   18582 
   18583 void Assembler::vldr(Condition cond,
   18584                      DataType dt,
   18585                      SRegister rd,
   18586                      const MemOperand& operand) {
   18587   VIXL_ASSERT(AllowAssembler());
   18588   CheckIT(cond);
   18589   if (operand.IsImmediate()) {
   18590     Register rn = operand.GetBaseRegister();
   18591     int32_t offset = operand.GetOffsetImmediate();
   18592     if (IsUsingT32()) {
   18593       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
   18594       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   18595           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
   18596         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   18597         uint32_t offset_ = abs(offset) >> 2;
   18598         EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
   18599         AdvanceIT();
   18600         return;
   18601       }
   18602       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
   18603       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   18604           ((offset % 4) == 0) && operand.IsOffset() &&
   18605           ((rn.GetCode() & 0xf) != 0xf)) {
   18606         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   18607         uint32_t offset_ = abs(offset) >> 2;
   18608         EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
   18609                    offset_ | (sign << 23));
   18610         AdvanceIT();
   18611         return;
   18612       }
   18613     } else {
   18614       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
   18615       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   18616           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
   18617           cond.IsNotNever()) {
   18618         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   18619         uint32_t offset_ = abs(offset) >> 2;
   18620         EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   18621                 offset_ | (sign << 23));
   18622         return;
   18623       }
   18624       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
   18625       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   18626           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
   18627           ((rn.GetCode() & 0xf) != 0xf)) {
   18628         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   18629         uint32_t offset_ = abs(offset) >> 2;
   18630         EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   18631                 (rn.GetCode() << 16) | offset_ | (sign << 23));
   18632         return;
   18633       }
   18634     }
   18635   }
   18636   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
   18637 }
   18638 
   18639 void Assembler::vmax(
   18640     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   18641   VIXL_ASSERT(AllowAssembler());
   18642   CheckIT(cond);
   18643   Dt_U_size_1 encoded_dt(dt);
   18644   if (IsUsingT32()) {
   18645     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   18646     if (dt.Is(F32)) {
   18647       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18648         EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18649                    rm.Encode(5, 0));
   18650         AdvanceIT();
   18651         return;
   18652       }
   18653     }
   18654     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   18655     if (encoded_dt.IsValid()) {
   18656       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18657         EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   18658                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   18659                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   18660         AdvanceIT();
   18661         return;
   18662       }
   18663     }
   18664   } else {
   18665     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   18666     if (dt.Is(F32)) {
   18667       if (cond.Is(al)) {
   18668         EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18669                 rm.Encode(5, 0));
   18670         return;
   18671       }
   18672     }
   18673     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   18674     if (encoded_dt.IsValid()) {
   18675       if (cond.Is(al)) {
   18676         EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   18677                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   18678                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   18679         return;
   18680       }
   18681     }
   18682   }
   18683   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
   18684 }
   18685 
   18686 void Assembler::vmax(
   18687     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   18688   VIXL_ASSERT(AllowAssembler());
   18689   CheckIT(cond);
   18690   Dt_U_size_1 encoded_dt(dt);
   18691   if (IsUsingT32()) {
   18692     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   18693     if (dt.Is(F32)) {
   18694       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18695         EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18696                    rm.Encode(5, 0));
   18697         AdvanceIT();
   18698         return;
   18699       }
   18700     }
   18701     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   18702     if (encoded_dt.IsValid()) {
   18703       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18704         EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   18705                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   18706                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   18707         AdvanceIT();
   18708         return;
   18709       }
   18710     }
   18711   } else {
   18712     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   18713     if (dt.Is(F32)) {
   18714       if (cond.Is(al)) {
   18715         EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18716                 rm.Encode(5, 0));
   18717         return;
   18718       }
   18719     }
   18720     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   18721     if (encoded_dt.IsValid()) {
   18722       if (cond.Is(al)) {
   18723         EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   18724                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   18725                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   18726         return;
   18727       }
   18728     }
   18729   }
   18730   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
   18731 }
   18732 
   18733 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   18734   VIXL_ASSERT(AllowAssembler());
   18735   CheckIT(al);
   18736   if (IsUsingT32()) {
   18737     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   18738     if (OutsideITBlock() && dt.Is(F32)) {
   18739       EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18740                  rm.Encode(5, 0));
   18741       AdvanceIT();
   18742       return;
   18743     }
   18744     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   18745     if (OutsideITBlock() && dt.Is(F64)) {
   18746       EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18747                  rm.Encode(5, 0));
   18748       AdvanceIT();
   18749       return;
   18750     }
   18751   } else {
   18752     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   18753     if (dt.Is(F32)) {
   18754       EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18755               rm.Encode(5, 0));
   18756       return;
   18757     }
   18758     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   18759     if (dt.Is(F64)) {
   18760       EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18761               rm.Encode(5, 0));
   18762       return;
   18763     }
   18764   }
   18765   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
   18766 }
   18767 
   18768 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   18769   VIXL_ASSERT(AllowAssembler());
   18770   CheckIT(al);
   18771   if (IsUsingT32()) {
   18772     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   18773     if (OutsideITBlock() && dt.Is(F32)) {
   18774       EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18775                  rm.Encode(5, 0));
   18776       AdvanceIT();
   18777       return;
   18778     }
   18779   } else {
   18780     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   18781     if (dt.Is(F32)) {
   18782       EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18783               rm.Encode(5, 0));
   18784       return;
   18785     }
   18786   }
   18787   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
   18788 }
   18789 
   18790 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   18791   VIXL_ASSERT(AllowAssembler());
   18792   CheckIT(al);
   18793   if (IsUsingT32()) {
   18794     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   18795     if (OutsideITBlock() && dt.Is(F32)) {
   18796       EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18797                  rm.Encode(5, 0));
   18798       AdvanceIT();
   18799       return;
   18800     }
   18801   } else {
   18802     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   18803     if (dt.Is(F32)) {
   18804       EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18805               rm.Encode(5, 0));
   18806       return;
   18807     }
   18808   }
   18809   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
   18810 }
   18811 
   18812 void Assembler::vmin(
   18813     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   18814   VIXL_ASSERT(AllowAssembler());
   18815   CheckIT(cond);
   18816   Dt_U_size_1 encoded_dt(dt);
   18817   if (IsUsingT32()) {
   18818     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   18819     if (dt.Is(F32)) {
   18820       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18821         EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18822                    rm.Encode(5, 0));
   18823         AdvanceIT();
   18824         return;
   18825       }
   18826     }
   18827     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   18828     if (encoded_dt.IsValid()) {
   18829       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18830         EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   18831                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   18832                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   18833         AdvanceIT();
   18834         return;
   18835       }
   18836     }
   18837   } else {
   18838     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   18839     if (dt.Is(F32)) {
   18840       if (cond.Is(al)) {
   18841         EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18842                 rm.Encode(5, 0));
   18843         return;
   18844       }
   18845     }
   18846     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   18847     if (encoded_dt.IsValid()) {
   18848       if (cond.Is(al)) {
   18849         EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   18850                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   18851                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   18852         return;
   18853       }
   18854     }
   18855   }
   18856   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
   18857 }
   18858 
   18859 void Assembler::vmin(
   18860     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   18861   VIXL_ASSERT(AllowAssembler());
   18862   CheckIT(cond);
   18863   Dt_U_size_1 encoded_dt(dt);
   18864   if (IsUsingT32()) {
   18865     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   18866     if (dt.Is(F32)) {
   18867       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18868         EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18869                    rm.Encode(5, 0));
   18870         AdvanceIT();
   18871         return;
   18872       }
   18873     }
   18874     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   18875     if (encoded_dt.IsValid()) {
   18876       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18877         EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   18878                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   18879                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   18880         AdvanceIT();
   18881         return;
   18882       }
   18883     }
   18884   } else {
   18885     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   18886     if (dt.Is(F32)) {
   18887       if (cond.Is(al)) {
   18888         EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18889                 rm.Encode(5, 0));
   18890         return;
   18891       }
   18892     }
   18893     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   18894     if (encoded_dt.IsValid()) {
   18895       if (cond.Is(al)) {
   18896         EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   18897                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   18898                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   18899         return;
   18900       }
   18901     }
   18902   }
   18903   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
   18904 }
   18905 
   18906 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   18907   VIXL_ASSERT(AllowAssembler());
   18908   CheckIT(al);
   18909   if (IsUsingT32()) {
   18910     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   18911     if (OutsideITBlock() && dt.Is(F32)) {
   18912       EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18913                  rm.Encode(5, 0));
   18914       AdvanceIT();
   18915       return;
   18916     }
   18917     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   18918     if (OutsideITBlock() && dt.Is(F64)) {
   18919       EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18920                  rm.Encode(5, 0));
   18921       AdvanceIT();
   18922       return;
   18923     }
   18924   } else {
   18925     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   18926     if (dt.Is(F32)) {
   18927       EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18928               rm.Encode(5, 0));
   18929       return;
   18930     }
   18931     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   18932     if (dt.Is(F64)) {
   18933       EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18934               rm.Encode(5, 0));
   18935       return;
   18936     }
   18937   }
   18938   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
   18939 }
   18940 
   18941 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   18942   VIXL_ASSERT(AllowAssembler());
   18943   CheckIT(al);
   18944   if (IsUsingT32()) {
   18945     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   18946     if (OutsideITBlock() && dt.Is(F32)) {
   18947       EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18948                  rm.Encode(5, 0));
   18949       AdvanceIT();
   18950       return;
   18951     }
   18952   } else {
   18953     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   18954     if (dt.Is(F32)) {
   18955       EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18956               rm.Encode(5, 0));
   18957       return;
   18958     }
   18959   }
   18960   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
   18961 }
   18962 
   18963 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   18964   VIXL_ASSERT(AllowAssembler());
   18965   CheckIT(al);
   18966   if (IsUsingT32()) {
   18967     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   18968     if (OutsideITBlock() && dt.Is(F32)) {
   18969       EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18970                  rm.Encode(5, 0));
   18971       AdvanceIT();
   18972       return;
   18973     }
   18974   } else {
   18975     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   18976     if (dt.Is(F32)) {
   18977       EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   18978               rm.Encode(5, 0));
   18979       return;
   18980     }
   18981   }
   18982   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
   18983 }
   18984 
   18985 void Assembler::vmla(
   18986     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
   18987   VIXL_ASSERT(AllowAssembler());
   18988   CheckIT(cond);
   18989   Dt_size_9 encoded_dt(dt);
   18990   if (IsUsingT32()) {
   18991     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
   18992     if (encoded_dt.IsValid() &&
   18993         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   18994          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   18995           (rm.GetLane() <= 1)))) {
   18996       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18997         EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
   18998                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   18999                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19000         AdvanceIT();
   19001         return;
   19002       }
   19003     }
   19004   } else {
   19005     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
   19006     if (encoded_dt.IsValid() &&
   19007         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19008          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19009           (rm.GetLane() <= 1)))) {
   19010       if (cond.Is(al)) {
   19011         EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
   19012                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19013                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19014         return;
   19015       }
   19016     }
   19017   }
   19018   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   19019 }
   19020 
   19021 void Assembler::vmla(
   19022     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
   19023   VIXL_ASSERT(AllowAssembler());
   19024   CheckIT(cond);
   19025   Dt_size_9 encoded_dt(dt);
   19026   if (IsUsingT32()) {
   19027     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
   19028     if (encoded_dt.IsValid() &&
   19029         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19030          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19031           (rm.GetLane() <= 1)))) {
   19032       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19033         EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
   19034                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19035                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19036         AdvanceIT();
   19037         return;
   19038       }
   19039     }
   19040   } else {
   19041     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
   19042     if (encoded_dt.IsValid() &&
   19043         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19044          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19045           (rm.GetLane() <= 1)))) {
   19046       if (cond.Is(al)) {
   19047         EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
   19048                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19049                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19050         return;
   19051       }
   19052     }
   19053   }
   19054   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   19055 }
   19056 
   19057 void Assembler::vmla(
   19058     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   19059   VIXL_ASSERT(AllowAssembler());
   19060   CheckIT(cond);
   19061   Dt_size_10 encoded_dt(dt);
   19062   if (IsUsingT32()) {
   19063     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   19064     if (dt.Is(F32)) {
   19065       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19066         EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19067                    rm.Encode(5, 0));
   19068         AdvanceIT();
   19069         return;
   19070       }
   19071     }
   19072     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   19073     if (dt.Is(F64)) {
   19074       EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19075                  rm.Encode(5, 0));
   19076       AdvanceIT();
   19077       return;
   19078     }
   19079     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
   19080     if (encoded_dt.IsValid()) {
   19081       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19082         EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
   19083                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19084         AdvanceIT();
   19085         return;
   19086       }
   19087     }
   19088   } else {
   19089     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   19090     if (dt.Is(F32)) {
   19091       if (cond.Is(al)) {
   19092         EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19093                 rm.Encode(5, 0));
   19094         return;
   19095       }
   19096     }
   19097     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   19098     if (dt.Is(F64) && cond.IsNotNever()) {
   19099       EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19100               rn.Encode(7, 16) | rm.Encode(5, 0));
   19101       return;
   19102     }
   19103     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
   19104     if (encoded_dt.IsValid()) {
   19105       if (cond.Is(al)) {
   19106         EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
   19107                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19108         return;
   19109       }
   19110     }
   19111   }
   19112   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   19113 }
   19114 
   19115 void Assembler::vmla(
   19116     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   19117   VIXL_ASSERT(AllowAssembler());
   19118   CheckIT(cond);
   19119   Dt_size_10 encoded_dt(dt);
   19120   if (IsUsingT32()) {
   19121     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   19122     if (dt.Is(F32)) {
   19123       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19124         EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19125                    rm.Encode(5, 0));
   19126         AdvanceIT();
   19127         return;
   19128       }
   19129     }
   19130     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
   19131     if (encoded_dt.IsValid()) {
   19132       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19133         EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
   19134                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19135         AdvanceIT();
   19136         return;
   19137       }
   19138     }
   19139   } else {
   19140     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   19141     if (dt.Is(F32)) {
   19142       if (cond.Is(al)) {
   19143         EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19144                 rm.Encode(5, 0));
   19145         return;
   19146       }
   19147     }
   19148     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
   19149     if (encoded_dt.IsValid()) {
   19150       if (cond.Is(al)) {
   19151         EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
   19152                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19153         return;
   19154       }
   19155     }
   19156   }
   19157   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   19158 }
   19159 
   19160 void Assembler::vmla(
   19161     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   19162   VIXL_ASSERT(AllowAssembler());
   19163   CheckIT(cond);
   19164   if (IsUsingT32()) {
   19165     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   19166     if (dt.Is(F32)) {
   19167       EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19168                  rm.Encode(5, 0));
   19169       AdvanceIT();
   19170       return;
   19171     }
   19172   } else {
   19173     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   19174     if (dt.Is(F32) && cond.IsNotNever()) {
   19175       EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19176               rn.Encode(7, 16) | rm.Encode(5, 0));
   19177       return;
   19178     }
   19179   }
   19180   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   19181 }
   19182 
   19183 void Assembler::vmlal(
   19184     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
   19185   VIXL_ASSERT(AllowAssembler());
   19186   CheckIT(cond);
   19187   Dt_size_11 encoded_dt(dt);
   19188   if (IsUsingT32()) {
   19189     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
   19190     if (encoded_dt.IsValid() &&
   19191         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19192          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19193           (rm.GetLane() <= 1)))) {
   19194       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19195         EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
   19196                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19197                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19198         AdvanceIT();
   19199         return;
   19200       }
   19201     }
   19202   } else {
   19203     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
   19204     if (encoded_dt.IsValid() &&
   19205         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19206          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19207           (rm.GetLane() <= 1)))) {
   19208       if (cond.Is(al)) {
   19209         EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
   19210                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19211                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19212         return;
   19213       }
   19214     }
   19215   }
   19216   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
   19217 }
   19218 
   19219 void Assembler::vmlal(
   19220     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   19221   VIXL_ASSERT(AllowAssembler());
   19222   CheckIT(cond);
   19223   Dt_size_12 encoded_dt(dt);
   19224   if (IsUsingT32()) {
   19225     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
   19226     if (encoded_dt.IsValid()) {
   19227       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19228         EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
   19229                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19230                    rn.Encode(7, 16) | rm.Encode(5, 0));
   19231         AdvanceIT();
   19232         return;
   19233       }
   19234     }
   19235   } else {
   19236     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
   19237     if (encoded_dt.IsValid()) {
   19238       if (cond.Is(al)) {
   19239         EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
   19240                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19241                 rn.Encode(7, 16) | rm.Encode(5, 0));
   19242         return;
   19243       }
   19244     }
   19245   }
   19246   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
   19247 }
   19248 
   19249 void Assembler::vmls(
   19250     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
   19251   VIXL_ASSERT(AllowAssembler());
   19252   CheckIT(cond);
   19253   Dt_size_9 encoded_dt(dt);
   19254   if (IsUsingT32()) {
   19255     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
   19256     if (encoded_dt.IsValid() &&
   19257         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19258          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19259           (rm.GetLane() <= 1)))) {
   19260       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19261         EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
   19262                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19263                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19264         AdvanceIT();
   19265         return;
   19266       }
   19267     }
   19268   } else {
   19269     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
   19270     if (encoded_dt.IsValid() &&
   19271         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19272          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19273           (rm.GetLane() <= 1)))) {
   19274       if (cond.Is(al)) {
   19275         EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
   19276                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19277                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19278         return;
   19279       }
   19280     }
   19281   }
   19282   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   19283 }
   19284 
   19285 void Assembler::vmls(
   19286     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
   19287   VIXL_ASSERT(AllowAssembler());
   19288   CheckIT(cond);
   19289   Dt_size_9 encoded_dt(dt);
   19290   if (IsUsingT32()) {
   19291     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
   19292     if (encoded_dt.IsValid() &&
   19293         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19294          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19295           (rm.GetLane() <= 1)))) {
   19296       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19297         EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
   19298                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19299                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19300         AdvanceIT();
   19301         return;
   19302       }
   19303     }
   19304   } else {
   19305     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
   19306     if (encoded_dt.IsValid() &&
   19307         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19308          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19309           (rm.GetLane() <= 1)))) {
   19310       if (cond.Is(al)) {
   19311         EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
   19312                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19313                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19314         return;
   19315       }
   19316     }
   19317   }
   19318   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   19319 }
   19320 
   19321 void Assembler::vmls(
   19322     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   19323   VIXL_ASSERT(AllowAssembler());
   19324   CheckIT(cond);
   19325   Dt_size_10 encoded_dt(dt);
   19326   if (IsUsingT32()) {
   19327     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   19328     if (dt.Is(F32)) {
   19329       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19330         EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19331                    rm.Encode(5, 0));
   19332         AdvanceIT();
   19333         return;
   19334       }
   19335     }
   19336     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   19337     if (dt.Is(F64)) {
   19338       EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19339                  rm.Encode(5, 0));
   19340       AdvanceIT();
   19341       return;
   19342     }
   19343     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
   19344     if (encoded_dt.IsValid()) {
   19345       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19346         EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
   19347                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19348         AdvanceIT();
   19349         return;
   19350       }
   19351     }
   19352   } else {
   19353     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   19354     if (dt.Is(F32)) {
   19355       if (cond.Is(al)) {
   19356         EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19357                 rm.Encode(5, 0));
   19358         return;
   19359       }
   19360     }
   19361     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   19362     if (dt.Is(F64) && cond.IsNotNever()) {
   19363       EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19364               rn.Encode(7, 16) | rm.Encode(5, 0));
   19365       return;
   19366     }
   19367     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
   19368     if (encoded_dt.IsValid()) {
   19369       if (cond.Is(al)) {
   19370         EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
   19371                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19372         return;
   19373       }
   19374     }
   19375   }
   19376   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   19377 }
   19378 
   19379 void Assembler::vmls(
   19380     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   19381   VIXL_ASSERT(AllowAssembler());
   19382   CheckIT(cond);
   19383   Dt_size_10 encoded_dt(dt);
   19384   if (IsUsingT32()) {
   19385     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   19386     if (dt.Is(F32)) {
   19387       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19388         EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19389                    rm.Encode(5, 0));
   19390         AdvanceIT();
   19391         return;
   19392       }
   19393     }
   19394     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
   19395     if (encoded_dt.IsValid()) {
   19396       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19397         EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
   19398                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19399         AdvanceIT();
   19400         return;
   19401       }
   19402     }
   19403   } else {
   19404     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   19405     if (dt.Is(F32)) {
   19406       if (cond.Is(al)) {
   19407         EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19408                 rm.Encode(5, 0));
   19409         return;
   19410       }
   19411     }
   19412     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
   19413     if (encoded_dt.IsValid()) {
   19414       if (cond.Is(al)) {
   19415         EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
   19416                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19417         return;
   19418       }
   19419     }
   19420   }
   19421   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   19422 }
   19423 
   19424 void Assembler::vmls(
   19425     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   19426   VIXL_ASSERT(AllowAssembler());
   19427   CheckIT(cond);
   19428   if (IsUsingT32()) {
   19429     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   19430     if (dt.Is(F32)) {
   19431       EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19432                  rm.Encode(5, 0));
   19433       AdvanceIT();
   19434       return;
   19435     }
   19436   } else {
   19437     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   19438     if (dt.Is(F32) && cond.IsNotNever()) {
   19439       EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19440               rn.Encode(7, 16) | rm.Encode(5, 0));
   19441       return;
   19442     }
   19443   }
   19444   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   19445 }
   19446 
   19447 void Assembler::vmlsl(
   19448     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
   19449   VIXL_ASSERT(AllowAssembler());
   19450   CheckIT(cond);
   19451   Dt_size_11 encoded_dt(dt);
   19452   if (IsUsingT32()) {
   19453     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
   19454     if (encoded_dt.IsValid() &&
   19455         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19456          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19457           (rm.GetLane() <= 1)))) {
   19458       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19459         EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
   19460                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19461                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19462         AdvanceIT();
   19463         return;
   19464       }
   19465     }
   19466   } else {
   19467     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
   19468     if (encoded_dt.IsValid() &&
   19469         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   19470          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   19471           (rm.GetLane() <= 1)))) {
   19472       if (cond.Is(al)) {
   19473         EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
   19474                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19475                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   19476         return;
   19477       }
   19478     }
   19479   }
   19480   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
   19481 }
   19482 
   19483 void Assembler::vmlsl(
   19484     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   19485   VIXL_ASSERT(AllowAssembler());
   19486   CheckIT(cond);
   19487   Dt_size_12 encoded_dt(dt);
   19488   if (IsUsingT32()) {
   19489     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
   19490     if (encoded_dt.IsValid()) {
   19491       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19492         EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
   19493                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19494                    rn.Encode(7, 16) | rm.Encode(5, 0));
   19495         AdvanceIT();
   19496         return;
   19497       }
   19498     }
   19499   } else {
   19500     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
   19501     if (encoded_dt.IsValid()) {
   19502       if (cond.Is(al)) {
   19503         EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
   19504                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   19505                 rn.Encode(7, 16) | rm.Encode(5, 0));
   19506         return;
   19507       }
   19508     }
   19509   }
   19510   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
   19511 }
   19512 
   19513 void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
   19514   VIXL_ASSERT(AllowAssembler());
   19515   CheckIT(cond);
   19516   if (IsUsingT32()) {
   19517     // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
   19518     EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
   19519     AdvanceIT();
   19520     return;
   19521   } else {
   19522     // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
   19523     if (cond.IsNotNever()) {
   19524       EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
   19525               rn.Encode(7, 16));
   19526       return;
   19527     }
   19528   }
   19529   Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
   19530 }
   19531 
   19532 void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
   19533   VIXL_ASSERT(AllowAssembler());
   19534   CheckIT(cond);
   19535   if (IsUsingT32()) {
   19536     // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
   19537     EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
   19538     AdvanceIT();
   19539     return;
   19540   } else {
   19541     // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
   19542     if (cond.IsNotNever()) {
   19543       EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
   19544               (rt.GetCode() << 12));
   19545       return;
   19546     }
   19547   }
   19548   Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
   19549 }
   19550 
   19551 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
   19552   VIXL_ASSERT(AllowAssembler());
   19553   CheckIT(cond);
   19554   if (IsUsingT32()) {
   19555     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
   19556     EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
   19557                rm.Encode(5, 0));
   19558     AdvanceIT();
   19559     return;
   19560   } else {
   19561     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
   19562     if (cond.IsNotNever()) {
   19563       EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
   19564               (rt2.GetCode() << 16) | rm.Encode(5, 0));
   19565       return;
   19566     }
   19567   }
   19568   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
   19569 }
   19570 
   19571 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
   19572   VIXL_ASSERT(AllowAssembler());
   19573   CheckIT(cond);
   19574   if (IsUsingT32()) {
   19575     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
   19576     EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
   19577                (rt2.GetCode() << 16));
   19578     AdvanceIT();
   19579     return;
   19580   } else {
   19581     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
   19582     if (cond.IsNotNever()) {
   19583       EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
   19584               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
   19585       return;
   19586     }
   19587   }
   19588   Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
   19589 }
   19590 
   19591 void Assembler::vmov(
   19592     Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
   19593   VIXL_ASSERT(AllowAssembler());
   19594   CheckIT(cond);
   19595   if (IsUsingT32()) {
   19596     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
   19597     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
   19598       EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
   19599                  rm.Encode(5, 0));
   19600       AdvanceIT();
   19601       return;
   19602     }
   19603   } else {
   19604     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
   19605     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
   19606         cond.IsNotNever()) {
   19607       EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
   19608               (rt2.GetCode() << 16) | rm.Encode(5, 0));
   19609       return;
   19610     }
   19611   }
   19612   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
   19613 }
   19614 
   19615 void Assembler::vmov(
   19616     Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
   19617   VIXL_ASSERT(AllowAssembler());
   19618   CheckIT(cond);
   19619   if (IsUsingT32()) {
   19620     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
   19621     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
   19622       EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
   19623                  (rt2.GetCode() << 16));
   19624       AdvanceIT();
   19625       return;
   19626     }
   19627   } else {
   19628     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
   19629     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
   19630         cond.IsNotNever()) {
   19631       EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
   19632               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
   19633       return;
   19634     }
   19635   }
   19636   Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
   19637 }
   19638 
   19639 void Assembler::vmov(Condition cond,
   19640                      DataType dt,
   19641                      DRegisterLane rd,
   19642                      Register rt) {
   19643   VIXL_ASSERT(AllowAssembler());
   19644   CheckIT(cond);
   19645   Dt_opc1_opc2_1 encoded_dt(dt, rd);
   19646   if (IsUsingT32()) {
   19647     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
   19648     if (encoded_dt.IsValid()) {
   19649       EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
   19650                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
   19651                  rd.Encode(7, 16) | (rt.GetCode() << 12));
   19652       AdvanceIT();
   19653       return;
   19654     }
   19655   } else {
   19656     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
   19657     if (encoded_dt.IsValid() && cond.IsNotNever()) {
   19658       EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
   19659               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
   19660               ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
   19661               (rt.GetCode() << 12));
   19662       return;
   19663     }
   19664   }
   19665   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
   19666 }
   19667 
   19668 void Assembler::vmov(Condition cond,
   19669                      DataType dt,
   19670                      DRegister rd,
   19671                      const DOperand& operand) {
   19672   VIXL_ASSERT(AllowAssembler());
   19673   CheckIT(cond);
   19674   if (operand.IsImmediate()) {
   19675     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
   19676     ImmediateVFP vfp(operand.GetNeonImmediate());
   19677     if (IsUsingT32()) {
   19678       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
   19679       if (encoded_dt.IsValid()) {
   19680         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19681           EmitT32_32(
   19682               0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
   19683               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
   19684               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   19685               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   19686               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   19687           AdvanceIT();
   19688           return;
   19689         }
   19690       }
   19691       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
   19692       if (dt.Is(F64) && vfp.IsValid()) {
   19693         EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
   19694                    (vfp.GetEncodingValue() & 0xf) |
   19695                    ((vfp.GetEncodingValue() & 0xf0) << 12));
   19696         AdvanceIT();
   19697         return;
   19698       }
   19699     } else {
   19700       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
   19701       if (encoded_dt.IsValid()) {
   19702         if (cond.Is(al)) {
   19703           EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
   19704                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
   19705                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   19706                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   19707                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   19708           return;
   19709         }
   19710       }
   19711       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
   19712       if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
   19713         EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19714                 (vfp.GetEncodingValue() & 0xf) |
   19715                 ((vfp.GetEncodingValue() & 0xf0) << 12));
   19716         return;
   19717       }
   19718     }
   19719   }
   19720   if (operand.IsRegister()) {
   19721     DRegister rm = operand.GetRegister();
   19722     if (IsUsingT32()) {
   19723       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
   19724       if (dt.Is(F64)) {
   19725         EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   19726         AdvanceIT();
   19727         return;
   19728       }
   19729       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
   19730       if (!dt.Is(F64)) {
   19731         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19732           EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   19733                      rm.Encode(5, 0));
   19734           AdvanceIT();
   19735           return;
   19736         }
   19737       }
   19738     } else {
   19739       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
   19740       if (dt.Is(F64) && cond.IsNotNever()) {
   19741         EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19742                 rm.Encode(5, 0));
   19743         return;
   19744       }
   19745       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
   19746       if (!dt.Is(F64)) {
   19747         if (cond.Is(al)) {
   19748           EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   19749                   rm.Encode(5, 0));
   19750           return;
   19751         }
   19752       }
   19753     }
   19754   }
   19755   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
   19756 }
   19757 
   19758 void Assembler::vmov(Condition cond,
   19759                      DataType dt,
   19760                      QRegister rd,
   19761                      const QOperand& operand) {
   19762   VIXL_ASSERT(AllowAssembler());
   19763   CheckIT(cond);
   19764   if (operand.IsImmediate()) {
   19765     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
   19766     if (IsUsingT32()) {
   19767       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
   19768       if (encoded_dt.IsValid()) {
   19769         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19770           EmitT32_32(
   19771               0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
   19772               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
   19773               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   19774               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   19775               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   19776           AdvanceIT();
   19777           return;
   19778         }
   19779       }
   19780     } else {
   19781       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
   19782       if (encoded_dt.IsValid()) {
   19783         if (cond.Is(al)) {
   19784           EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
   19785                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
   19786                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   19787                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   19788                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   19789           return;
   19790         }
   19791       }
   19792     }
   19793   }
   19794   if (operand.IsRegister()) {
   19795     QRegister rm = operand.GetRegister();
   19796     if (IsUsingT32()) {
   19797       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
   19798       if (!dt.Is(F64)) {
   19799         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19800           EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   19801                      rm.Encode(5, 0));
   19802           AdvanceIT();
   19803           return;
   19804         }
   19805       }
   19806     } else {
   19807       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
   19808       if (!dt.Is(F64)) {
   19809         if (cond.Is(al)) {
   19810           EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   19811                   rm.Encode(5, 0));
   19812           return;
   19813         }
   19814       }
   19815     }
   19816   }
   19817   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
   19818 }
   19819 
   19820 void Assembler::vmov(Condition cond,
   19821                      DataType dt,
   19822                      SRegister rd,
   19823                      const SOperand& operand) {
   19824   VIXL_ASSERT(AllowAssembler());
   19825   CheckIT(cond);
   19826   if (operand.IsImmediate()) {
   19827     ImmediateVFP vfp(operand.GetNeonImmediate());
   19828     if (IsUsingT32()) {
   19829       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
   19830       if (dt.Is(F32) && vfp.IsValid()) {
   19831         EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
   19832                    (vfp.GetEncodingValue() & 0xf) |
   19833                    ((vfp.GetEncodingValue() & 0xf0) << 12));
   19834         AdvanceIT();
   19835         return;
   19836       }
   19837     } else {
   19838       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
   19839       if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
   19840         EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19841                 (vfp.GetEncodingValue() & 0xf) |
   19842                 ((vfp.GetEncodingValue() & 0xf0) << 12));
   19843         return;
   19844       }
   19845     }
   19846   }
   19847   if (operand.IsRegister()) {
   19848     SRegister rm = operand.GetRegister();
   19849     if (IsUsingT32()) {
   19850       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
   19851       if (dt.Is(F32)) {
   19852         EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   19853         AdvanceIT();
   19854         return;
   19855       }
   19856     } else {
   19857       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
   19858       if (dt.Is(F32) && cond.IsNotNever()) {
   19859         EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19860                 rm.Encode(5, 0));
   19861         return;
   19862       }
   19863     }
   19864   }
   19865   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
   19866 }
   19867 
   19868 void Assembler::vmov(Condition cond,
   19869                      DataType dt,
   19870                      Register rt,
   19871                      DRegisterLane rn) {
   19872   VIXL_ASSERT(AllowAssembler());
   19873   CheckIT(cond);
   19874   Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
   19875   if (IsUsingT32()) {
   19876     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
   19877     if (encoded_dt.IsValid()) {
   19878       EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
   19879                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
   19880                  ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
   19881                  (rt.GetCode() << 12) | rn.Encode(7, 16));
   19882       AdvanceIT();
   19883       return;
   19884     }
   19885   } else {
   19886     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
   19887     if (encoded_dt.IsValid() && cond.IsNotNever()) {
   19888       EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
   19889               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
   19890               ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
   19891               ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
   19892               (rt.GetCode() << 12) | rn.Encode(7, 16));
   19893       return;
   19894     }
   19895   }
   19896   Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
   19897 }
   19898 
   19899 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
   19900   VIXL_ASSERT(AllowAssembler());
   19901   CheckIT(cond);
   19902   Dt_U_imm3H_1 encoded_dt(dt);
   19903   if (IsUsingT32()) {
   19904     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
   19905     if (encoded_dt.IsValid()) {
   19906       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19907         EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   19908                    ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
   19909                    rd.Encode(22, 12) | rm.Encode(5, 0));
   19910         AdvanceIT();
   19911         return;
   19912       }
   19913     }
   19914   } else {
   19915     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
   19916     if (encoded_dt.IsValid()) {
   19917       if (cond.Is(al)) {
   19918         EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   19919                 ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
   19920                 rd.Encode(22, 12) | rm.Encode(5, 0));
   19921         return;
   19922       }
   19923     }
   19924   }
   19925   Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
   19926 }
   19927 
   19928 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
   19929   VIXL_ASSERT(AllowAssembler());
   19930   CheckIT(cond);
   19931   Dt_size_3 encoded_dt(dt);
   19932   if (IsUsingT32()) {
   19933     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
   19934     if (encoded_dt.IsValid()) {
   19935       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19936         EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
   19937                    rd.Encode(22, 12) | rm.Encode(5, 0));
   19938         AdvanceIT();
   19939         return;
   19940       }
   19941     }
   19942   } else {
   19943     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
   19944     if (encoded_dt.IsValid()) {
   19945       if (cond.Is(al)) {
   19946         EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
   19947                 rd.Encode(22, 12) | rm.Encode(5, 0));
   19948         return;
   19949       }
   19950     }
   19951   }
   19952   Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
   19953 }
   19954 
   19955 void Assembler::vmrs(Condition cond,
   19956                      RegisterOrAPSR_nzcv rt,
   19957                      SpecialFPRegister spec_reg) {
   19958   VIXL_ASSERT(AllowAssembler());
   19959   CheckIT(cond);
   19960   if (IsUsingT32()) {
   19961     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
   19962     EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
   19963     AdvanceIT();
   19964     return;
   19965   } else {
   19966     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
   19967     if (cond.IsNotNever()) {
   19968       EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
   19969               (spec_reg.GetReg() << 16));
   19970       return;
   19971     }
   19972   }
   19973   Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
   19974 }
   19975 
   19976 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
   19977   VIXL_ASSERT(AllowAssembler());
   19978   CheckIT(cond);
   19979   if (IsUsingT32()) {
   19980     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
   19981     EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
   19982     AdvanceIT();
   19983     return;
   19984   } else {
   19985     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
   19986     if (cond.IsNotNever()) {
   19987       EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
   19988               (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
   19989       return;
   19990     }
   19991   }
   19992   Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
   19993 }
   19994 
   19995 void Assembler::vmul(Condition cond,
   19996                      DataType dt,
   19997                      DRegister rd,
   19998                      DRegister rn,
   19999                      DRegister dm,
   20000                      unsigned index) {
   20001   VIXL_ASSERT(AllowAssembler());
   20002   CheckIT(cond);
   20003   Dt_F_size_3 encoded_dt(dt);
   20004   if (IsUsingT32()) {
   20005     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
   20006     if (encoded_dt.IsValid() &&
   20007         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   20008          (!dt.Is(I16) && (index <= 1)))) {
   20009       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20010         uint32_t shift = 4;
   20011         if (dt.Is(I16)) {
   20012           shift = 3;
   20013         }
   20014         uint32_t mvm = dm.GetCode() | index << shift;
   20015         EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20016                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   20017                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   20018                    ((mvm & 0x10) << 1));
   20019         AdvanceIT();
   20020         return;
   20021       }
   20022     }
   20023   } else {
   20024     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
   20025     if (encoded_dt.IsValid() &&
   20026         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   20027          (!dt.Is(I16) && (index <= 1)))) {
   20028       if (cond.Is(al)) {
   20029         uint32_t shift = 4;
   20030         if (dt.Is(I16)) {
   20031           shift = 3;
   20032         }
   20033         uint32_t mvm = dm.GetCode() | index << shift;
   20034         EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20035                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   20036                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   20037                 ((mvm & 0x10) << 1));
   20038         return;
   20039       }
   20040     }
   20041   }
   20042   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
   20043 }
   20044 
   20045 void Assembler::vmul(Condition cond,
   20046                      DataType dt,
   20047                      QRegister rd,
   20048                      QRegister rn,
   20049                      DRegister dm,
   20050                      unsigned index) {
   20051   VIXL_ASSERT(AllowAssembler());
   20052   CheckIT(cond);
   20053   Dt_F_size_3 encoded_dt(dt);
   20054   if (IsUsingT32()) {
   20055     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
   20056     if (encoded_dt.IsValid() &&
   20057         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   20058          (!dt.Is(I16) && (index <= 1)))) {
   20059       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20060         uint32_t shift = 4;
   20061         if (dt.Is(I16)) {
   20062           shift = 3;
   20063         }
   20064         uint32_t mvm = dm.GetCode() | index << shift;
   20065         EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20066                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   20067                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   20068                    ((mvm & 0x10) << 1));
   20069         AdvanceIT();
   20070         return;
   20071       }
   20072     }
   20073   } else {
   20074     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
   20075     if (encoded_dt.IsValid() &&
   20076         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   20077          (!dt.Is(I16) && (index <= 1)))) {
   20078       if (cond.Is(al)) {
   20079         uint32_t shift = 4;
   20080         if (dt.Is(I16)) {
   20081           shift = 3;
   20082         }
   20083         uint32_t mvm = dm.GetCode() | index << shift;
   20084         EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20085                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   20086                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   20087                 ((mvm & 0x10) << 1));
   20088         return;
   20089       }
   20090     }
   20091   }
   20092   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
   20093 }
   20094 
   20095 void Assembler::vmul(
   20096     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20097   VIXL_ASSERT(AllowAssembler());
   20098   CheckIT(cond);
   20099   Dt_op_size_1 encoded_dt(dt);
   20100   if (IsUsingT32()) {
   20101     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   20102     if (dt.Is(F32)) {
   20103       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20104         EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20105                    rm.Encode(5, 0));
   20106         AdvanceIT();
   20107         return;
   20108       }
   20109     }
   20110     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
   20111     if (dt.Is(F64)) {
   20112       EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20113                  rm.Encode(5, 0));
   20114       AdvanceIT();
   20115       return;
   20116     }
   20117     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   20118     if (encoded_dt.IsValid()) {
   20119       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20120         EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20121                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   20122                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20123         AdvanceIT();
   20124         return;
   20125       }
   20126     }
   20127   } else {
   20128     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   20129     if (dt.Is(F32)) {
   20130       if (cond.Is(al)) {
   20131         EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20132                 rm.Encode(5, 0));
   20133         return;
   20134       }
   20135     }
   20136     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
   20137     if (dt.Is(F64) && cond.IsNotNever()) {
   20138       EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20139               rn.Encode(7, 16) | rm.Encode(5, 0));
   20140       return;
   20141     }
   20142     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   20143     if (encoded_dt.IsValid()) {
   20144       if (cond.Is(al)) {
   20145         EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20146                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   20147                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20148         return;
   20149       }
   20150     }
   20151   }
   20152   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
   20153 }
   20154 
   20155 void Assembler::vmul(
   20156     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   20157   VIXL_ASSERT(AllowAssembler());
   20158   CheckIT(cond);
   20159   Dt_op_size_1 encoded_dt(dt);
   20160   if (IsUsingT32()) {
   20161     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   20162     if (dt.Is(F32)) {
   20163       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20164         EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20165                    rm.Encode(5, 0));
   20166         AdvanceIT();
   20167         return;
   20168       }
   20169     }
   20170     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   20171     if (encoded_dt.IsValid()) {
   20172       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20173         EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20174                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   20175                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20176         AdvanceIT();
   20177         return;
   20178       }
   20179     }
   20180   } else {
   20181     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   20182     if (dt.Is(F32)) {
   20183       if (cond.Is(al)) {
   20184         EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20185                 rm.Encode(5, 0));
   20186         return;
   20187       }
   20188     }
   20189     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   20190     if (encoded_dt.IsValid()) {
   20191       if (cond.Is(al)) {
   20192         EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20193                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   20194                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20195         return;
   20196       }
   20197     }
   20198   }
   20199   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
   20200 }
   20201 
   20202 void Assembler::vmul(
   20203     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   20204   VIXL_ASSERT(AllowAssembler());
   20205   CheckIT(cond);
   20206   if (IsUsingT32()) {
   20207     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
   20208     if (dt.Is(F32)) {
   20209       EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20210                  rm.Encode(5, 0));
   20211       AdvanceIT();
   20212       return;
   20213     }
   20214   } else {
   20215     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
   20216     if (dt.Is(F32) && cond.IsNotNever()) {
   20217       EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20218               rn.Encode(7, 16) | rm.Encode(5, 0));
   20219       return;
   20220     }
   20221   }
   20222   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
   20223 }
   20224 
   20225 void Assembler::vmull(Condition cond,
   20226                       DataType dt,
   20227                       QRegister rd,
   20228                       DRegister rn,
   20229                       DRegister dm,
   20230                       unsigned index) {
   20231   VIXL_ASSERT(AllowAssembler());
   20232   CheckIT(cond);
   20233   Dt_U_size_2 encoded_dt(dt);
   20234   if (IsUsingT32()) {
   20235     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
   20236     if (encoded_dt.IsValid() &&
   20237         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
   20238          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
   20239       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20240         uint32_t shift = 4;
   20241         if (dt.Is(S16) || dt.Is(U16)) {
   20242           shift = 3;
   20243         }
   20244         uint32_t mvm = dm.GetCode() | index << shift;
   20245         EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20246                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   20247                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   20248                    ((mvm & 0x10) << 1));
   20249         AdvanceIT();
   20250         return;
   20251       }
   20252     }
   20253   } else {
   20254     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
   20255     if (encoded_dt.IsValid() &&
   20256         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
   20257          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
   20258       if (cond.Is(al)) {
   20259         uint32_t shift = 4;
   20260         if (dt.Is(S16) || dt.Is(U16)) {
   20261           shift = 3;
   20262         }
   20263         uint32_t mvm = dm.GetCode() | index << shift;
   20264         EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20265                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   20266                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   20267                 ((mvm & 0x10) << 1));
   20268         return;
   20269       }
   20270     }
   20271   }
   20272   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
   20273 }
   20274 
   20275 void Assembler::vmull(
   20276     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   20277   VIXL_ASSERT(AllowAssembler());
   20278   CheckIT(cond);
   20279   Dt_op_U_size_1 encoded_dt(dt);
   20280   if (IsUsingT32()) {
   20281     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   20282     if (encoded_dt.IsValid()) {
   20283       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20284         EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20285                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   20286                    ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
   20287                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20288         AdvanceIT();
   20289         return;
   20290       }
   20291     }
   20292   } else {
   20293     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   20294     if (encoded_dt.IsValid()) {
   20295       if (cond.Is(al)) {
   20296         EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20297                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   20298                 ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
   20299                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20300         return;
   20301       }
   20302     }
   20303   }
   20304   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
   20305 }
   20306 
   20307 void Assembler::vmvn(Condition cond,
   20308                      DataType dt,
   20309                      DRegister rd,
   20310                      const DOperand& operand) {
   20311   VIXL_ASSERT(AllowAssembler());
   20312   CheckIT(cond);
   20313   if (operand.IsImmediate()) {
   20314     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
   20315     if (IsUsingT32()) {
   20316       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
   20317       if (encoded_dt.IsValid()) {
   20318         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20319           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
   20320                      rd.Encode(22, 12) |
   20321                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   20322                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20323                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   20324           AdvanceIT();
   20325           return;
   20326         }
   20327       }
   20328     } else {
   20329       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
   20330       if (encoded_dt.IsValid()) {
   20331         if (cond.Is(al)) {
   20332           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
   20333                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   20334                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20335                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   20336           return;
   20337         }
   20338       }
   20339     }
   20340   }
   20341   if (operand.IsRegister()) {
   20342     DRegister rm = operand.GetRegister();
   20343     USE(dt);
   20344     if (IsUsingT32()) {
   20345       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
   20346       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20347         EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
   20348         AdvanceIT();
   20349         return;
   20350       }
   20351     } else {
   20352       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
   20353       if (cond.Is(al)) {
   20354         EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
   20355         return;
   20356       }
   20357     }
   20358   }
   20359   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
   20360 }
   20361 
   20362 void Assembler::vmvn(Condition cond,
   20363                      DataType dt,
   20364                      QRegister rd,
   20365                      const QOperand& operand) {
   20366   VIXL_ASSERT(AllowAssembler());
   20367   CheckIT(cond);
   20368   if (operand.IsImmediate()) {
   20369     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
   20370     if (IsUsingT32()) {
   20371       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
   20372       if (encoded_dt.IsValid()) {
   20373         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20374           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
   20375                      rd.Encode(22, 12) |
   20376                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   20377                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20378                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   20379           AdvanceIT();
   20380           return;
   20381         }
   20382       }
   20383     } else {
   20384       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
   20385       if (encoded_dt.IsValid()) {
   20386         if (cond.Is(al)) {
   20387           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
   20388                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   20389                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20390                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   20391           return;
   20392         }
   20393       }
   20394     }
   20395   }
   20396   if (operand.IsRegister()) {
   20397     QRegister rm = operand.GetRegister();
   20398     USE(dt);
   20399     if (IsUsingT32()) {
   20400       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
   20401       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20402         EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   20403         AdvanceIT();
   20404         return;
   20405       }
   20406     } else {
   20407       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
   20408       if (cond.Is(al)) {
   20409         EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   20410         return;
   20411       }
   20412     }
   20413   }
   20414   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
   20415 }
   20416 
   20417 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   20418   VIXL_ASSERT(AllowAssembler());
   20419   CheckIT(cond);
   20420   Dt_F_size_1 encoded_dt(dt);
   20421   if (IsUsingT32()) {
   20422     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   20423     if (encoded_dt.IsValid()) {
   20424       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20425         EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20426                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   20427                    rd.Encode(22, 12) | rm.Encode(5, 0));
   20428         AdvanceIT();
   20429         return;
   20430       }
   20431     }
   20432     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
   20433     if (dt.Is(F64)) {
   20434       EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   20435       AdvanceIT();
   20436       return;
   20437     }
   20438   } else {
   20439     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   20440     if (encoded_dt.IsValid()) {
   20441       if (cond.Is(al)) {
   20442         EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20443                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   20444                 rd.Encode(22, 12) | rm.Encode(5, 0));
   20445         return;
   20446       }
   20447     }
   20448     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
   20449     if (dt.Is(F64) && cond.IsNotNever()) {
   20450       EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20451               rm.Encode(5, 0));
   20452       return;
   20453     }
   20454   }
   20455   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
   20456 }
   20457 
   20458 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   20459   VIXL_ASSERT(AllowAssembler());
   20460   CheckIT(cond);
   20461   Dt_F_size_1 encoded_dt(dt);
   20462   if (IsUsingT32()) {
   20463     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   20464     if (encoded_dt.IsValid()) {
   20465       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20466         EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20467                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   20468                    rd.Encode(22, 12) | rm.Encode(5, 0));
   20469         AdvanceIT();
   20470         return;
   20471       }
   20472     }
   20473   } else {
   20474     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   20475     if (encoded_dt.IsValid()) {
   20476       if (cond.Is(al)) {
   20477         EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20478                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   20479                 rd.Encode(22, 12) | rm.Encode(5, 0));
   20480         return;
   20481       }
   20482     }
   20483   }
   20484   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
   20485 }
   20486 
   20487 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
   20488   VIXL_ASSERT(AllowAssembler());
   20489   CheckIT(cond);
   20490   if (IsUsingT32()) {
   20491     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
   20492     if (dt.Is(F32)) {
   20493       EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   20494       AdvanceIT();
   20495       return;
   20496     }
   20497   } else {
   20498     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
   20499     if (dt.Is(F32) && cond.IsNotNever()) {
   20500       EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20501               rm.Encode(5, 0));
   20502       return;
   20503     }
   20504   }
   20505   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
   20506 }
   20507 
   20508 void Assembler::vnmla(
   20509     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   20510   VIXL_ASSERT(AllowAssembler());
   20511   CheckIT(cond);
   20512   if (IsUsingT32()) {
   20513     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
   20514     if (dt.Is(F32)) {
   20515       EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20516                  rm.Encode(5, 0));
   20517       AdvanceIT();
   20518       return;
   20519     }
   20520   } else {
   20521     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
   20522     if (dt.Is(F32) && cond.IsNotNever()) {
   20523       EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20524               rn.Encode(7, 16) | rm.Encode(5, 0));
   20525       return;
   20526     }
   20527   }
   20528   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
   20529 }
   20530 
   20531 void Assembler::vnmla(
   20532     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20533   VIXL_ASSERT(AllowAssembler());
   20534   CheckIT(cond);
   20535   if (IsUsingT32()) {
   20536     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
   20537     if (dt.Is(F64)) {
   20538       EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20539                  rm.Encode(5, 0));
   20540       AdvanceIT();
   20541       return;
   20542     }
   20543   } else {
   20544     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
   20545     if (dt.Is(F64) && cond.IsNotNever()) {
   20546       EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20547               rn.Encode(7, 16) | rm.Encode(5, 0));
   20548       return;
   20549     }
   20550   }
   20551   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
   20552 }
   20553 
   20554 void Assembler::vnmls(
   20555     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   20556   VIXL_ASSERT(AllowAssembler());
   20557   CheckIT(cond);
   20558   if (IsUsingT32()) {
   20559     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
   20560     if (dt.Is(F32)) {
   20561       EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20562                  rm.Encode(5, 0));
   20563       AdvanceIT();
   20564       return;
   20565     }
   20566   } else {
   20567     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
   20568     if (dt.Is(F32) && cond.IsNotNever()) {
   20569       EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20570               rn.Encode(7, 16) | rm.Encode(5, 0));
   20571       return;
   20572     }
   20573   }
   20574   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
   20575 }
   20576 
   20577 void Assembler::vnmls(
   20578     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20579   VIXL_ASSERT(AllowAssembler());
   20580   CheckIT(cond);
   20581   if (IsUsingT32()) {
   20582     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
   20583     if (dt.Is(F64)) {
   20584       EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20585                  rm.Encode(5, 0));
   20586       AdvanceIT();
   20587       return;
   20588     }
   20589   } else {
   20590     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
   20591     if (dt.Is(F64) && cond.IsNotNever()) {
   20592       EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20593               rn.Encode(7, 16) | rm.Encode(5, 0));
   20594       return;
   20595     }
   20596   }
   20597   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
   20598 }
   20599 
   20600 void Assembler::vnmul(
   20601     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   20602   VIXL_ASSERT(AllowAssembler());
   20603   CheckIT(cond);
   20604   if (IsUsingT32()) {
   20605     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
   20606     if (dt.Is(F32)) {
   20607       EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20608                  rm.Encode(5, 0));
   20609       AdvanceIT();
   20610       return;
   20611     }
   20612   } else {
   20613     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
   20614     if (dt.Is(F32) && cond.IsNotNever()) {
   20615       EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20616               rn.Encode(7, 16) | rm.Encode(5, 0));
   20617       return;
   20618     }
   20619   }
   20620   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
   20621 }
   20622 
   20623 void Assembler::vnmul(
   20624     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20625   VIXL_ASSERT(AllowAssembler());
   20626   CheckIT(cond);
   20627   if (IsUsingT32()) {
   20628     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
   20629     if (dt.Is(F64)) {
   20630       EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20631                  rm.Encode(5, 0));
   20632       AdvanceIT();
   20633       return;
   20634     }
   20635   } else {
   20636     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
   20637     if (dt.Is(F64) && cond.IsNotNever()) {
   20638       EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20639               rn.Encode(7, 16) | rm.Encode(5, 0));
   20640       return;
   20641     }
   20642   }
   20643   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
   20644 }
   20645 
   20646 void Assembler::vorn(Condition cond,
   20647                      DataType dt,
   20648                      DRegister rd,
   20649                      DRegister rn,
   20650                      const DOperand& operand) {
   20651   VIXL_ASSERT(AllowAssembler());
   20652   CheckIT(cond);
   20653   if (operand.IsImmediate()) {
   20654     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
   20655     if (IsUsingT32()) {
   20656       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
   20657       if (encoded_dt.IsValid() && rd.Is(rn)) {
   20658         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20659           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
   20660                      rd.Encode(22, 12) |
   20661                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   20662                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20663                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   20664           AdvanceIT();
   20665           return;
   20666         }
   20667       }
   20668     } else {
   20669       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
   20670       if (encoded_dt.IsValid() && rd.Is(rn)) {
   20671         if (cond.Is(al)) {
   20672           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
   20673                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   20674                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20675                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   20676           return;
   20677         }
   20678       }
   20679     }
   20680   }
   20681   if (operand.IsRegister()) {
   20682     DRegister rm = operand.GetRegister();
   20683     USE(dt);
   20684     if (IsUsingT32()) {
   20685       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   20686       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20687         EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20688                    rm.Encode(5, 0));
   20689         AdvanceIT();
   20690         return;
   20691       }
   20692     } else {
   20693       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   20694       if (cond.Is(al)) {
   20695         EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20696                 rm.Encode(5, 0));
   20697         return;
   20698       }
   20699     }
   20700   }
   20701   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
   20702 }
   20703 
   20704 void Assembler::vorn(Condition cond,
   20705                      DataType dt,
   20706                      QRegister rd,
   20707                      QRegister rn,
   20708                      const QOperand& operand) {
   20709   VIXL_ASSERT(AllowAssembler());
   20710   CheckIT(cond);
   20711   if (operand.IsImmediate()) {
   20712     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
   20713     if (IsUsingT32()) {
   20714       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
   20715       if (encoded_dt.IsValid() && rd.Is(rn)) {
   20716         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20717           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
   20718                      rd.Encode(22, 12) |
   20719                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   20720                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20721                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   20722           AdvanceIT();
   20723           return;
   20724         }
   20725       }
   20726     } else {
   20727       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
   20728       if (encoded_dt.IsValid() && rd.Is(rn)) {
   20729         if (cond.Is(al)) {
   20730           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
   20731                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   20732                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20733                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   20734           return;
   20735         }
   20736       }
   20737     }
   20738   }
   20739   if (operand.IsRegister()) {
   20740     QRegister rm = operand.GetRegister();
   20741     USE(dt);
   20742     if (IsUsingT32()) {
   20743       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   20744       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20745         EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20746                    rm.Encode(5, 0));
   20747         AdvanceIT();
   20748         return;
   20749       }
   20750     } else {
   20751       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   20752       if (cond.Is(al)) {
   20753         EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20754                 rm.Encode(5, 0));
   20755         return;
   20756       }
   20757     }
   20758   }
   20759   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
   20760 }
   20761 
   20762 void Assembler::vorr(Condition cond,
   20763                      DataType dt,
   20764                      DRegister rd,
   20765                      DRegister rn,
   20766                      const DOperand& operand) {
   20767   VIXL_ASSERT(AllowAssembler());
   20768   CheckIT(cond);
   20769   if (operand.IsRegister()) {
   20770     DRegister rm = operand.GetRegister();
   20771     USE(dt);
   20772     if (IsUsingT32()) {
   20773       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   20774       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20775         EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20776                    rm.Encode(5, 0));
   20777         AdvanceIT();
   20778         return;
   20779       }
   20780     } else {
   20781       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   20782       if (cond.Is(al)) {
   20783         EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20784                 rm.Encode(5, 0));
   20785         return;
   20786       }
   20787     }
   20788   }
   20789   if (operand.IsImmediate()) {
   20790     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
   20791     if (IsUsingT32()) {
   20792       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
   20793       if (encoded_dt.IsValid() && rd.Is(rn)) {
   20794         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20795           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
   20796                      rd.Encode(22, 12) |
   20797                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   20798                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20799                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   20800           AdvanceIT();
   20801           return;
   20802         }
   20803       }
   20804     } else {
   20805       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
   20806       if (encoded_dt.IsValid() && rd.Is(rn)) {
   20807         if (cond.Is(al)) {
   20808           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
   20809                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   20810                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20811                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   20812           return;
   20813         }
   20814       }
   20815     }
   20816   }
   20817   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
   20818 }
   20819 
   20820 void Assembler::vorr(Condition cond,
   20821                      DataType dt,
   20822                      QRegister rd,
   20823                      QRegister rn,
   20824                      const QOperand& operand) {
   20825   VIXL_ASSERT(AllowAssembler());
   20826   CheckIT(cond);
   20827   if (operand.IsRegister()) {
   20828     QRegister rm = operand.GetRegister();
   20829     USE(dt);
   20830     if (IsUsingT32()) {
   20831       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   20832       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20833         EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20834                    rm.Encode(5, 0));
   20835         AdvanceIT();
   20836         return;
   20837       }
   20838     } else {
   20839       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   20840       if (cond.Is(al)) {
   20841         EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20842                 rm.Encode(5, 0));
   20843         return;
   20844       }
   20845     }
   20846   }
   20847   if (operand.IsImmediate()) {
   20848     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
   20849     if (IsUsingT32()) {
   20850       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
   20851       if (encoded_dt.IsValid() && rd.Is(rn)) {
   20852         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20853           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
   20854                      rd.Encode(22, 12) |
   20855                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   20856                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20857                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   20858           AdvanceIT();
   20859           return;
   20860         }
   20861       }
   20862     } else {
   20863       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
   20864       if (encoded_dt.IsValid() && rd.Is(rn)) {
   20865         if (cond.Is(al)) {
   20866           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
   20867                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   20868                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20869                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   20870           return;
   20871         }
   20872       }
   20873     }
   20874   }
   20875   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
   20876 }
   20877 
   20878 void Assembler::vpadal(Condition cond,
   20879                        DataType dt,
   20880                        DRegister rd,
   20881                        DRegister rm) {
   20882   VIXL_ASSERT(AllowAssembler());
   20883   CheckIT(cond);
   20884   Dt_op_size_2 encoded_dt(dt);
   20885   if (IsUsingT32()) {
   20886     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   20887     if (encoded_dt.IsValid()) {
   20888       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20889         EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20890                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   20891                    rd.Encode(22, 12) | rm.Encode(5, 0));
   20892         AdvanceIT();
   20893         return;
   20894       }
   20895     }
   20896   } else {
   20897     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   20898     if (encoded_dt.IsValid()) {
   20899       if (cond.Is(al)) {
   20900         EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20901                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   20902                 rd.Encode(22, 12) | rm.Encode(5, 0));
   20903         return;
   20904       }
   20905     }
   20906   }
   20907   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
   20908 }
   20909 
   20910 void Assembler::vpadal(Condition cond,
   20911                        DataType dt,
   20912                        QRegister rd,
   20913                        QRegister rm) {
   20914   VIXL_ASSERT(AllowAssembler());
   20915   CheckIT(cond);
   20916   Dt_op_size_2 encoded_dt(dt);
   20917   if (IsUsingT32()) {
   20918     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   20919     if (encoded_dt.IsValid()) {
   20920       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20921         EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20922                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   20923                    rd.Encode(22, 12) | rm.Encode(5, 0));
   20924         AdvanceIT();
   20925         return;
   20926       }
   20927     }
   20928   } else {
   20929     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   20930     if (encoded_dt.IsValid()) {
   20931       if (cond.Is(al)) {
   20932         EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20933                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   20934                 rd.Encode(22, 12) | rm.Encode(5, 0));
   20935         return;
   20936       }
   20937     }
   20938   }
   20939   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
   20940 }
   20941 
   20942 void Assembler::vpadd(
   20943     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20944   VIXL_ASSERT(AllowAssembler());
   20945   CheckIT(cond);
   20946   Dt_size_4 encoded_dt(dt);
   20947   if (IsUsingT32()) {
   20948     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   20949     if (dt.Is(F32)) {
   20950       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20951         EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20952                    rm.Encode(5, 0));
   20953         AdvanceIT();
   20954         return;
   20955       }
   20956     }
   20957     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   20958     if (encoded_dt.IsValid()) {
   20959       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20960         EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
   20961                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20962         AdvanceIT();
   20963         return;
   20964       }
   20965     }
   20966   } else {
   20967     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   20968     if (dt.Is(F32)) {
   20969       if (cond.Is(al)) {
   20970         EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20971                 rm.Encode(5, 0));
   20972         return;
   20973       }
   20974     }
   20975     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   20976     if (encoded_dt.IsValid()) {
   20977       if (cond.Is(al)) {
   20978         EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
   20979                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20980         return;
   20981       }
   20982     }
   20983   }
   20984   Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
   20985 }
   20986 
   20987 void Assembler::vpaddl(Condition cond,
   20988                        DataType dt,
   20989                        DRegister rd,
   20990                        DRegister rm) {
   20991   VIXL_ASSERT(AllowAssembler());
   20992   CheckIT(cond);
   20993   Dt_op_size_2 encoded_dt(dt);
   20994   if (IsUsingT32()) {
   20995     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   20996     if (encoded_dt.IsValid()) {
   20997       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20998         EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   20999                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   21000                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21001         AdvanceIT();
   21002         return;
   21003       }
   21004     }
   21005   } else {
   21006     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   21007     if (encoded_dt.IsValid()) {
   21008       if (cond.Is(al)) {
   21009         EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21010                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   21011                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21012         return;
   21013       }
   21014     }
   21015   }
   21016   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
   21017 }
   21018 
   21019 void Assembler::vpaddl(Condition cond,
   21020                        DataType dt,
   21021                        QRegister rd,
   21022                        QRegister rm) {
   21023   VIXL_ASSERT(AllowAssembler());
   21024   CheckIT(cond);
   21025   Dt_op_size_2 encoded_dt(dt);
   21026   if (IsUsingT32()) {
   21027     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   21028     if (encoded_dt.IsValid()) {
   21029       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21030         EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21031                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   21032                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21033         AdvanceIT();
   21034         return;
   21035       }
   21036     }
   21037   } else {
   21038     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   21039     if (encoded_dt.IsValid()) {
   21040       if (cond.Is(al)) {
   21041         EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21042                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   21043                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21044         return;
   21045       }
   21046     }
   21047   }
   21048   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
   21049 }
   21050 
   21051 void Assembler::vpmax(
   21052     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21053   VIXL_ASSERT(AllowAssembler());
   21054   CheckIT(cond);
   21055   Dt_U_size_1 encoded_dt(dt);
   21056   if (IsUsingT32()) {
   21057     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   21058     if (dt.Is(F32)) {
   21059       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21060         EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21061                    rm.Encode(5, 0));
   21062         AdvanceIT();
   21063         return;
   21064       }
   21065     }
   21066     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   21067     if (encoded_dt.IsValid()) {
   21068       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21069         EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21070                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21071                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21072         AdvanceIT();
   21073         return;
   21074       }
   21075     }
   21076   } else {
   21077     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   21078     if (dt.Is(F32)) {
   21079       if (cond.Is(al)) {
   21080         EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21081                 rm.Encode(5, 0));
   21082         return;
   21083       }
   21084     }
   21085     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   21086     if (encoded_dt.IsValid()) {
   21087       if (cond.Is(al)) {
   21088         EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21089                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21090                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21091         return;
   21092       }
   21093     }
   21094   }
   21095   Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
   21096 }
   21097 
   21098 void Assembler::vpmin(
   21099     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21100   VIXL_ASSERT(AllowAssembler());
   21101   CheckIT(cond);
   21102   Dt_U_size_1 encoded_dt(dt);
   21103   if (IsUsingT32()) {
   21104     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   21105     if (dt.Is(F32)) {
   21106       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21107         EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21108                    rm.Encode(5, 0));
   21109         AdvanceIT();
   21110         return;
   21111       }
   21112     }
   21113     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   21114     if (encoded_dt.IsValid()) {
   21115       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21116         EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21117                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21118                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21119         AdvanceIT();
   21120         return;
   21121       }
   21122     }
   21123   } else {
   21124     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   21125     if (dt.Is(F32)) {
   21126       if (cond.Is(al)) {
   21127         EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21128                 rm.Encode(5, 0));
   21129         return;
   21130       }
   21131     }
   21132     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   21133     if (encoded_dt.IsValid()) {
   21134       if (cond.Is(al)) {
   21135         EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21136                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21137                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21138         return;
   21139       }
   21140     }
   21141   }
   21142   Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
   21143 }
   21144 
   21145 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
   21146   VIXL_ASSERT(AllowAssembler());
   21147   CheckIT(cond);
   21148   USE(dt);
   21149   if (IsUsingT32()) {
   21150     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
   21151     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   21152       const DRegister& dreg = dreglist.GetFirstDRegister();
   21153       unsigned len = dreglist.GetLength() * 2;
   21154       EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
   21155       AdvanceIT();
   21156       return;
   21157     }
   21158   } else {
   21159     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
   21160     if (cond.IsNotNever() &&
   21161         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   21162       const DRegister& dreg = dreglist.GetFirstDRegister();
   21163       unsigned len = dreglist.GetLength() * 2;
   21164       EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
   21165               (len & 0xff));
   21166       return;
   21167     }
   21168   }
   21169   Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
   21170 }
   21171 
   21172 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
   21173   VIXL_ASSERT(AllowAssembler());
   21174   CheckIT(cond);
   21175   USE(dt);
   21176   if (IsUsingT32()) {
   21177     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
   21178     const SRegister& sreg = sreglist.GetFirstSRegister();
   21179     unsigned len = sreglist.GetLength();
   21180     EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
   21181     AdvanceIT();
   21182     return;
   21183   } else {
   21184     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
   21185     if (cond.IsNotNever()) {
   21186       const SRegister& sreg = sreglist.GetFirstSRegister();
   21187       unsigned len = sreglist.GetLength();
   21188       EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
   21189               (len & 0xff));
   21190       return;
   21191     }
   21192   }
   21193   Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
   21194 }
   21195 
   21196 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
   21197   VIXL_ASSERT(AllowAssembler());
   21198   CheckIT(cond);
   21199   USE(dt);
   21200   if (IsUsingT32()) {
   21201     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
   21202     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   21203       const DRegister& dreg = dreglist.GetFirstDRegister();
   21204       unsigned len = dreglist.GetLength() * 2;
   21205       EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
   21206       AdvanceIT();
   21207       return;
   21208     }
   21209   } else {
   21210     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
   21211     if (cond.IsNotNever() &&
   21212         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   21213       const DRegister& dreg = dreglist.GetFirstDRegister();
   21214       unsigned len = dreglist.GetLength() * 2;
   21215       EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
   21216               (len & 0xff));
   21217       return;
   21218     }
   21219   }
   21220   Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
   21221 }
   21222 
   21223 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
   21224   VIXL_ASSERT(AllowAssembler());
   21225   CheckIT(cond);
   21226   USE(dt);
   21227   if (IsUsingT32()) {
   21228     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
   21229     const SRegister& sreg = sreglist.GetFirstSRegister();
   21230     unsigned len = sreglist.GetLength();
   21231     EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
   21232     AdvanceIT();
   21233     return;
   21234   } else {
   21235     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
   21236     if (cond.IsNotNever()) {
   21237       const SRegister& sreg = sreglist.GetFirstSRegister();
   21238       unsigned len = sreglist.GetLength();
   21239       EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
   21240               (len & 0xff));
   21241       return;
   21242     }
   21243   }
   21244   Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
   21245 }
   21246 
   21247 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   21248   VIXL_ASSERT(AllowAssembler());
   21249   CheckIT(cond);
   21250   Dt_size_5 encoded_dt(dt);
   21251   if (IsUsingT32()) {
   21252     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   21253     if (encoded_dt.IsValid()) {
   21254       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21255         EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
   21256                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21257         AdvanceIT();
   21258         return;
   21259       }
   21260     }
   21261   } else {
   21262     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   21263     if (encoded_dt.IsValid()) {
   21264       if (cond.Is(al)) {
   21265         EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
   21266                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21267         return;
   21268       }
   21269     }
   21270   }
   21271   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
   21272 }
   21273 
   21274 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   21275   VIXL_ASSERT(AllowAssembler());
   21276   CheckIT(cond);
   21277   Dt_size_5 encoded_dt(dt);
   21278   if (IsUsingT32()) {
   21279     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   21280     if (encoded_dt.IsValid()) {
   21281       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21282         EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
   21283                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21284         AdvanceIT();
   21285         return;
   21286       }
   21287     }
   21288   } else {
   21289     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   21290     if (encoded_dt.IsValid()) {
   21291       if (cond.Is(al)) {
   21292         EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
   21293                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21294         return;
   21295       }
   21296     }
   21297   }
   21298   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
   21299 }
   21300 
   21301 void Assembler::vqadd(
   21302     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21303   VIXL_ASSERT(AllowAssembler());
   21304   CheckIT(cond);
   21305   Dt_U_size_3 encoded_dt(dt);
   21306   if (IsUsingT32()) {
   21307     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   21308     if (encoded_dt.IsValid()) {
   21309       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21310         EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21311                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21312                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21313         AdvanceIT();
   21314         return;
   21315       }
   21316     }
   21317   } else {
   21318     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   21319     if (encoded_dt.IsValid()) {
   21320       if (cond.Is(al)) {
   21321         EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21322                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21323                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21324         return;
   21325       }
   21326     }
   21327   }
   21328   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
   21329 }
   21330 
   21331 void Assembler::vqadd(
   21332     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   21333   VIXL_ASSERT(AllowAssembler());
   21334   CheckIT(cond);
   21335   Dt_U_size_3 encoded_dt(dt);
   21336   if (IsUsingT32()) {
   21337     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   21338     if (encoded_dt.IsValid()) {
   21339       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21340         EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21341                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21342                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21343         AdvanceIT();
   21344         return;
   21345       }
   21346     }
   21347   } else {
   21348     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   21349     if (encoded_dt.IsValid()) {
   21350       if (cond.Is(al)) {
   21351         EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21352                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21353                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21354         return;
   21355       }
   21356     }
   21357   }
   21358   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
   21359 }
   21360 
   21361 void Assembler::vqdmlal(
   21362     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   21363   VIXL_ASSERT(AllowAssembler());
   21364   CheckIT(cond);
   21365   Dt_size_13 encoded_dt(dt);
   21366   if (IsUsingT32()) {
   21367     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   21368     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   21369       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21370         EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
   21371                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21372         AdvanceIT();
   21373         return;
   21374       }
   21375     }
   21376   } else {
   21377     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   21378     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   21379       if (cond.Is(al)) {
   21380         EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
   21381                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21382         return;
   21383       }
   21384     }
   21385   }
   21386   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
   21387 }
   21388 
   21389 void Assembler::vqdmlal(Condition cond,
   21390                         DataType dt,
   21391                         QRegister rd,
   21392                         DRegister rn,
   21393                         DRegister dm,
   21394                         unsigned index) {
   21395   VIXL_ASSERT(AllowAssembler());
   21396   CheckIT(cond);
   21397   Dt_size_13 encoded_dt(dt);
   21398   if (IsUsingT32()) {
   21399     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
   21400     if (encoded_dt.IsValid() &&
   21401         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21402          (!dt.Is(S16) && (index <= 1))) &&
   21403         (dt.Is(S16) || dt.Is(S32))) {
   21404       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21405         uint32_t shift = 4;
   21406         if (dt.Is(S16)) {
   21407           shift = 3;
   21408         }
   21409         uint32_t mvm = dm.GetCode() | index << shift;
   21410         EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
   21411                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21412                    ((mvm & 0x10) << 1));
   21413         AdvanceIT();
   21414         return;
   21415       }
   21416     }
   21417   } else {
   21418     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
   21419     if (encoded_dt.IsValid() &&
   21420         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21421          (!dt.Is(S16) && (index <= 1))) &&
   21422         (dt.Is(S16) || dt.Is(S32))) {
   21423       if (cond.Is(al)) {
   21424         uint32_t shift = 4;
   21425         if (dt.Is(S16)) {
   21426           shift = 3;
   21427         }
   21428         uint32_t mvm = dm.GetCode() | index << shift;
   21429         EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
   21430                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21431                 ((mvm & 0x10) << 1));
   21432         return;
   21433       }
   21434     }
   21435   }
   21436   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
   21437 }
   21438 
   21439 void Assembler::vqdmlsl(
   21440     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   21441   VIXL_ASSERT(AllowAssembler());
   21442   CheckIT(cond);
   21443   Dt_size_13 encoded_dt(dt);
   21444   if (IsUsingT32()) {
   21445     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   21446     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   21447       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21448         EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
   21449                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21450         AdvanceIT();
   21451         return;
   21452       }
   21453     }
   21454   } else {
   21455     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   21456     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   21457       if (cond.Is(al)) {
   21458         EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
   21459                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21460         return;
   21461       }
   21462     }
   21463   }
   21464   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
   21465 }
   21466 
   21467 void Assembler::vqdmlsl(Condition cond,
   21468                         DataType dt,
   21469                         QRegister rd,
   21470                         DRegister rn,
   21471                         DRegister dm,
   21472                         unsigned index) {
   21473   VIXL_ASSERT(AllowAssembler());
   21474   CheckIT(cond);
   21475   Dt_size_13 encoded_dt(dt);
   21476   if (IsUsingT32()) {
   21477     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
   21478     if (encoded_dt.IsValid() &&
   21479         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21480          (!dt.Is(S16) && (index <= 1))) &&
   21481         (dt.Is(S16) || dt.Is(S32))) {
   21482       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21483         uint32_t shift = 4;
   21484         if (dt.Is(S16)) {
   21485           shift = 3;
   21486         }
   21487         uint32_t mvm = dm.GetCode() | index << shift;
   21488         EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
   21489                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21490                    ((mvm & 0x10) << 1));
   21491         AdvanceIT();
   21492         return;
   21493       }
   21494     }
   21495   } else {
   21496     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
   21497     if (encoded_dt.IsValid() &&
   21498         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21499          (!dt.Is(S16) && (index <= 1))) &&
   21500         (dt.Is(S16) || dt.Is(S32))) {
   21501       if (cond.Is(al)) {
   21502         uint32_t shift = 4;
   21503         if (dt.Is(S16)) {
   21504           shift = 3;
   21505         }
   21506         uint32_t mvm = dm.GetCode() | index << shift;
   21507         EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
   21508                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21509                 ((mvm & 0x10) << 1));
   21510         return;
   21511       }
   21512     }
   21513   }
   21514   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
   21515 }
   21516 
   21517 void Assembler::vqdmulh(
   21518     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21519   VIXL_ASSERT(AllowAssembler());
   21520   CheckIT(cond);
   21521   Dt_size_13 encoded_dt(dt);
   21522   if (IsUsingT32()) {
   21523     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   21524     if (encoded_dt.IsValid()) {
   21525       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21526         EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
   21527                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21528         AdvanceIT();
   21529         return;
   21530       }
   21531     }
   21532   } else {
   21533     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   21534     if (encoded_dt.IsValid()) {
   21535       if (cond.Is(al)) {
   21536         EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
   21537                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21538         return;
   21539       }
   21540     }
   21541   }
   21542   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
   21543 }
   21544 
   21545 void Assembler::vqdmulh(
   21546     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   21547   VIXL_ASSERT(AllowAssembler());
   21548   CheckIT(cond);
   21549   Dt_size_13 encoded_dt(dt);
   21550   if (IsUsingT32()) {
   21551     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   21552     if (encoded_dt.IsValid()) {
   21553       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21554         EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
   21555                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21556         AdvanceIT();
   21557         return;
   21558       }
   21559     }
   21560   } else {
   21561     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   21562     if (encoded_dt.IsValid()) {
   21563       if (cond.Is(al)) {
   21564         EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
   21565                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21566         return;
   21567       }
   21568     }
   21569   }
   21570   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
   21571 }
   21572 
   21573 void Assembler::vqdmulh(
   21574     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
   21575   VIXL_ASSERT(AllowAssembler());
   21576   CheckIT(cond);
   21577   Dt_size_13 encoded_dt(dt);
   21578   if (IsUsingT32()) {
   21579     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
   21580     if (encoded_dt.IsValid() &&
   21581         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21582          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21583           (rm.GetLane() <= 1))) &&
   21584         (dt.Is(S16) || dt.Is(S32))) {
   21585       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21586         EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
   21587                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21588         AdvanceIT();
   21589         return;
   21590       }
   21591     }
   21592   } else {
   21593     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
   21594     if (encoded_dt.IsValid() &&
   21595         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21596          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21597           (rm.GetLane() <= 1))) &&
   21598         (dt.Is(S16) || dt.Is(S32))) {
   21599       if (cond.Is(al)) {
   21600         EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
   21601                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21602         return;
   21603       }
   21604     }
   21605   }
   21606   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
   21607 }
   21608 
   21609 void Assembler::vqdmulh(
   21610     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
   21611   VIXL_ASSERT(AllowAssembler());
   21612   CheckIT(cond);
   21613   Dt_size_13 encoded_dt(dt);
   21614   if (IsUsingT32()) {
   21615     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
   21616     if (encoded_dt.IsValid() &&
   21617         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21618          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21619           (rm.GetLane() <= 1))) &&
   21620         (dt.Is(S16) || dt.Is(S32))) {
   21621       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21622         EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
   21623                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21624         AdvanceIT();
   21625         return;
   21626       }
   21627     }
   21628   } else {
   21629     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
   21630     if (encoded_dt.IsValid() &&
   21631         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21632          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21633           (rm.GetLane() <= 1))) &&
   21634         (dt.Is(S16) || dt.Is(S32))) {
   21635       if (cond.Is(al)) {
   21636         EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
   21637                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21638         return;
   21639       }
   21640     }
   21641   }
   21642   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
   21643 }
   21644 
   21645 void Assembler::vqdmull(
   21646     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   21647   VIXL_ASSERT(AllowAssembler());
   21648   CheckIT(cond);
   21649   Dt_size_13 encoded_dt(dt);
   21650   if (IsUsingT32()) {
   21651     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   21652     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   21653       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21654         EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
   21655                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21656         AdvanceIT();
   21657         return;
   21658       }
   21659     }
   21660   } else {
   21661     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   21662     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   21663       if (cond.Is(al)) {
   21664         EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
   21665                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21666         return;
   21667       }
   21668     }
   21669   }
   21670   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
   21671 }
   21672 
   21673 void Assembler::vqdmull(
   21674     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
   21675   VIXL_ASSERT(AllowAssembler());
   21676   CheckIT(cond);
   21677   Dt_size_13 encoded_dt(dt);
   21678   if (IsUsingT32()) {
   21679     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
   21680     if (encoded_dt.IsValid() &&
   21681         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21682          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21683           (rm.GetLane() <= 1))) &&
   21684         (dt.Is(S16) || dt.Is(S32))) {
   21685       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21686         EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
   21687                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21688         AdvanceIT();
   21689         return;
   21690       }
   21691     }
   21692   } else {
   21693     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
   21694     if (encoded_dt.IsValid() &&
   21695         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21696          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21697           (rm.GetLane() <= 1))) &&
   21698         (dt.Is(S16) || dt.Is(S32))) {
   21699       if (cond.Is(al)) {
   21700         EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
   21701                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21702         return;
   21703       }
   21704     }
   21705   }
   21706   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
   21707 }
   21708 
   21709 void Assembler::vqmovn(Condition cond,
   21710                        DataType dt,
   21711                        DRegister rd,
   21712                        QRegister rm) {
   21713   VIXL_ASSERT(AllowAssembler());
   21714   CheckIT(cond);
   21715   Dt_op_size_3 encoded_dt(dt);
   21716   if (IsUsingT32()) {
   21717     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
   21718     if (encoded_dt.IsValid()) {
   21719       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21720         EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21721                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   21722                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21723         AdvanceIT();
   21724         return;
   21725       }
   21726     }
   21727   } else {
   21728     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
   21729     if (encoded_dt.IsValid()) {
   21730       if (cond.Is(al)) {
   21731         EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21732                 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   21733                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21734         return;
   21735       }
   21736     }
   21737   }
   21738   Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
   21739 }
   21740 
   21741 void Assembler::vqmovun(Condition cond,
   21742                         DataType dt,
   21743                         DRegister rd,
   21744                         QRegister rm) {
   21745   VIXL_ASSERT(AllowAssembler());
   21746   CheckIT(cond);
   21747   Dt_size_14 encoded_dt(dt);
   21748   if (IsUsingT32()) {
   21749     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
   21750     if (encoded_dt.IsValid()) {
   21751       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21752         EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
   21753                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21754         AdvanceIT();
   21755         return;
   21756       }
   21757     }
   21758   } else {
   21759     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
   21760     if (encoded_dt.IsValid()) {
   21761       if (cond.Is(al)) {
   21762         EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
   21763                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21764         return;
   21765       }
   21766     }
   21767   }
   21768   Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
   21769 }
   21770 
   21771 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   21772   VIXL_ASSERT(AllowAssembler());
   21773   CheckIT(cond);
   21774   Dt_size_5 encoded_dt(dt);
   21775   if (IsUsingT32()) {
   21776     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   21777     if (encoded_dt.IsValid()) {
   21778       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21779         EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
   21780                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21781         AdvanceIT();
   21782         return;
   21783       }
   21784     }
   21785   } else {
   21786     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   21787     if (encoded_dt.IsValid()) {
   21788       if (cond.Is(al)) {
   21789         EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
   21790                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21791         return;
   21792       }
   21793     }
   21794   }
   21795   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
   21796 }
   21797 
   21798 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   21799   VIXL_ASSERT(AllowAssembler());
   21800   CheckIT(cond);
   21801   Dt_size_5 encoded_dt(dt);
   21802   if (IsUsingT32()) {
   21803     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   21804     if (encoded_dt.IsValid()) {
   21805       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21806         EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
   21807                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21808         AdvanceIT();
   21809         return;
   21810       }
   21811     }
   21812   } else {
   21813     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   21814     if (encoded_dt.IsValid()) {
   21815       if (cond.Is(al)) {
   21816         EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
   21817                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21818         return;
   21819       }
   21820     }
   21821   }
   21822   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
   21823 }
   21824 
   21825 void Assembler::vqrdmulh(
   21826     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21827   VIXL_ASSERT(AllowAssembler());
   21828   CheckIT(cond);
   21829   Dt_size_13 encoded_dt(dt);
   21830   if (IsUsingT32()) {
   21831     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   21832     if (encoded_dt.IsValid()) {
   21833       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21834         EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
   21835                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21836         AdvanceIT();
   21837         return;
   21838       }
   21839     }
   21840   } else {
   21841     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   21842     if (encoded_dt.IsValid()) {
   21843       if (cond.Is(al)) {
   21844         EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
   21845                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21846         return;
   21847       }
   21848     }
   21849   }
   21850   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
   21851 }
   21852 
   21853 void Assembler::vqrdmulh(
   21854     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   21855   VIXL_ASSERT(AllowAssembler());
   21856   CheckIT(cond);
   21857   Dt_size_13 encoded_dt(dt);
   21858   if (IsUsingT32()) {
   21859     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   21860     if (encoded_dt.IsValid()) {
   21861       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21862         EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
   21863                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21864         AdvanceIT();
   21865         return;
   21866       }
   21867     }
   21868   } else {
   21869     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   21870     if (encoded_dt.IsValid()) {
   21871       if (cond.Is(al)) {
   21872         EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
   21873                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21874         return;
   21875       }
   21876     }
   21877   }
   21878   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
   21879 }
   21880 
   21881 void Assembler::vqrdmulh(
   21882     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
   21883   VIXL_ASSERT(AllowAssembler());
   21884   CheckIT(cond);
   21885   Dt_size_13 encoded_dt(dt);
   21886   if (IsUsingT32()) {
   21887     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
   21888     if (encoded_dt.IsValid() &&
   21889         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21890          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21891           (rm.GetLane() <= 1))) &&
   21892         (dt.Is(S16) || dt.Is(S32))) {
   21893       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21894         EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
   21895                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21896         AdvanceIT();
   21897         return;
   21898       }
   21899     }
   21900   } else {
   21901     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
   21902     if (encoded_dt.IsValid() &&
   21903         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21904          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21905           (rm.GetLane() <= 1))) &&
   21906         (dt.Is(S16) || dt.Is(S32))) {
   21907       if (cond.Is(al)) {
   21908         EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
   21909                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21910         return;
   21911       }
   21912     }
   21913   }
   21914   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
   21915 }
   21916 
   21917 void Assembler::vqrdmulh(
   21918     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
   21919   VIXL_ASSERT(AllowAssembler());
   21920   CheckIT(cond);
   21921   Dt_size_13 encoded_dt(dt);
   21922   if (IsUsingT32()) {
   21923     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
   21924     if (encoded_dt.IsValid() &&
   21925         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21926          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21927           (rm.GetLane() <= 1))) &&
   21928         (dt.Is(S16) || dt.Is(S32))) {
   21929       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21930         EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
   21931                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21932         AdvanceIT();
   21933         return;
   21934       }
   21935     }
   21936   } else {
   21937     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
   21938     if (encoded_dt.IsValid() &&
   21939         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   21940          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   21941           (rm.GetLane() <= 1))) &&
   21942         (dt.Is(S16) || dt.Is(S32))) {
   21943       if (cond.Is(al)) {
   21944         EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
   21945                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   21946         return;
   21947       }
   21948     }
   21949   }
   21950   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
   21951 }
   21952 
   21953 void Assembler::vqrshl(
   21954     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
   21955   VIXL_ASSERT(AllowAssembler());
   21956   CheckIT(cond);
   21957   Dt_U_size_3 encoded_dt(dt);
   21958   if (IsUsingT32()) {
   21959     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
   21960     if (encoded_dt.IsValid()) {
   21961       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21962         EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21963                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21964                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   21965         AdvanceIT();
   21966         return;
   21967       }
   21968     }
   21969   } else {
   21970     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
   21971     if (encoded_dt.IsValid()) {
   21972       if (cond.Is(al)) {
   21973         EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21974                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21975                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   21976         return;
   21977       }
   21978     }
   21979   }
   21980   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
   21981 }
   21982 
   21983 void Assembler::vqrshl(
   21984     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
   21985   VIXL_ASSERT(AllowAssembler());
   21986   CheckIT(cond);
   21987   Dt_U_size_3 encoded_dt(dt);
   21988   if (IsUsingT32()) {
   21989     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
   21990     if (encoded_dt.IsValid()) {
   21991       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21992         EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21993                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21994                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   21995         AdvanceIT();
   21996         return;
   21997       }
   21998     }
   21999   } else {
   22000     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
   22001     if (encoded_dt.IsValid()) {
   22002       if (cond.Is(al)) {
   22003         EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22004                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22005                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   22006         return;
   22007       }
   22008     }
   22009   }
   22010   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
   22011 }
   22012 
   22013 void Assembler::vqrshrn(Condition cond,
   22014                         DataType dt,
   22015                         DRegister rd,
   22016                         QRegister rm,
   22017                         const QOperand& operand) {
   22018   VIXL_ASSERT(AllowAssembler());
   22019   CheckIT(cond);
   22020   if (operand.IsImmediate()) {
   22021     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   22022       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   22023       Dt_op_size_3 encoded_dt(dt);
   22024       Dt_imm6_1 encoded_dt_2(dt);
   22025       if (IsUsingT32()) {
   22026         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   22027         if (encoded_dt.IsValid() && (imm == 0)) {
   22028           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22029             EmitT32_32(0xffb20280U |
   22030                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22031                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   22032                        rd.Encode(22, 12) | rm.Encode(5, 0));
   22033             AdvanceIT();
   22034             return;
   22035           }
   22036         }
   22037         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
   22038         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   22039           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22040             uint32_t imm6 = dt.GetSize() / 2 - imm;
   22041             EmitT32_32(0xef800950U |
   22042                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
   22043                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
   22044                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22045             AdvanceIT();
   22046             return;
   22047           }
   22048         }
   22049       } else {
   22050         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   22051         if (encoded_dt.IsValid() && (imm == 0)) {
   22052           if (cond.Is(al)) {
   22053             EmitA32(0xf3b20280U |
   22054                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22055                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   22056                     rd.Encode(22, 12) | rm.Encode(5, 0));
   22057             return;
   22058           }
   22059         }
   22060         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
   22061         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   22062           if (cond.Is(al)) {
   22063             uint32_t imm6 = dt.GetSize() / 2 - imm;
   22064             EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
   22065                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
   22066                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22067             return;
   22068           }
   22069         }
   22070       }
   22071     }
   22072   }
   22073   Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
   22074 }
   22075 
   22076 void Assembler::vqrshrun(Condition cond,
   22077                          DataType dt,
   22078                          DRegister rd,
   22079                          QRegister rm,
   22080                          const QOperand& operand) {
   22081   VIXL_ASSERT(AllowAssembler());
   22082   CheckIT(cond);
   22083   if (operand.IsImmediate()) {
   22084     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   22085       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   22086       Dt_imm6_2 encoded_dt(dt);
   22087       Dt_size_14 encoded_dt_2(dt);
   22088       if (IsUsingT32()) {
   22089         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
   22090         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   22091           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22092             uint32_t imm6 = dt.GetSize() / 2 - imm;
   22093             EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
   22094                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22095                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22096             AdvanceIT();
   22097             return;
   22098           }
   22099         }
   22100         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   22101         if (encoded_dt_2.IsValid() && (imm == 0)) {
   22102           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22103             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
   22104                        rd.Encode(22, 12) | rm.Encode(5, 0));
   22105             AdvanceIT();
   22106             return;
   22107           }
   22108         }
   22109       } else {
   22110         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
   22111         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   22112           if (cond.Is(al)) {
   22113             uint32_t imm6 = dt.GetSize() / 2 - imm;
   22114             EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
   22115                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22116                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22117             return;
   22118           }
   22119         }
   22120         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   22121         if (encoded_dt_2.IsValid() && (imm == 0)) {
   22122           if (cond.Is(al)) {
   22123             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
   22124                     rd.Encode(22, 12) | rm.Encode(5, 0));
   22125             return;
   22126           }
   22127         }
   22128       }
   22129     }
   22130   }
   22131   Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
   22132 }
   22133 
   22134 void Assembler::vqshl(Condition cond,
   22135                       DataType dt,
   22136                       DRegister rd,
   22137                       DRegister rm,
   22138                       const DOperand& operand) {
   22139   VIXL_ASSERT(AllowAssembler());
   22140   CheckIT(cond);
   22141   if (operand.IsRegister()) {
   22142     DRegister rn = operand.GetRegister();
   22143     Dt_U_size_3 encoded_dt(dt);
   22144     if (IsUsingT32()) {
   22145       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
   22146       if (encoded_dt.IsValid()) {
   22147         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22148           EmitT32_32(0xef000410U |
   22149                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22150                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22151                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   22152           AdvanceIT();
   22153           return;
   22154         }
   22155       }
   22156     } else {
   22157       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
   22158       if (encoded_dt.IsValid()) {
   22159         if (cond.Is(al)) {
   22160           EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22161                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22162                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   22163           return;
   22164         }
   22165       }
   22166     }
   22167   }
   22168   if (operand.IsImmediate()) {
   22169     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   22170       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   22171       Dt_L_imm6_1 encoded_dt(dt);
   22172       if (IsUsingT32()) {
   22173         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   22174         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   22175           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22176             uint32_t imm6 = imm;
   22177             EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
   22178                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22179                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   22180                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22181             AdvanceIT();
   22182             return;
   22183           }
   22184         }
   22185       } else {
   22186         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   22187         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   22188           if (cond.Is(al)) {
   22189             uint32_t imm6 = imm;
   22190             EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
   22191                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22192                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   22193                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22194             return;
   22195           }
   22196         }
   22197       }
   22198     }
   22199   }
   22200   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
   22201 }
   22202 
   22203 void Assembler::vqshl(Condition cond,
   22204                       DataType dt,
   22205                       QRegister rd,
   22206                       QRegister rm,
   22207                       const QOperand& operand) {
   22208   VIXL_ASSERT(AllowAssembler());
   22209   CheckIT(cond);
   22210   if (operand.IsRegister()) {
   22211     QRegister rn = operand.GetRegister();
   22212     Dt_U_size_3 encoded_dt(dt);
   22213     if (IsUsingT32()) {
   22214       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
   22215       if (encoded_dt.IsValid()) {
   22216         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22217           EmitT32_32(0xef000450U |
   22218                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22219                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22220                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   22221           AdvanceIT();
   22222           return;
   22223         }
   22224       }
   22225     } else {
   22226       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
   22227       if (encoded_dt.IsValid()) {
   22228         if (cond.Is(al)) {
   22229           EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22230                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22231                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   22232           return;
   22233         }
   22234       }
   22235     }
   22236   }
   22237   if (operand.IsImmediate()) {
   22238     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   22239       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   22240       Dt_L_imm6_1 encoded_dt(dt);
   22241       if (IsUsingT32()) {
   22242         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   22243         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   22244           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22245             uint32_t imm6 = imm;
   22246             EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
   22247                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22248                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   22249                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22250             AdvanceIT();
   22251             return;
   22252           }
   22253         }
   22254       } else {
   22255         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   22256         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   22257           if (cond.Is(al)) {
   22258             uint32_t imm6 = imm;
   22259             EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
   22260                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22261                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   22262                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22263             return;
   22264           }
   22265         }
   22266       }
   22267     }
   22268   }
   22269   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
   22270 }
   22271 
   22272 void Assembler::vqshlu(Condition cond,
   22273                        DataType dt,
   22274                        DRegister rd,
   22275                        DRegister rm,
   22276                        const DOperand& operand) {
   22277   VIXL_ASSERT(AllowAssembler());
   22278   CheckIT(cond);
   22279   if (operand.IsImmediate()) {
   22280     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   22281       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   22282       Dt_L_imm6_2 encoded_dt(dt);
   22283       if (IsUsingT32()) {
   22284         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   22285         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   22286           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22287             uint32_t imm6 = imm;
   22288             EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
   22289                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22290                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   22291                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22292             AdvanceIT();
   22293             return;
   22294           }
   22295         }
   22296       } else {
   22297         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   22298         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   22299           if (cond.Is(al)) {
   22300             uint32_t imm6 = imm;
   22301             EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
   22302                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22303                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   22304                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22305             return;
   22306           }
   22307         }
   22308       }
   22309     }
   22310   }
   22311   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
   22312 }
   22313 
   22314 void Assembler::vqshlu(Condition cond,
   22315                        DataType dt,
   22316                        QRegister rd,
   22317                        QRegister rm,
   22318                        const QOperand& operand) {
   22319   VIXL_ASSERT(AllowAssembler());
   22320   CheckIT(cond);
   22321   if (operand.IsImmediate()) {
   22322     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   22323       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   22324       Dt_L_imm6_2 encoded_dt(dt);
   22325       if (IsUsingT32()) {
   22326         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   22327         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   22328           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22329             uint32_t imm6 = imm;
   22330             EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
   22331                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22332                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   22333                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22334             AdvanceIT();
   22335             return;
   22336           }
   22337         }
   22338       } else {
   22339         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   22340         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   22341           if (cond.Is(al)) {
   22342             uint32_t imm6 = imm;
   22343             EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
   22344                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22345                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   22346                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22347             return;
   22348           }
   22349         }
   22350       }
   22351     }
   22352   }
   22353   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
   22354 }
   22355 
   22356 void Assembler::vqshrn(Condition cond,
   22357                        DataType dt,
   22358                        DRegister rd,
   22359                        QRegister rm,
   22360                        const QOperand& operand) {
   22361   VIXL_ASSERT(AllowAssembler());
   22362   CheckIT(cond);
   22363   if (operand.IsImmediate()) {
   22364     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   22365       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   22366       Dt_op_size_3 encoded_dt(dt);
   22367       Dt_imm6_1 encoded_dt_2(dt);
   22368       if (IsUsingT32()) {
   22369         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   22370         if (encoded_dt.IsValid() && (imm == 0)) {
   22371           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22372             EmitT32_32(0xffb20280U |
   22373                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22374                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   22375                        rd.Encode(22, 12) | rm.Encode(5, 0));
   22376             AdvanceIT();
   22377             return;
   22378           }
   22379         }
   22380         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
   22381         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   22382           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22383             uint32_t imm6 = dt.GetSize() / 2 - imm;
   22384             EmitT32_32(0xef800910U |
   22385                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
   22386                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
   22387                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22388             AdvanceIT();
   22389             return;
   22390           }
   22391         }
   22392       } else {
   22393         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   22394         if (encoded_dt.IsValid() && (imm == 0)) {
   22395           if (cond.Is(al)) {
   22396             EmitA32(0xf3b20280U |
   22397                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22398                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   22399                     rd.Encode(22, 12) | rm.Encode(5, 0));
   22400             return;
   22401           }
   22402         }
   22403         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
   22404         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   22405           if (cond.Is(al)) {
   22406             uint32_t imm6 = dt.GetSize() / 2 - imm;
   22407             EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
   22408                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
   22409                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22410             return;
   22411           }
   22412         }
   22413       }
   22414     }
   22415   }
   22416   Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
   22417 }
   22418 
   22419 void Assembler::vqshrun(Condition cond,
   22420                         DataType dt,
   22421                         DRegister rd,
   22422                         QRegister rm,
   22423                         const QOperand& operand) {
   22424   VIXL_ASSERT(AllowAssembler());
   22425   CheckIT(cond);
   22426   if (operand.IsImmediate()) {
   22427     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   22428       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   22429       Dt_imm6_2 encoded_dt(dt);
   22430       Dt_size_14 encoded_dt_2(dt);
   22431       if (IsUsingT32()) {
   22432         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
   22433         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   22434           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22435             uint32_t imm6 = dt.GetSize() / 2 - imm;
   22436             EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
   22437                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22438                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22439             AdvanceIT();
   22440             return;
   22441           }
   22442         }
   22443         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   22444         if (encoded_dt_2.IsValid() && (imm == 0)) {
   22445           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22446             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
   22447                        rd.Encode(22, 12) | rm.Encode(5, 0));
   22448             AdvanceIT();
   22449             return;
   22450           }
   22451         }
   22452       } else {
   22453         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
   22454         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   22455           if (cond.Is(al)) {
   22456             uint32_t imm6 = dt.GetSize() / 2 - imm;
   22457             EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
   22458                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   22459                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   22460             return;
   22461           }
   22462         }
   22463         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   22464         if (encoded_dt_2.IsValid() && (imm == 0)) {
   22465           if (cond.Is(al)) {
   22466             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
   22467                     rd.Encode(22, 12) | rm.Encode(5, 0));
   22468             return;
   22469           }
   22470         }
   22471       }
   22472     }
   22473   }
   22474   Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
   22475 }
   22476 
   22477 void Assembler::vqsub(
   22478     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   22479   VIXL_ASSERT(AllowAssembler());
   22480   CheckIT(cond);
   22481   Dt_U_size_3 encoded_dt(dt);
   22482   if (IsUsingT32()) {
   22483     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   22484     if (encoded_dt.IsValid()) {
   22485       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22486         EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22487                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22488                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22489         AdvanceIT();
   22490         return;
   22491       }
   22492     }
   22493   } else {
   22494     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   22495     if (encoded_dt.IsValid()) {
   22496       if (cond.Is(al)) {
   22497         EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22498                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22499                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22500         return;
   22501       }
   22502     }
   22503   }
   22504   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
   22505 }
   22506 
   22507 void Assembler::vqsub(
   22508     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   22509   VIXL_ASSERT(AllowAssembler());
   22510   CheckIT(cond);
   22511   Dt_U_size_3 encoded_dt(dt);
   22512   if (IsUsingT32()) {
   22513     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   22514     if (encoded_dt.IsValid()) {
   22515       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22516         EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22517                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22518                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22519         AdvanceIT();
   22520         return;
   22521       }
   22522     }
   22523   } else {
   22524     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   22525     if (encoded_dt.IsValid()) {
   22526       if (cond.Is(al)) {
   22527         EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22528                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22529                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22530         return;
   22531       }
   22532     }
   22533   }
   22534   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
   22535 }
   22536 
   22537 void Assembler::vraddhn(
   22538     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
   22539   VIXL_ASSERT(AllowAssembler());
   22540   CheckIT(cond);
   22541   Dt_size_3 encoded_dt(dt);
   22542   if (IsUsingT32()) {
   22543     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
   22544     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   22545       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22546         EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) |
   22547                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22548         AdvanceIT();
   22549         return;
   22550       }
   22551     }
   22552   } else {
   22553     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
   22554     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   22555       if (cond.Is(al)) {
   22556         EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
   22557                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22558         return;
   22559       }
   22560     }
   22561   }
   22562   Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
   22563 }
   22564 
   22565 void Assembler::vrecpe(Condition cond,
   22566                        DataType dt,
   22567                        DRegister rd,
   22568                        DRegister rm) {
   22569   VIXL_ASSERT(AllowAssembler());
   22570   CheckIT(cond);
   22571   Dt_F_size_4 encoded_dt(dt);
   22572   if (IsUsingT32()) {
   22573     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   22574     if (encoded_dt.IsValid()) {
   22575       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22576         EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22577                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   22578                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22579         AdvanceIT();
   22580         return;
   22581       }
   22582     }
   22583   } else {
   22584     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   22585     if (encoded_dt.IsValid()) {
   22586       if (cond.Is(al)) {
   22587         EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22588                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   22589                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22590         return;
   22591       }
   22592     }
   22593   }
   22594   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
   22595 }
   22596 
   22597 void Assembler::vrecpe(Condition cond,
   22598                        DataType dt,
   22599                        QRegister rd,
   22600                        QRegister rm) {
   22601   VIXL_ASSERT(AllowAssembler());
   22602   CheckIT(cond);
   22603   Dt_F_size_4 encoded_dt(dt);
   22604   if (IsUsingT32()) {
   22605     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   22606     if (encoded_dt.IsValid()) {
   22607       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22608         EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22609                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   22610                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22611         AdvanceIT();
   22612         return;
   22613       }
   22614     }
   22615   } else {
   22616     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   22617     if (encoded_dt.IsValid()) {
   22618       if (cond.Is(al)) {
   22619         EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22620                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   22621                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22622         return;
   22623       }
   22624     }
   22625   }
   22626   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
   22627 }
   22628 
   22629 void Assembler::vrecps(
   22630     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   22631   VIXL_ASSERT(AllowAssembler());
   22632   CheckIT(cond);
   22633   if (IsUsingT32()) {
   22634     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   22635     if (dt.Is(F32)) {
   22636       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22637         EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22638                    rm.Encode(5, 0));
   22639         AdvanceIT();
   22640         return;
   22641       }
   22642     }
   22643   } else {
   22644     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   22645     if (dt.Is(F32)) {
   22646       if (cond.Is(al)) {
   22647         EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22648                 rm.Encode(5, 0));
   22649         return;
   22650       }
   22651     }
   22652   }
   22653   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
   22654 }
   22655 
   22656 void Assembler::vrecps(
   22657     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   22658   VIXL_ASSERT(AllowAssembler());
   22659   CheckIT(cond);
   22660   if (IsUsingT32()) {
   22661     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   22662     if (dt.Is(F32)) {
   22663       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22664         EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22665                    rm.Encode(5, 0));
   22666         AdvanceIT();
   22667         return;
   22668       }
   22669     }
   22670   } else {
   22671     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   22672     if (dt.Is(F32)) {
   22673       if (cond.Is(al)) {
   22674         EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22675                 rm.Encode(5, 0));
   22676         return;
   22677       }
   22678     }
   22679   }
   22680   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
   22681 }
   22682 
   22683 void Assembler::vrev16(Condition cond,
   22684                        DataType dt,
   22685                        DRegister rd,
   22686                        DRegister rm) {
   22687   VIXL_ASSERT(AllowAssembler());
   22688   CheckIT(cond);
   22689   Dt_size_1 encoded_dt(dt);
   22690   if (IsUsingT32()) {
   22691     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   22692     if (encoded_dt.IsValid()) {
   22693       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22694         EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
   22695                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22696         AdvanceIT();
   22697         return;
   22698       }
   22699     }
   22700   } else {
   22701     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   22702     if (encoded_dt.IsValid()) {
   22703       if (cond.Is(al)) {
   22704         EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
   22705                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22706         return;
   22707       }
   22708     }
   22709   }
   22710   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
   22711 }
   22712 
   22713 void Assembler::vrev16(Condition cond,
   22714                        DataType dt,
   22715                        QRegister rd,
   22716                        QRegister rm) {
   22717   VIXL_ASSERT(AllowAssembler());
   22718   CheckIT(cond);
   22719   Dt_size_1 encoded_dt(dt);
   22720   if (IsUsingT32()) {
   22721     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   22722     if (encoded_dt.IsValid()) {
   22723       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22724         EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
   22725                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22726         AdvanceIT();
   22727         return;
   22728       }
   22729     }
   22730   } else {
   22731     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   22732     if (encoded_dt.IsValid()) {
   22733       if (cond.Is(al)) {
   22734         EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
   22735                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22736         return;
   22737       }
   22738     }
   22739   }
   22740   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
   22741 }
   22742 
   22743 void Assembler::vrev32(Condition cond,
   22744                        DataType dt,
   22745                        DRegister rd,
   22746                        DRegister rm) {
   22747   VIXL_ASSERT(AllowAssembler());
   22748   CheckIT(cond);
   22749   Dt_size_15 encoded_dt(dt);
   22750   if (IsUsingT32()) {
   22751     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   22752     if (encoded_dt.IsValid()) {
   22753       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22754         EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
   22755                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22756         AdvanceIT();
   22757         return;
   22758       }
   22759     }
   22760   } else {
   22761     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   22762     if (encoded_dt.IsValid()) {
   22763       if (cond.Is(al)) {
   22764         EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
   22765                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22766         return;
   22767       }
   22768     }
   22769   }
   22770   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
   22771 }
   22772 
   22773 void Assembler::vrev32(Condition cond,
   22774                        DataType dt,
   22775                        QRegister rd,
   22776                        QRegister rm) {
   22777   VIXL_ASSERT(AllowAssembler());
   22778   CheckIT(cond);
   22779   Dt_size_15 encoded_dt(dt);
   22780   if (IsUsingT32()) {
   22781     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   22782     if (encoded_dt.IsValid()) {
   22783       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22784         EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
   22785                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22786         AdvanceIT();
   22787         return;
   22788       }
   22789     }
   22790   } else {
   22791     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   22792     if (encoded_dt.IsValid()) {
   22793       if (cond.Is(al)) {
   22794         EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
   22795                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22796         return;
   22797       }
   22798     }
   22799   }
   22800   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
   22801 }
   22802 
   22803 void Assembler::vrev64(Condition cond,
   22804                        DataType dt,
   22805                        DRegister rd,
   22806                        DRegister rm) {
   22807   VIXL_ASSERT(AllowAssembler());
   22808   CheckIT(cond);
   22809   Dt_size_7 encoded_dt(dt);
   22810   if (IsUsingT32()) {
   22811     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   22812     if (encoded_dt.IsValid()) {
   22813       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22814         EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
   22815                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22816         AdvanceIT();
   22817         return;
   22818       }
   22819     }
   22820   } else {
   22821     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   22822     if (encoded_dt.IsValid()) {
   22823       if (cond.Is(al)) {
   22824         EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
   22825                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22826         return;
   22827       }
   22828     }
   22829   }
   22830   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
   22831 }
   22832 
   22833 void Assembler::vrev64(Condition cond,
   22834                        DataType dt,
   22835                        QRegister rd,
   22836                        QRegister rm) {
   22837   VIXL_ASSERT(AllowAssembler());
   22838   CheckIT(cond);
   22839   Dt_size_7 encoded_dt(dt);
   22840   if (IsUsingT32()) {
   22841     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   22842     if (encoded_dt.IsValid()) {
   22843       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22844         EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
   22845                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22846         AdvanceIT();
   22847         return;
   22848       }
   22849     }
   22850   } else {
   22851     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   22852     if (encoded_dt.IsValid()) {
   22853       if (cond.Is(al)) {
   22854         EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
   22855                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22856         return;
   22857       }
   22858     }
   22859   }
   22860   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
   22861 }
   22862 
   22863 void Assembler::vrhadd(
   22864     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   22865   VIXL_ASSERT(AllowAssembler());
   22866   CheckIT(cond);
   22867   Dt_U_size_1 encoded_dt(dt);
   22868   if (IsUsingT32()) {
   22869     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   22870     if (encoded_dt.IsValid()) {
   22871       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22872         EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22873                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22874                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22875         AdvanceIT();
   22876         return;
   22877       }
   22878     }
   22879   } else {
   22880     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   22881     if (encoded_dt.IsValid()) {
   22882       if (cond.Is(al)) {
   22883         EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22884                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22885                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22886         return;
   22887       }
   22888     }
   22889   }
   22890   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
   22891 }
   22892 
   22893 void Assembler::vrhadd(
   22894     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   22895   VIXL_ASSERT(AllowAssembler());
   22896   CheckIT(cond);
   22897   Dt_U_size_1 encoded_dt(dt);
   22898   if (IsUsingT32()) {
   22899     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   22900     if (encoded_dt.IsValid()) {
   22901       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22902         EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22903                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22904                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22905         AdvanceIT();
   22906         return;
   22907       }
   22908     }
   22909   } else {
   22910     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   22911     if (encoded_dt.IsValid()) {
   22912       if (cond.Is(al)) {
   22913         EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22914                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22915                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22916         return;
   22917       }
   22918     }
   22919   }
   22920   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
   22921 }
   22922 
   22923 void Assembler::vrinta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   22924   VIXL_ASSERT(AllowAssembler());
   22925   CheckIT(al);
   22926   if (IsUsingT32()) {
   22927     // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; T1
   22928     if (dt1.Is(F32) && dt2.Is(F32)) {
   22929       EmitT32_32(0xffba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
   22930       AdvanceIT();
   22931       return;
   22932     }
   22933     // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; T1
   22934     if (dt1.Is(F64) && dt2.Is(F64)) {
   22935       EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   22936       AdvanceIT();
   22937       return;
   22938     }
   22939   } else {
   22940     // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; A1
   22941     if (dt1.Is(F32) && dt2.Is(F32)) {
   22942       EmitA32(0xf3ba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
   22943       return;
   22944     }
   22945     // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; A1
   22946     if (dt1.Is(F64) && dt2.Is(F64)) {
   22947       EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   22948       return;
   22949     }
   22950   }
   22951   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
   22952 }
   22953 
   22954 void Assembler::vrinta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   22955   VIXL_ASSERT(AllowAssembler());
   22956   CheckIT(al);
   22957   if (IsUsingT32()) {
   22958     // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; T1
   22959     if (dt1.Is(F32) && dt2.Is(F32)) {
   22960       EmitT32_32(0xffba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
   22961       AdvanceIT();
   22962       return;
   22963     }
   22964   } else {
   22965     // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; A1
   22966     if (dt1.Is(F32) && dt2.Is(F32)) {
   22967       EmitA32(0xf3ba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
   22968       return;
   22969     }
   22970   }
   22971   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
   22972 }
   22973 
   22974 void Assembler::vrinta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   22975   VIXL_ASSERT(AllowAssembler());
   22976   CheckIT(al);
   22977   if (IsUsingT32()) {
   22978     // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; T1
   22979     if (dt1.Is(F32) && dt2.Is(F32)) {
   22980       EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   22981       AdvanceIT();
   22982       return;
   22983     }
   22984   } else {
   22985     // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; A1
   22986     if (dt1.Is(F32) && dt2.Is(F32)) {
   22987       EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   22988       return;
   22989     }
   22990   }
   22991   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
   22992 }
   22993 
   22994 void Assembler::vrintm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   22995   VIXL_ASSERT(AllowAssembler());
   22996   CheckIT(al);
   22997   if (IsUsingT32()) {
   22998     // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; T1
   22999     if (dt1.Is(F32) && dt2.Is(F32)) {
   23000       EmitT32_32(0xffba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23001       AdvanceIT();
   23002       return;
   23003     }
   23004     // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; T1
   23005     if (dt1.Is(F64) && dt2.Is(F64)) {
   23006       EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23007       AdvanceIT();
   23008       return;
   23009     }
   23010   } else {
   23011     // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; A1
   23012     if (dt1.Is(F32) && dt2.Is(F32)) {
   23013       EmitA32(0xf3ba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23014       return;
   23015     }
   23016     // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; A1
   23017     if (dt1.Is(F64) && dt2.Is(F64)) {
   23018       EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23019       return;
   23020     }
   23021   }
   23022   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
   23023 }
   23024 
   23025 void Assembler::vrintm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   23026   VIXL_ASSERT(AllowAssembler());
   23027   CheckIT(al);
   23028   if (IsUsingT32()) {
   23029     // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; T1
   23030     if (dt1.Is(F32) && dt2.Is(F32)) {
   23031       EmitT32_32(0xffba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23032       AdvanceIT();
   23033       return;
   23034     }
   23035   } else {
   23036     // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; A1
   23037     if (dt1.Is(F32) && dt2.Is(F32)) {
   23038       EmitA32(0xf3ba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23039       return;
   23040     }
   23041   }
   23042   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
   23043 }
   23044 
   23045 void Assembler::vrintm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   23046   VIXL_ASSERT(AllowAssembler());
   23047   CheckIT(al);
   23048   if (IsUsingT32()) {
   23049     // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; T1
   23050     if (dt1.Is(F32) && dt2.Is(F32)) {
   23051       EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23052       AdvanceIT();
   23053       return;
   23054     }
   23055   } else {
   23056     // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; A1
   23057     if (dt1.Is(F32) && dt2.Is(F32)) {
   23058       EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23059       return;
   23060     }
   23061   }
   23062   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
   23063 }
   23064 
   23065 void Assembler::vrintn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   23066   VIXL_ASSERT(AllowAssembler());
   23067   CheckIT(al);
   23068   if (IsUsingT32()) {
   23069     // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; T1
   23070     if (dt1.Is(F32) && dt2.Is(F32)) {
   23071       EmitT32_32(0xffba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23072       AdvanceIT();
   23073       return;
   23074     }
   23075     // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; T1
   23076     if (dt1.Is(F64) && dt2.Is(F64)) {
   23077       EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23078       AdvanceIT();
   23079       return;
   23080     }
   23081   } else {
   23082     // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; A1
   23083     if (dt1.Is(F32) && dt2.Is(F32)) {
   23084       EmitA32(0xf3ba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23085       return;
   23086     }
   23087     // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; A1
   23088     if (dt1.Is(F64) && dt2.Is(F64)) {
   23089       EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23090       return;
   23091     }
   23092   }
   23093   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
   23094 }
   23095 
   23096 void Assembler::vrintn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   23097   VIXL_ASSERT(AllowAssembler());
   23098   CheckIT(al);
   23099   if (IsUsingT32()) {
   23100     // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; T1
   23101     if (dt1.Is(F32) && dt2.Is(F32)) {
   23102       EmitT32_32(0xffba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23103       AdvanceIT();
   23104       return;
   23105     }
   23106   } else {
   23107     // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; A1
   23108     if (dt1.Is(F32) && dt2.Is(F32)) {
   23109       EmitA32(0xf3ba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23110       return;
   23111     }
   23112   }
   23113   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
   23114 }
   23115 
   23116 void Assembler::vrintn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   23117   VIXL_ASSERT(AllowAssembler());
   23118   CheckIT(al);
   23119   if (IsUsingT32()) {
   23120     // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; T1
   23121     if (dt1.Is(F32) && dt2.Is(F32)) {
   23122       EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23123       AdvanceIT();
   23124       return;
   23125     }
   23126   } else {
   23127     // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; A1
   23128     if (dt1.Is(F32) && dt2.Is(F32)) {
   23129       EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23130       return;
   23131     }
   23132   }
   23133   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
   23134 }
   23135 
   23136 void Assembler::vrintp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   23137   VIXL_ASSERT(AllowAssembler());
   23138   CheckIT(al);
   23139   if (IsUsingT32()) {
   23140     // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; T1
   23141     if (dt1.Is(F32) && dt2.Is(F32)) {
   23142       EmitT32_32(0xffba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23143       AdvanceIT();
   23144       return;
   23145     }
   23146     // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; T1
   23147     if (dt1.Is(F64) && dt2.Is(F64)) {
   23148       EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23149       AdvanceIT();
   23150       return;
   23151     }
   23152   } else {
   23153     // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; A1
   23154     if (dt1.Is(F32) && dt2.Is(F32)) {
   23155       EmitA32(0xf3ba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23156       return;
   23157     }
   23158     // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; A1
   23159     if (dt1.Is(F64) && dt2.Is(F64)) {
   23160       EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23161       return;
   23162     }
   23163   }
   23164   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
   23165 }
   23166 
   23167 void Assembler::vrintp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   23168   VIXL_ASSERT(AllowAssembler());
   23169   CheckIT(al);
   23170   if (IsUsingT32()) {
   23171     // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; T1
   23172     if (dt1.Is(F32) && dt2.Is(F32)) {
   23173       EmitT32_32(0xffba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23174       AdvanceIT();
   23175       return;
   23176     }
   23177   } else {
   23178     // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; A1
   23179     if (dt1.Is(F32) && dt2.Is(F32)) {
   23180       EmitA32(0xf3ba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23181       return;
   23182     }
   23183   }
   23184   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
   23185 }
   23186 
   23187 void Assembler::vrintp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   23188   VIXL_ASSERT(AllowAssembler());
   23189   CheckIT(al);
   23190   if (IsUsingT32()) {
   23191     // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; T1
   23192     if (dt1.Is(F32) && dt2.Is(F32)) {
   23193       EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23194       AdvanceIT();
   23195       return;
   23196     }
   23197   } else {
   23198     // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; A1
   23199     if (dt1.Is(F32) && dt2.Is(F32)) {
   23200       EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23201       return;
   23202     }
   23203   }
   23204   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
   23205 }
   23206 
   23207 void Assembler::vrintr(
   23208     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   23209   VIXL_ASSERT(AllowAssembler());
   23210   CheckIT(cond);
   23211   if (IsUsingT32()) {
   23212     // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
   23213     if (dt1.Is(F32) && dt2.Is(F32)) {
   23214       EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23215       AdvanceIT();
   23216       return;
   23217     }
   23218   } else {
   23219     // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
   23220     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
   23221       EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   23222               rm.Encode(5, 0));
   23223       return;
   23224     }
   23225   }
   23226   Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
   23227 }
   23228 
   23229 void Assembler::vrintr(
   23230     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   23231   VIXL_ASSERT(AllowAssembler());
   23232   CheckIT(cond);
   23233   if (IsUsingT32()) {
   23234     // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
   23235     if (dt1.Is(F64) && dt2.Is(F64)) {
   23236       EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23237       AdvanceIT();
   23238       return;
   23239     }
   23240   } else {
   23241     // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
   23242     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
   23243       EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   23244               rm.Encode(5, 0));
   23245       return;
   23246     }
   23247   }
   23248   Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
   23249 }
   23250 
   23251 void Assembler::vrintx(
   23252     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   23253   VIXL_ASSERT(AllowAssembler());
   23254   CheckIT(cond);
   23255   if (IsUsingT32()) {
   23256     // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; T1
   23257     if (dt1.Is(F32) && dt2.Is(F32)) {
   23258       EmitT32_32(0xffba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23259       AdvanceIT();
   23260       return;
   23261     }
   23262     // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
   23263     if (dt1.Is(F64) && dt2.Is(F64)) {
   23264       EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23265       AdvanceIT();
   23266       return;
   23267     }
   23268   } else {
   23269     // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; A1
   23270     if (dt1.Is(F32) && dt2.Is(F32)) {
   23271       EmitA32(0xf3ba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23272       return;
   23273     }
   23274     // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
   23275     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
   23276       EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   23277               rm.Encode(5, 0));
   23278       return;
   23279     }
   23280   }
   23281   Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
   23282 }
   23283 
   23284 void Assembler::vrintx(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   23285   VIXL_ASSERT(AllowAssembler());
   23286   CheckIT(al);
   23287   if (IsUsingT32()) {
   23288     // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; T1
   23289     if (dt1.Is(F32) && dt2.Is(F32)) {
   23290       EmitT32_32(0xffba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23291       AdvanceIT();
   23292       return;
   23293     }
   23294   } else {
   23295     // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; A1
   23296     if (dt1.Is(F32) && dt2.Is(F32)) {
   23297       EmitA32(0xf3ba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23298       return;
   23299     }
   23300   }
   23301   Delegate(kVrintx, &Assembler::vrintx, dt1, dt2, rd, rm);
   23302 }
   23303 
   23304 void Assembler::vrintx(
   23305     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   23306   VIXL_ASSERT(AllowAssembler());
   23307   CheckIT(cond);
   23308   if (IsUsingT32()) {
   23309     // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
   23310     if (dt1.Is(F32) && dt2.Is(F32)) {
   23311       EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23312       AdvanceIT();
   23313       return;
   23314     }
   23315   } else {
   23316     // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
   23317     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
   23318       EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   23319               rm.Encode(5, 0));
   23320       return;
   23321     }
   23322   }
   23323   Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
   23324 }
   23325 
   23326 void Assembler::vrintz(
   23327     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   23328   VIXL_ASSERT(AllowAssembler());
   23329   CheckIT(cond);
   23330   if (IsUsingT32()) {
   23331     // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; T1
   23332     if (dt1.Is(F32) && dt2.Is(F32)) {
   23333       EmitT32_32(0xffba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23334       AdvanceIT();
   23335       return;
   23336     }
   23337     // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
   23338     if (dt1.Is(F64) && dt2.Is(F64)) {
   23339       EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23340       AdvanceIT();
   23341       return;
   23342     }
   23343   } else {
   23344     // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; A1
   23345     if (dt1.Is(F32) && dt2.Is(F32)) {
   23346       EmitA32(0xf3ba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23347       return;
   23348     }
   23349     // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
   23350     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
   23351       EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   23352               rm.Encode(5, 0));
   23353       return;
   23354     }
   23355   }
   23356   Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
   23357 }
   23358 
   23359 void Assembler::vrintz(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   23360   VIXL_ASSERT(AllowAssembler());
   23361   CheckIT(al);
   23362   if (IsUsingT32()) {
   23363     // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; T1
   23364     if (dt1.Is(F32) && dt2.Is(F32)) {
   23365       EmitT32_32(0xffba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23366       AdvanceIT();
   23367       return;
   23368     }
   23369   } else {
   23370     // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; A1
   23371     if (dt1.Is(F32) && dt2.Is(F32)) {
   23372       EmitA32(0xf3ba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23373       return;
   23374     }
   23375   }
   23376   Delegate(kVrintz, &Assembler::vrintz, dt1, dt2, rd, rm);
   23377 }
   23378 
   23379 void Assembler::vrintz(
   23380     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   23381   VIXL_ASSERT(AllowAssembler());
   23382   CheckIT(cond);
   23383   if (IsUsingT32()) {
   23384     // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
   23385     if (dt1.Is(F32) && dt2.Is(F32)) {
   23386       EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   23387       AdvanceIT();
   23388       return;
   23389     }
   23390   } else {
   23391     // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
   23392     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
   23393       EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   23394               rm.Encode(5, 0));
   23395       return;
   23396     }
   23397   }
   23398   Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
   23399 }
   23400 
   23401 void Assembler::vrshl(
   23402     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
   23403   VIXL_ASSERT(AllowAssembler());
   23404   CheckIT(cond);
   23405   Dt_U_size_3 encoded_dt(dt);
   23406   if (IsUsingT32()) {
   23407     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
   23408     if (encoded_dt.IsValid()) {
   23409       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23410         EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23411                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   23412                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23413         AdvanceIT();
   23414         return;
   23415       }
   23416     }
   23417   } else {
   23418     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
   23419     if (encoded_dt.IsValid()) {
   23420       if (cond.Is(al)) {
   23421         EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23422                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   23423                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23424         return;
   23425       }
   23426     }
   23427   }
   23428   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
   23429 }
   23430 
   23431 void Assembler::vrshl(
   23432     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
   23433   VIXL_ASSERT(AllowAssembler());
   23434   CheckIT(cond);
   23435   Dt_U_size_3 encoded_dt(dt);
   23436   if (IsUsingT32()) {
   23437     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
   23438     if (encoded_dt.IsValid()) {
   23439       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23440         EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23441                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   23442                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23443         AdvanceIT();
   23444         return;
   23445       }
   23446     }
   23447   } else {
   23448     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
   23449     if (encoded_dt.IsValid()) {
   23450       if (cond.Is(al)) {
   23451         EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23452                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   23453                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23454         return;
   23455       }
   23456     }
   23457   }
   23458   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
   23459 }
   23460 
   23461 void Assembler::vrshr(Condition cond,
   23462                       DataType dt,
   23463                       DRegister rd,
   23464                       DRegister rm,
   23465                       const DOperand& operand) {
   23466   VIXL_ASSERT(AllowAssembler());
   23467   CheckIT(cond);
   23468   if (operand.IsImmediate()) {
   23469     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23470       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23471       Dt_L_imm6_1 encoded_dt(dt);
   23472       if (IsUsingT32()) {
   23473         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   23474         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   23475           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23476             uint32_t imm6 = dt.GetSize() - imm;
   23477             EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23478                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23479                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23480                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23481             AdvanceIT();
   23482             return;
   23483           }
   23484         }
   23485         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
   23486         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   23487           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23488             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   23489                        rm.Encode(5, 0));
   23490             AdvanceIT();
   23491             return;
   23492           }
   23493         }
   23494       } else {
   23495         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   23496         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   23497           if (cond.Is(al)) {
   23498             uint32_t imm6 = dt.GetSize() - imm;
   23499             EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23500                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23501                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23502                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23503             return;
   23504           }
   23505         }
   23506         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
   23507         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   23508           if (cond.Is(al)) {
   23509             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   23510                     rm.Encode(5, 0));
   23511             return;
   23512           }
   23513         }
   23514       }
   23515     }
   23516   }
   23517   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
   23518 }
   23519 
   23520 void Assembler::vrshr(Condition cond,
   23521                       DataType dt,
   23522                       QRegister rd,
   23523                       QRegister rm,
   23524                       const QOperand& operand) {
   23525   VIXL_ASSERT(AllowAssembler());
   23526   CheckIT(cond);
   23527   if (operand.IsImmediate()) {
   23528     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23529       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23530       Dt_L_imm6_1 encoded_dt(dt);
   23531       if (IsUsingT32()) {
   23532         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   23533         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   23534           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23535             uint32_t imm6 = dt.GetSize() - imm;
   23536             EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23537                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23538                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23539                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23540             AdvanceIT();
   23541             return;
   23542           }
   23543         }
   23544         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
   23545         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   23546           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23547             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   23548                        rm.Encode(5, 0));
   23549             AdvanceIT();
   23550             return;
   23551           }
   23552         }
   23553       } else {
   23554         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   23555         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   23556           if (cond.Is(al)) {
   23557             uint32_t imm6 = dt.GetSize() - imm;
   23558             EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23559                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23560                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23561                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23562             return;
   23563           }
   23564         }
   23565         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
   23566         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   23567           if (cond.Is(al)) {
   23568             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   23569                     rm.Encode(5, 0));
   23570             return;
   23571           }
   23572         }
   23573       }
   23574     }
   23575   }
   23576   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
   23577 }
   23578 
   23579 void Assembler::vrshrn(Condition cond,
   23580                        DataType dt,
   23581                        DRegister rd,
   23582                        QRegister rm,
   23583                        const QOperand& operand) {
   23584   VIXL_ASSERT(AllowAssembler());
   23585   CheckIT(cond);
   23586   if (operand.IsImmediate()) {
   23587     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23588       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23589       Dt_imm6_3 encoded_dt(dt);
   23590       Dt_size_3 encoded_dt_2(dt);
   23591       if (IsUsingT32()) {
   23592         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
   23593         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23594           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23595             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23596             EmitT32_32(0xef800850U |
   23597                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23598                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23599             AdvanceIT();
   23600             return;
   23601           }
   23602         }
   23603         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   23604         if (encoded_dt_2.IsValid() && (imm == 0)) {
   23605           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23606             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
   23607                        rd.Encode(22, 12) | rm.Encode(5, 0));
   23608             AdvanceIT();
   23609             return;
   23610           }
   23611         }
   23612       } else {
   23613         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
   23614         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23615           if (cond.Is(al)) {
   23616             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23617             EmitA32(0xf2800850U |
   23618                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23619                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23620             return;
   23621           }
   23622         }
   23623         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   23624         if (encoded_dt_2.IsValid() && (imm == 0)) {
   23625           if (cond.Is(al)) {
   23626             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
   23627                     rd.Encode(22, 12) | rm.Encode(5, 0));
   23628             return;
   23629           }
   23630         }
   23631       }
   23632     }
   23633   }
   23634   Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
   23635 }
   23636 
   23637 void Assembler::vrsqrte(Condition cond,
   23638                         DataType dt,
   23639                         DRegister rd,
   23640                         DRegister rm) {
   23641   VIXL_ASSERT(AllowAssembler());
   23642   CheckIT(cond);
   23643   Dt_F_size_4 encoded_dt(dt);
   23644   if (IsUsingT32()) {
   23645     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   23646     if (encoded_dt.IsValid()) {
   23647       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23648         EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23649                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   23650                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23651         AdvanceIT();
   23652         return;
   23653       }
   23654     }
   23655   } else {
   23656     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   23657     if (encoded_dt.IsValid()) {
   23658       if (cond.Is(al)) {
   23659         EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23660                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   23661                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23662         return;
   23663       }
   23664     }
   23665   }
   23666   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
   23667 }
   23668 
   23669 void Assembler::vrsqrte(Condition cond,
   23670                         DataType dt,
   23671                         QRegister rd,
   23672                         QRegister rm) {
   23673   VIXL_ASSERT(AllowAssembler());
   23674   CheckIT(cond);
   23675   Dt_F_size_4 encoded_dt(dt);
   23676   if (IsUsingT32()) {
   23677     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   23678     if (encoded_dt.IsValid()) {
   23679       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23680         EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23681                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   23682                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23683         AdvanceIT();
   23684         return;
   23685       }
   23686     }
   23687   } else {
   23688     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   23689     if (encoded_dt.IsValid()) {
   23690       if (cond.Is(al)) {
   23691         EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23692                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   23693                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23694         return;
   23695       }
   23696     }
   23697   }
   23698   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
   23699 }
   23700 
   23701 void Assembler::vrsqrts(
   23702     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   23703   VIXL_ASSERT(AllowAssembler());
   23704   CheckIT(cond);
   23705   if (IsUsingT32()) {
   23706     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   23707     if (dt.Is(F32)) {
   23708       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23709         EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23710                    rm.Encode(5, 0));
   23711         AdvanceIT();
   23712         return;
   23713       }
   23714     }
   23715   } else {
   23716     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   23717     if (dt.Is(F32)) {
   23718       if (cond.Is(al)) {
   23719         EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23720                 rm.Encode(5, 0));
   23721         return;
   23722       }
   23723     }
   23724   }
   23725   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
   23726 }
   23727 
   23728 void Assembler::vrsqrts(
   23729     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   23730   VIXL_ASSERT(AllowAssembler());
   23731   CheckIT(cond);
   23732   if (IsUsingT32()) {
   23733     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   23734     if (dt.Is(F32)) {
   23735       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23736         EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23737                    rm.Encode(5, 0));
   23738         AdvanceIT();
   23739         return;
   23740       }
   23741     }
   23742   } else {
   23743     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   23744     if (dt.Is(F32)) {
   23745       if (cond.Is(al)) {
   23746         EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23747                 rm.Encode(5, 0));
   23748         return;
   23749       }
   23750     }
   23751   }
   23752   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
   23753 }
   23754 
   23755 void Assembler::vrsra(Condition cond,
   23756                       DataType dt,
   23757                       DRegister rd,
   23758                       DRegister rm,
   23759                       const DOperand& operand) {
   23760   VIXL_ASSERT(AllowAssembler());
   23761   CheckIT(cond);
   23762   if (operand.IsImmediate()) {
   23763     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23764       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23765       Dt_L_imm6_1 encoded_dt(dt);
   23766       if (IsUsingT32()) {
   23767         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   23768         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   23769           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23770             uint32_t imm6 = dt.GetSize() - imm;
   23771             EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23772                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23773                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23774                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23775             AdvanceIT();
   23776             return;
   23777           }
   23778         }
   23779       } else {
   23780         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   23781         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   23782           if (cond.Is(al)) {
   23783             uint32_t imm6 = dt.GetSize() - imm;
   23784             EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23785                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23786                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23787                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23788             return;
   23789           }
   23790         }
   23791       }
   23792     }
   23793   }
   23794   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
   23795 }
   23796 
   23797 void Assembler::vrsra(Condition cond,
   23798                       DataType dt,
   23799                       QRegister rd,
   23800                       QRegister rm,
   23801                       const QOperand& operand) {
   23802   VIXL_ASSERT(AllowAssembler());
   23803   CheckIT(cond);
   23804   if (operand.IsImmediate()) {
   23805     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23806       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23807       Dt_L_imm6_1 encoded_dt(dt);
   23808       if (IsUsingT32()) {
   23809         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   23810         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   23811           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23812             uint32_t imm6 = dt.GetSize() - imm;
   23813             EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23814                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23815                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23816                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23817             AdvanceIT();
   23818             return;
   23819           }
   23820         }
   23821       } else {
   23822         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   23823         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   23824           if (cond.Is(al)) {
   23825             uint32_t imm6 = dt.GetSize() - imm;
   23826             EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23827                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23828                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23829                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23830             return;
   23831           }
   23832         }
   23833       }
   23834     }
   23835   }
   23836   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
   23837 }
   23838 
   23839 void Assembler::vrsubhn(
   23840     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
   23841   VIXL_ASSERT(AllowAssembler());
   23842   CheckIT(cond);
   23843   Dt_size_3 encoded_dt(dt);
   23844   if (IsUsingT32()) {
   23845     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
   23846     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   23847       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23848         EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
   23849                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23850         AdvanceIT();
   23851         return;
   23852       }
   23853     }
   23854   } else {
   23855     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
   23856     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   23857       if (cond.Is(al)) {
   23858         EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
   23859                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23860         return;
   23861       }
   23862     }
   23863   }
   23864   Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
   23865 }
   23866 
   23867 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   23868   VIXL_ASSERT(AllowAssembler());
   23869   CheckIT(al);
   23870   if (IsUsingT32()) {
   23871     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
   23872     if (OutsideITBlock() && dt.Is(F64)) {
   23873       EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23874                  rm.Encode(5, 0));
   23875       AdvanceIT();
   23876       return;
   23877     }
   23878   } else {
   23879     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
   23880     if (dt.Is(F64)) {
   23881       EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23882               rm.Encode(5, 0));
   23883       return;
   23884     }
   23885   }
   23886   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
   23887 }
   23888 
   23889 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   23890   VIXL_ASSERT(AllowAssembler());
   23891   CheckIT(al);
   23892   if (IsUsingT32()) {
   23893     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
   23894     if (OutsideITBlock() && dt.Is(F32)) {
   23895       EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23896                  rm.Encode(5, 0));
   23897       AdvanceIT();
   23898       return;
   23899     }
   23900   } else {
   23901     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
   23902     if (dt.Is(F32)) {
   23903       EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23904               rm.Encode(5, 0));
   23905       return;
   23906     }
   23907   }
   23908   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
   23909 }
   23910 
   23911 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   23912   VIXL_ASSERT(AllowAssembler());
   23913   CheckIT(al);
   23914   if (IsUsingT32()) {
   23915     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
   23916     if (OutsideITBlock() && dt.Is(F64)) {
   23917       EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23918                  rm.Encode(5, 0));
   23919       AdvanceIT();
   23920       return;
   23921     }
   23922   } else {
   23923     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
   23924     if (dt.Is(F64)) {
   23925       EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23926               rm.Encode(5, 0));
   23927       return;
   23928     }
   23929   }
   23930   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
   23931 }
   23932 
   23933 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   23934   VIXL_ASSERT(AllowAssembler());
   23935   CheckIT(al);
   23936   if (IsUsingT32()) {
   23937     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
   23938     if (OutsideITBlock() && dt.Is(F32)) {
   23939       EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23940                  rm.Encode(5, 0));
   23941       AdvanceIT();
   23942       return;
   23943     }
   23944   } else {
   23945     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
   23946     if (dt.Is(F32)) {
   23947       EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23948               rm.Encode(5, 0));
   23949       return;
   23950     }
   23951   }
   23952   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
   23953 }
   23954 
   23955 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   23956   VIXL_ASSERT(AllowAssembler());
   23957   CheckIT(al);
   23958   if (IsUsingT32()) {
   23959     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
   23960     if (OutsideITBlock() && dt.Is(F64)) {
   23961       EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23962                  rm.Encode(5, 0));
   23963       AdvanceIT();
   23964       return;
   23965     }
   23966   } else {
   23967     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
   23968     if (dt.Is(F64)) {
   23969       EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23970               rm.Encode(5, 0));
   23971       return;
   23972     }
   23973   }
   23974   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
   23975 }
   23976 
   23977 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   23978   VIXL_ASSERT(AllowAssembler());
   23979   CheckIT(al);
   23980   if (IsUsingT32()) {
   23981     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
   23982     if (OutsideITBlock() && dt.Is(F32)) {
   23983       EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23984                  rm.Encode(5, 0));
   23985       AdvanceIT();
   23986       return;
   23987     }
   23988   } else {
   23989     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
   23990     if (dt.Is(F32)) {
   23991       EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23992               rm.Encode(5, 0));
   23993       return;
   23994     }
   23995   }
   23996   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
   23997 }
   23998 
   23999 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   24000   VIXL_ASSERT(AllowAssembler());
   24001   CheckIT(al);
   24002   if (IsUsingT32()) {
   24003     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
   24004     if (OutsideITBlock() && dt.Is(F64)) {
   24005       EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   24006                  rm.Encode(5, 0));
   24007       AdvanceIT();
   24008       return;
   24009     }
   24010   } else {
   24011     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
   24012     if (dt.Is(F64)) {
   24013       EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   24014               rm.Encode(5, 0));
   24015       return;
   24016     }
   24017   }
   24018   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
   24019 }
   24020 
   24021 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   24022   VIXL_ASSERT(AllowAssembler());
   24023   CheckIT(al);
   24024   if (IsUsingT32()) {
   24025     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
   24026     if (OutsideITBlock() && dt.Is(F32)) {
   24027       EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   24028                  rm.Encode(5, 0));
   24029       AdvanceIT();
   24030       return;
   24031     }
   24032   } else {
   24033     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
   24034     if (dt.Is(F32)) {
   24035       EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   24036               rm.Encode(5, 0));
   24037       return;
   24038     }
   24039   }
   24040   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
   24041 }
   24042 
   24043 void Assembler::vshl(Condition cond,
   24044                      DataType dt,
   24045                      DRegister rd,
   24046                      DRegister rm,
   24047                      const DOperand& operand) {
   24048   VIXL_ASSERT(AllowAssembler());
   24049   CheckIT(cond);
   24050   if (operand.IsImmediate()) {
   24051     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24052       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24053       Dt_L_imm6_3 encoded_dt(dt);
   24054       if (IsUsingT32()) {
   24055         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
   24056         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   24057           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24058             uint32_t imm6 = imm;
   24059             EmitT32_32(0xef800510U |
   24060                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24061                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24062                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24063             AdvanceIT();
   24064             return;
   24065           }
   24066         }
   24067       } else {
   24068         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
   24069         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   24070           if (cond.Is(al)) {
   24071             uint32_t imm6 = imm;
   24072             EmitA32(0xf2800510U |
   24073                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24074                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24075                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24076             return;
   24077           }
   24078         }
   24079       }
   24080     }
   24081   }
   24082   if (operand.IsRegister()) {
   24083     DRegister rn = operand.GetRegister();
   24084     Dt_U_size_3 encoded_dt(dt);
   24085     if (IsUsingT32()) {
   24086       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
   24087       if (encoded_dt.IsValid()) {
   24088         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24089           EmitT32_32(0xef000400U |
   24090                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24091                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   24092                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   24093           AdvanceIT();
   24094           return;
   24095         }
   24096       }
   24097     } else {
   24098       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
   24099       if (encoded_dt.IsValid()) {
   24100         if (cond.Is(al)) {
   24101           EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24102                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   24103                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   24104           return;
   24105         }
   24106       }
   24107     }
   24108   }
   24109   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
   24110 }
   24111 
   24112 void Assembler::vshl(Condition cond,
   24113                      DataType dt,
   24114                      QRegister rd,
   24115                      QRegister rm,
   24116                      const QOperand& operand) {
   24117   VIXL_ASSERT(AllowAssembler());
   24118   CheckIT(cond);
   24119   if (operand.IsImmediate()) {
   24120     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24121       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24122       Dt_L_imm6_3 encoded_dt(dt);
   24123       if (IsUsingT32()) {
   24124         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
   24125         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   24126           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24127             uint32_t imm6 = imm;
   24128             EmitT32_32(0xef800550U |
   24129                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24130                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24131                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24132             AdvanceIT();
   24133             return;
   24134           }
   24135         }
   24136       } else {
   24137         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
   24138         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   24139           if (cond.Is(al)) {
   24140             uint32_t imm6 = imm;
   24141             EmitA32(0xf2800550U |
   24142                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24143                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24144                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24145             return;
   24146           }
   24147         }
   24148       }
   24149     }
   24150   }
   24151   if (operand.IsRegister()) {
   24152     QRegister rn = operand.GetRegister();
   24153     Dt_U_size_3 encoded_dt(dt);
   24154     if (IsUsingT32()) {
   24155       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
   24156       if (encoded_dt.IsValid()) {
   24157         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24158           EmitT32_32(0xef000440U |
   24159                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24160                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   24161                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   24162           AdvanceIT();
   24163           return;
   24164         }
   24165       }
   24166     } else {
   24167       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
   24168       if (encoded_dt.IsValid()) {
   24169         if (cond.Is(al)) {
   24170           EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24171                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   24172                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   24173           return;
   24174         }
   24175       }
   24176     }
   24177   }
   24178   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
   24179 }
   24180 
   24181 void Assembler::vshll(Condition cond,
   24182                       DataType dt,
   24183                       QRegister rd,
   24184                       DRegister rm,
   24185                       const DOperand& operand) {
   24186   VIXL_ASSERT(AllowAssembler());
   24187   CheckIT(cond);
   24188   if (operand.IsImmediate()) {
   24189     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24190       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24191       Dt_imm6_4 encoded_dt(dt);
   24192       Dt_size_16 encoded_dt_2(dt);
   24193       if (IsUsingT32()) {
   24194         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
   24195         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
   24196           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24197             uint32_t imm6 = dt.GetSize() + imm;
   24198             EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
   24199                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24200                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24201             AdvanceIT();
   24202             return;
   24203           }
   24204         }
   24205         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
   24206         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
   24207           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24208             EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
   24209                        rd.Encode(22, 12) | rm.Encode(5, 0));
   24210             AdvanceIT();
   24211             return;
   24212           }
   24213         }
   24214       } else {
   24215         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
   24216         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
   24217           if (cond.Is(al)) {
   24218             uint32_t imm6 = dt.GetSize() + imm;
   24219             EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
   24220                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24221                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24222             return;
   24223           }
   24224         }
   24225         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
   24226         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
   24227           if (cond.Is(al)) {
   24228             EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
   24229                     rd.Encode(22, 12) | rm.Encode(5, 0));
   24230             return;
   24231           }
   24232         }
   24233       }
   24234     }
   24235   }
   24236   Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
   24237 }
   24238 
   24239 void Assembler::vshr(Condition cond,
   24240                      DataType dt,
   24241                      DRegister rd,
   24242                      DRegister rm,
   24243                      const DOperand& operand) {
   24244   VIXL_ASSERT(AllowAssembler());
   24245   CheckIT(cond);
   24246   if (operand.IsImmediate()) {
   24247     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24248       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24249       Dt_L_imm6_1 encoded_dt(dt);
   24250       if (IsUsingT32()) {
   24251         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   24252         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24253           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24254             uint32_t imm6 = dt.GetSize() - imm;
   24255             EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
   24256                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24257                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24258                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24259             AdvanceIT();
   24260             return;
   24261           }
   24262         }
   24263         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
   24264         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   24265           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24266             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   24267                        rm.Encode(5, 0));
   24268             AdvanceIT();
   24269             return;
   24270           }
   24271         }
   24272       } else {
   24273         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   24274         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24275           if (cond.Is(al)) {
   24276             uint32_t imm6 = dt.GetSize() - imm;
   24277             EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
   24278                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24279                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24280                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24281             return;
   24282           }
   24283         }
   24284         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
   24285         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   24286           if (cond.Is(al)) {
   24287             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   24288                     rm.Encode(5, 0));
   24289             return;
   24290           }
   24291         }
   24292       }
   24293     }
   24294   }
   24295   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
   24296 }
   24297 
   24298 void Assembler::vshr(Condition cond,
   24299                      DataType dt,
   24300                      QRegister rd,
   24301                      QRegister rm,
   24302                      const QOperand& operand) {
   24303   VIXL_ASSERT(AllowAssembler());
   24304   CheckIT(cond);
   24305   if (operand.IsImmediate()) {
   24306     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24307       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24308       Dt_L_imm6_1 encoded_dt(dt);
   24309       if (IsUsingT32()) {
   24310         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   24311         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24312           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24313             uint32_t imm6 = dt.GetSize() - imm;
   24314             EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
   24315                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24316                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24317                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24318             AdvanceIT();
   24319             return;
   24320           }
   24321         }
   24322         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
   24323         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   24324           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24325             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   24326                        rm.Encode(5, 0));
   24327             AdvanceIT();
   24328             return;
   24329           }
   24330         }
   24331       } else {
   24332         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   24333         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24334           if (cond.Is(al)) {
   24335             uint32_t imm6 = dt.GetSize() - imm;
   24336             EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
   24337                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24338                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24339                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24340             return;
   24341           }
   24342         }
   24343         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
   24344         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   24345           if (cond.Is(al)) {
   24346             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   24347                     rm.Encode(5, 0));
   24348             return;
   24349           }
   24350         }
   24351       }
   24352     }
   24353   }
   24354   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
   24355 }
   24356 
   24357 void Assembler::vshrn(Condition cond,
   24358                       DataType dt,
   24359                       DRegister rd,
   24360                       QRegister rm,
   24361                       const QOperand& operand) {
   24362   VIXL_ASSERT(AllowAssembler());
   24363   CheckIT(cond);
   24364   if (operand.IsImmediate()) {
   24365     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24366       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24367       Dt_imm6_3 encoded_dt(dt);
   24368       Dt_size_3 encoded_dt_2(dt);
   24369       if (IsUsingT32()) {
   24370         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
   24371         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   24372           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24373             uint32_t imm6 = dt.GetSize() / 2 - imm;
   24374             EmitT32_32(0xef800810U |
   24375                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24376                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24377             AdvanceIT();
   24378             return;
   24379           }
   24380         }
   24381         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   24382         if (encoded_dt_2.IsValid() && (imm == 0)) {
   24383           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24384             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
   24385                        rd.Encode(22, 12) | rm.Encode(5, 0));
   24386             AdvanceIT();
   24387             return;
   24388           }
   24389         }
   24390       } else {
   24391         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
   24392         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   24393           if (cond.Is(al)) {
   24394             uint32_t imm6 = dt.GetSize() / 2 - imm;
   24395             EmitA32(0xf2800810U |
   24396                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24397                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24398             return;
   24399           }
   24400         }
   24401         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   24402         if (encoded_dt_2.IsValid() && (imm == 0)) {
   24403           if (cond.Is(al)) {
   24404             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
   24405                     rd.Encode(22, 12) | rm.Encode(5, 0));
   24406             return;
   24407           }
   24408         }
   24409       }
   24410     }
   24411   }
   24412   Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
   24413 }
   24414 
   24415 void Assembler::vsli(Condition cond,
   24416                      DataType dt,
   24417                      DRegister rd,
   24418                      DRegister rm,
   24419                      const DOperand& operand) {
   24420   VIXL_ASSERT(AllowAssembler());
   24421   CheckIT(cond);
   24422   if (operand.IsImmediate()) {
   24423     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24424       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24425       Dt_L_imm6_4 encoded_dt(dt);
   24426       if (IsUsingT32()) {
   24427         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
   24428         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   24429           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24430             uint32_t imm6 = imm;
   24431             EmitT32_32(0xff800510U |
   24432                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24433                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24434                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24435             AdvanceIT();
   24436             return;
   24437           }
   24438         }
   24439       } else {
   24440         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
   24441         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   24442           if (cond.Is(al)) {
   24443             uint32_t imm6 = imm;
   24444             EmitA32(0xf3800510U |
   24445                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24446                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24447                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24448             return;
   24449           }
   24450         }
   24451       }
   24452     }
   24453   }
   24454   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
   24455 }
   24456 
   24457 void Assembler::vsli(Condition cond,
   24458                      DataType dt,
   24459                      QRegister rd,
   24460                      QRegister rm,
   24461                      const QOperand& operand) {
   24462   VIXL_ASSERT(AllowAssembler());
   24463   CheckIT(cond);
   24464   if (operand.IsImmediate()) {
   24465     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24466       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24467       Dt_L_imm6_4 encoded_dt(dt);
   24468       if (IsUsingT32()) {
   24469         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
   24470         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   24471           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24472             uint32_t imm6 = imm;
   24473             EmitT32_32(0xff800550U |
   24474                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24475                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24476                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24477             AdvanceIT();
   24478             return;
   24479           }
   24480         }
   24481       } else {
   24482         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
   24483         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   24484           if (cond.Is(al)) {
   24485             uint32_t imm6 = imm;
   24486             EmitA32(0xf3800550U |
   24487                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24488                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24489                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24490             return;
   24491           }
   24492         }
   24493       }
   24494     }
   24495   }
   24496   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
   24497 }
   24498 
   24499 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
   24500   VIXL_ASSERT(AllowAssembler());
   24501   CheckIT(cond);
   24502   if (IsUsingT32()) {
   24503     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
   24504     if (dt.Is(F32)) {
   24505       EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24506       AdvanceIT();
   24507       return;
   24508     }
   24509   } else {
   24510     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
   24511     if (dt.Is(F32) && cond.IsNotNever()) {
   24512       EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   24513               rm.Encode(5, 0));
   24514       return;
   24515     }
   24516   }
   24517   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
   24518 }
   24519 
   24520 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   24521   VIXL_ASSERT(AllowAssembler());
   24522   CheckIT(cond);
   24523   if (IsUsingT32()) {
   24524     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
   24525     if (dt.Is(F64)) {
   24526       EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24527       AdvanceIT();
   24528       return;
   24529     }
   24530   } else {
   24531     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
   24532     if (dt.Is(F64) && cond.IsNotNever()) {
   24533       EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   24534               rm.Encode(5, 0));
   24535       return;
   24536     }
   24537   }
   24538   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
   24539 }
   24540 
   24541 void Assembler::vsra(Condition cond,
   24542                      DataType dt,
   24543                      DRegister rd,
   24544                      DRegister rm,
   24545                      const DOperand& operand) {
   24546   VIXL_ASSERT(AllowAssembler());
   24547   CheckIT(cond);
   24548   if (operand.IsImmediate()) {
   24549     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24550       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24551       Dt_L_imm6_1 encoded_dt(dt);
   24552       if (IsUsingT32()) {
   24553         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   24554         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24555           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24556             uint32_t imm6 = dt.GetSize() - imm;
   24557             EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
   24558                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24559                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24560                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24561             AdvanceIT();
   24562             return;
   24563           }
   24564         }
   24565       } else {
   24566         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   24567         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24568           if (cond.Is(al)) {
   24569             uint32_t imm6 = dt.GetSize() - imm;
   24570             EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
   24571                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24572                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24573                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24574             return;
   24575           }
   24576         }
   24577       }
   24578     }
   24579   }
   24580   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
   24581 }
   24582 
   24583 void Assembler::vsra(Condition cond,
   24584                      DataType dt,
   24585                      QRegister rd,
   24586                      QRegister rm,
   24587                      const QOperand& operand) {
   24588   VIXL_ASSERT(AllowAssembler());
   24589   CheckIT(cond);
   24590   if (operand.IsImmediate()) {
   24591     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24592       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24593       Dt_L_imm6_1 encoded_dt(dt);
   24594       if (IsUsingT32()) {
   24595         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   24596         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24597           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24598             uint32_t imm6 = dt.GetSize() - imm;
   24599             EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
   24600                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24601                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24602                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24603             AdvanceIT();
   24604             return;
   24605           }
   24606         }
   24607       } else {
   24608         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   24609         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24610           if (cond.Is(al)) {
   24611             uint32_t imm6 = dt.GetSize() - imm;
   24612             EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
   24613                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24614                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24615                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24616             return;
   24617           }
   24618         }
   24619       }
   24620     }
   24621   }
   24622   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
   24623 }
   24624 
   24625 void Assembler::vsri(Condition cond,
   24626                      DataType dt,
   24627                      DRegister rd,
   24628                      DRegister rm,
   24629                      const DOperand& operand) {
   24630   VIXL_ASSERT(AllowAssembler());
   24631   CheckIT(cond);
   24632   if (operand.IsImmediate()) {
   24633     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24634       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24635       Dt_L_imm6_4 encoded_dt(dt);
   24636       if (IsUsingT32()) {
   24637         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
   24638         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24639           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24640             uint32_t imm6 = dt.GetSize() - imm;
   24641             EmitT32_32(0xff800410U |
   24642                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24643                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24644                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24645             AdvanceIT();
   24646             return;
   24647           }
   24648         }
   24649       } else {
   24650         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
   24651         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24652           if (cond.Is(al)) {
   24653             uint32_t imm6 = dt.GetSize() - imm;
   24654             EmitA32(0xf3800410U |
   24655                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24656                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24657                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24658             return;
   24659           }
   24660         }
   24661       }
   24662     }
   24663   }
   24664   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
   24665 }
   24666 
   24667 void Assembler::vsri(Condition cond,
   24668                      DataType dt,
   24669                      QRegister rd,
   24670                      QRegister rm,
   24671                      const QOperand& operand) {
   24672   VIXL_ASSERT(AllowAssembler());
   24673   CheckIT(cond);
   24674   if (operand.IsImmediate()) {
   24675     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24676       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24677       Dt_L_imm6_4 encoded_dt(dt);
   24678       if (IsUsingT32()) {
   24679         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
   24680         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24681           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24682             uint32_t imm6 = dt.GetSize() - imm;
   24683             EmitT32_32(0xff800450U |
   24684                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24685                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24686                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24687             AdvanceIT();
   24688             return;
   24689           }
   24690         }
   24691       } else {
   24692         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
   24693         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24694           if (cond.Is(al)) {
   24695             uint32_t imm6 = dt.GetSize() - imm;
   24696             EmitA32(0xf3800450U |
   24697                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24698                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24699                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24700             return;
   24701           }
   24702         }
   24703       }
   24704     }
   24705   }
   24706   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
   24707 }
   24708 
   24709 void Assembler::vst1(Condition cond,
   24710                      DataType dt,
   24711                      const NeonRegisterList& nreglist,
   24712                      const AlignedMemOperand& operand) {
   24713   VIXL_ASSERT(AllowAssembler());
   24714   CheckIT(cond);
   24715   if (operand.IsImmediateZero()) {
   24716     Register rn = operand.GetBaseRegister();
   24717     Alignment align = operand.GetAlignment();
   24718     Dt_size_6 encoded_dt(dt);
   24719     Dt_size_7 encoded_dt_2(dt);
   24720     Align_align_5 encoded_align_1(align, nreglist);
   24721     Align_index_align_1 encoded_align_2(align, nreglist, dt);
   24722     if (IsUsingT32()) {
   24723       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   24724       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   24725           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   24726           operand.IsOffset() && encoded_align_1.IsValid() &&
   24727           (!rn.IsPC() || AllowUnpredictable())) {
   24728         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24729           const DRegister& first = nreglist.GetFirstDRegister();
   24730           uint32_t len_encoding;
   24731           switch (nreglist.GetLength()) {
   24732             default:
   24733               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   24734             case 1:
   24735               len_encoding = 0x7;
   24736               break;
   24737             case 2:
   24738               len_encoding = 0xa;
   24739               break;
   24740             case 3:
   24741               len_encoding = 0x6;
   24742               break;
   24743             case 4:
   24744               len_encoding = 0x2;
   24745               break;
   24746           }
   24747           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
   24748                      (encoded_align_1.GetEncodingValue() << 4) |
   24749                      first.Encode(22, 12) | (len_encoding << 8) |
   24750                      (rn.GetCode() << 16));
   24751           AdvanceIT();
   24752           return;
   24753         }
   24754       }
   24755       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   24756       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   24757           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   24758           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   24759           (!rn.IsPC() || AllowUnpredictable())) {
   24760         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24761           const DRegister& first = nreglist.GetFirstDRegister();
   24762           uint32_t len_encoding;
   24763           switch (nreglist.GetLength()) {
   24764             default:
   24765               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   24766             case 1:
   24767               len_encoding = 0x7;
   24768               break;
   24769             case 2:
   24770               len_encoding = 0xa;
   24771               break;
   24772             case 3:
   24773               len_encoding = 0x6;
   24774               break;
   24775             case 4:
   24776               len_encoding = 0x2;
   24777               break;
   24778           }
   24779           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
   24780                      (encoded_align_1.GetEncodingValue() << 4) |
   24781                      first.Encode(22, 12) | (len_encoding << 8) |
   24782                      (rn.GetCode() << 16));
   24783           AdvanceIT();
   24784           return;
   24785         }
   24786       }
   24787       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   24788       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   24789           (nreglist.GetLength() == 1) && operand.IsOffset() &&
   24790           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   24791         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24792           const DRegister& first = nreglist.GetFirstDRegister();
   24793           EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
   24794                      (encoded_align_2.GetEncodingValue() << 4) |
   24795                      first.Encode(22, 12) | (rn.GetCode() << 16));
   24796           AdvanceIT();
   24797           return;
   24798         }
   24799       }
   24800       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   24801       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   24802           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
   24803           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   24804         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24805           const DRegister& first = nreglist.GetFirstDRegister();
   24806           EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
   24807                      (encoded_align_2.GetEncodingValue() << 4) |
   24808                      first.Encode(22, 12) | (rn.GetCode() << 16));
   24809           AdvanceIT();
   24810           return;
   24811         }
   24812       }
   24813     } else {
   24814       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   24815       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   24816           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   24817           operand.IsOffset() && encoded_align_1.IsValid() &&
   24818           (!rn.IsPC() || AllowUnpredictable())) {
   24819         if (cond.Is(al)) {
   24820           const DRegister& first = nreglist.GetFirstDRegister();
   24821           uint32_t len_encoding;
   24822           switch (nreglist.GetLength()) {
   24823             default:
   24824               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   24825             case 1:
   24826               len_encoding = 0x7;
   24827               break;
   24828             case 2:
   24829               len_encoding = 0xa;
   24830               break;
   24831             case 3:
   24832               len_encoding = 0x6;
   24833               break;
   24834             case 4:
   24835               len_encoding = 0x2;
   24836               break;
   24837           }
   24838           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
   24839                   (encoded_align_1.GetEncodingValue() << 4) |
   24840                   first.Encode(22, 12) | (len_encoding << 8) |
   24841                   (rn.GetCode() << 16));
   24842           return;
   24843         }
   24844       }
   24845       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   24846       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   24847           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   24848           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   24849           (!rn.IsPC() || AllowUnpredictable())) {
   24850         if (cond.Is(al)) {
   24851           const DRegister& first = nreglist.GetFirstDRegister();
   24852           uint32_t len_encoding;
   24853           switch (nreglist.GetLength()) {
   24854             default:
   24855               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   24856             case 1:
   24857               len_encoding = 0x7;
   24858               break;
   24859             case 2:
   24860               len_encoding = 0xa;
   24861               break;
   24862             case 3:
   24863               len_encoding = 0x6;
   24864               break;
   24865             case 4:
   24866               len_encoding = 0x2;
   24867               break;
   24868           }
   24869           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
   24870                   (encoded_align_1.GetEncodingValue() << 4) |
   24871                   first.Encode(22, 12) | (len_encoding << 8) |
   24872                   (rn.GetCode() << 16));
   24873           return;
   24874         }
   24875       }
   24876       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   24877       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   24878           (nreglist.GetLength() == 1) && operand.IsOffset() &&
   24879           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   24880         if (cond.Is(al)) {
   24881           const DRegister& first = nreglist.GetFirstDRegister();
   24882           EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
   24883                   (encoded_align_2.GetEncodingValue() << 4) |
   24884                   first.Encode(22, 12) | (rn.GetCode() << 16));
   24885           return;
   24886         }
   24887       }
   24888       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   24889       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   24890           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
   24891           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   24892         if (cond.Is(al)) {
   24893           const DRegister& first = nreglist.GetFirstDRegister();
   24894           EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
   24895                   (encoded_align_2.GetEncodingValue() << 4) |
   24896                   first.Encode(22, 12) | (rn.GetCode() << 16));
   24897           return;
   24898         }
   24899       }
   24900     }
   24901   }
   24902   if (operand.IsPlainRegister()) {
   24903     Register rn = operand.GetBaseRegister();
   24904     Alignment align = operand.GetAlignment();
   24905     Register rm = operand.GetOffsetRegister();
   24906     Dt_size_6 encoded_dt(dt);
   24907     Dt_size_7 encoded_dt_2(dt);
   24908     Align_align_5 encoded_align_1(align, nreglist);
   24909     Align_index_align_1 encoded_align_2(align, nreglist, dt);
   24910     if (IsUsingT32()) {
   24911       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   24912       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   24913           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   24914           !rm.IsPC() && !rm.IsSP()) {
   24915         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24916           const DRegister& first = nreglist.GetFirstDRegister();
   24917           uint32_t len_encoding;
   24918           switch (nreglist.GetLength()) {
   24919             default:
   24920               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   24921             case 1:
   24922               len_encoding = 0x7;
   24923               break;
   24924             case 2:
   24925               len_encoding = 0xa;
   24926               break;
   24927             case 3:
   24928               len_encoding = 0x6;
   24929               break;
   24930             case 4:
   24931               len_encoding = 0x2;
   24932               break;
   24933           }
   24934           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
   24935                      (encoded_align_1.GetEncodingValue() << 4) |
   24936                      first.Encode(22, 12) | (len_encoding << 8) |
   24937                      (rn.GetCode() << 16) | rm.GetCode());
   24938           AdvanceIT();
   24939           return;
   24940         }
   24941       }
   24942       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   24943       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   24944           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
   24945         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24946           const DRegister& first = nreglist.GetFirstDRegister();
   24947           EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
   24948                      (encoded_align_2.GetEncodingValue() << 4) |
   24949                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   24950                      rm.GetCode());
   24951           AdvanceIT();
   24952           return;
   24953         }
   24954       }
   24955     } else {
   24956       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   24957       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   24958           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   24959           !rm.IsPC() && !rm.IsSP()) {
   24960         if (cond.Is(al)) {
   24961           const DRegister& first = nreglist.GetFirstDRegister();
   24962           uint32_t len_encoding;
   24963           switch (nreglist.GetLength()) {
   24964             default:
   24965               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   24966             case 1:
   24967               len_encoding = 0x7;
   24968               break;
   24969             case 2:
   24970               len_encoding = 0xa;
   24971               break;
   24972             case 3:
   24973               len_encoding = 0x6;
   24974               break;
   24975             case 4:
   24976               len_encoding = 0x2;
   24977               break;
   24978           }
   24979           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
   24980                   (encoded_align_1.GetEncodingValue() << 4) |
   24981                   first.Encode(22, 12) | (len_encoding << 8) |
   24982                   (rn.GetCode() << 16) | rm.GetCode());
   24983           return;
   24984         }
   24985       }
   24986       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   24987       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   24988           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
   24989         if (cond.Is(al)) {
   24990           const DRegister& first = nreglist.GetFirstDRegister();
   24991           EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
   24992                   (encoded_align_2.GetEncodingValue() << 4) |
   24993                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   24994           return;
   24995         }
   24996       }
   24997     }
   24998   }
   24999   Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
   25000 }
   25001 
   25002 void Assembler::vst2(Condition cond,
   25003                      DataType dt,
   25004                      const NeonRegisterList& nreglist,
   25005                      const AlignedMemOperand& operand) {
   25006   VIXL_ASSERT(AllowAssembler());
   25007   CheckIT(cond);
   25008   if (operand.IsImmediateZero()) {
   25009     Register rn = operand.GetBaseRegister();
   25010     Alignment align = operand.GetAlignment();
   25011     Dt_size_7 encoded_dt(dt);
   25012     Align_align_2 encoded_align_1(align, nreglist);
   25013     Align_index_align_2 encoded_align_2(align, nreglist, dt);
   25014     if (IsUsingT32()) {
   25015       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   25016       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25017           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25018            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   25019            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   25020           operand.IsOffset() && encoded_align_1.IsValid() &&
   25021           (!rn.IsPC() || AllowUnpredictable())) {
   25022         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25023           const DRegister& first = nreglist.GetFirstDRegister();
   25024           uint32_t len_encoding;
   25025           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   25026             len_encoding = 0x8;
   25027           }
   25028           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   25029             len_encoding = 0x9;
   25030           }
   25031           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   25032             len_encoding = 0x3;
   25033           }
   25034           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
   25035                      (encoded_align_1.GetEncodingValue() << 4) |
   25036                      first.Encode(22, 12) | (len_encoding << 8) |
   25037                      (rn.GetCode() << 16));
   25038           AdvanceIT();
   25039           return;
   25040         }
   25041       }
   25042       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   25043       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25044           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25045            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   25046            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   25047           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   25048           (!rn.IsPC() || AllowUnpredictable())) {
   25049         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25050           const DRegister& first = nreglist.GetFirstDRegister();
   25051           uint32_t len_encoding;
   25052           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   25053             len_encoding = 0x8;
   25054           }
   25055           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   25056             len_encoding = 0x9;
   25057           }
   25058           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   25059             len_encoding = 0x3;
   25060           }
   25061           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
   25062                      (encoded_align_1.GetEncodingValue() << 4) |
   25063                      first.Encode(22, 12) | (len_encoding << 8) |
   25064                      (rn.GetCode() << 16));
   25065           AdvanceIT();
   25066           return;
   25067         }
   25068       }
   25069       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   25070       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25071           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25072            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   25073           operand.IsOffset() && encoded_align_2.IsValid() &&
   25074           (!rn.IsPC() || AllowUnpredictable())) {
   25075         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25076           const DRegister& first = nreglist.GetFirstDRegister();
   25077           EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
   25078                      (encoded_align_2.GetEncodingValue() << 4) |
   25079                      first.Encode(22, 12) | (rn.GetCode() << 16));
   25080           AdvanceIT();
   25081           return;
   25082         }
   25083       }
   25084       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   25085       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25086           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25087            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   25088           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   25089           (!rn.IsPC() || AllowUnpredictable())) {
   25090         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25091           const DRegister& first = nreglist.GetFirstDRegister();
   25092           EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
   25093                      (encoded_align_2.GetEncodingValue() << 4) |
   25094                      first.Encode(22, 12) | (rn.GetCode() << 16));
   25095           AdvanceIT();
   25096           return;
   25097         }
   25098       }
   25099     } else {
   25100       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   25101       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25102           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25103            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   25104            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   25105           operand.IsOffset() && encoded_align_1.IsValid() &&
   25106           (!rn.IsPC() || AllowUnpredictable())) {
   25107         if (cond.Is(al)) {
   25108           const DRegister& first = nreglist.GetFirstDRegister();
   25109           uint32_t len_encoding;
   25110           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   25111             len_encoding = 0x8;
   25112           }
   25113           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   25114             len_encoding = 0x9;
   25115           }
   25116           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   25117             len_encoding = 0x3;
   25118           }
   25119           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
   25120                   (encoded_align_1.GetEncodingValue() << 4) |
   25121                   first.Encode(22, 12) | (len_encoding << 8) |
   25122                   (rn.GetCode() << 16));
   25123           return;
   25124         }
   25125       }
   25126       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   25127       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25128           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25129            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   25130            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   25131           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   25132           (!rn.IsPC() || AllowUnpredictable())) {
   25133         if (cond.Is(al)) {
   25134           const DRegister& first = nreglist.GetFirstDRegister();
   25135           uint32_t len_encoding;
   25136           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   25137             len_encoding = 0x8;
   25138           }
   25139           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   25140             len_encoding = 0x9;
   25141           }
   25142           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   25143             len_encoding = 0x3;
   25144           }
   25145           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
   25146                   (encoded_align_1.GetEncodingValue() << 4) |
   25147                   first.Encode(22, 12) | (len_encoding << 8) |
   25148                   (rn.GetCode() << 16));
   25149           return;
   25150         }
   25151       }
   25152       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   25153       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25154           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25155            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   25156           operand.IsOffset() && encoded_align_2.IsValid() &&
   25157           (!rn.IsPC() || AllowUnpredictable())) {
   25158         if (cond.Is(al)) {
   25159           const DRegister& first = nreglist.GetFirstDRegister();
   25160           EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
   25161                   (encoded_align_2.GetEncodingValue() << 4) |
   25162                   first.Encode(22, 12) | (rn.GetCode() << 16));
   25163           return;
   25164         }
   25165       }
   25166       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   25167       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25168           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25169            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   25170           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   25171           (!rn.IsPC() || AllowUnpredictable())) {
   25172         if (cond.Is(al)) {
   25173           const DRegister& first = nreglist.GetFirstDRegister();
   25174           EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
   25175                   (encoded_align_2.GetEncodingValue() << 4) |
   25176                   first.Encode(22, 12) | (rn.GetCode() << 16));
   25177           return;
   25178         }
   25179       }
   25180     }
   25181   }
   25182   if (operand.IsPlainRegister()) {
   25183     Register rn = operand.GetBaseRegister();
   25184     Alignment align = operand.GetAlignment();
   25185     Register rm = operand.GetOffsetRegister();
   25186     Dt_size_7 encoded_dt(dt);
   25187     Align_align_2 encoded_align_1(align, nreglist);
   25188     Align_index_align_2 encoded_align_2(align, nreglist, dt);
   25189     if (IsUsingT32()) {
   25190       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   25191       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25192           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25193            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   25194            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   25195           !rm.IsPC() && !rm.IsSP()) {
   25196         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25197           const DRegister& first = nreglist.GetFirstDRegister();
   25198           uint32_t len_encoding;
   25199           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   25200             len_encoding = 0x8;
   25201           }
   25202           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   25203             len_encoding = 0x9;
   25204           }
   25205           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   25206             len_encoding = 0x3;
   25207           }
   25208           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
   25209                      (encoded_align_1.GetEncodingValue() << 4) |
   25210                      first.Encode(22, 12) | (len_encoding << 8) |
   25211                      (rn.GetCode() << 16) | rm.GetCode());
   25212           AdvanceIT();
   25213           return;
   25214         }
   25215       }
   25216       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   25217       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25218           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25219            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   25220           !rm.IsPC() && !rm.IsSP()) {
   25221         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25222           const DRegister& first = nreglist.GetFirstDRegister();
   25223           EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
   25224                      (encoded_align_2.GetEncodingValue() << 4) |
   25225                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   25226                      rm.GetCode());
   25227           AdvanceIT();
   25228           return;
   25229         }
   25230       }
   25231     } else {
   25232       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   25233       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25234           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25235            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   25236            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   25237           !rm.IsPC() && !rm.IsSP()) {
   25238         if (cond.Is(al)) {
   25239           const DRegister& first = nreglist.GetFirstDRegister();
   25240           uint32_t len_encoding;
   25241           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   25242             len_encoding = 0x8;
   25243           }
   25244           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   25245             len_encoding = 0x9;
   25246           }
   25247           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   25248             len_encoding = 0x3;
   25249           }
   25250           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
   25251                   (encoded_align_1.GetEncodingValue() << 4) |
   25252                   first.Encode(22, 12) | (len_encoding << 8) |
   25253                   (rn.GetCode() << 16) | rm.GetCode());
   25254           return;
   25255         }
   25256       }
   25257       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   25258       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25259           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   25260            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   25261           !rm.IsPC() && !rm.IsSP()) {
   25262         if (cond.Is(al)) {
   25263           const DRegister& first = nreglist.GetFirstDRegister();
   25264           EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
   25265                   (encoded_align_2.GetEncodingValue() << 4) |
   25266                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   25267           return;
   25268         }
   25269       }
   25270     }
   25271   }
   25272   Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
   25273 }
   25274 
   25275 void Assembler::vst3(Condition cond,
   25276                      DataType dt,
   25277                      const NeonRegisterList& nreglist,
   25278                      const AlignedMemOperand& operand) {
   25279   VIXL_ASSERT(AllowAssembler());
   25280   CheckIT(cond);
   25281   if (operand.IsImmediateZero()) {
   25282     Register rn = operand.GetBaseRegister();
   25283     Alignment align = operand.GetAlignment();
   25284     Dt_size_7 encoded_dt(dt);
   25285     Align_align_3 encoded_align_1(align);
   25286     if (IsUsingT32()) {
   25287       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   25288       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25289           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25290            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25291           operand.IsOffset() && encoded_align_1.IsValid() &&
   25292           (!rn.IsPC() || AllowUnpredictable())) {
   25293         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25294           const DRegister& first = nreglist.GetFirstDRegister();
   25295           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   25296           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
   25297                      (encoded_align_1.GetEncodingValue() << 4) |
   25298                      first.Encode(22, 12) | (len_encoding << 8) |
   25299                      (rn.GetCode() << 16));
   25300           AdvanceIT();
   25301           return;
   25302         }
   25303       }
   25304       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   25305       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25306           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25307            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25308           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   25309           (!rn.IsPC() || AllowUnpredictable())) {
   25310         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25311           const DRegister& first = nreglist.GetFirstDRegister();
   25312           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   25313           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
   25314                      (encoded_align_1.GetEncodingValue() << 4) |
   25315                      first.Encode(22, 12) | (len_encoding << 8) |
   25316                      (rn.GetCode() << 16));
   25317           AdvanceIT();
   25318           return;
   25319         }
   25320       }
   25321     } else {
   25322       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   25323       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25324           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25325            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25326           operand.IsOffset() && encoded_align_1.IsValid() &&
   25327           (!rn.IsPC() || AllowUnpredictable())) {
   25328         if (cond.Is(al)) {
   25329           const DRegister& first = nreglist.GetFirstDRegister();
   25330           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   25331           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
   25332                   (encoded_align_1.GetEncodingValue() << 4) |
   25333                   first.Encode(22, 12) | (len_encoding << 8) |
   25334                   (rn.GetCode() << 16));
   25335           return;
   25336         }
   25337       }
   25338       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   25339       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25340           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25341            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25342           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   25343           (!rn.IsPC() || AllowUnpredictable())) {
   25344         if (cond.Is(al)) {
   25345           const DRegister& first = nreglist.GetFirstDRegister();
   25346           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   25347           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
   25348                   (encoded_align_1.GetEncodingValue() << 4) |
   25349                   first.Encode(22, 12) | (len_encoding << 8) |
   25350                   (rn.GetCode() << 16));
   25351           return;
   25352         }
   25353       }
   25354     }
   25355   }
   25356   if (operand.IsPlainRegister()) {
   25357     Register rn = operand.GetBaseRegister();
   25358     Alignment align = operand.GetAlignment();
   25359     Register rm = operand.GetOffsetRegister();
   25360     Dt_size_7 encoded_dt(dt);
   25361     Align_align_3 encoded_align_1(align);
   25362     if (IsUsingT32()) {
   25363       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   25364       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25365           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25366            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25367           !rm.IsPC() && !rm.IsSP()) {
   25368         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25369           const DRegister& first = nreglist.GetFirstDRegister();
   25370           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   25371           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
   25372                      (encoded_align_1.GetEncodingValue() << 4) |
   25373                      first.Encode(22, 12) | (len_encoding << 8) |
   25374                      (rn.GetCode() << 16) | rm.GetCode());
   25375           AdvanceIT();
   25376           return;
   25377         }
   25378       }
   25379     } else {
   25380       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   25381       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25382           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25383            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25384           !rm.IsPC() && !rm.IsSP()) {
   25385         if (cond.Is(al)) {
   25386           const DRegister& first = nreglist.GetFirstDRegister();
   25387           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   25388           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
   25389                   (encoded_align_1.GetEncodingValue() << 4) |
   25390                   first.Encode(22, 12) | (len_encoding << 8) |
   25391                   (rn.GetCode() << 16) | rm.GetCode());
   25392           return;
   25393         }
   25394       }
   25395     }
   25396   }
   25397   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
   25398 }
   25399 
   25400 void Assembler::vst3(Condition cond,
   25401                      DataType dt,
   25402                      const NeonRegisterList& nreglist,
   25403                      const MemOperand& operand) {
   25404   VIXL_ASSERT(AllowAssembler());
   25405   CheckIT(cond);
   25406   if (operand.IsImmediateZero()) {
   25407     Register rn = operand.GetBaseRegister();
   25408     Dt_size_7 encoded_dt(dt);
   25409     Index_1 encoded_align_1(nreglist, dt);
   25410     if (IsUsingT32()) {
   25411       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
   25412       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25413           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25414            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25415           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   25416         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25417           const DRegister& first = nreglist.GetFirstDRegister();
   25418           EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
   25419                      (encoded_align_1.GetEncodingValue() << 4) |
   25420                      first.Encode(22, 12) | (rn.GetCode() << 16));
   25421           AdvanceIT();
   25422           return;
   25423         }
   25424       }
   25425       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
   25426       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25427           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25428            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25429           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   25430         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25431           const DRegister& first = nreglist.GetFirstDRegister();
   25432           EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
   25433                      (encoded_align_1.GetEncodingValue() << 4) |
   25434                      first.Encode(22, 12) | (rn.GetCode() << 16));
   25435           AdvanceIT();
   25436           return;
   25437         }
   25438       }
   25439     } else {
   25440       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
   25441       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25442           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25443            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25444           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   25445         if (cond.Is(al)) {
   25446           const DRegister& first = nreglist.GetFirstDRegister();
   25447           EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
   25448                   (encoded_align_1.GetEncodingValue() << 4) |
   25449                   first.Encode(22, 12) | (rn.GetCode() << 16));
   25450           return;
   25451         }
   25452       }
   25453       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
   25454       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25455           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25456            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25457           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   25458         if (cond.Is(al)) {
   25459           const DRegister& first = nreglist.GetFirstDRegister();
   25460           EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
   25461                   (encoded_align_1.GetEncodingValue() << 4) |
   25462                   first.Encode(22, 12) | (rn.GetCode() << 16));
   25463           return;
   25464         }
   25465       }
   25466     }
   25467   }
   25468   if (operand.IsPlainRegister()) {
   25469     Register rn = operand.GetBaseRegister();
   25470     Sign sign = operand.GetSign();
   25471     Register rm = operand.GetOffsetRegister();
   25472     Dt_size_7 encoded_dt(dt);
   25473     Index_1 encoded_align_1(nreglist, dt);
   25474     if (IsUsingT32()) {
   25475       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
   25476       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25477           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25478            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25479           sign.IsPlus() && operand.IsPostIndex()) {
   25480         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25481           const DRegister& first = nreglist.GetFirstDRegister();
   25482           EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
   25483                      (encoded_align_1.GetEncodingValue() << 4) |
   25484                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   25485                      rm.GetCode());
   25486           AdvanceIT();
   25487           return;
   25488         }
   25489       }
   25490     } else {
   25491       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
   25492       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25493           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   25494            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   25495           sign.IsPlus() && operand.IsPostIndex()) {
   25496         if (cond.Is(al)) {
   25497           const DRegister& first = nreglist.GetFirstDRegister();
   25498           EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
   25499                   (encoded_align_1.GetEncodingValue() << 4) |
   25500                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   25501           return;
   25502         }
   25503       }
   25504     }
   25505   }
   25506   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
   25507 }
   25508 
   25509 void Assembler::vst4(Condition cond,
   25510                      DataType dt,
   25511                      const NeonRegisterList& nreglist,
   25512                      const AlignedMemOperand& operand) {
   25513   VIXL_ASSERT(AllowAssembler());
   25514   CheckIT(cond);
   25515   if (operand.IsImmediateZero()) {
   25516     Register rn = operand.GetBaseRegister();
   25517     Alignment align = operand.GetAlignment();
   25518     Dt_size_7 encoded_dt(dt);
   25519     Align_align_4 encoded_align_1(align);
   25520     Align_index_align_3 encoded_align_2(align, nreglist, dt);
   25521     if (IsUsingT32()) {
   25522       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   25523       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25524           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25525            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25526           operand.IsOffset() && encoded_align_1.IsValid() &&
   25527           (!rn.IsPC() || AllowUnpredictable())) {
   25528         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25529           const DRegister& first = nreglist.GetFirstDRegister();
   25530           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   25531           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
   25532                      (encoded_align_1.GetEncodingValue() << 4) |
   25533                      first.Encode(22, 12) | (len_encoding << 8) |
   25534                      (rn.GetCode() << 16));
   25535           AdvanceIT();
   25536           return;
   25537         }
   25538       }
   25539       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   25540       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25541           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25542            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25543           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   25544           (!rn.IsPC() || AllowUnpredictable())) {
   25545         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25546           const DRegister& first = nreglist.GetFirstDRegister();
   25547           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   25548           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
   25549                      (encoded_align_1.GetEncodingValue() << 4) |
   25550                      first.Encode(22, 12) | (len_encoding << 8) |
   25551                      (rn.GetCode() << 16));
   25552           AdvanceIT();
   25553           return;
   25554         }
   25555       }
   25556       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   25557       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25558           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25559            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25560           operand.IsOffset() && encoded_align_2.IsValid() &&
   25561           (!rn.IsPC() || AllowUnpredictable())) {
   25562         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25563           const DRegister& first = nreglist.GetFirstDRegister();
   25564           EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
   25565                      (encoded_align_2.GetEncodingValue() << 4) |
   25566                      first.Encode(22, 12) | (rn.GetCode() << 16));
   25567           AdvanceIT();
   25568           return;
   25569         }
   25570       }
   25571       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   25572       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25573           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25574            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25575           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   25576           (!rn.IsPC() || AllowUnpredictable())) {
   25577         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25578           const DRegister& first = nreglist.GetFirstDRegister();
   25579           EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
   25580                      (encoded_align_2.GetEncodingValue() << 4) |
   25581                      first.Encode(22, 12) | (rn.GetCode() << 16));
   25582           AdvanceIT();
   25583           return;
   25584         }
   25585       }
   25586     } else {
   25587       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   25588       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25589           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25590            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25591           operand.IsOffset() && encoded_align_1.IsValid() &&
   25592           (!rn.IsPC() || AllowUnpredictable())) {
   25593         if (cond.Is(al)) {
   25594           const DRegister& first = nreglist.GetFirstDRegister();
   25595           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   25596           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
   25597                   (encoded_align_1.GetEncodingValue() << 4) |
   25598                   first.Encode(22, 12) | (len_encoding << 8) |
   25599                   (rn.GetCode() << 16));
   25600           return;
   25601         }
   25602       }
   25603       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   25604       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25605           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25606            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25607           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   25608           (!rn.IsPC() || AllowUnpredictable())) {
   25609         if (cond.Is(al)) {
   25610           const DRegister& first = nreglist.GetFirstDRegister();
   25611           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   25612           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
   25613                   (encoded_align_1.GetEncodingValue() << 4) |
   25614                   first.Encode(22, 12) | (len_encoding << 8) |
   25615                   (rn.GetCode() << 16));
   25616           return;
   25617         }
   25618       }
   25619       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   25620       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25621           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25622            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25623           operand.IsOffset() && encoded_align_2.IsValid() &&
   25624           (!rn.IsPC() || AllowUnpredictable())) {
   25625         if (cond.Is(al)) {
   25626           const DRegister& first = nreglist.GetFirstDRegister();
   25627           EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
   25628                   (encoded_align_2.GetEncodingValue() << 4) |
   25629                   first.Encode(22, 12) | (rn.GetCode() << 16));
   25630           return;
   25631         }
   25632       }
   25633       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   25634       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25635           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25636            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25637           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   25638           (!rn.IsPC() || AllowUnpredictable())) {
   25639         if (cond.Is(al)) {
   25640           const DRegister& first = nreglist.GetFirstDRegister();
   25641           EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
   25642                   (encoded_align_2.GetEncodingValue() << 4) |
   25643                   first.Encode(22, 12) | (rn.GetCode() << 16));
   25644           return;
   25645         }
   25646       }
   25647     }
   25648   }
   25649   if (operand.IsPlainRegister()) {
   25650     Register rn = operand.GetBaseRegister();
   25651     Alignment align = operand.GetAlignment();
   25652     Register rm = operand.GetOffsetRegister();
   25653     Dt_size_7 encoded_dt(dt);
   25654     Align_align_4 encoded_align_1(align);
   25655     Align_index_align_3 encoded_align_2(align, nreglist, dt);
   25656     if (IsUsingT32()) {
   25657       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   25658       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25659           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25660            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25661           !rm.IsPC() && !rm.IsSP()) {
   25662         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25663           const DRegister& first = nreglist.GetFirstDRegister();
   25664           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   25665           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
   25666                      (encoded_align_1.GetEncodingValue() << 4) |
   25667                      first.Encode(22, 12) | (len_encoding << 8) |
   25668                      (rn.GetCode() << 16) | rm.GetCode());
   25669           AdvanceIT();
   25670           return;
   25671         }
   25672       }
   25673       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   25674       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25675           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25676            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25677           !rm.IsPC() && !rm.IsSP()) {
   25678         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25679           const DRegister& first = nreglist.GetFirstDRegister();
   25680           EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
   25681                      (encoded_align_2.GetEncodingValue() << 4) |
   25682                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   25683                      rm.GetCode());
   25684           AdvanceIT();
   25685           return;
   25686         }
   25687       }
   25688     } else {
   25689       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   25690       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25691           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25692            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25693           !rm.IsPC() && !rm.IsSP()) {
   25694         if (cond.Is(al)) {
   25695           const DRegister& first = nreglist.GetFirstDRegister();
   25696           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   25697           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
   25698                   (encoded_align_1.GetEncodingValue() << 4) |
   25699                   first.Encode(22, 12) | (len_encoding << 8) |
   25700                   (rn.GetCode() << 16) | rm.GetCode());
   25701           return;
   25702         }
   25703       }
   25704       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   25705       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   25706           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   25707            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   25708           !rm.IsPC() && !rm.IsSP()) {
   25709         if (cond.Is(al)) {
   25710           const DRegister& first = nreglist.GetFirstDRegister();
   25711           EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
   25712                   (encoded_align_2.GetEncodingValue() << 4) |
   25713                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   25714           return;
   25715         }
   25716       }
   25717     }
   25718   }
   25719   Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
   25720 }
   25721 
   25722 void Assembler::vstm(Condition cond,
   25723                      DataType dt,
   25724                      Register rn,
   25725                      WriteBack write_back,
   25726                      DRegisterList dreglist) {
   25727   VIXL_ASSERT(AllowAssembler());
   25728   CheckIT(cond);
   25729   USE(dt);
   25730   if (IsUsingT32()) {
   25731     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
   25732     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   25733       const DRegister& dreg = dreglist.GetFirstDRegister();
   25734       unsigned len = dreglist.GetLength() * 2;
   25735       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
   25736                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   25737                  (len & 0xff));
   25738       AdvanceIT();
   25739       return;
   25740     }
   25741   } else {
   25742     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
   25743     if (cond.IsNotNever() &&
   25744         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   25745       const DRegister& dreg = dreglist.GetFirstDRegister();
   25746       unsigned len = dreglist.GetLength() * 2;
   25747       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   25748               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   25749               (len & 0xff));
   25750       return;
   25751     }
   25752   }
   25753   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
   25754 }
   25755 
   25756 void Assembler::vstm(Condition cond,
   25757                      DataType dt,
   25758                      Register rn,
   25759                      WriteBack write_back,
   25760                      SRegisterList sreglist) {
   25761   VIXL_ASSERT(AllowAssembler());
   25762   CheckIT(cond);
   25763   USE(dt);
   25764   if (IsUsingT32()) {
   25765     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
   25766     const SRegister& sreg = sreglist.GetFirstSRegister();
   25767     unsigned len = sreglist.GetLength();
   25768     EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
   25769                (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   25770                (len & 0xff));
   25771     AdvanceIT();
   25772     return;
   25773   } else {
   25774     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
   25775     if (cond.IsNotNever()) {
   25776       const SRegister& sreg = sreglist.GetFirstSRegister();
   25777       unsigned len = sreglist.GetLength();
   25778       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   25779               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   25780               (len & 0xff));
   25781       return;
   25782     }
   25783   }
   25784   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
   25785 }
   25786 
   25787 void Assembler::vstmdb(Condition cond,
   25788                        DataType dt,
   25789                        Register rn,
   25790                        WriteBack write_back,
   25791                        DRegisterList dreglist) {
   25792   VIXL_ASSERT(AllowAssembler());
   25793   CheckIT(cond);
   25794   USE(dt);
   25795   if (IsUsingT32()) {
   25796     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
   25797     if (write_back.DoesWriteBack() &&
   25798         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   25799       const DRegister& dreg = dreglist.GetFirstDRegister();
   25800       unsigned len = dreglist.GetLength() * 2;
   25801       EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   25802                  (len & 0xff));
   25803       AdvanceIT();
   25804       return;
   25805     }
   25806   } else {
   25807     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
   25808     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   25809         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   25810       const DRegister& dreg = dreglist.GetFirstDRegister();
   25811       unsigned len = dreglist.GetLength() * 2;
   25812       EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   25813               dreg.Encode(22, 12) | (len & 0xff));
   25814       return;
   25815     }
   25816   }
   25817   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
   25818 }
   25819 
   25820 void Assembler::vstmdb(Condition cond,
   25821                        DataType dt,
   25822                        Register rn,
   25823                        WriteBack write_back,
   25824                        SRegisterList sreglist) {
   25825   VIXL_ASSERT(AllowAssembler());
   25826   CheckIT(cond);
   25827   USE(dt);
   25828   if (IsUsingT32()) {
   25829     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
   25830     if (write_back.DoesWriteBack()) {
   25831       const SRegister& sreg = sreglist.GetFirstSRegister();
   25832       unsigned len = sreglist.GetLength();
   25833       EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
   25834                  (len & 0xff));
   25835       AdvanceIT();
   25836       return;
   25837     }
   25838   } else {
   25839     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
   25840     if (write_back.DoesWriteBack() && cond.IsNotNever()) {
   25841       const SRegister& sreg = sreglist.GetFirstSRegister();
   25842       unsigned len = sreglist.GetLength();
   25843       EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   25844               sreg.Encode(22, 12) | (len & 0xff));
   25845       return;
   25846     }
   25847   }
   25848   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
   25849 }
   25850 
   25851 void Assembler::vstmia(Condition cond,
   25852                        DataType dt,
   25853                        Register rn,
   25854                        WriteBack write_back,
   25855                        DRegisterList dreglist) {
   25856   VIXL_ASSERT(AllowAssembler());
   25857   CheckIT(cond);
   25858   USE(dt);
   25859   if (IsUsingT32()) {
   25860     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
   25861     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   25862       const DRegister& dreg = dreglist.GetFirstDRegister();
   25863       unsigned len = dreglist.GetLength() * 2;
   25864       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
   25865                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   25866                  (len & 0xff));
   25867       AdvanceIT();
   25868       return;
   25869     }
   25870   } else {
   25871     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
   25872     if (cond.IsNotNever() &&
   25873         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   25874       const DRegister& dreg = dreglist.GetFirstDRegister();
   25875       unsigned len = dreglist.GetLength() * 2;
   25876       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   25877               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   25878               (len & 0xff));
   25879       return;
   25880     }
   25881   }
   25882   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
   25883 }
   25884 
   25885 void Assembler::vstmia(Condition cond,
   25886                        DataType dt,
   25887                        Register rn,
   25888                        WriteBack write_back,
   25889                        SRegisterList sreglist) {
   25890   VIXL_ASSERT(AllowAssembler());
   25891   CheckIT(cond);
   25892   USE(dt);
   25893   if (IsUsingT32()) {
   25894     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
   25895     const SRegister& sreg = sreglist.GetFirstSRegister();
   25896     unsigned len = sreglist.GetLength();
   25897     EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
   25898                (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   25899                (len & 0xff));
   25900     AdvanceIT();
   25901     return;
   25902   } else {
   25903     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
   25904     if (cond.IsNotNever()) {
   25905       const SRegister& sreg = sreglist.GetFirstSRegister();
   25906       unsigned len = sreglist.GetLength();
   25907       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   25908               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   25909               (len & 0xff));
   25910       return;
   25911     }
   25912   }
   25913   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
   25914 }
   25915 
   25916 void Assembler::vstr(Condition cond,
   25917                      DataType dt,
   25918                      DRegister rd,
   25919                      const MemOperand& operand) {
   25920   VIXL_ASSERT(AllowAssembler());
   25921   CheckIT(cond);
   25922   if (operand.IsImmediate()) {
   25923     Register rn = operand.GetBaseRegister();
   25924     int32_t offset = operand.GetOffsetImmediate();
   25925     if (IsUsingT32()) {
   25926       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
   25927       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   25928           ((offset % 4) == 0) && operand.IsOffset()) {
   25929         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   25930         uint32_t offset_ = abs(offset) >> 2;
   25931         EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
   25932                    offset_ | (sign << 23));
   25933         AdvanceIT();
   25934         return;
   25935       }
   25936     } else {
   25937       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
   25938       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   25939           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
   25940         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   25941         uint32_t offset_ = abs(offset) >> 2;
   25942         EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   25943                 (rn.GetCode() << 16) | offset_ | (sign << 23));
   25944         return;
   25945       }
   25946     }
   25947   }
   25948   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
   25949 }
   25950 
   25951 void Assembler::vstr(Condition cond,
   25952                      DataType dt,
   25953                      SRegister rd,
   25954                      const MemOperand& operand) {
   25955   VIXL_ASSERT(AllowAssembler());
   25956   CheckIT(cond);
   25957   if (operand.IsImmediate()) {
   25958     Register rn = operand.GetBaseRegister();
   25959     int32_t offset = operand.GetOffsetImmediate();
   25960     if (IsUsingT32()) {
   25961       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
   25962       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   25963           ((offset % 4) == 0) && operand.IsOffset()) {
   25964         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   25965         uint32_t offset_ = abs(offset) >> 2;
   25966         EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
   25967                    offset_ | (sign << 23));
   25968         AdvanceIT();
   25969         return;
   25970       }
   25971     } else {
   25972       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
   25973       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   25974           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
   25975         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   25976         uint32_t offset_ = abs(offset) >> 2;
   25977         EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   25978                 (rn.GetCode() << 16) | offset_ | (sign << 23));
   25979         return;
   25980       }
   25981     }
   25982   }
   25983   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
   25984 }
   25985 
   25986 void Assembler::vsub(
   25987     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   25988   VIXL_ASSERT(AllowAssembler());
   25989   CheckIT(cond);
   25990   Dt_size_2 encoded_dt(dt);
   25991   if (IsUsingT32()) {
   25992     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   25993     if (dt.Is(F32)) {
   25994       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25995         EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25996                    rm.Encode(5, 0));
   25997         AdvanceIT();
   25998         return;
   25999       }
   26000     }
   26001     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
   26002     if (dt.Is(F64)) {
   26003       EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   26004                  rm.Encode(5, 0));
   26005       AdvanceIT();
   26006       return;
   26007     }
   26008     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   26009     if (encoded_dt.IsValid()) {
   26010       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26011         EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
   26012                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26013         AdvanceIT();
   26014         return;
   26015       }
   26016     }
   26017   } else {
   26018     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   26019     if (dt.Is(F32)) {
   26020       if (cond.Is(al)) {
   26021         EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   26022                 rm.Encode(5, 0));
   26023         return;
   26024       }
   26025     }
   26026     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
   26027     if (dt.Is(F64) && cond.IsNotNever()) {
   26028       EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   26029               rn.Encode(7, 16) | rm.Encode(5, 0));
   26030       return;
   26031     }
   26032     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   26033     if (encoded_dt.IsValid()) {
   26034       if (cond.Is(al)) {
   26035         EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
   26036                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26037         return;
   26038       }
   26039     }
   26040   }
   26041   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
   26042 }
   26043 
   26044 void Assembler::vsub(
   26045     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   26046   VIXL_ASSERT(AllowAssembler());
   26047   CheckIT(cond);
   26048   Dt_size_2 encoded_dt(dt);
   26049   if (IsUsingT32()) {
   26050     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   26051     if (dt.Is(F32)) {
   26052       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26053         EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   26054                    rm.Encode(5, 0));
   26055         AdvanceIT();
   26056         return;
   26057       }
   26058     }
   26059     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   26060     if (encoded_dt.IsValid()) {
   26061       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26062         EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
   26063                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26064         AdvanceIT();
   26065         return;
   26066       }
   26067     }
   26068   } else {
   26069     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   26070     if (dt.Is(F32)) {
   26071       if (cond.Is(al)) {
   26072         EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   26073                 rm.Encode(5, 0));
   26074         return;
   26075       }
   26076     }
   26077     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   26078     if (encoded_dt.IsValid()) {
   26079       if (cond.Is(al)) {
   26080         EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
   26081                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26082         return;
   26083       }
   26084     }
   26085   }
   26086   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
   26087 }
   26088 
   26089 void Assembler::vsub(
   26090     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   26091   VIXL_ASSERT(AllowAssembler());
   26092   CheckIT(cond);
   26093   if (IsUsingT32()) {
   26094     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
   26095     if (dt.Is(F32)) {
   26096       EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   26097                  rm.Encode(5, 0));
   26098       AdvanceIT();
   26099       return;
   26100     }
   26101   } else {
   26102     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
   26103     if (dt.Is(F32) && cond.IsNotNever()) {
   26104       EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   26105               rn.Encode(7, 16) | rm.Encode(5, 0));
   26106       return;
   26107     }
   26108   }
   26109   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
   26110 }
   26111 
   26112 void Assembler::vsubhn(
   26113     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
   26114   VIXL_ASSERT(AllowAssembler());
   26115   CheckIT(cond);
   26116   Dt_size_3 encoded_dt(dt);
   26117   if (IsUsingT32()) {
   26118     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
   26119     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   26120       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26121         EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
   26122                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26123         AdvanceIT();
   26124         return;
   26125       }
   26126     }
   26127   } else {
   26128     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
   26129     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   26130       if (cond.Is(al)) {
   26131         EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
   26132                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26133         return;
   26134       }
   26135     }
   26136   }
   26137   Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
   26138 }
   26139 
   26140 void Assembler::vsubl(
   26141     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   26142   VIXL_ASSERT(AllowAssembler());
   26143   CheckIT(cond);
   26144   Dt_U_size_1 encoded_dt(dt);
   26145   if (IsUsingT32()) {
   26146     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   26147     if (encoded_dt.IsValid()) {
   26148       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26149         EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   26150                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   26151                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26152         AdvanceIT();
   26153         return;
   26154       }
   26155     }
   26156   } else {
   26157     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   26158     if (encoded_dt.IsValid()) {
   26159       if (cond.Is(al)) {
   26160         EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   26161                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   26162                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26163         return;
   26164       }
   26165     }
   26166   }
   26167   Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
   26168 }
   26169 
   26170 void Assembler::vsubw(
   26171     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
   26172   VIXL_ASSERT(AllowAssembler());
   26173   CheckIT(cond);
   26174   Dt_U_size_1 encoded_dt(dt);
   26175   if (IsUsingT32()) {
   26176     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
   26177     if (encoded_dt.IsValid()) {
   26178       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26179         EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   26180                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   26181                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26182         AdvanceIT();
   26183         return;
   26184       }
   26185     }
   26186   } else {
   26187     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
   26188     if (encoded_dt.IsValid()) {
   26189       if (cond.Is(al)) {
   26190         EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   26191                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   26192                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26193         return;
   26194       }
   26195     }
   26196   }
   26197   Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
   26198 }
   26199 
   26200 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   26201   VIXL_ASSERT(AllowAssembler());
   26202   CheckIT(cond);
   26203   USE(dt);
   26204   if (IsUsingT32()) {
   26205     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
   26206     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26207       EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
   26208       AdvanceIT();
   26209       return;
   26210     }
   26211   } else {
   26212     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
   26213     if (cond.Is(al)) {
   26214       EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
   26215       return;
   26216     }
   26217   }
   26218   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
   26219 }
   26220 
   26221 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   26222   VIXL_ASSERT(AllowAssembler());
   26223   CheckIT(cond);
   26224   USE(dt);
   26225   if (IsUsingT32()) {
   26226     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
   26227     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26228       EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
   26229       AdvanceIT();
   26230       return;
   26231     }
   26232   } else {
   26233     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
   26234     if (cond.Is(al)) {
   26235       EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
   26236       return;
   26237     }
   26238   }
   26239   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
   26240 }
   26241 
   26242 void Assembler::vtbl(Condition cond,
   26243                      DataType dt,
   26244                      DRegister rd,
   26245                      const NeonRegisterList& nreglist,
   26246                      DRegister rm) {
   26247   VIXL_ASSERT(AllowAssembler());
   26248   CheckIT(cond);
   26249   if (IsUsingT32()) {
   26250     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
   26251     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
   26252         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
   26253       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26254         const DRegister& first = nreglist.GetFirstDRegister();
   26255         uint32_t len_encoding = nreglist.GetLength() - 1;
   26256         EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
   26257                    (len_encoding << 8) | rm.Encode(5, 0));
   26258         AdvanceIT();
   26259         return;
   26260       }
   26261     }
   26262   } else {
   26263     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
   26264     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
   26265         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
   26266       if (cond.Is(al)) {
   26267         const DRegister& first = nreglist.GetFirstDRegister();
   26268         uint32_t len_encoding = nreglist.GetLength() - 1;
   26269         EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
   26270                 (len_encoding << 8) | rm.Encode(5, 0));
   26271         return;
   26272       }
   26273     }
   26274   }
   26275   Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
   26276 }
   26277 
   26278 void Assembler::vtbx(Condition cond,
   26279                      DataType dt,
   26280                      DRegister rd,
   26281                      const NeonRegisterList& nreglist,
   26282                      DRegister rm) {
   26283   VIXL_ASSERT(AllowAssembler());
   26284   CheckIT(cond);
   26285   if (IsUsingT32()) {
   26286     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
   26287     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
   26288         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
   26289       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26290         const DRegister& first = nreglist.GetFirstDRegister();
   26291         uint32_t len_encoding = nreglist.GetLength() - 1;
   26292         EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
   26293                    (len_encoding << 8) | rm.Encode(5, 0));
   26294         AdvanceIT();
   26295         return;
   26296       }
   26297     }
   26298   } else {
   26299     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
   26300     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
   26301         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
   26302       if (cond.Is(al)) {
   26303         const DRegister& first = nreglist.GetFirstDRegister();
   26304         uint32_t len_encoding = nreglist.GetLength() - 1;
   26305         EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
   26306                 (len_encoding << 8) | rm.Encode(5, 0));
   26307         return;
   26308       }
   26309     }
   26310   }
   26311   Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
   26312 }
   26313 
   26314 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   26315   VIXL_ASSERT(AllowAssembler());
   26316   CheckIT(cond);
   26317   Dt_size_7 encoded_dt(dt);
   26318   if (IsUsingT32()) {
   26319     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   26320     if (encoded_dt.IsValid()) {
   26321       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26322         EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
   26323                    rd.Encode(22, 12) | rm.Encode(5, 0));
   26324         AdvanceIT();
   26325         return;
   26326       }
   26327     }
   26328   } else {
   26329     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   26330     if (encoded_dt.IsValid()) {
   26331       if (cond.Is(al)) {
   26332         EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
   26333                 rd.Encode(22, 12) | rm.Encode(5, 0));
   26334         return;
   26335       }
   26336     }
   26337   }
   26338   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
   26339 }
   26340 
   26341 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   26342   VIXL_ASSERT(AllowAssembler());
   26343   CheckIT(cond);
   26344   Dt_size_7 encoded_dt(dt);
   26345   if (IsUsingT32()) {
   26346     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   26347     if (encoded_dt.IsValid()) {
   26348       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26349         EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
   26350                    rd.Encode(22, 12) | rm.Encode(5, 0));
   26351         AdvanceIT();
   26352         return;
   26353       }
   26354     }
   26355   } else {
   26356     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   26357     if (encoded_dt.IsValid()) {
   26358       if (cond.Is(al)) {
   26359         EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
   26360                 rd.Encode(22, 12) | rm.Encode(5, 0));
   26361         return;
   26362       }
   26363     }
   26364   }
   26365   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
   26366 }
   26367 
   26368 void Assembler::vtst(
   26369     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   26370   VIXL_ASSERT(AllowAssembler());
   26371   CheckIT(cond);
   26372   Dt_size_7 encoded_dt(dt);
   26373   if (IsUsingT32()) {
   26374     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   26375     if (encoded_dt.IsValid()) {
   26376       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26377         EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
   26378                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26379         AdvanceIT();
   26380         return;
   26381       }
   26382     }
   26383   } else {
   26384     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   26385     if (encoded_dt.IsValid()) {
   26386       if (cond.Is(al)) {
   26387         EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
   26388                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26389         return;
   26390       }
   26391     }
   26392   }
   26393   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
   26394 }
   26395 
   26396 void Assembler::vtst(
   26397     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   26398   VIXL_ASSERT(AllowAssembler());
   26399   CheckIT(cond);
   26400   Dt_size_7 encoded_dt(dt);
   26401   if (IsUsingT32()) {
   26402     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   26403     if (encoded_dt.IsValid()) {
   26404       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26405         EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
   26406                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26407         AdvanceIT();
   26408         return;
   26409       }
   26410     }
   26411   } else {
   26412     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   26413     if (encoded_dt.IsValid()) {
   26414       if (cond.Is(al)) {
   26415         EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
   26416                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   26417         return;
   26418       }
   26419     }
   26420   }
   26421   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
   26422 }
   26423 
   26424 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   26425   VIXL_ASSERT(AllowAssembler());
   26426   CheckIT(cond);
   26427   Dt_size_15 encoded_dt(dt);
   26428   if (IsUsingT32()) {
   26429     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   26430     if (encoded_dt.IsValid()) {
   26431       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26432         EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
   26433                    rd.Encode(22, 12) | rm.Encode(5, 0));
   26434         AdvanceIT();
   26435         return;
   26436       }
   26437     }
   26438     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
   26439     if (dt.Is(Untyped32)) {
   26440       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26441         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
   26442         AdvanceIT();
   26443         return;
   26444       }
   26445     }
   26446   } else {
   26447     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   26448     if (encoded_dt.IsValid()) {
   26449       if (cond.Is(al)) {
   26450         EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
   26451                 rd.Encode(22, 12) | rm.Encode(5, 0));
   26452         return;
   26453       }
   26454     }
   26455     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
   26456     if (dt.Is(Untyped32)) {
   26457       if (cond.Is(al)) {
   26458         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
   26459         return;
   26460       }
   26461     }
   26462   }
   26463   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
   26464 }
   26465 
   26466 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   26467   VIXL_ASSERT(AllowAssembler());
   26468   CheckIT(cond);
   26469   Dt_size_7 encoded_dt(dt);
   26470   if (IsUsingT32()) {
   26471     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   26472     if (encoded_dt.IsValid()) {
   26473       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26474         EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
   26475                    rd.Encode(22, 12) | rm.Encode(5, 0));
   26476         AdvanceIT();
   26477         return;
   26478       }
   26479     }
   26480   } else {
   26481     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   26482     if (encoded_dt.IsValid()) {
   26483       if (cond.Is(al)) {
   26484         EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
   26485                 rd.Encode(22, 12) | rm.Encode(5, 0));
   26486         return;
   26487       }
   26488     }
   26489   }
   26490   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
   26491 }
   26492 
   26493 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   26494   VIXL_ASSERT(AllowAssembler());
   26495   CheckIT(cond);
   26496   Dt_size_15 encoded_dt(dt);
   26497   if (IsUsingT32()) {
   26498     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   26499     if (encoded_dt.IsValid()) {
   26500       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26501         EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
   26502                    rd.Encode(22, 12) | rm.Encode(5, 0));
   26503         AdvanceIT();
   26504         return;
   26505       }
   26506     }
   26507     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
   26508     if (dt.Is(Untyped32)) {
   26509       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26510         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
   26511         AdvanceIT();
   26512         return;
   26513       }
   26514     }
   26515   } else {
   26516     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   26517     if (encoded_dt.IsValid()) {
   26518       if (cond.Is(al)) {
   26519         EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
   26520                 rd.Encode(22, 12) | rm.Encode(5, 0));
   26521         return;
   26522       }
   26523     }
   26524     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
   26525     if (dt.Is(Untyped32)) {
   26526       if (cond.Is(al)) {
   26527         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
   26528         return;
   26529       }
   26530     }
   26531   }
   26532   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
   26533 }
   26534 
   26535 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   26536   VIXL_ASSERT(AllowAssembler());
   26537   CheckIT(cond);
   26538   Dt_size_7 encoded_dt(dt);
   26539   if (IsUsingT32()) {
   26540     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   26541     if (encoded_dt.IsValid()) {
   26542       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26543         EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
   26544                    rd.Encode(22, 12) | rm.Encode(5, 0));
   26545         AdvanceIT();
   26546         return;
   26547       }
   26548     }
   26549   } else {
   26550     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   26551     if (encoded_dt.IsValid()) {
   26552       if (cond.Is(al)) {
   26553         EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
   26554                 rd.Encode(22, 12) | rm.Encode(5, 0));
   26555         return;
   26556       }
   26557     }
   26558   }
   26559   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
   26560 }
   26561 
   26562 void Assembler::yield(Condition cond, EncodingSize size) {
   26563   VIXL_ASSERT(AllowAssembler());
   26564   CheckIT(cond);
   26565   if (IsUsingT32()) {
   26566     // YIELD{<c>}{<q>} ; T1
   26567     if (!size.IsWide()) {
   26568       EmitT32_16(0xbf10);
   26569       AdvanceIT();
   26570       return;
   26571     }
   26572     // YIELD{<c>}.W ; T2
   26573     if (!size.IsNarrow()) {
   26574       EmitT32_32(0xf3af8001U);
   26575       AdvanceIT();
   26576       return;
   26577     }
   26578   } else {
   26579     // YIELD{<c>}{<q>} ; A1
   26580     if (cond.IsNotNever()) {
   26581       EmitA32(0x0320f001U | (cond.GetCondition() << 28));
   26582       return;
   26583     }
   26584   }
   26585   Delegate(kYield, &Assembler::yield, cond, size);
   26586 }
   26587 // End of generated code.
   26588 
   26589 }  // namespace aarch32
   26590 }  // namespace vixl
   26591