Home | History | Annotate | Download | only in aarch32
      1 // Copyright 2017, VIXL authors
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 extern "C" {
     28 #include <stdint.h>
     29 }
     30 
     31 #include <cassert>
     32 #include <cstdio>
     33 #include <cstdlib>
     34 #include <cstring>
     35 #include <iostream>
     36 
     37 #include "utils-vixl.h"
     38 #include "aarch32/assembler-aarch32.h"
     39 #include "aarch32/constants-aarch32.h"
     40 #include "aarch32/instructions-aarch32.h"
     41 #include "aarch32/operands-aarch32.h"
     42 
     43 namespace vixl {
     44 namespace aarch32 {
     45 
     46 void Assembler::EmitT32_16(uint16_t instr) {
     47   VIXL_ASSERT(buffer_.Is16bitAligned());
     48   buffer_.Emit16(instr);
     49 }
     50 
     51 
     52 void Assembler::EmitT32_32(uint32_t instr) {
     53   VIXL_ASSERT(buffer_.Is16bitAligned());
     54   buffer_.Emit16(static_cast<uint16_t>(instr >> 16));
     55   buffer_.Emit16(static_cast<uint16_t>(instr & 0xffff));
     56 }
     57 
     58 
     59 void Assembler::EmitA32(uint32_t instr) {
     60   VIXL_ASSERT(buffer_.Is32bitAligned());
     61   buffer_.Emit32(instr);
     62 }
     63 
     64 
     65 #ifdef VIXL_DEBUG
     66 void Assembler::PerformCheckIT(Condition condition) {
     67   if (it_mask_ == 0) {
     68     VIXL_ASSERT(IsUsingA32() || condition.Is(al));
     69   } else {
     70     VIXL_ASSERT(condition.Is(first_condition_));
     71     // For A32, AdavanceIT() is not called by the assembler. We must call it
     72     // in order to check that IT instructions are used consistently with
     73     // the following conditional instructions.
     74     if (IsUsingA32()) AdvanceIT();
     75   }
     76 }
     77 #endif
     78 
     79 
     80 void Assembler::BindHelper(Label* label) {
     81   VIXL_ASSERT(!label->IsBound());
     82   label->SetLocation(this, GetCursorOffset());
     83   label->MarkBound();
     84 }
     85 
     86 uint32_t Assembler::Link(uint32_t instr,
     87                          Location* location,
     88                          const Location::EmitOperator& op,
     89                          const ReferenceInfo* info) {
     90   location->SetReferenced();
     91   if (location->IsBound()) {
     92     return op.Encode(instr, GetCursorOffset(), location);
     93   }
     94   location->AddForwardRef(GetCursorOffset(), op, info);
     95   return instr;
     96 }
     97 
     98 
     99 // Start of generated code.
    100 class Dt_L_imm6_1 : public EncodingValue {
    101   uint32_t type_;
    102 
    103  public:
    104   explicit Dt_L_imm6_1(DataType dt);
    105   uint32_t GetTypeEncodingValue() const { return type_; }
    106 };
    107 
    108 Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
    109   switch (dt.GetValue()) {
    110     case S8:
    111       type_ = 0x0;
    112       SetEncodingValue(0x1);
    113       break;
    114     case U8:
    115       type_ = 0x1;
    116       SetEncodingValue(0x1);
    117       break;
    118     case S16:
    119       type_ = 0x0;
    120       SetEncodingValue(0x2);
    121       break;
    122     case U16:
    123       type_ = 0x1;
    124       SetEncodingValue(0x2);
    125       break;
    126     case S32:
    127       type_ = 0x0;
    128       SetEncodingValue(0x4);
    129       break;
    130     case U32:
    131       type_ = 0x1;
    132       SetEncodingValue(0x4);
    133       break;
    134     case S64:
    135       type_ = 0x0;
    136       SetEncodingValue(0x8);
    137       break;
    138     case U64:
    139       type_ = 0x1;
    140       SetEncodingValue(0x8);
    141       break;
    142     default:
    143       VIXL_UNREACHABLE();
    144       type_ = 0x0;
    145       break;
    146   }
    147 }
    148 
    149 class Dt_L_imm6_2 : public EncodingValue {
    150   uint32_t type_;
    151 
    152  public:
    153   explicit Dt_L_imm6_2(DataType dt);
    154   uint32_t GetTypeEncodingValue() const { return type_; }
    155 };
    156 
    157 Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
    158   switch (dt.GetValue()) {
    159     case S8:
    160       type_ = 0x1;
    161       SetEncodingValue(0x1);
    162       break;
    163     case S16:
    164       type_ = 0x1;
    165       SetEncodingValue(0x2);
    166       break;
    167     case S32:
    168       type_ = 0x1;
    169       SetEncodingValue(0x4);
    170       break;
    171     case S64:
    172       type_ = 0x1;
    173       SetEncodingValue(0x8);
    174       break;
    175     default:
    176       VIXL_UNREACHABLE();
    177       type_ = 0x0;
    178       break;
    179   }
    180 }
    181 
    182 class Dt_L_imm6_3 : public EncodingValue {
    183  public:
    184   explicit Dt_L_imm6_3(DataType dt);
    185 };
    186 
    187 Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
    188   switch (dt.GetValue()) {
    189     case I8:
    190       SetEncodingValue(0x1);
    191       break;
    192     case I16:
    193       SetEncodingValue(0x2);
    194       break;
    195     case I32:
    196       SetEncodingValue(0x4);
    197       break;
    198     case I64:
    199       SetEncodingValue(0x8);
    200       break;
    201     default:
    202       break;
    203   }
    204 }
    205 
    206 class Dt_L_imm6_4 : public EncodingValue {
    207  public:
    208   explicit Dt_L_imm6_4(DataType dt);
    209 };
    210 
    211 Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
    212   switch (dt.GetValue()) {
    213     case Untyped8:
    214       SetEncodingValue(0x1);
    215       break;
    216     case Untyped16:
    217       SetEncodingValue(0x2);
    218       break;
    219     case Untyped32:
    220       SetEncodingValue(0x4);
    221       break;
    222     case Untyped64:
    223       SetEncodingValue(0x8);
    224       break;
    225     default:
    226       break;
    227   }
    228 }
    229 
    230 class Dt_imm6_1 : public EncodingValue {
    231   uint32_t type_;
    232 
    233  public:
    234   explicit Dt_imm6_1(DataType dt);
    235   uint32_t GetTypeEncodingValue() const { return type_; }
    236 };
    237 
    238 Dt_imm6_1::Dt_imm6_1(DataType dt) {
    239   switch (dt.GetValue()) {
    240     case S16:
    241       type_ = 0x0;
    242       SetEncodingValue(0x1);
    243       break;
    244     case U16:
    245       type_ = 0x1;
    246       SetEncodingValue(0x1);
    247       break;
    248     case S32:
    249       type_ = 0x0;
    250       SetEncodingValue(0x2);
    251       break;
    252     case U32:
    253       type_ = 0x1;
    254       SetEncodingValue(0x2);
    255       break;
    256     case S64:
    257       type_ = 0x0;
    258       SetEncodingValue(0x4);
    259       break;
    260     case U64:
    261       type_ = 0x1;
    262       SetEncodingValue(0x4);
    263       break;
    264     default:
    265       VIXL_UNREACHABLE();
    266       type_ = 0x0;
    267       break;
    268   }
    269 }
    270 
    271 class Dt_imm6_2 : public EncodingValue {
    272   uint32_t type_;
    273 
    274  public:
    275   explicit Dt_imm6_2(DataType dt);
    276   uint32_t GetTypeEncodingValue() const { return type_; }
    277 };
    278 
    279 Dt_imm6_2::Dt_imm6_2(DataType dt) {
    280   switch (dt.GetValue()) {
    281     case S16:
    282       type_ = 0x1;
    283       SetEncodingValue(0x1);
    284       break;
    285     case S32:
    286       type_ = 0x1;
    287       SetEncodingValue(0x2);
    288       break;
    289     case S64:
    290       type_ = 0x1;
    291       SetEncodingValue(0x4);
    292       break;
    293     default:
    294       VIXL_UNREACHABLE();
    295       type_ = 0x0;
    296       break;
    297   }
    298 }
    299 
    300 class Dt_imm6_3 : public EncodingValue {
    301  public:
    302   explicit Dt_imm6_3(DataType dt);
    303 };
    304 
    305 Dt_imm6_3::Dt_imm6_3(DataType dt) {
    306   switch (dt.GetValue()) {
    307     case I16:
    308       SetEncodingValue(0x1);
    309       break;
    310     case I32:
    311       SetEncodingValue(0x2);
    312       break;
    313     case I64:
    314       SetEncodingValue(0x4);
    315       break;
    316     default:
    317       break;
    318   }
    319 }
    320 
    321 class Dt_imm6_4 : public EncodingValue {
    322   uint32_t type_;
    323 
    324  public:
    325   explicit Dt_imm6_4(DataType dt);
    326   uint32_t GetTypeEncodingValue() const { return type_; }
    327 };
    328 
    329 Dt_imm6_4::Dt_imm6_4(DataType dt) {
    330   switch (dt.GetValue()) {
    331     case S8:
    332       type_ = 0x0;
    333       SetEncodingValue(0x1);
    334       break;
    335     case U8:
    336       type_ = 0x1;
    337       SetEncodingValue(0x1);
    338       break;
    339     case S16:
    340       type_ = 0x0;
    341       SetEncodingValue(0x2);
    342       break;
    343     case U16:
    344       type_ = 0x1;
    345       SetEncodingValue(0x2);
    346       break;
    347     case S32:
    348       type_ = 0x0;
    349       SetEncodingValue(0x4);
    350       break;
    351     case U32:
    352       type_ = 0x1;
    353       SetEncodingValue(0x4);
    354       break;
    355     default:
    356       VIXL_UNREACHABLE();
    357       type_ = 0x0;
    358       break;
    359   }
    360 }
    361 
    362 class Dt_op_U_size_1 : public EncodingValue {
    363  public:
    364   explicit Dt_op_U_size_1(DataType dt);
    365 };
    366 
    367 Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
    368   switch (dt.GetValue()) {
    369     case S8:
    370       SetEncodingValue(0x0);
    371       break;
    372     case S16:
    373       SetEncodingValue(0x1);
    374       break;
    375     case S32:
    376       SetEncodingValue(0x2);
    377       break;
    378     case U8:
    379       SetEncodingValue(0x4);
    380       break;
    381     case U16:
    382       SetEncodingValue(0x5);
    383       break;
    384     case U32:
    385       SetEncodingValue(0x6);
    386       break;
    387     case P8:
    388       SetEncodingValue(0x8);
    389       break;
    390     case P64:
    391       SetEncodingValue(0xa);
    392       break;
    393     default:
    394       break;
    395   }
    396 }
    397 
    398 class Dt_op_size_1 : public EncodingValue {
    399  public:
    400   explicit Dt_op_size_1(DataType dt);
    401 };
    402 
    403 Dt_op_size_1::Dt_op_size_1(DataType dt) {
    404   switch (dt.GetValue()) {
    405     case I8:
    406       SetEncodingValue(0x0);
    407       break;
    408     case I16:
    409       SetEncodingValue(0x1);
    410       break;
    411     case I32:
    412       SetEncodingValue(0x2);
    413       break;
    414     case P8:
    415       SetEncodingValue(0x4);
    416       break;
    417     default:
    418       break;
    419   }
    420 }
    421 
    422 class Dt_op_size_2 : public EncodingValue {
    423  public:
    424   explicit Dt_op_size_2(DataType dt);
    425 };
    426 
    427 Dt_op_size_2::Dt_op_size_2(DataType dt) {
    428   switch (dt.GetValue()) {
    429     case S8:
    430       SetEncodingValue(0x0);
    431       break;
    432     case S16:
    433       SetEncodingValue(0x1);
    434       break;
    435     case S32:
    436       SetEncodingValue(0x2);
    437       break;
    438     case U8:
    439       SetEncodingValue(0x4);
    440       break;
    441     case U16:
    442       SetEncodingValue(0x5);
    443       break;
    444     case U32:
    445       SetEncodingValue(0x6);
    446       break;
    447     default:
    448       break;
    449   }
    450 }
    451 
    452 class Dt_op_size_3 : public EncodingValue {
    453  public:
    454   explicit Dt_op_size_3(DataType dt);
    455 };
    456 
    457 Dt_op_size_3::Dt_op_size_3(DataType dt) {
    458   switch (dt.GetValue()) {
    459     case S16:
    460       SetEncodingValue(0x0);
    461       break;
    462     case S32:
    463       SetEncodingValue(0x1);
    464       break;
    465     case S64:
    466       SetEncodingValue(0x2);
    467       break;
    468     case U16:
    469       SetEncodingValue(0x4);
    470       break;
    471     case U32:
    472       SetEncodingValue(0x5);
    473       break;
    474     case U64:
    475       SetEncodingValue(0x6);
    476       break;
    477     default:
    478       break;
    479   }
    480 }
    481 
    482 class Dt_U_imm3H_1 : public EncodingValue {
    483  public:
    484   explicit Dt_U_imm3H_1(DataType dt);
    485 };
    486 
    487 Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
    488   switch (dt.GetValue()) {
    489     case S8:
    490       SetEncodingValue(0x1);
    491       break;
    492     case S16:
    493       SetEncodingValue(0x2);
    494       break;
    495     case S32:
    496       SetEncodingValue(0x4);
    497       break;
    498     case U8:
    499       SetEncodingValue(0x9);
    500       break;
    501     case U16:
    502       SetEncodingValue(0xa);
    503       break;
    504     case U32:
    505       SetEncodingValue(0xc);
    506       break;
    507     default:
    508       break;
    509   }
    510 }
    511 
    512 class Dt_U_opc1_opc2_1 : public EncodingValue {
    513  public:
    514   explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
    515 };
    516 
    517 Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
    518   switch (dt.GetValue()) {
    519     case S8:
    520       if ((lane.GetLane() & 7) != lane.GetLane()) {
    521         return;
    522       }
    523       SetEncodingValue(0x8 | lane.GetLane());
    524       break;
    525     case S16:
    526       if ((lane.GetLane() & 3) != lane.GetLane()) {
    527         return;
    528       }
    529       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    530       break;
    531     case U8:
    532       if ((lane.GetLane() & 7) != lane.GetLane()) {
    533         return;
    534       }
    535       SetEncodingValue(0x18 | lane.GetLane());
    536       break;
    537     case U16:
    538       if ((lane.GetLane() & 3) != lane.GetLane()) {
    539         return;
    540       }
    541       SetEncodingValue(0x11 | (lane.GetLane() << 1));
    542       break;
    543     case Untyped32:
    544       if ((lane.GetLane() & 1) != lane.GetLane()) {
    545         return;
    546       }
    547       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    548       break;
    549     case kDataTypeValueNone:
    550       if ((lane.GetLane() & 1) != lane.GetLane()) {
    551         return;
    552       }
    553       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    554       break;
    555     default:
    556       break;
    557   }
    558 }
    559 
    560 class Dt_opc1_opc2_1 : public EncodingValue {
    561  public:
    562   explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
    563 };
    564 
    565 Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
    566   switch (dt.GetValue()) {
    567     case Untyped8:
    568       if ((lane.GetLane() & 7) != lane.GetLane()) {
    569         return;
    570       }
    571       SetEncodingValue(0x8 | lane.GetLane());
    572       break;
    573     case Untyped16:
    574       if ((lane.GetLane() & 3) != lane.GetLane()) {
    575         return;
    576       }
    577       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    578       break;
    579     case Untyped32:
    580       if ((lane.GetLane() & 1) != lane.GetLane()) {
    581         return;
    582       }
    583       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    584       break;
    585     case kDataTypeValueNone:
    586       if ((lane.GetLane() & 1) != lane.GetLane()) {
    587         return;
    588       }
    589       SetEncodingValue(0x0 | (lane.GetLane() << 2));
    590       break;
    591     default:
    592       break;
    593   }
    594 }
    595 
    596 class Dt_imm4_1 : public EncodingValue {
    597  public:
    598   explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
    599 };
    600 
    601 Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
    602   switch (dt.GetValue()) {
    603     case Untyped8:
    604       if ((lane.GetLane() & 7) != lane.GetLane()) {
    605         return;
    606       }
    607       SetEncodingValue(0x1 | (lane.GetLane() << 1));
    608       break;
    609     case Untyped16:
    610       if ((lane.GetLane() & 3) != lane.GetLane()) {
    611         return;
    612       }
    613       SetEncodingValue(0x2 | (lane.GetLane() << 2));
    614       break;
    615     case Untyped32:
    616       if ((lane.GetLane() & 1) != lane.GetLane()) {
    617         return;
    618       }
    619       SetEncodingValue(0x4 | (lane.GetLane() << 3));
    620       break;
    621     default:
    622       break;
    623   }
    624 }
    625 
    626 class Dt_B_E_1 : public EncodingValue {
    627  public:
    628   explicit Dt_B_E_1(DataType dt);
    629 };
    630 
    631 Dt_B_E_1::Dt_B_E_1(DataType dt) {
    632   switch (dt.GetValue()) {
    633     case Untyped8:
    634       SetEncodingValue(0x2);
    635       break;
    636     case Untyped16:
    637       SetEncodingValue(0x1);
    638       break;
    639     case Untyped32:
    640       SetEncodingValue(0x0);
    641       break;
    642     default:
    643       break;
    644   }
    645 }
    646 
    647 class Dt_op_1 : public EncodingValue {
    648  public:
    649   Dt_op_1(DataType dt1, DataType dt2);
    650 };
    651 
    652 Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
    653   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
    654     SetEncodingValue(0x0);
    655     return;
    656   }
    657   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
    658     SetEncodingValue(0x1);
    659     return;
    660   }
    661   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
    662     SetEncodingValue(0x2);
    663     return;
    664   }
    665   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
    666     SetEncodingValue(0x3);
    667     return;
    668   }
    669 }
    670 
    671 class Dt_op_2 : public EncodingValue {
    672  public:
    673   explicit Dt_op_2(DataType dt);
    674 };
    675 
    676 Dt_op_2::Dt_op_2(DataType dt) {
    677   switch (dt.GetValue()) {
    678     case U32:
    679       SetEncodingValue(0x0);
    680       break;
    681     case S32:
    682       SetEncodingValue(0x1);
    683       break;
    684     default:
    685       break;
    686   }
    687 }
    688 
    689 class Dt_op_3 : public EncodingValue {
    690  public:
    691   explicit Dt_op_3(DataType dt);
    692 };
    693 
    694 Dt_op_3::Dt_op_3(DataType dt) {
    695   switch (dt.GetValue()) {
    696     case S32:
    697       SetEncodingValue(0x0);
    698       break;
    699     case U32:
    700       SetEncodingValue(0x1);
    701       break;
    702     default:
    703       break;
    704   }
    705 }
    706 
    707 class Dt_U_sx_1 : public EncodingValue {
    708  public:
    709   explicit Dt_U_sx_1(DataType dt);
    710 };
    711 
    712 Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
    713   switch (dt.GetValue()) {
    714     case S16:
    715       SetEncodingValue(0x0);
    716       break;
    717     case S32:
    718       SetEncodingValue(0x1);
    719       break;
    720     case U16:
    721       SetEncodingValue(0x2);
    722       break;
    723     case U32:
    724       SetEncodingValue(0x3);
    725       break;
    726     default:
    727       break;
    728   }
    729 }
    730 
    731 class Dt_op_U_1 : public EncodingValue {
    732  public:
    733   Dt_op_U_1(DataType dt1, DataType dt2);
    734 };
    735 
    736 Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
    737   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
    738     SetEncodingValue(0x0);
    739     return;
    740   }
    741   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
    742     SetEncodingValue(0x1);
    743     return;
    744   }
    745   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
    746     SetEncodingValue(0x2);
    747     return;
    748   }
    749   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
    750     SetEncodingValue(0x3);
    751     return;
    752   }
    753 }
    754 
    755 class Dt_sz_1 : public EncodingValue {
    756  public:
    757   explicit Dt_sz_1(DataType dt);
    758 };
    759 
    760 Dt_sz_1::Dt_sz_1(DataType dt) {
    761   switch (dt.GetValue()) {
    762     case F32:
    763       SetEncodingValue(0x0);
    764       break;
    765     default:
    766       break;
    767   }
    768 }
    769 
    770 class Dt_F_size_1 : public EncodingValue {
    771  public:
    772   explicit Dt_F_size_1(DataType dt);
    773 };
    774 
    775 Dt_F_size_1::Dt_F_size_1(DataType dt) {
    776   switch (dt.GetValue()) {
    777     case S8:
    778       SetEncodingValue(0x0);
    779       break;
    780     case S16:
    781       SetEncodingValue(0x1);
    782       break;
    783     case S32:
    784       SetEncodingValue(0x2);
    785       break;
    786     case F32:
    787       SetEncodingValue(0x6);
    788       break;
    789     default:
    790       break;
    791   }
    792 }
    793 
    794 class Dt_F_size_2 : public EncodingValue {
    795  public:
    796   explicit Dt_F_size_2(DataType dt);
    797 };
    798 
    799 Dt_F_size_2::Dt_F_size_2(DataType dt) {
    800   switch (dt.GetValue()) {
    801     case I8:
    802       SetEncodingValue(0x0);
    803       break;
    804     case I16:
    805       SetEncodingValue(0x1);
    806       break;
    807     case I32:
    808       SetEncodingValue(0x2);
    809       break;
    810     case F32:
    811       SetEncodingValue(0x6);
    812       break;
    813     default:
    814       break;
    815   }
    816 }
    817 
    818 class Dt_F_size_3 : public EncodingValue {
    819  public:
    820   explicit Dt_F_size_3(DataType dt);
    821 };
    822 
    823 Dt_F_size_3::Dt_F_size_3(DataType dt) {
    824   switch (dt.GetValue()) {
    825     case I16:
    826       SetEncodingValue(0x1);
    827       break;
    828     case I32:
    829       SetEncodingValue(0x2);
    830       break;
    831     case F32:
    832       SetEncodingValue(0x6);
    833       break;
    834     default:
    835       break;
    836   }
    837 }
    838 
    839 class Dt_F_size_4 : public EncodingValue {
    840  public:
    841   explicit Dt_F_size_4(DataType dt);
    842 };
    843 
    844 Dt_F_size_4::Dt_F_size_4(DataType dt) {
    845   switch (dt.GetValue()) {
    846     case U32:
    847       SetEncodingValue(0x2);
    848       break;
    849     case F32:
    850       SetEncodingValue(0x6);
    851       break;
    852     default:
    853       break;
    854   }
    855 }
    856 
    857 class Dt_U_size_1 : public EncodingValue {
    858  public:
    859   explicit Dt_U_size_1(DataType dt);
    860 };
    861 
    862 Dt_U_size_1::Dt_U_size_1(DataType dt) {
    863   switch (dt.GetValue()) {
    864     case S8:
    865       SetEncodingValue(0x0);
    866       break;
    867     case S16:
    868       SetEncodingValue(0x1);
    869       break;
    870     case S32:
    871       SetEncodingValue(0x2);
    872       break;
    873     case U8:
    874       SetEncodingValue(0x4);
    875       break;
    876     case U16:
    877       SetEncodingValue(0x5);
    878       break;
    879     case U32:
    880       SetEncodingValue(0x6);
    881       break;
    882     default:
    883       break;
    884   }
    885 }
    886 
    887 class Dt_U_size_2 : public EncodingValue {
    888  public:
    889   explicit Dt_U_size_2(DataType dt);
    890 };
    891 
    892 Dt_U_size_2::Dt_U_size_2(DataType dt) {
    893   switch (dt.GetValue()) {
    894     case S16:
    895       SetEncodingValue(0x1);
    896       break;
    897     case S32:
    898       SetEncodingValue(0x2);
    899       break;
    900     case U16:
    901       SetEncodingValue(0x5);
    902       break;
    903     case U32:
    904       SetEncodingValue(0x6);
    905       break;
    906     default:
    907       break;
    908   }
    909 }
    910 
    911 class Dt_U_size_3 : public EncodingValue {
    912  public:
    913   explicit Dt_U_size_3(DataType dt);
    914 };
    915 
    916 Dt_U_size_3::Dt_U_size_3(DataType dt) {
    917   switch (dt.GetValue()) {
    918     case S8:
    919       SetEncodingValue(0x0);
    920       break;
    921     case S16:
    922       SetEncodingValue(0x1);
    923       break;
    924     case S32:
    925       SetEncodingValue(0x2);
    926       break;
    927     case S64:
    928       SetEncodingValue(0x3);
    929       break;
    930     case U8:
    931       SetEncodingValue(0x4);
    932       break;
    933     case U16:
    934       SetEncodingValue(0x5);
    935       break;
    936     case U32:
    937       SetEncodingValue(0x6);
    938       break;
    939     case U64:
    940       SetEncodingValue(0x7);
    941       break;
    942     default:
    943       break;
    944   }
    945 }
    946 
    947 class Dt_size_1 : public EncodingValue {
    948  public:
    949   explicit Dt_size_1(DataType dt);
    950 };
    951 
    952 Dt_size_1::Dt_size_1(DataType dt) {
    953   switch (dt.GetValue()) {
    954     case Untyped8:
    955       SetEncodingValue(0x0);
    956       break;
    957     default:
    958       break;
    959   }
    960 }
    961 
    962 class Dt_size_2 : public EncodingValue {
    963  public:
    964   explicit Dt_size_2(DataType dt);
    965 };
    966 
    967 Dt_size_2::Dt_size_2(DataType dt) {
    968   switch (dt.GetValue()) {
    969     case I8:
    970       SetEncodingValue(0x0);
    971       break;
    972     case I16:
    973       SetEncodingValue(0x1);
    974       break;
    975     case I32:
    976       SetEncodingValue(0x2);
    977       break;
    978     case I64:
    979       SetEncodingValue(0x3);
    980       break;
    981     default:
    982       break;
    983   }
    984 }
    985 
    986 class Dt_size_3 : public EncodingValue {
    987  public:
    988   explicit Dt_size_3(DataType dt);
    989 };
    990 
    991 Dt_size_3::Dt_size_3(DataType dt) {
    992   switch (dt.GetValue()) {
    993     case I16:
    994       SetEncodingValue(0x0);
    995       break;
    996     case I32:
    997       SetEncodingValue(0x1);
    998       break;
    999     case I64:
   1000       SetEncodingValue(0x2);
   1001       break;
   1002     default:
   1003       break;
   1004   }
   1005 }
   1006 
   1007 class Dt_size_4 : public EncodingValue {
   1008  public:
   1009   explicit Dt_size_4(DataType dt);
   1010 };
   1011 
   1012 Dt_size_4::Dt_size_4(DataType dt) {
   1013   switch (dt.GetValue()) {
   1014     case I8:
   1015       SetEncodingValue(0x0);
   1016       break;
   1017     case I16:
   1018       SetEncodingValue(0x1);
   1019       break;
   1020     case I32:
   1021       SetEncodingValue(0x2);
   1022       break;
   1023     default:
   1024       break;
   1025   }
   1026 }
   1027 
   1028 class Dt_size_5 : public EncodingValue {
   1029  public:
   1030   explicit Dt_size_5(DataType dt);
   1031 };
   1032 
   1033 Dt_size_5::Dt_size_5(DataType dt) {
   1034   switch (dt.GetValue()) {
   1035     case S8:
   1036       SetEncodingValue(0x0);
   1037       break;
   1038     case S16:
   1039       SetEncodingValue(0x1);
   1040       break;
   1041     case S32:
   1042       SetEncodingValue(0x2);
   1043       break;
   1044     default:
   1045       break;
   1046   }
   1047 }
   1048 
   1049 class Dt_size_6 : public EncodingValue {
   1050  public:
   1051   explicit Dt_size_6(DataType dt);
   1052 };
   1053 
   1054 Dt_size_6::Dt_size_6(DataType dt) {
   1055   switch (dt.GetValue()) {
   1056     case Untyped8:
   1057       SetEncodingValue(0x0);
   1058       break;
   1059     case Untyped16:
   1060       SetEncodingValue(0x1);
   1061       break;
   1062     case Untyped32:
   1063       SetEncodingValue(0x2);
   1064       break;
   1065     case Untyped64:
   1066       SetEncodingValue(0x3);
   1067       break;
   1068     default:
   1069       break;
   1070   }
   1071 }
   1072 
   1073 class Dt_size_7 : public EncodingValue {
   1074  public:
   1075   explicit Dt_size_7(DataType dt);
   1076 };
   1077 
   1078 Dt_size_7::Dt_size_7(DataType dt) {
   1079   switch (dt.GetValue()) {
   1080     case Untyped8:
   1081       SetEncodingValue(0x0);
   1082       break;
   1083     case Untyped16:
   1084       SetEncodingValue(0x1);
   1085       break;
   1086     case Untyped32:
   1087       SetEncodingValue(0x2);
   1088       break;
   1089     default:
   1090       break;
   1091   }
   1092 }
   1093 
   1094 class Dt_size_8 : public EncodingValue {
   1095  public:
   1096   Dt_size_8(DataType dt, Alignment align);
   1097 };
   1098 
   1099 Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
   1100   switch (dt.GetValue()) {
   1101     case Untyped8:
   1102       SetEncodingValue(0x0);
   1103       break;
   1104     case Untyped16:
   1105       SetEncodingValue(0x1);
   1106       break;
   1107     case Untyped32:
   1108       if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
   1109         SetEncodingValue(0x2);
   1110       } else if (align.Is(k128BitAlign)) {
   1111         SetEncodingValue(0x3);
   1112       }
   1113       break;
   1114     default:
   1115       break;
   1116   }
   1117 }
   1118 
   1119 class Dt_size_9 : public EncodingValue {
   1120   uint32_t type_;
   1121 
   1122  public:
   1123   explicit Dt_size_9(DataType dt);
   1124   uint32_t GetTypeEncodingValue() const { return type_; }
   1125 };
   1126 
   1127 Dt_size_9::Dt_size_9(DataType dt) {
   1128   switch (dt.GetValue()) {
   1129     case I16:
   1130       type_ = 0x0;
   1131       SetEncodingValue(0x1);
   1132       break;
   1133     case I32:
   1134       type_ = 0x0;
   1135       SetEncodingValue(0x2);
   1136       break;
   1137     case F32:
   1138       type_ = 0x1;
   1139       SetEncodingValue(0x2);
   1140       break;
   1141     default:
   1142       VIXL_UNREACHABLE();
   1143       type_ = 0x0;
   1144       break;
   1145   }
   1146 }
   1147 
   1148 class Dt_size_10 : public EncodingValue {
   1149  public:
   1150   explicit Dt_size_10(DataType dt);
   1151 };
   1152 
   1153 Dt_size_10::Dt_size_10(DataType dt) {
   1154   switch (dt.GetValue()) {
   1155     case S8:
   1156     case U8:
   1157     case I8:
   1158       SetEncodingValue(0x0);
   1159       break;
   1160     case S16:
   1161     case U16:
   1162     case I16:
   1163       SetEncodingValue(0x1);
   1164       break;
   1165     case S32:
   1166     case U32:
   1167     case I32:
   1168       SetEncodingValue(0x2);
   1169       break;
   1170     default:
   1171       break;
   1172   }
   1173 }
   1174 
   1175 class Dt_size_11 : public EncodingValue {
   1176   uint32_t type_;
   1177 
   1178  public:
   1179   explicit Dt_size_11(DataType dt);
   1180   uint32_t GetTypeEncodingValue() const { return type_; }
   1181 };
   1182 
   1183 Dt_size_11::Dt_size_11(DataType dt) {
   1184   switch (dt.GetValue()) {
   1185     case S16:
   1186       type_ = 0x0;
   1187       SetEncodingValue(0x1);
   1188       break;
   1189     case U16:
   1190       type_ = 0x1;
   1191       SetEncodingValue(0x1);
   1192       break;
   1193     case S32:
   1194       type_ = 0x0;
   1195       SetEncodingValue(0x2);
   1196       break;
   1197     case U32:
   1198       type_ = 0x1;
   1199       SetEncodingValue(0x2);
   1200       break;
   1201     default:
   1202       VIXL_UNREACHABLE();
   1203       type_ = 0x0;
   1204       break;
   1205   }
   1206 }
   1207 
   1208 class Dt_size_12 : public EncodingValue {
   1209   uint32_t type_;
   1210 
   1211  public:
   1212   explicit Dt_size_12(DataType dt);
   1213   uint32_t GetTypeEncodingValue() const { return type_; }
   1214 };
   1215 
   1216 Dt_size_12::Dt_size_12(DataType dt) {
   1217   switch (dt.GetValue()) {
   1218     case S8:
   1219       type_ = 0x0;
   1220       SetEncodingValue(0x0);
   1221       break;
   1222     case U8:
   1223       type_ = 0x1;
   1224       SetEncodingValue(0x0);
   1225       break;
   1226     case S16:
   1227       type_ = 0x0;
   1228       SetEncodingValue(0x1);
   1229       break;
   1230     case U16:
   1231       type_ = 0x1;
   1232       SetEncodingValue(0x1);
   1233       break;
   1234     case S32:
   1235       type_ = 0x0;
   1236       SetEncodingValue(0x2);
   1237       break;
   1238     case U32:
   1239       type_ = 0x1;
   1240       SetEncodingValue(0x2);
   1241       break;
   1242     default:
   1243       VIXL_UNREACHABLE();
   1244       type_ = 0x0;
   1245       break;
   1246   }
   1247 }
   1248 
   1249 class Dt_size_13 : public EncodingValue {
   1250  public:
   1251   explicit Dt_size_13(DataType dt);
   1252 };
   1253 
   1254 Dt_size_13::Dt_size_13(DataType dt) {
   1255   switch (dt.GetValue()) {
   1256     case S16:
   1257       SetEncodingValue(0x1);
   1258       break;
   1259     case S32:
   1260       SetEncodingValue(0x2);
   1261       break;
   1262     default:
   1263       break;
   1264   }
   1265 }
   1266 
   1267 class Dt_size_14 : public EncodingValue {
   1268  public:
   1269   explicit Dt_size_14(DataType dt);
   1270 };
   1271 
   1272 Dt_size_14::Dt_size_14(DataType dt) {
   1273   switch (dt.GetValue()) {
   1274     case S16:
   1275       SetEncodingValue(0x0);
   1276       break;
   1277     case S32:
   1278       SetEncodingValue(0x1);
   1279       break;
   1280     case S64:
   1281       SetEncodingValue(0x2);
   1282       break;
   1283     default:
   1284       break;
   1285   }
   1286 }
   1287 
   1288 class Dt_size_15 : public EncodingValue {
   1289  public:
   1290   explicit Dt_size_15(DataType dt);
   1291 };
   1292 
   1293 Dt_size_15::Dt_size_15(DataType dt) {
   1294   switch (dt.GetValue()) {
   1295     case Untyped8:
   1296       SetEncodingValue(0x0);
   1297       break;
   1298     case Untyped16:
   1299       SetEncodingValue(0x1);
   1300       break;
   1301     default:
   1302       break;
   1303   }
   1304 }
   1305 
   1306 class Dt_size_16 : public EncodingValue {
   1307  public:
   1308   explicit Dt_size_16(DataType dt);
   1309 };
   1310 
   1311 Dt_size_16::Dt_size_16(DataType dt) {
   1312   switch (dt.GetValue()) {
   1313     case I8:
   1314       SetEncodingValue(0x0);
   1315       break;
   1316     case I16:
   1317       SetEncodingValue(0x1);
   1318       break;
   1319     case I32:
   1320       SetEncodingValue(0x2);
   1321       break;
   1322     default:
   1323       break;
   1324   }
   1325 }
   1326 
   1327 class Index_1 : public EncodingValue {
   1328  public:
   1329   Index_1(const NeonRegisterList& nreglist, DataType dt);
   1330 };
   1331 
   1332 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
   1333   switch (dt.GetValue()) {
   1334     case Untyped8: {
   1335       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1336         return;
   1337       }
   1338       uint32_t value = nreglist.GetTransferLane() << 1;
   1339       if (!nreglist.IsSingleSpaced()) return;
   1340       SetEncodingValue(value);
   1341       break;
   1342     }
   1343     case Untyped16: {
   1344       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1345         return;
   1346       }
   1347       uint32_t value = nreglist.GetTransferLane() << 2;
   1348       if (nreglist.IsDoubleSpaced()) value |= 2;
   1349       SetEncodingValue(value);
   1350       break;
   1351     }
   1352     case Untyped32: {
   1353       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1354         return;
   1355       }
   1356       uint32_t value = nreglist.GetTransferLane() << 3;
   1357       if (nreglist.IsDoubleSpaced()) value |= 4;
   1358       SetEncodingValue(value);
   1359       break;
   1360     }
   1361     default:
   1362       break;
   1363   }
   1364 }
   1365 
   1366 class Align_index_align_1 : public EncodingValue {
   1367  public:
   1368   Align_index_align_1(Alignment align,
   1369                       const NeonRegisterList& nreglist,
   1370                       DataType dt);
   1371 };
   1372 
   1373 Align_index_align_1::Align_index_align_1(Alignment align,
   1374                                          const NeonRegisterList& nreglist,
   1375                                          DataType dt) {
   1376   switch (dt.GetValue()) {
   1377     case Untyped8: {
   1378       uint32_t value;
   1379       if (align.GetType() == kNoAlignment) {
   1380         value = 0;
   1381       } else {
   1382         return;
   1383       }
   1384       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1385         return;
   1386       }
   1387       value |= nreglist.GetTransferLane() << 1;
   1388       SetEncodingValue(value);
   1389       break;
   1390     }
   1391     case Untyped16: {
   1392       uint32_t value;
   1393       if (align.GetType() == k16BitAlign) {
   1394         value = 1;
   1395       } else if (align.GetType() == kNoAlignment) {
   1396         value = 0;
   1397       } else {
   1398         return;
   1399       }
   1400       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1401         return;
   1402       }
   1403       value |= nreglist.GetTransferLane() << 2;
   1404       SetEncodingValue(value);
   1405       break;
   1406     }
   1407     case Untyped32: {
   1408       uint32_t value;
   1409       if (align.GetType() == k32BitAlign) {
   1410         value = 3;
   1411       } else if (align.GetType() == kNoAlignment) {
   1412         value = 0;
   1413       } else {
   1414         return;
   1415       }
   1416       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1417         return;
   1418       }
   1419       value |= nreglist.GetTransferLane() << 3;
   1420       SetEncodingValue(value);
   1421       break;
   1422     }
   1423     default:
   1424       break;
   1425   }
   1426 }
   1427 
   1428 class Align_index_align_2 : public EncodingValue {
   1429  public:
   1430   Align_index_align_2(Alignment align,
   1431                       const NeonRegisterList& nreglist,
   1432                       DataType dt);
   1433 };
   1434 
   1435 Align_index_align_2::Align_index_align_2(Alignment align,
   1436                                          const NeonRegisterList& nreglist,
   1437                                          DataType dt) {
   1438   switch (dt.GetValue()) {
   1439     case Untyped8: {
   1440       uint32_t value;
   1441       if (align.GetType() == k16BitAlign) {
   1442         value = 1;
   1443       } else if (align.GetType() == kNoAlignment) {
   1444         value = 0;
   1445       } else {
   1446         return;
   1447       }
   1448       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1449         return;
   1450       }
   1451       value |= nreglist.GetTransferLane() << 1;
   1452       if (!nreglist.IsSingleSpaced()) return;
   1453       SetEncodingValue(value);
   1454       break;
   1455     }
   1456     case Untyped16: {
   1457       uint32_t value;
   1458       if (align.GetType() == k32BitAlign) {
   1459         value = 1;
   1460       } else if (align.GetType() == kNoAlignment) {
   1461         value = 0;
   1462       } else {
   1463         return;
   1464       }
   1465       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1466         return;
   1467       }
   1468       value |= nreglist.GetTransferLane() << 2;
   1469       if (nreglist.IsDoubleSpaced()) value |= 2;
   1470       SetEncodingValue(value);
   1471       break;
   1472     }
   1473     case Untyped32: {
   1474       uint32_t value;
   1475       if (align.GetType() == k64BitAlign) {
   1476         value = 1;
   1477       } else if (align.GetType() == kNoAlignment) {
   1478         value = 0;
   1479       } else {
   1480         return;
   1481       }
   1482       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1483         return;
   1484       }
   1485       value |= nreglist.GetTransferLane() << 3;
   1486       if (nreglist.IsDoubleSpaced()) value |= 4;
   1487       SetEncodingValue(value);
   1488       break;
   1489     }
   1490     default:
   1491       break;
   1492   }
   1493 }
   1494 
   1495 class Align_index_align_3 : public EncodingValue {
   1496  public:
   1497   Align_index_align_3(Alignment align,
   1498                       const NeonRegisterList& nreglist,
   1499                       DataType dt);
   1500 };
   1501 
   1502 Align_index_align_3::Align_index_align_3(Alignment align,
   1503                                          const NeonRegisterList& nreglist,
   1504                                          DataType dt) {
   1505   switch (dt.GetValue()) {
   1506     case Untyped8: {
   1507       uint32_t value;
   1508       if (align.GetType() == k32BitAlign) {
   1509         value = 1;
   1510       } else if (align.GetType() == kNoAlignment) {
   1511         value = 0;
   1512       } else {
   1513         return;
   1514       }
   1515       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
   1516         return;
   1517       }
   1518       value |= nreglist.GetTransferLane() << 1;
   1519       if (!nreglist.IsSingleSpaced()) return;
   1520       SetEncodingValue(value);
   1521       break;
   1522     }
   1523     case Untyped16: {
   1524       uint32_t value;
   1525       if (align.GetType() == k64BitAlign) {
   1526         value = 1;
   1527       } else if (align.GetType() == kNoAlignment) {
   1528         value = 0;
   1529       } else {
   1530         return;
   1531       }
   1532       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
   1533         return;
   1534       }
   1535       value |= nreglist.GetTransferLane() << 2;
   1536       if (nreglist.IsDoubleSpaced()) value |= 2;
   1537       SetEncodingValue(value);
   1538       break;
   1539     }
   1540     case Untyped32: {
   1541       uint32_t value;
   1542       if (align.GetType() == k64BitAlign) {
   1543         value = 1;
   1544       } else if (align.GetType() == k128BitAlign) {
   1545         value = 2;
   1546       } else if (align.GetType() == kNoAlignment) {
   1547         value = 0;
   1548       } else {
   1549         return;
   1550       }
   1551       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
   1552         return;
   1553       }
   1554       value |= nreglist.GetTransferLane() << 3;
   1555       if (nreglist.IsDoubleSpaced()) value |= 4;
   1556       SetEncodingValue(value);
   1557       break;
   1558     }
   1559     default:
   1560       break;
   1561   }
   1562 }
   1563 
   1564 class Align_a_1 : public EncodingValue {
   1565  public:
   1566   Align_a_1(Alignment align, DataType dt);
   1567 };
   1568 
   1569 Align_a_1::Align_a_1(Alignment align, DataType dt) {
   1570   switch (align.GetType()) {
   1571     case k16BitAlign:
   1572       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
   1573       break;
   1574     case k32BitAlign:
   1575       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1576       break;
   1577     case kNoAlignment:
   1578       SetEncodingValue(0x0);
   1579       break;
   1580     default:
   1581       break;
   1582   }
   1583 }
   1584 
   1585 class Align_a_2 : public EncodingValue {
   1586  public:
   1587   Align_a_2(Alignment align, DataType dt);
   1588 };
   1589 
   1590 Align_a_2::Align_a_2(Alignment align, DataType dt) {
   1591   switch (align.GetType()) {
   1592     case k16BitAlign:
   1593       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
   1594       break;
   1595     case k32BitAlign:
   1596       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
   1597       break;
   1598     case k64BitAlign:
   1599       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1600       break;
   1601     case kNoAlignment:
   1602       SetEncodingValue(0x0);
   1603       break;
   1604     default:
   1605       break;
   1606   }
   1607 }
   1608 
   1609 class Align_a_3 : public EncodingValue {
   1610  public:
   1611   Align_a_3(Alignment align, DataType dt);
   1612 };
   1613 
   1614 Align_a_3::Align_a_3(Alignment align, DataType dt) {
   1615   switch (align.GetType()) {
   1616     case k32BitAlign:
   1617       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
   1618       break;
   1619     case k64BitAlign:
   1620       if (dt.Is(Untyped16))
   1621         SetEncodingValue(0x1);
   1622       else if (dt.Is(Untyped32))
   1623         SetEncodingValue(0x1);
   1624       break;
   1625     case k128BitAlign:
   1626       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
   1627       break;
   1628     case kNoAlignment:
   1629       SetEncodingValue(0x0);
   1630       break;
   1631     default:
   1632       break;
   1633   }
   1634 }
   1635 
   1636 class Align_align_1 : public EncodingValue {
   1637  public:
   1638   Align_align_1(Alignment align, const NeonRegisterList& nreglist);
   1639 };
   1640 
   1641 Align_align_1::Align_align_1(Alignment align,
   1642                              const NeonRegisterList& nreglist) {
   1643   switch (align.GetType()) {
   1644     case k64BitAlign:
   1645       SetEncodingValue(0x1);
   1646       break;
   1647     case k128BitAlign:
   1648       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1649         SetEncodingValue(0x2);
   1650       break;
   1651     case k256BitAlign:
   1652       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1653         SetEncodingValue(0x3);
   1654       break;
   1655     case kNoAlignment:
   1656       SetEncodingValue(0x0);
   1657       break;
   1658     default:
   1659       break;
   1660   }
   1661 }
   1662 
   1663 class Align_align_2 : public EncodingValue {
   1664  public:
   1665   Align_align_2(Alignment align, const NeonRegisterList& nreglist);
   1666 };
   1667 
   1668 Align_align_2::Align_align_2(Alignment align,
   1669                              const NeonRegisterList& nreglist) {
   1670   switch (align.GetType()) {
   1671     case k64BitAlign:
   1672       SetEncodingValue(0x1);
   1673       break;
   1674     case k128BitAlign:
   1675       SetEncodingValue(0x2);
   1676       break;
   1677     case k256BitAlign:
   1678       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
   1679       break;
   1680     case kNoAlignment:
   1681       SetEncodingValue(0x0);
   1682       break;
   1683     default:
   1684       break;
   1685   }
   1686 }
   1687 
   1688 class Align_align_3 : public EncodingValue {
   1689  public:
   1690   explicit Align_align_3(Alignment align);
   1691 };
   1692 
   1693 Align_align_3::Align_align_3(Alignment align) {
   1694   switch (align.GetType()) {
   1695     case k64BitAlign:
   1696       SetEncodingValue(0x1);
   1697       break;
   1698     case kNoAlignment:
   1699       SetEncodingValue(0x0);
   1700       break;
   1701     default:
   1702       break;
   1703   }
   1704 }
   1705 
   1706 class Align_align_4 : public EncodingValue {
   1707  public:
   1708   explicit Align_align_4(Alignment align);
   1709 };
   1710 
   1711 Align_align_4::Align_align_4(Alignment align) {
   1712   switch (align.GetType()) {
   1713     case k64BitAlign:
   1714       SetEncodingValue(0x1);
   1715       break;
   1716     case k128BitAlign:
   1717       SetEncodingValue(0x2);
   1718       break;
   1719     case k256BitAlign:
   1720       SetEncodingValue(0x3);
   1721       break;
   1722     case kNoAlignment:
   1723       SetEncodingValue(0x0);
   1724       break;
   1725     default:
   1726       break;
   1727   }
   1728 }
   1729 
   1730 class Align_align_5 : public EncodingValue {
   1731  public:
   1732   Align_align_5(Alignment align, const NeonRegisterList& nreglist);
   1733 };
   1734 
   1735 Align_align_5::Align_align_5(Alignment align,
   1736                              const NeonRegisterList& nreglist) {
   1737   switch (align.GetType()) {
   1738     case k64BitAlign:
   1739       SetEncodingValue(0x1);
   1740       break;
   1741     case k128BitAlign:
   1742       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
   1743         SetEncodingValue(0x2);
   1744       break;
   1745     case k256BitAlign:
   1746       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
   1747       break;
   1748     case kNoAlignment:
   1749       SetEncodingValue(0x0);
   1750       break;
   1751     default:
   1752       break;
   1753   }
   1754 }
   1755 
   1756 
   1757 // CBNZ{<q>} <Rn>, <label> ; T1
   1758 // CBZ{<q>} <Rn>, <label> ; T1
   1759 static const struct ReferenceInfo kT16CbzInfo =
   1760     {k16BitT32InstructionSizeInBytes,
   1761      0,    // Min offset.
   1762      126,  // Max offset.
   1763      2,    // Alignment.
   1764      ReferenceInfo::kDontAlignPc};
   1765 
   1766 
   1767 // B<c>{<q>} <label> ; T1
   1768 static const struct ReferenceInfo kT16ConditionalBranchInfo =
   1769     {k16BitT32InstructionSizeInBytes,
   1770      -256,  // Min offset.
   1771      254,   // Max offset.
   1772      2,     // Alignment.
   1773      ReferenceInfo::kDontAlignPc};
   1774 
   1775 
   1776 // ADR{<c>}{<q>} <Rd>, <label> ; T1
   1777 // LDR{<c>}{<q>} <Rt>, <label> ; T1
   1778 static const struct ReferenceInfo kT16DataInfo =
   1779     {k16BitT32InstructionSizeInBytes,
   1780      0,     // Min offset.
   1781      1020,  // Max offset.
   1782      4,     // Alignment.
   1783      ReferenceInfo::kAlignPc};
   1784 
   1785 
   1786 // B{<c>}{<q>} <label> ; T2
   1787 static const struct ReferenceInfo kT16BranchInfo =
   1788     {k16BitT32InstructionSizeInBytes,
   1789      -2048,  // Min offset.
   1790      2046,   // Max offset.
   1791      2,      // Alignment.
   1792      ReferenceInfo::kDontAlignPc};
   1793 
   1794 
   1795 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
   1796 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
   1797 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
   1798 static const struct ReferenceInfo kT32DataInfo =
   1799     {k32BitT32InstructionSizeInBytes,
   1800      -1020,  // Min offset.
   1801      1020,   // Max offset.
   1802      4,      // Alignment.
   1803      ReferenceInfo::kAlignPc};
   1804 
   1805 
   1806 // ADR{<c>}{<q>} <Rd>, <label> ; T3
   1807 // LDR{<c>}{<q>} <Rt>, <label> ; T2
   1808 // LDRB{<c>}{<q>} <Rt>, <label> ; T1
   1809 // LDRH{<c>}{<q>} <Rt>, <label> ; T1
   1810 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
   1811 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
   1812 // PLD{<c>}{<q>} <label> ; T1
   1813 // PLI{<c>}{<q>} <label> ; T3
   1814 static const struct ReferenceInfo kT32FarDataInfo =
   1815     {k32BitT32InstructionSizeInBytes,
   1816      -4095,  // Min offset.
   1817      4095,   // Max offset.
   1818      1,      // Alignment.
   1819      ReferenceInfo::kAlignPc};
   1820 
   1821 
   1822 // B<c>{<q>} <label> ; T3
   1823 static const struct ReferenceInfo kT32ConditionalBranchInfo =
   1824     {k32BitT32InstructionSizeInBytes,
   1825      -1048576,  // Min offset.
   1826      1048574,   // Max offset.
   1827      2,         // Alignment.
   1828      ReferenceInfo::kDontAlignPc};
   1829 
   1830 
   1831 // B{<c>}{<q>} <label> ; T4
   1832 // BL{<c>}{<q>} <label> ; T1
   1833 static const struct ReferenceInfo kT32BranchInfo =
   1834     {k32BitT32InstructionSizeInBytes,
   1835      -16777216,  // Min offset.
   1836      16777214,   // Max offset.
   1837      2,          // Alignment.
   1838      ReferenceInfo::kDontAlignPc};
   1839 
   1840 
   1841 // BLX{<c>}{<q>} <label> ; T2
   1842 static const struct ReferenceInfo kT32BlxInfo =
   1843     {k32BitT32InstructionSizeInBytes,
   1844      -16777216,  // Min offset.
   1845      16777212,   // Max offset.
   1846      4,          // Alignment.
   1847      ReferenceInfo::kAlignPc};
   1848 
   1849 
   1850 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
   1851 // LDRH{<c>}{<q>} <Rt>, <label> ; A1
   1852 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
   1853 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
   1854 static const struct ReferenceInfo kA32VeryNearDataInfo =
   1855     {kA32InstructionSizeInBytes,
   1856      -255,  // Min offset.
   1857      255,   // Max offset.
   1858      1,     // Alignment.
   1859      ReferenceInfo::kAlignPc};
   1860 
   1861 
   1862 // ADR{<c>}{<q>} <Rd>, <label> ; A1
   1863 static const struct ReferenceInfo kA32AdrInfo = {kA32InstructionSizeInBytes,
   1864                                                  -256,  // Min offset.
   1865                                                  256,   // Max offset.
   1866                                                  1,     // Alignment.
   1867                                                  ReferenceInfo::kAlignPc};
   1868 
   1869 
   1870 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
   1871 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
   1872 static const struct ReferenceInfo kA32DataInfo = {kA32InstructionSizeInBytes,
   1873                                                   -1020,  // Min offset.
   1874                                                   1020,   // Max offset.
   1875                                                   4,      // Alignment.
   1876                                                   ReferenceInfo::kAlignPc};
   1877 
   1878 
   1879 // LDR{<c>}{<q>} <Rt>, <label> ; A1
   1880 // LDRB{<c>}{<q>} <Rt>, <label> ; A1
   1881 // PLD{<c>}{<q>} <label> ; A1
   1882 // PLI{<c>}{<q>} <label> ; A1
   1883 static const struct ReferenceInfo kA32FarDataInfo = {kA32InstructionSizeInBytes,
   1884                                                      -4095,  // Min offset.
   1885                                                      4095,   // Max offset.
   1886                                                      1,      // Alignment.
   1887                                                      ReferenceInfo::kAlignPc};
   1888 
   1889 
   1890 // B{<c>}{<q>} <label> ; A1
   1891 // BL{<c>}{<q>} <label> ; A1
   1892 static const struct ReferenceInfo kA32BranchInfo =
   1893     {kA32InstructionSizeInBytes,
   1894      -33554432,  // Min offset.
   1895      33554428,   // Max offset.
   1896      4,          // Alignment.
   1897      ReferenceInfo::kDontAlignPc};
   1898 
   1899 
   1900 // BLX{<c>}{<q>} <label> ; A2
   1901 static const struct ReferenceInfo kA32BlxInfo = {kA32InstructionSizeInBytes,
   1902                                                  -33554432,  // Min offset.
   1903                                                  33554430,   // Max offset.
   1904                                                  2,          // Alignment.
   1905                                                  ReferenceInfo::kAlignPc};
   1906 
   1907 
   1908 void Assembler::adc(Condition cond,
   1909                     EncodingSize size,
   1910                     Register rd,
   1911                     Register rn,
   1912                     const Operand& operand) {
   1913   VIXL_ASSERT(AllowAssembler());
   1914   CheckIT(cond);
   1915   if (operand.IsImmediate()) {
   1916     uint32_t imm = operand.GetImmediate();
   1917     if (IsUsingT32()) {
   1918       ImmediateT32 immediate_t32(imm);
   1919       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   1920       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   1921           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   1922         EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   1923                    (immediate_t32.GetEncodingValue() & 0xff) |
   1924                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   1925                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   1926         AdvanceIT();
   1927         return;
   1928       }
   1929     } else {
   1930       ImmediateA32 immediate_a32(imm);
   1931       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   1932       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   1933         EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
   1934                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   1935                 immediate_a32.GetEncodingValue());
   1936         return;
   1937       }
   1938     }
   1939   }
   1940   if (operand.IsImmediateShiftedRegister()) {
   1941     Register rm = operand.GetBaseRegister();
   1942     if (operand.IsPlainRegister()) {
   1943       if (IsUsingT32()) {
   1944         // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   1945         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   1946             rm.IsLow()) {
   1947           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
   1948           AdvanceIT();
   1949           return;
   1950         }
   1951       }
   1952     }
   1953     Shift shift = operand.GetShift();
   1954     uint32_t amount = operand.GetShiftAmount();
   1955     if (IsUsingT32()) {
   1956       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   1957       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   1958           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   1959         uint32_t amount_ = amount % 32;
   1960         EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   1961                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   1962                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   1963         AdvanceIT();
   1964         return;
   1965       }
   1966     } else {
   1967       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   1968       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   1969         uint32_t amount_ = amount % 32;
   1970         EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
   1971                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   1972                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   1973         return;
   1974       }
   1975     }
   1976   }
   1977   if (operand.IsRegisterShiftedRegister()) {
   1978     Register rm = operand.GetBaseRegister();
   1979     Shift shift = operand.GetShift();
   1980     Register rs = operand.GetShiftRegister();
   1981     if (IsUsingA32()) {
   1982       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   1983       if (cond.IsNotNever() &&
   1984           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   1985            AllowUnpredictable())) {
   1986         EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
   1987                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   1988                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   1989         return;
   1990       }
   1991     }
   1992   }
   1993   Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
   1994 }
   1995 
   1996 void Assembler::adcs(Condition cond,
   1997                      EncodingSize size,
   1998                      Register rd,
   1999                      Register rn,
   2000                      const Operand& operand) {
   2001   VIXL_ASSERT(AllowAssembler());
   2002   CheckIT(cond);
   2003   if (operand.IsImmediate()) {
   2004     uint32_t imm = operand.GetImmediate();
   2005     if (IsUsingT32()) {
   2006       ImmediateT32 immediate_t32(imm);
   2007       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   2008       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   2009           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   2010         EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2011                    (immediate_t32.GetEncodingValue() & 0xff) |
   2012                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2013                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2014         AdvanceIT();
   2015         return;
   2016       }
   2017     } else {
   2018       ImmediateA32 immediate_a32(imm);
   2019       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2020       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   2021         EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
   2022                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2023                 immediate_a32.GetEncodingValue());
   2024         return;
   2025       }
   2026     }
   2027   }
   2028   if (operand.IsImmediateShiftedRegister()) {
   2029     Register rm = operand.GetBaseRegister();
   2030     if (operand.IsPlainRegister()) {
   2031       if (IsUsingT32()) {
   2032         // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   2033         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2034             rm.IsLow()) {
   2035           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
   2036           AdvanceIT();
   2037           return;
   2038         }
   2039       }
   2040     }
   2041     Shift shift = operand.GetShift();
   2042     uint32_t amount = operand.GetShiftAmount();
   2043     if (IsUsingT32()) {
   2044       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   2045       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   2046           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2047         uint32_t amount_ = amount % 32;
   2048         EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2049                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2050                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2051         AdvanceIT();
   2052         return;
   2053       }
   2054     } else {
   2055       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2056       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2057         uint32_t amount_ = amount % 32;
   2058         EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
   2059                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2060                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2061         return;
   2062       }
   2063     }
   2064   }
   2065   if (operand.IsRegisterShiftedRegister()) {
   2066     Register rm = operand.GetBaseRegister();
   2067     Shift shift = operand.GetShift();
   2068     Register rs = operand.GetShiftRegister();
   2069     if (IsUsingA32()) {
   2070       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2071       if (cond.IsNotNever() &&
   2072           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2073            AllowUnpredictable())) {
   2074         EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
   2075                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2076                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2077         return;
   2078       }
   2079     }
   2080   }
   2081   Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
   2082 }
   2083 
   2084 void Assembler::add(Condition cond,
   2085                     EncodingSize size,
   2086                     Register rd,
   2087                     Register rn,
   2088                     const Operand& operand) {
   2089   VIXL_ASSERT(AllowAssembler());
   2090   CheckIT(cond);
   2091   if (operand.IsImmediate()) {
   2092     uint32_t imm = operand.GetImmediate();
   2093     if (IsUsingT32()) {
   2094       ImmediateT32 immediate_t32(imm);
   2095       // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
   2096       if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
   2097           ((imm % 4) == 0)) {
   2098         uint32_t imm_ = imm >> 2;
   2099         EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
   2100         AdvanceIT();
   2101         return;
   2102       }
   2103       // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
   2104       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2105           (imm <= 7)) {
   2106         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   2107         AdvanceIT();
   2108         return;
   2109       }
   2110       // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   2111       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2112           (imm <= 255)) {
   2113         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2114         AdvanceIT();
   2115         return;
   2116       }
   2117       // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
   2118       if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
   2119           ((imm % 4) == 0)) {
   2120         uint32_t imm_ = imm >> 2;
   2121         EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
   2122         AdvanceIT();
   2123         return;
   2124       }
   2125       // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
   2126       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
   2127           ((imm % 4) == 0)) {
   2128         uint32_t imm_ = imm >> 2;
   2129         EmitT32_16(0xb000 | imm_);
   2130         AdvanceIT();
   2131         return;
   2132       }
   2133       // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
   2134       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
   2135           (!rd.IsPC() || AllowUnpredictable())) {
   2136         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2137                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2138         AdvanceIT();
   2139         return;
   2140       }
   2141       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   2142       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   2143           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   2144         EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2145                    (immediate_t32.GetEncodingValue() & 0xff) |
   2146                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2147                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2148         AdvanceIT();
   2149         return;
   2150       }
   2151       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   2152       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
   2153           (!rd.IsPC() || AllowUnpredictable())) {
   2154         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2155                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2156         AdvanceIT();
   2157         return;
   2158       }
   2159       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
   2160       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   2161           (!rd.IsPC() || AllowUnpredictable())) {
   2162         EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
   2163                    (immediate_t32.GetEncodingValue() & 0xff) |
   2164                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2165                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2166         AdvanceIT();
   2167         return;
   2168       }
   2169       // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
   2170       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
   2171           (!rd.IsPC() || AllowUnpredictable())) {
   2172         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2173                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2174         AdvanceIT();
   2175         return;
   2176       }
   2177     } else {
   2178       ImmediateA32 immediate_a32(imm);
   2179       // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
   2180       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2181         EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
   2182                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2183         return;
   2184       }
   2185       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2186       if (immediate_a32.IsValid() && cond.IsNotNever() &&
   2187           ((rn.GetCode() & 0xd) != 0xd)) {
   2188         EmitA32(0x02800000U | (cond.GetCondition() << 28) |
   2189                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2190                 immediate_a32.GetEncodingValue());
   2191         return;
   2192       }
   2193       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   2194       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2195         EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
   2196                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2197         return;
   2198       }
   2199     }
   2200   }
   2201   if (operand.IsImmediateShiftedRegister()) {
   2202     Register rm = operand.GetBaseRegister();
   2203     if (operand.IsPlainRegister()) {
   2204       if (IsUsingT32()) {
   2205         // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
   2206         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2207             rm.IsLow()) {
   2208           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
   2209                      (rm.GetCode() << 6));
   2210           AdvanceIT();
   2211           return;
   2212         }
   2213         // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
   2214         if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) &&
   2215             (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
   2216               (!rd.IsPC() || !rm.IsPC())) ||
   2217              AllowUnpredictable())) {
   2218           EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
   2219                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   2220           AdvanceIT();
   2221           return;
   2222         }
   2223         // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
   2224         if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) &&
   2225             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   2226              AllowUnpredictable())) {
   2227           EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
   2228                      ((rd.GetCode() & 0x8) << 4));
   2229           AdvanceIT();
   2230           return;
   2231         }
   2232         // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
   2233         if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
   2234           EmitT32_16(0x4485 | (rm.GetCode() << 3));
   2235           AdvanceIT();
   2236           return;
   2237         }
   2238       }
   2239     }
   2240     Shift shift = operand.GetShift();
   2241     uint32_t amount = operand.GetShiftAmount();
   2242     if (IsUsingT32()) {
   2243       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
   2244       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   2245           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2246         uint32_t amount_ = amount % 32;
   2247         EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2248                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2249                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2250         AdvanceIT();
   2251         return;
   2252       }
   2253       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
   2254       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   2255           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2256         uint32_t amount_ = amount % 32;
   2257         EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
   2258                    (operand.GetTypeEncodingValue() << 4) |
   2259                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2260         AdvanceIT();
   2261         return;
   2262       }
   2263     } else {
   2264       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2265       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   2266         uint32_t amount_ = amount % 32;
   2267         EmitA32(0x00800000U | (cond.GetCondition() << 28) |
   2268                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2269                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2270         return;
   2271       }
   2272       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   2273       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2274         uint32_t amount_ = amount % 32;
   2275         EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
   2276                 (rd.GetCode() << 12) | rm.GetCode() |
   2277                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2278         return;
   2279       }
   2280     }
   2281   }
   2282   if (operand.IsRegisterShiftedRegister()) {
   2283     Register rm = operand.GetBaseRegister();
   2284     Shift shift = operand.GetShift();
   2285     Register rs = operand.GetShiftRegister();
   2286     if (IsUsingA32()) {
   2287       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2288       if (cond.IsNotNever() &&
   2289           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2290            AllowUnpredictable())) {
   2291         EmitA32(0x00800010U | (cond.GetCondition() << 28) |
   2292                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2293                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2294         return;
   2295       }
   2296     }
   2297   }
   2298   Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
   2299 }
   2300 
   2301 void Assembler::add(Condition cond, Register rd, const Operand& operand) {
   2302   VIXL_ASSERT(AllowAssembler());
   2303   CheckIT(cond);
   2304   if (operand.IsImmediate()) {
   2305     uint32_t imm = operand.GetImmediate();
   2306     if (IsUsingT32()) {
   2307       // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
   2308       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
   2309         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2310         AdvanceIT();
   2311         return;
   2312       }
   2313     }
   2314   }
   2315   if (operand.IsPlainRegister()) {
   2316     Register rm = operand.GetBaseRegister();
   2317     if (IsUsingT32()) {
   2318       // ADD<c>{<q>} <Rdn>, <Rm> ; T2
   2319       if (InITBlock() && !rm.Is(sp) &&
   2320           (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
   2321             (!rd.IsPC() || !rm.IsPC())) ||
   2322            AllowUnpredictable())) {
   2323         EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
   2324                    (rm.GetCode() << 3));
   2325         AdvanceIT();
   2326         return;
   2327       }
   2328     }
   2329   }
   2330   Delegate(kAdd, &Assembler::add, cond, rd, operand);
   2331 }
   2332 
   2333 void Assembler::adds(Condition cond,
   2334                      EncodingSize size,
   2335                      Register rd,
   2336                      Register rn,
   2337                      const Operand& operand) {
   2338   VIXL_ASSERT(AllowAssembler());
   2339   CheckIT(cond);
   2340   if (operand.IsImmediate()) {
   2341     uint32_t imm = operand.GetImmediate();
   2342     if (IsUsingT32()) {
   2343       ImmediateT32 immediate_t32(imm);
   2344       // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
   2345       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2346           (imm <= 7)) {
   2347         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   2348         AdvanceIT();
   2349         return;
   2350       }
   2351       // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   2352       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2353           (imm <= 255)) {
   2354         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2355         AdvanceIT();
   2356         return;
   2357       }
   2358       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   2359       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   2360           !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
   2361         EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2362                    (immediate_t32.GetEncodingValue() & 0xff) |
   2363                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2364                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2365         AdvanceIT();
   2366         return;
   2367       }
   2368       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
   2369       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   2370           !rd.Is(pc)) {
   2371         EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
   2372                    (immediate_t32.GetEncodingValue() & 0xff) |
   2373                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2374                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2375         AdvanceIT();
   2376         return;
   2377       }
   2378     } else {
   2379       ImmediateA32 immediate_a32(imm);
   2380       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2381       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
   2382         EmitA32(0x02900000U | (cond.GetCondition() << 28) |
   2383                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2384                 immediate_a32.GetEncodingValue());
   2385         return;
   2386       }
   2387       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   2388       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   2389         EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
   2390                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   2391         return;
   2392       }
   2393     }
   2394   }
   2395   if (operand.IsImmediateShiftedRegister()) {
   2396     Register rm = operand.GetBaseRegister();
   2397     if (operand.IsPlainRegister()) {
   2398       if (IsUsingT32()) {
   2399         // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   2400         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   2401             rm.IsLow()) {
   2402           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
   2403                      (rm.GetCode() << 6));
   2404           AdvanceIT();
   2405           return;
   2406         }
   2407       }
   2408     }
   2409     Shift shift = operand.GetShift();
   2410     uint32_t amount = operand.GetShiftAmount();
   2411     if (IsUsingT32()) {
   2412       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
   2413       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   2414           !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2415         uint32_t amount_ = amount % 32;
   2416         EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2417                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2418                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2419         AdvanceIT();
   2420         return;
   2421       }
   2422       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
   2423       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   2424           !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
   2425         uint32_t amount_ = amount % 32;
   2426         EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
   2427                    (operand.GetTypeEncodingValue() << 4) |
   2428                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2429         AdvanceIT();
   2430         return;
   2431       }
   2432     } else {
   2433       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2434       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   2435         uint32_t amount_ = amount % 32;
   2436         EmitA32(0x00900000U | (cond.GetCondition() << 28) |
   2437                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2438                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2439         return;
   2440       }
   2441       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   2442       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2443         uint32_t amount_ = amount % 32;
   2444         EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
   2445                 (rd.GetCode() << 12) | rm.GetCode() |
   2446                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2447         return;
   2448       }
   2449     }
   2450   }
   2451   if (operand.IsRegisterShiftedRegister()) {
   2452     Register rm = operand.GetBaseRegister();
   2453     Shift shift = operand.GetShift();
   2454     Register rs = operand.GetShiftRegister();
   2455     if (IsUsingA32()) {
   2456       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2457       if (cond.IsNotNever() &&
   2458           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2459            AllowUnpredictable())) {
   2460         EmitA32(0x00900010U | (cond.GetCondition() << 28) |
   2461                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2462                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2463         return;
   2464       }
   2465     }
   2466   }
   2467   Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
   2468 }
   2469 
   2470 void Assembler::adds(Register rd, const Operand& operand) {
   2471   VIXL_ASSERT(AllowAssembler());
   2472   CheckIT(al);
   2473   if (operand.IsImmediate()) {
   2474     uint32_t imm = operand.GetImmediate();
   2475     if (IsUsingT32()) {
   2476       // ADDS{<q>} <Rdn>, #<imm8> ; T2
   2477       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
   2478         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
   2479         AdvanceIT();
   2480         return;
   2481       }
   2482     }
   2483   }
   2484   Delegate(kAdds, &Assembler::adds, rd, operand);
   2485 }
   2486 
   2487 void Assembler::addw(Condition cond,
   2488                      Register rd,
   2489                      Register rn,
   2490                      const Operand& operand) {
   2491   VIXL_ASSERT(AllowAssembler());
   2492   CheckIT(cond);
   2493   if (operand.IsImmediate()) {
   2494     uint32_t imm = operand.GetImmediate();
   2495     if (IsUsingT32()) {
   2496       // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
   2497       if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2498         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2499                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2500         AdvanceIT();
   2501         return;
   2502       }
   2503       // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   2504       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
   2505           (!rd.IsPC() || AllowUnpredictable())) {
   2506         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2507                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2508         AdvanceIT();
   2509         return;
   2510       }
   2511       // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
   2512       if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2513         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   2514                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   2515         AdvanceIT();
   2516         return;
   2517       }
   2518     }
   2519   }
   2520   Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
   2521 }
   2522 
   2523 void Assembler::adr(Condition cond,
   2524                     EncodingSize size,
   2525                     Register rd,
   2526                     Location* location) {
   2527   VIXL_ASSERT(AllowAssembler());
   2528   CheckIT(cond);
   2529   Location::Offset offset =
   2530       location->IsBound()
   2531           ? location->GetLocation() -
   2532                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   2533           : 0;
   2534   if (IsUsingT32()) {
   2535     int32_t neg_offset = -offset;
   2536     // ADR{<c>}{<q>} <Rd>, <label> ; T1
   2537     if (!size.IsWide() && rd.IsLow() &&
   2538         ((location->IsBound() && (offset >= 0) && (offset <= 1020) &&
   2539           ((offset & 0x3) == 0)) ||
   2540          (!location->IsBound() && size.IsNarrow()))) {
   2541       static class EmitOp : public Location::EmitOperator {
   2542        public:
   2543         EmitOp() : Location::EmitOperator(T32) {}
   2544         virtual uint32_t Encode(uint32_t instr,
   2545                                 Location::Offset pc,
   2546                                 const Location* location) const VIXL_OVERRIDE {
   2547           pc += kT32PcDelta;
   2548           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   2549           VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
   2550                       ((offset & 0x3) == 0));
   2551           const int32_t target = offset >> 2;
   2552           return instr | (target & 0xff);
   2553         }
   2554       } immop;
   2555       EmitT32_16(
   2556           Link(0xa000 | (rd.GetCode() << 8), location, immop, &kT16DataInfo));
   2557       AdvanceIT();
   2558       return;
   2559     }
   2560     // ADR{<c>}{<q>} <Rd>, <label> ; T2
   2561     if (!size.IsNarrow() && location->IsBound() && (neg_offset > 0) &&
   2562         (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   2563       EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
   2564                  ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
   2565       AdvanceIT();
   2566       return;
   2567     }
   2568     // ADR{<c>}{<q>} <Rd>, <label> ; T3
   2569     if (!size.IsNarrow() &&
   2570         (!location->IsBound() || ((offset >= 0) && (offset <= 4095))) &&
   2571         (!rd.IsPC() || AllowUnpredictable())) {
   2572       static class EmitOp : public Location::EmitOperator {
   2573        public:
   2574         EmitOp() : Location::EmitOperator(T32) {}
   2575         virtual uint32_t Encode(uint32_t instr,
   2576                                 Location::Offset pc,
   2577                                 const Location* location) const VIXL_OVERRIDE {
   2578           pc += kT32PcDelta;
   2579           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   2580           int32_t target;
   2581           if ((offset >= 0) && (offset <= 4095)) {
   2582             target = offset;
   2583           } else {
   2584             target = -offset;
   2585             VIXL_ASSERT((target >= 0) && (target <= 4095));
   2586             // Emit the T2 encoding.
   2587             instr |= 0x00a00000;
   2588           }
   2589           return instr | (target & 0xff) | ((target & 0x700) << 4) |
   2590                  ((target & 0x800) << 15);
   2591         }
   2592       } immop;
   2593       EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8),
   2594                       location,
   2595                       immop,
   2596                       &kT32FarDataInfo));
   2597       AdvanceIT();
   2598       return;
   2599     }
   2600   } else {
   2601     ImmediateA32 positive_immediate_a32(offset);
   2602     ImmediateA32 negative_immediate_a32(-offset);
   2603     // ADR{<c>}{<q>} <Rd>, <label> ; A1
   2604     if ((!location->IsBound() || positive_immediate_a32.IsValid()) &&
   2605         cond.IsNotNever()) {
   2606       static class EmitOp : public Location::EmitOperator {
   2607        public:
   2608         EmitOp() : Location::EmitOperator(A32) {}
   2609         virtual uint32_t Encode(uint32_t instr,
   2610                                 Location::Offset pc,
   2611                                 const Location* location) const VIXL_OVERRIDE {
   2612           pc += kA32PcDelta;
   2613           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   2614           int32_t target;
   2615           ImmediateA32 positive_immediate_a32(offset);
   2616           if (positive_immediate_a32.IsValid()) {
   2617             target = positive_immediate_a32.GetEncodingValue();
   2618           } else {
   2619             ImmediateA32 negative_immediate_a32(-offset);
   2620             VIXL_ASSERT(negative_immediate_a32.IsValid());
   2621             // Emit the A2 encoding.
   2622             target = negative_immediate_a32.GetEncodingValue();
   2623             instr = (instr & ~0x00f00000) | 0x00400000;
   2624           }
   2625           return instr | (target & 0xfff);
   2626         }
   2627       } immop;
   2628       EmitA32(
   2629           Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
   2630                location,
   2631                immop,
   2632                &kA32AdrInfo));
   2633       return;
   2634     }
   2635     // ADR{<c>}{<q>} <Rd>, <label> ; A2
   2636     if (location->IsBound() && negative_immediate_a32.IsValid() &&
   2637         cond.IsNotNever()) {
   2638       EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   2639               negative_immediate_a32.GetEncodingValue());
   2640       return;
   2641     }
   2642   }
   2643   Delegate(kAdr, &Assembler::adr, cond, size, rd, location);
   2644 }
   2645 
   2646 bool Assembler::adr_info(Condition cond,
   2647                          EncodingSize size,
   2648                          Register rd,
   2649                          Location* location,
   2650                          const struct ReferenceInfo** info) {
   2651   VIXL_ASSERT(!location->IsBound());
   2652   USE(location);
   2653   if (IsUsingT32()) {
   2654     // ADR{<c>}{<q>} <Rd>, <label> ; T1
   2655     if (!size.IsWide() && rd.IsLow() && size.IsNarrow()) {
   2656       *info = &kT16DataInfo;
   2657       return true;
   2658     }
   2659     // Skipped T2, as it is a negative offset variant.
   2660     // The minimum offset is included in the corresponding
   2661     // positive variant.
   2662     // ADR{<c>}{<q>} <Rd>, <label> ; T3
   2663     if (!size.IsNarrow()) {
   2664       *info = &kT32FarDataInfo;
   2665       return true;
   2666     }
   2667   } else {
   2668     // ADR{<c>}{<q>} <Rd>, <label> ; A1
   2669     if (cond.IsNotNever()) {
   2670       *info = &kA32AdrInfo;
   2671       return true;
   2672     }
   2673     // Skipped A2, as it is a negative offset variant.
   2674     // The minimum offset is included in the corresponding
   2675     // positive variant.
   2676   }
   2677   return false;
   2678 }
   2679 
   2680 void Assembler::and_(Condition cond,
   2681                      EncodingSize size,
   2682                      Register rd,
   2683                      Register rn,
   2684                      const Operand& operand) {
   2685   VIXL_ASSERT(AllowAssembler());
   2686   CheckIT(cond);
   2687   if (operand.IsImmediate()) {
   2688     uint32_t imm = operand.GetImmediate();
   2689     if (IsUsingT32()) {
   2690       ImmediateT32 immediate_t32(imm);
   2691       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   2692       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   2693           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   2694         EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2695                    (immediate_t32.GetEncodingValue() & 0xff) |
   2696                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2697                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2698         AdvanceIT();
   2699         return;
   2700       }
   2701     } else {
   2702       ImmediateA32 immediate_a32(imm);
   2703       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2704       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   2705         EmitA32(0x02000000U | (cond.GetCondition() << 28) |
   2706                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2707                 immediate_a32.GetEncodingValue());
   2708         return;
   2709       }
   2710     }
   2711   }
   2712   if (operand.IsImmediateShiftedRegister()) {
   2713     Register rm = operand.GetBaseRegister();
   2714     if (operand.IsPlainRegister()) {
   2715       if (IsUsingT32()) {
   2716         // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   2717         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2718             rm.IsLow()) {
   2719           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
   2720           AdvanceIT();
   2721           return;
   2722         }
   2723       }
   2724     }
   2725     Shift shift = operand.GetShift();
   2726     uint32_t amount = operand.GetShiftAmount();
   2727     if (IsUsingT32()) {
   2728       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   2729       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   2730           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2731         uint32_t amount_ = amount % 32;
   2732         EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2733                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2734                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2735         AdvanceIT();
   2736         return;
   2737       }
   2738     } else {
   2739       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2740       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2741         uint32_t amount_ = amount % 32;
   2742         EmitA32(0x00000000U | (cond.GetCondition() << 28) |
   2743                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2744                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2745         return;
   2746       }
   2747     }
   2748   }
   2749   if (operand.IsRegisterShiftedRegister()) {
   2750     Register rm = operand.GetBaseRegister();
   2751     Shift shift = operand.GetShift();
   2752     Register rs = operand.GetShiftRegister();
   2753     if (IsUsingA32()) {
   2754       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2755       if (cond.IsNotNever() &&
   2756           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2757            AllowUnpredictable())) {
   2758         EmitA32(0x00000010U | (cond.GetCondition() << 28) |
   2759                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2760                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2761         return;
   2762       }
   2763     }
   2764   }
   2765   Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
   2766 }
   2767 
   2768 void Assembler::ands(Condition cond,
   2769                      EncodingSize size,
   2770                      Register rd,
   2771                      Register rn,
   2772                      const Operand& operand) {
   2773   VIXL_ASSERT(AllowAssembler());
   2774   CheckIT(cond);
   2775   if (operand.IsImmediate()) {
   2776     uint32_t imm = operand.GetImmediate();
   2777     if (IsUsingT32()) {
   2778       ImmediateT32 immediate_t32(imm);
   2779       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   2780       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) &&
   2781           (!rn.IsPC() || AllowUnpredictable())) {
   2782         EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2783                    (immediate_t32.GetEncodingValue() & 0xff) |
   2784                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   2785                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   2786         AdvanceIT();
   2787         return;
   2788       }
   2789     } else {
   2790       ImmediateA32 immediate_a32(imm);
   2791       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   2792       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   2793         EmitA32(0x02100000U | (cond.GetCondition() << 28) |
   2794                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   2795                 immediate_a32.GetEncodingValue());
   2796         return;
   2797       }
   2798     }
   2799   }
   2800   if (operand.IsImmediateShiftedRegister()) {
   2801     Register rm = operand.GetBaseRegister();
   2802     if (operand.IsPlainRegister()) {
   2803       if (IsUsingT32()) {
   2804         // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   2805         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   2806             rm.IsLow()) {
   2807           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
   2808           AdvanceIT();
   2809           return;
   2810         }
   2811       }
   2812     }
   2813     Shift shift = operand.GetShift();
   2814     uint32_t amount = operand.GetShiftAmount();
   2815     if (IsUsingT32()) {
   2816       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   2817       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) &&
   2818           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2819         uint32_t amount_ = amount % 32;
   2820         EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   2821                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   2822                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2823         AdvanceIT();
   2824         return;
   2825       }
   2826     } else {
   2827       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   2828       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   2829         uint32_t amount_ = amount % 32;
   2830         EmitA32(0x00100000U | (cond.GetCondition() << 28) |
   2831                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2832                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   2833         return;
   2834       }
   2835     }
   2836   }
   2837   if (operand.IsRegisterShiftedRegister()) {
   2838     Register rm = operand.GetBaseRegister();
   2839     Shift shift = operand.GetShift();
   2840     Register rs = operand.GetShiftRegister();
   2841     if (IsUsingA32()) {
   2842       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   2843       if (cond.IsNotNever() &&
   2844           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   2845            AllowUnpredictable())) {
   2846         EmitA32(0x00100010U | (cond.GetCondition() << 28) |
   2847                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   2848                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   2849         return;
   2850       }
   2851     }
   2852   }
   2853   Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
   2854 }
   2855 
   2856 void Assembler::asr(Condition cond,
   2857                     EncodingSize size,
   2858                     Register rd,
   2859                     Register rm,
   2860                     const Operand& operand) {
   2861   VIXL_ASSERT(AllowAssembler());
   2862   CheckIT(cond);
   2863   if (operand.IsImmediate()) {
   2864     uint32_t imm = operand.GetImmediate();
   2865     if (IsUsingT32()) {
   2866       // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   2867       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   2868           (imm >= 1) && (imm <= 32)) {
   2869         uint32_t amount_ = imm % 32;
   2870         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
   2871                    (amount_ << 6));
   2872         AdvanceIT();
   2873         return;
   2874       }
   2875       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   2876       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
   2877           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2878         uint32_t amount_ = imm % 32;
   2879         EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
   2880                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2881         AdvanceIT();
   2882         return;
   2883       }
   2884     } else {
   2885       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   2886       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   2887         uint32_t amount_ = imm % 32;
   2888         EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
   2889                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   2890         return;
   2891       }
   2892     }
   2893   }
   2894   if (operand.IsPlainRegister()) {
   2895     Register rs = operand.GetBaseRegister();
   2896     if (IsUsingT32()) {
   2897       // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   2898       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   2899           rs.IsLow()) {
   2900         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   2901         AdvanceIT();
   2902         return;
   2903       }
   2904       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   2905       if (!size.IsNarrow() &&
   2906           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   2907         EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   2908                    rs.GetCode());
   2909         AdvanceIT();
   2910         return;
   2911       }
   2912     } else {
   2913       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   2914       if (cond.IsNotNever() &&
   2915           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   2916         EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
   2917                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   2918         return;
   2919       }
   2920     }
   2921   }
   2922   Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
   2923 }
   2924 
   2925 void Assembler::asrs(Condition cond,
   2926                      EncodingSize size,
   2927                      Register rd,
   2928                      Register rm,
   2929                      const Operand& operand) {
   2930   VIXL_ASSERT(AllowAssembler());
   2931   CheckIT(cond);
   2932   if (operand.IsImmediate()) {
   2933     uint32_t imm = operand.GetImmediate();
   2934     if (IsUsingT32()) {
   2935       // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   2936       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   2937           (imm >= 1) && (imm <= 32)) {
   2938         uint32_t amount_ = imm % 32;
   2939         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
   2940                    (amount_ << 6));
   2941         AdvanceIT();
   2942         return;
   2943       }
   2944       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   2945       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
   2946           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   2947         uint32_t amount_ = imm % 32;
   2948         EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
   2949                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   2950         AdvanceIT();
   2951         return;
   2952       }
   2953     } else {
   2954       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   2955       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   2956         uint32_t amount_ = imm % 32;
   2957         EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
   2958                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   2959         return;
   2960       }
   2961     }
   2962   }
   2963   if (operand.IsPlainRegister()) {
   2964     Register rs = operand.GetBaseRegister();
   2965     if (IsUsingT32()) {
   2966       // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   2967       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   2968           rs.IsLow()) {
   2969         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   2970         AdvanceIT();
   2971         return;
   2972       }
   2973       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   2974       if (!size.IsNarrow() &&
   2975           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   2976         EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   2977                    rs.GetCode());
   2978         AdvanceIT();
   2979         return;
   2980       }
   2981     } else {
   2982       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   2983       if (cond.IsNotNever() &&
   2984           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   2985         EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
   2986                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   2987         return;
   2988       }
   2989     }
   2990   }
   2991   Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
   2992 }
   2993 
   2994 void Assembler::b(Condition cond, EncodingSize size, Location* location) {
   2995   VIXL_ASSERT(AllowAssembler());
   2996   Location::Offset offset =
   2997       location->IsBound()
   2998           ? location->GetLocation() -
   2999                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3000           : 0;
   3001   if (IsUsingT32()) {
   3002     // B<c>{<q>} <label> ; T1
   3003     if (OutsideITBlock() && !size.IsWide() &&
   3004         ((location->IsBound() && (offset >= -256) && (offset <= 254) &&
   3005           ((offset & 0x1) == 0)) ||
   3006          (!location->IsBound() && size.IsNarrow())) &&
   3007         !cond.Is(al) && cond.IsNotNever()) {
   3008       static class EmitOp : public Location::EmitOperator {
   3009        public:
   3010         EmitOp() : Location::EmitOperator(T32) {}
   3011         virtual uint32_t Encode(uint32_t instr,
   3012                                 Location::Offset pc,
   3013                                 const Location* location) const VIXL_OVERRIDE {
   3014           pc += kT32PcDelta;
   3015           Location::Offset offset = location->GetLocation() - pc;
   3016           VIXL_ASSERT((offset >= -256) && (offset <= 254) &&
   3017                       ((offset & 0x1) == 0));
   3018           const int32_t target = offset >> 1;
   3019           return instr | (target & 0xff);
   3020         }
   3021       } immop;
   3022       EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8),
   3023                       location,
   3024                       immop,
   3025                       &kT16ConditionalBranchInfo));
   3026       AdvanceIT();
   3027       return;
   3028     }
   3029     // B{<c>}{<q>} <label> ; T2
   3030     if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
   3031         ((location->IsBound() && (offset >= -2048) && (offset <= 2046) &&
   3032           ((offset & 0x1) == 0)) ||
   3033          (!location->IsBound() && size.IsNarrow()))) {
   3034       CheckIT(cond);
   3035       static class EmitOp : public Location::EmitOperator {
   3036        public:
   3037         EmitOp() : Location::EmitOperator(T32) {}
   3038         virtual uint32_t Encode(uint32_t instr,
   3039                                 Location::Offset pc,
   3040                                 const Location* location) const VIXL_OVERRIDE {
   3041           pc += kT32PcDelta;
   3042           Location::Offset offset = location->GetLocation() - pc;
   3043           VIXL_ASSERT((offset >= -2048) && (offset <= 2046) &&
   3044                       ((offset & 0x1) == 0));
   3045           const int32_t target = offset >> 1;
   3046           return instr | (target & 0x7ff);
   3047         }
   3048       } immop;
   3049       EmitT32_16(Link(0xe000, location, immop, &kT16BranchInfo));
   3050       AdvanceIT();
   3051       return;
   3052     }
   3053     // B<c>{<q>} <label> ; T3
   3054     if (OutsideITBlock() && !size.IsNarrow() &&
   3055         ((location->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
   3056           ((offset & 0x1) == 0)) ||
   3057          !location->IsBound()) &&
   3058         !cond.Is(al) && cond.IsNotNever()) {
   3059       static class EmitOp : public Location::EmitOperator {
   3060        public:
   3061         EmitOp() : Location::EmitOperator(T32) {}
   3062         virtual uint32_t Encode(uint32_t instr,
   3063                                 Location::Offset pc,
   3064                                 const Location* location) const VIXL_OVERRIDE {
   3065           pc += kT32PcDelta;
   3066           Location::Offset offset = location->GetLocation() - pc;
   3067           VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) &&
   3068                       ((offset & 0x1) == 0));
   3069           const int32_t target = offset >> 1;
   3070           return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
   3071                  ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
   3072                  ((target & 0x80000) << 7);
   3073         }
   3074       } immop;
   3075       EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22),
   3076                       location,
   3077                       immop,
   3078                       &kT32ConditionalBranchInfo));
   3079       AdvanceIT();
   3080       return;
   3081     }
   3082     // B{<c>}{<q>} <label> ; T4
   3083     if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
   3084         ((location->IsBound() && (offset >= -16777216) &&
   3085           (offset <= 16777214) && ((offset & 0x1) == 0)) ||
   3086          !location->IsBound())) {
   3087       CheckIT(cond);
   3088       static class EmitOp : public Location::EmitOperator {
   3089        public:
   3090         EmitOp() : Location::EmitOperator(T32) {}
   3091         virtual uint32_t Encode(uint32_t instr,
   3092                                 Location::Offset pc,
   3093                                 const Location* location) const VIXL_OVERRIDE {
   3094           pc += kT32PcDelta;
   3095           Location::Offset offset = location->GetLocation() - pc;
   3096           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
   3097                       ((offset & 0x1) == 0));
   3098           int32_t target = offset >> 1;
   3099           uint32_t S = target & (1 << 23);
   3100           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
   3101           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
   3102                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
   3103                  ((target & 0x800000) << 3);
   3104         }
   3105       } immop;
   3106       EmitT32_32(Link(0xf0009000U, location, immop, &kT32BranchInfo));
   3107       AdvanceIT();
   3108       return;
   3109     }
   3110   } else {
   3111     // B{<c>}{<q>} <label> ; A1
   3112     if (((location->IsBound() && (offset >= -33554432) &&
   3113           (offset <= 33554428) && ((offset & 0x3) == 0)) ||
   3114          !location->IsBound()) &&
   3115         cond.IsNotNever()) {
   3116       static class EmitOp : public Location::EmitOperator {
   3117        public:
   3118         EmitOp() : Location::EmitOperator(A32) {}
   3119         virtual uint32_t Encode(uint32_t instr,
   3120                                 Location::Offset pc,
   3121                                 const Location* location) const VIXL_OVERRIDE {
   3122           pc += kA32PcDelta;
   3123           Location::Offset offset = location->GetLocation() - pc;
   3124           VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
   3125                       ((offset & 0x3) == 0));
   3126           const int32_t target = offset >> 2;
   3127           return instr | (target & 0xffffff);
   3128         }
   3129       } immop;
   3130       EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28),
   3131                    location,
   3132                    immop,
   3133                    &kA32BranchInfo));
   3134       return;
   3135     }
   3136   }
   3137   Delegate(kB, &Assembler::b, cond, size, location);
   3138 }
   3139 
   3140 bool Assembler::b_info(Condition cond,
   3141                        EncodingSize size,
   3142                        Location* location,
   3143                        const struct ReferenceInfo** info) {
   3144   VIXL_ASSERT(!location->IsBound());
   3145   USE(location);
   3146   if (IsUsingT32()) {
   3147     // B<c>{<q>} <label> ; T1
   3148     if (OutsideITBlock() && !size.IsWide() && size.IsNarrow() && !cond.Is(al) &&
   3149         cond.IsNotNever()) {
   3150       *info = &kT16ConditionalBranchInfo;
   3151       return true;
   3152     }
   3153     // B{<c>}{<q>} <label> ; T2
   3154     if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && size.IsNarrow()) {
   3155       *info = &kT16BranchInfo;
   3156       return true;
   3157     }
   3158     // B<c>{<q>} <label> ; T3
   3159     if (OutsideITBlock() && !size.IsNarrow() && !cond.Is(al) &&
   3160         cond.IsNotNever()) {
   3161       *info = &kT32ConditionalBranchInfo;
   3162       return true;
   3163     }
   3164     // B{<c>}{<q>} <label> ; T4
   3165     if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow()) {
   3166       *info = &kT32BranchInfo;
   3167       return true;
   3168     }
   3169   } else {
   3170     // B{<c>}{<q>} <label> ; A1
   3171     if (cond.IsNotNever()) {
   3172       *info = &kA32BranchInfo;
   3173       return true;
   3174     }
   3175   }
   3176   return false;
   3177 }
   3178 
   3179 void Assembler::bfc(Condition cond, Register rd, uint32_t lsb, uint32_t width) {
   3180   VIXL_ASSERT(AllowAssembler());
   3181   CheckIT(cond);
   3182   if (IsUsingT32()) {
   3183     // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
   3184     if ((lsb <= 31) && (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
   3185                         AllowUnpredictable())) {
   3186       uint32_t msb = lsb + width - 1;
   3187       EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
   3188                  ((lsb & 0x1c) << 10) | msb);
   3189       AdvanceIT();
   3190       return;
   3191     }
   3192   } else {
   3193     // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
   3194     if ((lsb <= 31) && cond.IsNotNever() &&
   3195         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
   3196          AllowUnpredictable())) {
   3197       uint32_t msb = lsb + width - 1;
   3198       EmitA32(0x07c0001fU | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3199               (lsb << 7) | (msb << 16));
   3200       return;
   3201     }
   3202   }
   3203   Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, width);
   3204 }
   3205 
   3206 void Assembler::bfi(
   3207     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
   3208   VIXL_ASSERT(AllowAssembler());
   3209   CheckIT(cond);
   3210   if (IsUsingT32()) {
   3211     // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
   3212     if ((lsb <= 31) && !rn.Is(pc) &&
   3213         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
   3214          AllowUnpredictable())) {
   3215       uint32_t msb = lsb + width - 1;
   3216       EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3217                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
   3218       AdvanceIT();
   3219       return;
   3220     }
   3221   } else {
   3222     // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
   3223     if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
   3224         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
   3225          AllowUnpredictable())) {
   3226       uint32_t msb = lsb + width - 1;
   3227       EmitA32(0x07c00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3228               rn.GetCode() | (lsb << 7) | (msb << 16));
   3229       return;
   3230     }
   3231   }
   3232   Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, width);
   3233 }
   3234 
   3235 void Assembler::bic(Condition cond,
   3236                     EncodingSize size,
   3237                     Register rd,
   3238                     Register rn,
   3239                     const Operand& operand) {
   3240   VIXL_ASSERT(AllowAssembler());
   3241   CheckIT(cond);
   3242   if (operand.IsImmediate()) {
   3243     uint32_t imm = operand.GetImmediate();
   3244     if (IsUsingT32()) {
   3245       ImmediateT32 immediate_t32(imm);
   3246       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   3247       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   3248           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   3249         EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3250                    (immediate_t32.GetEncodingValue() & 0xff) |
   3251                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3252                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3253         AdvanceIT();
   3254         return;
   3255       }
   3256     } else {
   3257       ImmediateA32 immediate_a32(imm);
   3258       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   3259       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3260         EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
   3261                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   3262                 immediate_a32.GetEncodingValue());
   3263         return;
   3264       }
   3265     }
   3266   }
   3267   if (operand.IsImmediateShiftedRegister()) {
   3268     Register rm = operand.GetBaseRegister();
   3269     if (operand.IsPlainRegister()) {
   3270       if (IsUsingT32()) {
   3271         // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   3272         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   3273             rm.IsLow()) {
   3274           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
   3275           AdvanceIT();
   3276           return;
   3277         }
   3278       }
   3279     }
   3280     Shift shift = operand.GetShift();
   3281     uint32_t amount = operand.GetShiftAmount();
   3282     if (IsUsingT32()) {
   3283       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3284       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   3285           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3286         uint32_t amount_ = amount % 32;
   3287         EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3288                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   3289                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3290         AdvanceIT();
   3291         return;
   3292       }
   3293     } else {
   3294       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3295       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3296         uint32_t amount_ = amount % 32;
   3297         EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
   3298                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3299                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3300         return;
   3301       }
   3302     }
   3303   }
   3304   if (operand.IsRegisterShiftedRegister()) {
   3305     Register rm = operand.GetBaseRegister();
   3306     Shift shift = operand.GetShift();
   3307     Register rs = operand.GetShiftRegister();
   3308     if (IsUsingA32()) {
   3309       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   3310       if (cond.IsNotNever() &&
   3311           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   3312            AllowUnpredictable())) {
   3313         EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
   3314                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3315                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   3316         return;
   3317       }
   3318     }
   3319   }
   3320   Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
   3321 }
   3322 
   3323 void Assembler::bics(Condition cond,
   3324                      EncodingSize size,
   3325                      Register rd,
   3326                      Register rn,
   3327                      const Operand& operand) {
   3328   VIXL_ASSERT(AllowAssembler());
   3329   CheckIT(cond);
   3330   if (operand.IsImmediate()) {
   3331     uint32_t imm = operand.GetImmediate();
   3332     if (IsUsingT32()) {
   3333       ImmediateT32 immediate_t32(imm);
   3334       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   3335       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   3336           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   3337         EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3338                    (immediate_t32.GetEncodingValue() & 0xff) |
   3339                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3340                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3341         AdvanceIT();
   3342         return;
   3343       }
   3344     } else {
   3345       ImmediateA32 immediate_a32(imm);
   3346       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   3347       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3348         EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
   3349                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   3350                 immediate_a32.GetEncodingValue());
   3351         return;
   3352       }
   3353     }
   3354   }
   3355   if (operand.IsImmediateShiftedRegister()) {
   3356     Register rm = operand.GetBaseRegister();
   3357     if (operand.IsPlainRegister()) {
   3358       if (IsUsingT32()) {
   3359         // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   3360         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   3361             rm.IsLow()) {
   3362           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
   3363           AdvanceIT();
   3364           return;
   3365         }
   3366       }
   3367     }
   3368     Shift shift = operand.GetShift();
   3369     uint32_t amount = operand.GetShiftAmount();
   3370     if (IsUsingT32()) {
   3371       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3372       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   3373           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3374         uint32_t amount_ = amount % 32;
   3375         EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   3376                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   3377                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3378         AdvanceIT();
   3379         return;
   3380       }
   3381     } else {
   3382       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3383       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3384         uint32_t amount_ = amount % 32;
   3385         EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
   3386                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3387                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3388         return;
   3389       }
   3390     }
   3391   }
   3392   if (operand.IsRegisterShiftedRegister()) {
   3393     Register rm = operand.GetBaseRegister();
   3394     Shift shift = operand.GetShift();
   3395     Register rs = operand.GetShiftRegister();
   3396     if (IsUsingA32()) {
   3397       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   3398       if (cond.IsNotNever() &&
   3399           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   3400            AllowUnpredictable())) {
   3401         EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
   3402                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   3403                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   3404         return;
   3405       }
   3406     }
   3407   }
   3408   Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
   3409 }
   3410 
   3411 void Assembler::bkpt(Condition cond, uint32_t imm) {
   3412   VIXL_ASSERT(AllowAssembler());
   3413   CheckIT(cond);
   3414   if (IsUsingT32()) {
   3415     // BKPT{<q>} {#}<imm> ; T1
   3416     if ((imm <= 255)) {
   3417       EmitT32_16(0xbe00 | imm);
   3418       AdvanceIT();
   3419       return;
   3420     }
   3421   } else {
   3422     // BKPT{<q>} {#}<imm> ; A1
   3423     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   3424       EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   3425               ((imm & 0xfff0) << 4));
   3426       return;
   3427     }
   3428   }
   3429   Delegate(kBkpt, &Assembler::bkpt, cond, imm);
   3430 }
   3431 
   3432 void Assembler::bl(Condition cond, Location* location) {
   3433   VIXL_ASSERT(AllowAssembler());
   3434   CheckIT(cond);
   3435   Location::Offset offset =
   3436       location->IsBound()
   3437           ? location->GetLocation() -
   3438                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3439           : 0;
   3440   if (IsUsingT32()) {
   3441     // BL{<c>}{<q>} <label> ; T1
   3442     if (((location->IsBound() && (offset >= -16777216) &&
   3443           (offset <= 16777214) && ((offset & 0x1) == 0)) ||
   3444          !location->IsBound()) &&
   3445         (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
   3446       static class EmitOp : public Location::EmitOperator {
   3447        public:
   3448         EmitOp() : Location::EmitOperator(T32) {}
   3449         virtual uint32_t Encode(uint32_t instr,
   3450                                 Location::Offset pc,
   3451                                 const Location* location) const VIXL_OVERRIDE {
   3452           pc += kT32PcDelta;
   3453           Location::Offset offset = location->GetLocation() - pc;
   3454           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
   3455                       ((offset & 0x1) == 0));
   3456           int32_t target = offset >> 1;
   3457           uint32_t S = target & (1 << 23);
   3458           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
   3459           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
   3460                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
   3461                  ((target & 0x800000) << 3);
   3462         }
   3463       } immop;
   3464       EmitT32_32(Link(0xf000d000U, location, immop, &kT32BranchInfo));
   3465       AdvanceIT();
   3466       return;
   3467     }
   3468   } else {
   3469     // BL{<c>}{<q>} <label> ; A1
   3470     if (((location->IsBound() && (offset >= -33554432) &&
   3471           (offset <= 33554428) && ((offset & 0x3) == 0)) ||
   3472          !location->IsBound()) &&
   3473         cond.IsNotNever()) {
   3474       static class EmitOp : public Location::EmitOperator {
   3475        public:
   3476         EmitOp() : Location::EmitOperator(A32) {}
   3477         virtual uint32_t Encode(uint32_t instr,
   3478                                 Location::Offset pc,
   3479                                 const Location* location) const VIXL_OVERRIDE {
   3480           pc += kA32PcDelta;
   3481           Location::Offset offset = location->GetLocation() - pc;
   3482           VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
   3483                       ((offset & 0x3) == 0));
   3484           const int32_t target = offset >> 2;
   3485           return instr | (target & 0xffffff);
   3486         }
   3487       } immop;
   3488       EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28),
   3489                    location,
   3490                    immop,
   3491                    &kA32BranchInfo));
   3492       return;
   3493     }
   3494   }
   3495   Delegate(kBl, &Assembler::bl, cond, location);
   3496 }
   3497 
   3498 bool Assembler::bl_info(Condition cond,
   3499                         Location* location,
   3500                         const struct ReferenceInfo** info) {
   3501   VIXL_ASSERT(!location->IsBound());
   3502   USE(location);
   3503   if (IsUsingT32()) {
   3504     // BL{<c>}{<q>} <label> ; T1
   3505     if (true) {
   3506       *info = &kT32BranchInfo;
   3507       return true;
   3508     }
   3509   } else {
   3510     // BL{<c>}{<q>} <label> ; A1
   3511     if (cond.IsNotNever()) {
   3512       *info = &kA32BranchInfo;
   3513       return true;
   3514     }
   3515   }
   3516   return false;
   3517 }
   3518 
   3519 void Assembler::blx(Condition cond, Location* location) {
   3520   VIXL_ASSERT(AllowAssembler());
   3521   CheckIT(cond);
   3522   Location::Offset offset =
   3523       location->IsBound()
   3524           ? location->GetLocation() -
   3525                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   3526           : 0;
   3527   if (IsUsingT32()) {
   3528     // BLX{<c>}{<q>} <label> ; T2
   3529     if (((location->IsBound() && (offset >= -16777216) &&
   3530           (offset <= 16777212) && ((offset & 0x3) == 0)) ||
   3531          !location->IsBound()) &&
   3532         (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
   3533       static class EmitOp : public Location::EmitOperator {
   3534        public:
   3535         EmitOp() : Location::EmitOperator(T32) {}
   3536         virtual uint32_t Encode(uint32_t instr,
   3537                                 Location::Offset pc,
   3538                                 const Location* location) const VIXL_OVERRIDE {
   3539           pc += kT32PcDelta;
   3540           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   3541           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) &&
   3542                       ((offset & 0x3) == 0));
   3543           int32_t target = offset >> 2;
   3544           uint32_t S = target & (1 << 22);
   3545           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
   3546           return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
   3547                  ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
   3548                  ((target & 0x400000) << 4);
   3549         }
   3550       } immop;
   3551       EmitT32_32(Link(0xf000c000U, location, immop, &kT32BlxInfo));
   3552       AdvanceIT();
   3553       return;
   3554     }
   3555   } else {
   3556     // BLX{<c>}{<q>} <label> ; A2
   3557     if (((location->IsBound() && (offset >= -33554432) &&
   3558           (offset <= 33554430) && ((offset & 0x1) == 0)) ||
   3559          !location->IsBound())) {
   3560       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   3561         static class EmitOp : public Location::EmitOperator {
   3562          public:
   3563           EmitOp() : Location::EmitOperator(A32) {}
   3564           virtual uint32_t Encode(uint32_t instr,
   3565                                   Location::Offset pc,
   3566                                   const Location* location) const
   3567               VIXL_OVERRIDE {
   3568             pc += kA32PcDelta;
   3569             Location::Offset offset =
   3570                 location->GetLocation() - AlignDown(pc, 4);
   3571             VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) &&
   3572                         ((offset & 0x1) == 0));
   3573             const int32_t target = offset >> 1;
   3574             return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
   3575           }
   3576         } immop;
   3577         EmitA32(Link(0xfa000000U, location, immop, &kA32BlxInfo));
   3578         return;
   3579       }
   3580     }
   3581   }
   3582   Delegate(kBlx, &Assembler::blx, cond, location);
   3583 }
   3584 
   3585 bool Assembler::blx_info(Condition cond,
   3586                          Location* location,
   3587                          const struct ReferenceInfo** info) {
   3588   VIXL_ASSERT(!location->IsBound());
   3589   USE(location);
   3590   USE(cond);
   3591   if (IsUsingT32()) {
   3592     // BLX{<c>}{<q>} <label> ; T2
   3593     if (true) {
   3594       *info = &kT32BlxInfo;
   3595       return true;
   3596     }
   3597   } else {
   3598     // BLX{<c>}{<q>} <label> ; A2
   3599     if (true) {
   3600       *info = &kA32BlxInfo;
   3601       return true;
   3602     }
   3603   }
   3604   return false;
   3605 }
   3606 
   3607 void Assembler::blx(Condition cond, Register rm) {
   3608   VIXL_ASSERT(AllowAssembler());
   3609   CheckIT(cond);
   3610   if (IsUsingT32()) {
   3611     // BLX{<c>}{<q>} <Rm> ; T1
   3612     if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
   3613          AllowUnpredictable())) {
   3614       EmitT32_16(0x4780 | (rm.GetCode() << 3));
   3615       AdvanceIT();
   3616       return;
   3617     }
   3618   } else {
   3619     // BLX{<c>}{<q>} <Rm> ; A1
   3620     if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
   3621       EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
   3622       return;
   3623     }
   3624   }
   3625   Delegate(kBlx, &Assembler::blx, cond, rm);
   3626 }
   3627 
   3628 void Assembler::bx(Condition cond, Register rm) {
   3629   VIXL_ASSERT(AllowAssembler());
   3630   CheckIT(cond);
   3631   if (IsUsingT32()) {
   3632     // BX{<c>}{<q>} <Rm> ; T1
   3633     if ((OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
   3634       EmitT32_16(0x4700 | (rm.GetCode() << 3));
   3635       AdvanceIT();
   3636       return;
   3637     }
   3638   } else {
   3639     // BX{<c>}{<q>} <Rm> ; A1
   3640     if (cond.IsNotNever()) {
   3641       EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
   3642       return;
   3643     }
   3644   }
   3645   Delegate(kBx, &Assembler::bx, cond, rm);
   3646 }
   3647 
   3648 void Assembler::bxj(Condition cond, Register rm) {
   3649   VIXL_ASSERT(AllowAssembler());
   3650   CheckIT(cond);
   3651   if (IsUsingT32()) {
   3652     // BXJ{<c>}{<q>} <Rm> ; T1
   3653     if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
   3654          AllowUnpredictable())) {
   3655       EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
   3656       AdvanceIT();
   3657       return;
   3658     }
   3659   } else {
   3660     // BXJ{<c>}{<q>} <Rm> ; A1
   3661     if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
   3662       EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
   3663       return;
   3664     }
   3665   }
   3666   Delegate(kBxj, &Assembler::bxj, cond, rm);
   3667 }
   3668 
   3669 void Assembler::cbnz(Register rn, Location* location) {
   3670   VIXL_ASSERT(AllowAssembler());
   3671   CheckIT(al);
   3672   Location::Offset offset =
   3673       location->IsBound()
   3674           ? location->GetLocation() -
   3675                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3676           : 0;
   3677   if (IsUsingT32()) {
   3678     // CBNZ{<q>} <Rn>, <label> ; T1
   3679     if (rn.IsLow() && ((location->IsBound() && (offset >= 0) &&
   3680                         (offset <= 126) && ((offset & 0x1) == 0)) ||
   3681                        !location->IsBound())) {
   3682       static class EmitOp : public Location::EmitOperator {
   3683        public:
   3684         EmitOp() : Location::EmitOperator(T32) {}
   3685         virtual uint32_t Encode(uint32_t instr,
   3686                                 Location::Offset pc,
   3687                                 const Location* location) const VIXL_OVERRIDE {
   3688           pc += kT32PcDelta;
   3689           Location::Offset offset = location->GetLocation() - pc;
   3690           VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
   3691                       ((offset & 0x1) == 0));
   3692           const int32_t target = offset >> 1;
   3693           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
   3694         }
   3695       } immop;
   3696       EmitT32_16(Link(0xb900 | rn.GetCode(), location, immop, &kT16CbzInfo));
   3697       AdvanceIT();
   3698       return;
   3699     }
   3700   }
   3701   Delegate(kCbnz, &Assembler::cbnz, rn, location);
   3702 }
   3703 
   3704 bool Assembler::cbnz_info(Register rn,
   3705                           Location* location,
   3706                           const struct ReferenceInfo** info) {
   3707   VIXL_ASSERT(!location->IsBound());
   3708   USE(location);
   3709   if (IsUsingT32()) {
   3710     // CBNZ{<q>} <Rn>, <label> ; T1
   3711     if (rn.IsLow()) {
   3712       *info = &kT16CbzInfo;
   3713       return true;
   3714     }
   3715   }
   3716   return false;
   3717 }
   3718 
   3719 void Assembler::cbz(Register rn, Location* location) {
   3720   VIXL_ASSERT(AllowAssembler());
   3721   CheckIT(al);
   3722   Location::Offset offset =
   3723       location->IsBound()
   3724           ? location->GetLocation() -
   3725                 (GetCursorOffset() + GetArchitectureStatePCOffset())
   3726           : 0;
   3727   if (IsUsingT32()) {
   3728     // CBZ{<q>} <Rn>, <label> ; T1
   3729     if (rn.IsLow() && ((location->IsBound() && (offset >= 0) &&
   3730                         (offset <= 126) && ((offset & 0x1) == 0)) ||
   3731                        !location->IsBound())) {
   3732       static class EmitOp : public Location::EmitOperator {
   3733        public:
   3734         EmitOp() : Location::EmitOperator(T32) {}
   3735         virtual uint32_t Encode(uint32_t instr,
   3736                                 Location::Offset pc,
   3737                                 const Location* location) const VIXL_OVERRIDE {
   3738           pc += kT32PcDelta;
   3739           Location::Offset offset = location->GetLocation() - pc;
   3740           VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
   3741                       ((offset & 0x1) == 0));
   3742           const int32_t target = offset >> 1;
   3743           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
   3744         }
   3745       } immop;
   3746       EmitT32_16(Link(0xb100 | rn.GetCode(), location, immop, &kT16CbzInfo));
   3747       AdvanceIT();
   3748       return;
   3749     }
   3750   }
   3751   Delegate(kCbz, &Assembler::cbz, rn, location);
   3752 }
   3753 
   3754 bool Assembler::cbz_info(Register rn,
   3755                          Location* location,
   3756                          const struct ReferenceInfo** info) {
   3757   VIXL_ASSERT(!location->IsBound());
   3758   USE(location);
   3759   if (IsUsingT32()) {
   3760     // CBZ{<q>} <Rn>, <label> ; T1
   3761     if (rn.IsLow()) {
   3762       *info = &kT16CbzInfo;
   3763       return true;
   3764     }
   3765   }
   3766   return false;
   3767 }
   3768 
   3769 void Assembler::clrex(Condition cond) {
   3770   VIXL_ASSERT(AllowAssembler());
   3771   CheckIT(cond);
   3772   if (IsUsingT32()) {
   3773     // CLREX{<c>}{<q>} ; T1
   3774     EmitT32_32(0xf3bf8f2fU);
   3775     AdvanceIT();
   3776     return;
   3777   } else {
   3778     // CLREX{<c>}{<q>} ; A1
   3779     if (cond.Is(al)) {
   3780       EmitA32(0xf57ff01fU);
   3781       return;
   3782     }
   3783   }
   3784   Delegate(kClrex, &Assembler::clrex, cond);
   3785 }
   3786 
   3787 void Assembler::clz(Condition cond, Register rd, Register rm) {
   3788   VIXL_ASSERT(AllowAssembler());
   3789   CheckIT(cond);
   3790   if (IsUsingT32()) {
   3791     // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
   3792     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3793       EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
   3794                  (rm.GetCode() << 16));
   3795       AdvanceIT();
   3796       return;
   3797     }
   3798   } else {
   3799     // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
   3800     if (cond.IsNotNever() &&
   3801         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3802       EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   3803               rm.GetCode());
   3804       return;
   3805     }
   3806   }
   3807   Delegate(kClz, &Assembler::clz, cond, rd, rm);
   3808 }
   3809 
   3810 void Assembler::cmn(Condition cond,
   3811                     EncodingSize size,
   3812                     Register rn,
   3813                     const Operand& operand) {
   3814   VIXL_ASSERT(AllowAssembler());
   3815   CheckIT(cond);
   3816   if (operand.IsImmediate()) {
   3817     uint32_t imm = operand.GetImmediate();
   3818     if (IsUsingT32()) {
   3819       ImmediateT32 immediate_t32(imm);
   3820       // CMN{<c>}{<q>} <Rn>, #<const> ; T1
   3821       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   3822           (!rn.IsPC() || AllowUnpredictable())) {
   3823         EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
   3824                    (immediate_t32.GetEncodingValue() & 0xff) |
   3825                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3826                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3827         AdvanceIT();
   3828         return;
   3829       }
   3830     } else {
   3831       ImmediateA32 immediate_a32(imm);
   3832       // CMN{<c>}{<q>} <Rn>, #<const> ; A1
   3833       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3834         EmitA32(0x03700000U | (cond.GetCondition() << 28) |
   3835                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   3836         return;
   3837       }
   3838     }
   3839   }
   3840   if (operand.IsImmediateShiftedRegister()) {
   3841     Register rm = operand.GetBaseRegister();
   3842     if (operand.IsPlainRegister()) {
   3843       if (IsUsingT32()) {
   3844         // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
   3845         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
   3846           EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
   3847           AdvanceIT();
   3848           return;
   3849         }
   3850       }
   3851     }
   3852     Shift shift = operand.GetShift();
   3853     uint32_t amount = operand.GetShiftAmount();
   3854     if (IsUsingT32()) {
   3855       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
   3856       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   3857           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3858         uint32_t amount_ = amount % 32;
   3859         EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
   3860                    (operand.GetTypeEncodingValue() << 4) |
   3861                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3862         AdvanceIT();
   3863         return;
   3864       }
   3865     } else {
   3866       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3867       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3868         uint32_t amount_ = amount % 32;
   3869         EmitA32(0x01700000U | (cond.GetCondition() << 28) |
   3870                 (rn.GetCode() << 16) | rm.GetCode() |
   3871                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3872         return;
   3873       }
   3874     }
   3875   }
   3876   if (operand.IsRegisterShiftedRegister()) {
   3877     Register rm = operand.GetBaseRegister();
   3878     Shift shift = operand.GetShift();
   3879     Register rs = operand.GetShiftRegister();
   3880     if (IsUsingA32()) {
   3881       // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   3882       if (cond.IsNotNever() &&
   3883           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   3884         EmitA32(0x01700010U | (cond.GetCondition() << 28) |
   3885                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   3886                 (rs.GetCode() << 8));
   3887         return;
   3888       }
   3889     }
   3890   }
   3891   Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
   3892 }
   3893 
   3894 void Assembler::cmp(Condition cond,
   3895                     EncodingSize size,
   3896                     Register rn,
   3897                     const Operand& operand) {
   3898   VIXL_ASSERT(AllowAssembler());
   3899   CheckIT(cond);
   3900   if (operand.IsImmediate()) {
   3901     uint32_t imm = operand.GetImmediate();
   3902     if (IsUsingT32()) {
   3903       ImmediateT32 immediate_t32(imm);
   3904       // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
   3905       if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
   3906         EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
   3907         AdvanceIT();
   3908         return;
   3909       }
   3910       // CMP{<c>}{<q>} <Rn>, #<const> ; T2
   3911       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   3912           (!rn.IsPC() || AllowUnpredictable())) {
   3913         EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
   3914                    (immediate_t32.GetEncodingValue() & 0xff) |
   3915                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   3916                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   3917         AdvanceIT();
   3918         return;
   3919       }
   3920     } else {
   3921       ImmediateA32 immediate_a32(imm);
   3922       // CMP{<c>}{<q>} <Rn>, #<const> ; A1
   3923       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   3924         EmitA32(0x03500000U | (cond.GetCondition() << 28) |
   3925                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   3926         return;
   3927       }
   3928     }
   3929   }
   3930   if (operand.IsImmediateShiftedRegister()) {
   3931     Register rm = operand.GetBaseRegister();
   3932     if (operand.IsPlainRegister()) {
   3933       if (IsUsingT32()) {
   3934         // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
   3935         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
   3936           EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
   3937           AdvanceIT();
   3938           return;
   3939         }
   3940         // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
   3941         if (!size.IsWide() &&
   3942             ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3943           EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
   3944                      ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   3945           AdvanceIT();
   3946           return;
   3947         }
   3948       }
   3949     }
   3950     Shift shift = operand.GetShift();
   3951     uint32_t amount = operand.GetShiftAmount();
   3952     if (IsUsingT32()) {
   3953       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
   3954       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   3955           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   3956         uint32_t amount_ = amount % 32;
   3957         EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
   3958                    (operand.GetTypeEncodingValue() << 4) |
   3959                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   3960         AdvanceIT();
   3961         return;
   3962       }
   3963     } else {
   3964       // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   3965       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   3966         uint32_t amount_ = amount % 32;
   3967         EmitA32(0x01500000U | (cond.GetCondition() << 28) |
   3968                 (rn.GetCode() << 16) | rm.GetCode() |
   3969                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   3970         return;
   3971       }
   3972     }
   3973   }
   3974   if (operand.IsRegisterShiftedRegister()) {
   3975     Register rm = operand.GetBaseRegister();
   3976     Shift shift = operand.GetShift();
   3977     Register rs = operand.GetShiftRegister();
   3978     if (IsUsingA32()) {
   3979       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   3980       if (cond.IsNotNever() &&
   3981           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   3982         EmitA32(0x01500010U | (cond.GetCondition() << 28) |
   3983                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   3984                 (rs.GetCode() << 8));
   3985         return;
   3986       }
   3987     }
   3988   }
   3989   Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
   3990 }
   3991 
   3992 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
   3993   VIXL_ASSERT(AllowAssembler());
   3994   CheckIT(cond);
   3995   if (IsUsingT32()) {
   3996     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
   3997     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   3998          AllowUnpredictable())) {
   3999       EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4000                  rm.GetCode());
   4001       AdvanceIT();
   4002       return;
   4003     }
   4004   } else {
   4005     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
   4006     if ((cond.Is(al) || AllowUnpredictable()) &&
   4007         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4008       EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4009               (rn.GetCode() << 16) | rm.GetCode());
   4010       return;
   4011     }
   4012   }
   4013   Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
   4014 }
   4015 
   4016 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
   4017   VIXL_ASSERT(AllowAssembler());
   4018   CheckIT(cond);
   4019   if (IsUsingT32()) {
   4020     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
   4021     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4022          AllowUnpredictable())) {
   4023       EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4024                  rm.GetCode());
   4025       AdvanceIT();
   4026       return;
   4027     }
   4028   } else {
   4029     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
   4030     if ((cond.Is(al) || AllowUnpredictable()) &&
   4031         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4032       EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4033               (rn.GetCode() << 16) | rm.GetCode());
   4034       return;
   4035     }
   4036   }
   4037   Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
   4038 }
   4039 
   4040 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
   4041   VIXL_ASSERT(AllowAssembler());
   4042   CheckIT(cond);
   4043   if (IsUsingT32()) {
   4044     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
   4045     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4046          AllowUnpredictable())) {
   4047       EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4048                  rm.GetCode());
   4049       AdvanceIT();
   4050       return;
   4051     }
   4052   } else {
   4053     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
   4054     if ((cond.Is(al) || AllowUnpredictable()) &&
   4055         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4056       EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4057               (rn.GetCode() << 16) | rm.GetCode());
   4058       return;
   4059     }
   4060   }
   4061   Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
   4062 }
   4063 
   4064 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
   4065   VIXL_ASSERT(AllowAssembler());
   4066   CheckIT(cond);
   4067   if (IsUsingT32()) {
   4068     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
   4069     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4070          AllowUnpredictable())) {
   4071       EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4072                  rm.GetCode());
   4073       AdvanceIT();
   4074       return;
   4075     }
   4076   } else {
   4077     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
   4078     if ((cond.Is(al) || AllowUnpredictable()) &&
   4079         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4080       EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4081               (rn.GetCode() << 16) | rm.GetCode());
   4082       return;
   4083     }
   4084   }
   4085   Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
   4086 }
   4087 
   4088 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
   4089   VIXL_ASSERT(AllowAssembler());
   4090   CheckIT(cond);
   4091   if (IsUsingT32()) {
   4092     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
   4093     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4094          AllowUnpredictable())) {
   4095       EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4096                  rm.GetCode());
   4097       AdvanceIT();
   4098       return;
   4099     }
   4100   } else {
   4101     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
   4102     if ((cond.Is(al) || AllowUnpredictable()) &&
   4103         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4104       EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4105               (rn.GetCode() << 16) | rm.GetCode());
   4106       return;
   4107     }
   4108   }
   4109   Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
   4110 }
   4111 
   4112 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
   4113   VIXL_ASSERT(AllowAssembler());
   4114   CheckIT(cond);
   4115   if (IsUsingT32()) {
   4116     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
   4117     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
   4118          AllowUnpredictable())) {
   4119       EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4120                  rm.GetCode());
   4121       AdvanceIT();
   4122       return;
   4123     }
   4124   } else {
   4125     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
   4126     if ((cond.Is(al) || AllowUnpredictable()) &&
   4127         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4128       EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   4129               (rn.GetCode() << 16) | rm.GetCode());
   4130       return;
   4131     }
   4132   }
   4133   Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
   4134 }
   4135 
   4136 void Assembler::dmb(Condition cond, MemoryBarrier option) {
   4137   VIXL_ASSERT(AllowAssembler());
   4138   CheckIT(cond);
   4139   if (IsUsingT32()) {
   4140     // DMB{<c>}{<q>} {<option>} ; T1
   4141     EmitT32_32(0xf3bf8f50U | option.GetType());
   4142     AdvanceIT();
   4143     return;
   4144   } else {
   4145     // DMB{<c>}{<q>} {<option>} ; A1
   4146     if (cond.Is(al)) {
   4147       EmitA32(0xf57ff050U | option.GetType());
   4148       return;
   4149     }
   4150   }
   4151   Delegate(kDmb, &Assembler::dmb, cond, option);
   4152 }
   4153 
   4154 void Assembler::dsb(Condition cond, MemoryBarrier option) {
   4155   VIXL_ASSERT(AllowAssembler());
   4156   CheckIT(cond);
   4157   if (IsUsingT32()) {
   4158     // DSB{<c>}{<q>} {<option>} ; T1
   4159     EmitT32_32(0xf3bf8f40U | option.GetType());
   4160     AdvanceIT();
   4161     return;
   4162   } else {
   4163     // DSB{<c>}{<q>} {<option>} ; A1
   4164     if (cond.Is(al)) {
   4165       EmitA32(0xf57ff040U | option.GetType());
   4166       return;
   4167     }
   4168   }
   4169   Delegate(kDsb, &Assembler::dsb, cond, option);
   4170 }
   4171 
   4172 void Assembler::eor(Condition cond,
   4173                     EncodingSize size,
   4174                     Register rd,
   4175                     Register rn,
   4176                     const Operand& operand) {
   4177   VIXL_ASSERT(AllowAssembler());
   4178   CheckIT(cond);
   4179   if (operand.IsImmediate()) {
   4180     uint32_t imm = operand.GetImmediate();
   4181     if (IsUsingT32()) {
   4182       ImmediateT32 immediate_t32(imm);
   4183       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   4184       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   4185           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4186         EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4187                    (immediate_t32.GetEncodingValue() & 0xff) |
   4188                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   4189                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   4190         AdvanceIT();
   4191         return;
   4192       }
   4193     } else {
   4194       ImmediateA32 immediate_a32(imm);
   4195       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   4196       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   4197         EmitA32(0x02200000U | (cond.GetCondition() << 28) |
   4198                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   4199                 immediate_a32.GetEncodingValue());
   4200         return;
   4201       }
   4202     }
   4203   }
   4204   if (operand.IsImmediateShiftedRegister()) {
   4205     Register rm = operand.GetBaseRegister();
   4206     if (operand.IsPlainRegister()) {
   4207       if (IsUsingT32()) {
   4208         // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   4209         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   4210             rm.IsLow()) {
   4211           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
   4212           AdvanceIT();
   4213           return;
   4214         }
   4215       }
   4216     }
   4217     Shift shift = operand.GetShift();
   4218     uint32_t amount = operand.GetShiftAmount();
   4219     if (IsUsingT32()) {
   4220       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   4221       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   4222           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4223         uint32_t amount_ = amount % 32;
   4224         EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4225                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   4226                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   4227         AdvanceIT();
   4228         return;
   4229       }
   4230     } else {
   4231       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   4232       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   4233         uint32_t amount_ = amount % 32;
   4234         EmitA32(0x00200000U | (cond.GetCondition() << 28) |
   4235                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4236                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   4237         return;
   4238       }
   4239     }
   4240   }
   4241   if (operand.IsRegisterShiftedRegister()) {
   4242     Register rm = operand.GetBaseRegister();
   4243     Shift shift = operand.GetShift();
   4244     Register rs = operand.GetShiftRegister();
   4245     if (IsUsingA32()) {
   4246       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   4247       if (cond.IsNotNever() &&
   4248           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   4249            AllowUnpredictable())) {
   4250         EmitA32(0x00200010U | (cond.GetCondition() << 28) |
   4251                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4252                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   4253         return;
   4254       }
   4255     }
   4256   }
   4257   Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
   4258 }
   4259 
   4260 void Assembler::eors(Condition cond,
   4261                      EncodingSize size,
   4262                      Register rd,
   4263                      Register rn,
   4264                      const Operand& operand) {
   4265   VIXL_ASSERT(AllowAssembler());
   4266   CheckIT(cond);
   4267   if (operand.IsImmediate()) {
   4268     uint32_t imm = operand.GetImmediate();
   4269     if (IsUsingT32()) {
   4270       ImmediateT32 immediate_t32(imm);
   4271       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   4272       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) &&
   4273           (!rn.IsPC() || AllowUnpredictable())) {
   4274         EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4275                    (immediate_t32.GetEncodingValue() & 0xff) |
   4276                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   4277                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   4278         AdvanceIT();
   4279         return;
   4280       }
   4281     } else {
   4282       ImmediateA32 immediate_a32(imm);
   4283       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   4284       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   4285         EmitA32(0x02300000U | (cond.GetCondition() << 28) |
   4286                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   4287                 immediate_a32.GetEncodingValue());
   4288         return;
   4289       }
   4290     }
   4291   }
   4292   if (operand.IsImmediateShiftedRegister()) {
   4293     Register rm = operand.GetBaseRegister();
   4294     if (operand.IsPlainRegister()) {
   4295       if (IsUsingT32()) {
   4296         // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   4297         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   4298             rm.IsLow()) {
   4299           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
   4300           AdvanceIT();
   4301           return;
   4302         }
   4303       }
   4304     }
   4305     Shift shift = operand.GetShift();
   4306     uint32_t amount = operand.GetShiftAmount();
   4307     if (IsUsingT32()) {
   4308       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   4309       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) &&
   4310           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   4311         uint32_t amount_ = amount % 32;
   4312         EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   4313                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   4314                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   4315         AdvanceIT();
   4316         return;
   4317       }
   4318     } else {
   4319       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   4320       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   4321         uint32_t amount_ = amount % 32;
   4322         EmitA32(0x00300000U | (cond.GetCondition() << 28) |
   4323                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4324                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   4325         return;
   4326       }
   4327     }
   4328   }
   4329   if (operand.IsRegisterShiftedRegister()) {
   4330     Register rm = operand.GetBaseRegister();
   4331     Shift shift = operand.GetShift();
   4332     Register rs = operand.GetShiftRegister();
   4333     if (IsUsingA32()) {
   4334       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   4335       if (cond.IsNotNever() &&
   4336           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   4337            AllowUnpredictable())) {
   4338         EmitA32(0x00300010U | (cond.GetCondition() << 28) |
   4339                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   4340                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   4341         return;
   4342       }
   4343     }
   4344   }
   4345   Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
   4346 }
   4347 
   4348 void Assembler::fldmdbx(Condition cond,
   4349                         Register rn,
   4350                         WriteBack write_back,
   4351                         DRegisterList dreglist) {
   4352   VIXL_ASSERT(AllowAssembler());
   4353   CheckIT(cond);
   4354   if (IsUsingT32()) {
   4355     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
   4356     if (write_back.DoesWriteBack() &&
   4357         (((dreglist.GetLength() <= 16) &&
   4358           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4359          AllowUnpredictable())) {
   4360       const DRegister& dreg = dreglist.GetFirstDRegister();
   4361       unsigned len = dreglist.GetLength() * 2;
   4362       EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   4363                  (len & 0xff));
   4364       AdvanceIT();
   4365       return;
   4366     }
   4367   } else {
   4368     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
   4369     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   4370         (((dreglist.GetLength() <= 16) &&
   4371           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4372          AllowUnpredictable())) {
   4373       const DRegister& dreg = dreglist.GetFirstDRegister();
   4374       unsigned len = dreglist.GetLength() * 2;
   4375       EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4376               dreg.Encode(22, 12) | (len & 0xff));
   4377       return;
   4378     }
   4379   }
   4380   Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
   4381 }
   4382 
   4383 void Assembler::fldmiax(Condition cond,
   4384                         Register rn,
   4385                         WriteBack write_back,
   4386                         DRegisterList dreglist) {
   4387   VIXL_ASSERT(AllowAssembler());
   4388   CheckIT(cond);
   4389   if (IsUsingT32()) {
   4390     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
   4391     if ((((dreglist.GetLength() <= 16) &&
   4392           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4393          AllowUnpredictable())) {
   4394       const DRegister& dreg = dreglist.GetFirstDRegister();
   4395       unsigned len = dreglist.GetLength() * 2;
   4396       EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
   4397                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4398                  (len & 0xff));
   4399       AdvanceIT();
   4400       return;
   4401     }
   4402   } else {
   4403     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
   4404     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   4405                                (dreglist.GetLastDRegister().GetCode() < 16) &&
   4406                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
   4407                               AllowUnpredictable())) {
   4408       const DRegister& dreg = dreglist.GetFirstDRegister();
   4409       unsigned len = dreglist.GetLength() * 2;
   4410       EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4411               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4412               (len & 0xff));
   4413       return;
   4414     }
   4415   }
   4416   Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
   4417 }
   4418 
   4419 void Assembler::fstmdbx(Condition cond,
   4420                         Register rn,
   4421                         WriteBack write_back,
   4422                         DRegisterList dreglist) {
   4423   VIXL_ASSERT(AllowAssembler());
   4424   CheckIT(cond);
   4425   if (IsUsingT32()) {
   4426     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
   4427     if (write_back.DoesWriteBack() &&
   4428         (((dreglist.GetLength() <= 16) &&
   4429           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4430          AllowUnpredictable())) {
   4431       const DRegister& dreg = dreglist.GetFirstDRegister();
   4432       unsigned len = dreglist.GetLength() * 2;
   4433       EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   4434                  (len & 0xff));
   4435       AdvanceIT();
   4436       return;
   4437     }
   4438   } else {
   4439     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
   4440     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   4441         (((dreglist.GetLength() <= 16) &&
   4442           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4443          AllowUnpredictable())) {
   4444       const DRegister& dreg = dreglist.GetFirstDRegister();
   4445       unsigned len = dreglist.GetLength() * 2;
   4446       EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4447               dreg.Encode(22, 12) | (len & 0xff));
   4448       return;
   4449     }
   4450   }
   4451   Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
   4452 }
   4453 
   4454 void Assembler::fstmiax(Condition cond,
   4455                         Register rn,
   4456                         WriteBack write_back,
   4457                         DRegisterList dreglist) {
   4458   VIXL_ASSERT(AllowAssembler());
   4459   CheckIT(cond);
   4460   if (IsUsingT32()) {
   4461     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
   4462     if ((((dreglist.GetLength() <= 16) &&
   4463           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
   4464          AllowUnpredictable())) {
   4465       const DRegister& dreg = dreglist.GetFirstDRegister();
   4466       unsigned len = dreglist.GetLength() * 2;
   4467       EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
   4468                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4469                  (len & 0xff));
   4470       AdvanceIT();
   4471       return;
   4472     }
   4473   } else {
   4474     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
   4475     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   4476                                (dreglist.GetLastDRegister().GetCode() < 16) &&
   4477                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
   4478                               AllowUnpredictable())) {
   4479       const DRegister& dreg = dreglist.GetFirstDRegister();
   4480       unsigned len = dreglist.GetLength() * 2;
   4481       EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4482               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   4483               (len & 0xff));
   4484       return;
   4485     }
   4486   }
   4487   Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
   4488 }
   4489 
   4490 void Assembler::hlt(Condition cond, uint32_t imm) {
   4491   VIXL_ASSERT(AllowAssembler());
   4492   CheckIT(cond);
   4493   if (IsUsingT32()) {
   4494     // HLT{<q>} {#}<imm> ; T1
   4495     if ((imm <= 63)) {
   4496       EmitT32_16(0xba80 | imm);
   4497       AdvanceIT();
   4498       return;
   4499     }
   4500   } else {
   4501     // HLT{<q>} {#}<imm> ; A1
   4502     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   4503       EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   4504               ((imm & 0xfff0) << 4));
   4505       return;
   4506     }
   4507   }
   4508   Delegate(kHlt, &Assembler::hlt, cond, imm);
   4509 }
   4510 
   4511 void Assembler::hvc(Condition cond, uint32_t imm) {
   4512   VIXL_ASSERT(AllowAssembler());
   4513   CheckIT(cond);
   4514   if (IsUsingT32()) {
   4515     // HVC{<q>} {#}<imm16> ; T1
   4516     if ((imm <= 65535) && (OutsideITBlock() || AllowUnpredictable())) {
   4517       EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
   4518       AdvanceIT();
   4519       return;
   4520     }
   4521   } else {
   4522     // HVC{<q>} {#}<imm16> ; A1
   4523     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
   4524       EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
   4525               ((imm & 0xfff0) << 4));
   4526       return;
   4527     }
   4528   }
   4529   Delegate(kHvc, &Assembler::hvc, cond, imm);
   4530 }
   4531 
   4532 void Assembler::isb(Condition cond, MemoryBarrier option) {
   4533   VIXL_ASSERT(AllowAssembler());
   4534   CheckIT(cond);
   4535   if (IsUsingT32()) {
   4536     // ISB{<c>}{<q>} {<option>} ; T1
   4537     EmitT32_32(0xf3bf8f60U | option.GetType());
   4538     AdvanceIT();
   4539     return;
   4540   } else {
   4541     // ISB{<c>}{<q>} {<option>} ; A1
   4542     if (cond.Is(al)) {
   4543       EmitA32(0xf57ff060U | option.GetType());
   4544       return;
   4545     }
   4546   }
   4547   Delegate(kIsb, &Assembler::isb, cond, option);
   4548 }
   4549 
   4550 void Assembler::it(Condition cond, uint16_t mask) {
   4551   VIXL_ASSERT(AllowAssembler());
   4552   CheckNotIT();
   4553   if (mask != 0) {
   4554     if ((cond.GetCondition() & 0x1) != 0) {
   4555       if ((mask & 0x1) != 0) {
   4556         mask ^= 0xE;
   4557       } else if ((mask & 0x2) != 0) {
   4558         mask ^= 0xC;
   4559       } else if ((mask & 0x4) != 0) {
   4560         mask ^= 0x8;
   4561       }
   4562     }
   4563     if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
   4564     SetIT(cond, mask);
   4565     return;
   4566   }
   4567   DelegateIt(cond, mask);
   4568 }
   4569 
   4570 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
   4571   VIXL_ASSERT(AllowAssembler());
   4572   CheckIT(cond);
   4573   if (operand.IsImmediateZero()) {
   4574     Register rn = operand.GetBaseRegister();
   4575     if (IsUsingT32()) {
   4576       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4577       if (operand.IsOffset() &&
   4578           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4579         EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4580         AdvanceIT();
   4581         return;
   4582       }
   4583     } else {
   4584       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4585       if (operand.IsOffset() && cond.IsNotNever() &&
   4586           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4587         EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
   4588                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4589         return;
   4590       }
   4591     }
   4592   }
   4593   Delegate(kLda, &Assembler::lda, cond, rt, operand);
   4594 }
   4595 
   4596 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
   4597   VIXL_ASSERT(AllowAssembler());
   4598   CheckIT(cond);
   4599   if (operand.IsImmediateZero()) {
   4600     Register rn = operand.GetBaseRegister();
   4601     if (IsUsingT32()) {
   4602       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4603       if (operand.IsOffset() &&
   4604           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4605         EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4606         AdvanceIT();
   4607         return;
   4608       }
   4609     } else {
   4610       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4611       if (operand.IsOffset() && cond.IsNotNever() &&
   4612           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4613         EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
   4614                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4615         return;
   4616       }
   4617     }
   4618   }
   4619   Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
   4620 }
   4621 
   4622 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
   4623   VIXL_ASSERT(AllowAssembler());
   4624   CheckIT(cond);
   4625   if (operand.IsImmediateZero()) {
   4626     Register rn = operand.GetBaseRegister();
   4627     if (IsUsingT32()) {
   4628       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4629       if (operand.IsOffset() &&
   4630           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4631         EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4632         AdvanceIT();
   4633         return;
   4634       }
   4635     } else {
   4636       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4637       if (operand.IsOffset() && cond.IsNotNever() &&
   4638           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4639         EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
   4640                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4641         return;
   4642       }
   4643     }
   4644   }
   4645   Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
   4646 }
   4647 
   4648 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
   4649   VIXL_ASSERT(AllowAssembler());
   4650   CheckIT(cond);
   4651   if (operand.IsImmediateZero()) {
   4652     Register rn = operand.GetBaseRegister();
   4653     if (IsUsingT32()) {
   4654       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4655       if (operand.IsOffset() &&
   4656           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4657         EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4658         AdvanceIT();
   4659         return;
   4660       }
   4661     } else {
   4662       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4663       if (operand.IsOffset() && cond.IsNotNever() &&
   4664           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4665         EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
   4666                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4667         return;
   4668       }
   4669     }
   4670   }
   4671   Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
   4672 }
   4673 
   4674 void Assembler::ldaexd(Condition cond,
   4675                        Register rt,
   4676                        Register rt2,
   4677                        const MemOperand& operand) {
   4678   VIXL_ASSERT(AllowAssembler());
   4679   CheckIT(cond);
   4680   if (operand.IsImmediateZero()) {
   4681     Register rn = operand.GetBaseRegister();
   4682     if (IsUsingT32()) {
   4683       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
   4684       if (operand.IsOffset() &&
   4685           ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4686         EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   4687                    (rn.GetCode() << 16));
   4688         AdvanceIT();
   4689         return;
   4690       }
   4691     } else {
   4692       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
   4693       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   4694           operand.IsOffset() && cond.IsNotNever() &&
   4695           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) ||
   4696            AllowUnpredictable())) {
   4697         EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
   4698                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4699         return;
   4700       }
   4701     }
   4702   }
   4703   Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
   4704 }
   4705 
   4706 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
   4707   VIXL_ASSERT(AllowAssembler());
   4708   CheckIT(cond);
   4709   if (operand.IsImmediateZero()) {
   4710     Register rn = operand.GetBaseRegister();
   4711     if (IsUsingT32()) {
   4712       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4713       if (operand.IsOffset() &&
   4714           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4715         EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4716         AdvanceIT();
   4717         return;
   4718       }
   4719     } else {
   4720       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4721       if (operand.IsOffset() && cond.IsNotNever() &&
   4722           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4723         EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
   4724                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4725         return;
   4726       }
   4727     }
   4728   }
   4729   Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
   4730 }
   4731 
   4732 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
   4733   VIXL_ASSERT(AllowAssembler());
   4734   CheckIT(cond);
   4735   if (operand.IsImmediateZero()) {
   4736     Register rn = operand.GetBaseRegister();
   4737     if (IsUsingT32()) {
   4738       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   4739       if (operand.IsOffset() &&
   4740           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4741         EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4742         AdvanceIT();
   4743         return;
   4744       }
   4745     } else {
   4746       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   4747       if (operand.IsOffset() && cond.IsNotNever() &&
   4748           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   4749         EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
   4750                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   4751         return;
   4752       }
   4753     }
   4754   }
   4755   Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
   4756 }
   4757 
   4758 void Assembler::ldm(Condition cond,
   4759                     EncodingSize size,
   4760                     Register rn,
   4761                     WriteBack write_back,
   4762                     RegisterList registers) {
   4763   VIXL_ASSERT(AllowAssembler());
   4764   CheckIT(cond);
   4765   if (IsUsingT32()) {
   4766     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4767     if (!size.IsWide() && rn.IsLow() &&
   4768         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
   4769          write_back.DoesWriteBack()) &&
   4770         ((registers.GetList() & ~0xff) == 0)) {
   4771       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
   4772                  GetRegisterListEncoding(registers, 0, 8));
   4773       AdvanceIT();
   4774       return;
   4775     }
   4776     // LDM{<c>}{<q>} SP!, <registers> ; T1
   4777     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
   4778         ((registers.GetList() & ~0x80ff) == 0)) {
   4779       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
   4780                  GetRegisterListEncoding(registers, 0, 8));
   4781       AdvanceIT();
   4782       return;
   4783     }
   4784     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
   4785     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) &&
   4786         (!rn.IsPC() || AllowUnpredictable())) {
   4787       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
   4788                  (write_back.GetWriteBackUint32() << 21) |
   4789                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4790                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4791                  GetRegisterListEncoding(registers, 0, 13));
   4792       AdvanceIT();
   4793       return;
   4794     }
   4795   } else {
   4796     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4797     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4798       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4799               (write_back.GetWriteBackUint32() << 21) |
   4800               GetRegisterListEncoding(registers, 0, 16));
   4801       return;
   4802     }
   4803   }
   4804   Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
   4805 }
   4806 
   4807 void Assembler::ldmda(Condition cond,
   4808                       Register rn,
   4809                       WriteBack write_back,
   4810                       RegisterList registers) {
   4811   VIXL_ASSERT(AllowAssembler());
   4812   CheckIT(cond);
   4813   if (IsUsingA32()) {
   4814     // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4815     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4816       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4817               (write_back.GetWriteBackUint32() << 21) |
   4818               GetRegisterListEncoding(registers, 0, 16));
   4819       return;
   4820     }
   4821   }
   4822   Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
   4823 }
   4824 
   4825 void Assembler::ldmdb(Condition cond,
   4826                       Register rn,
   4827                       WriteBack write_back,
   4828                       RegisterList registers) {
   4829   VIXL_ASSERT(AllowAssembler());
   4830   CheckIT(cond);
   4831   if (IsUsingT32()) {
   4832     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4833     if (((registers.GetList() & ~0xdfff) == 0) &&
   4834         (!rn.IsPC() || AllowUnpredictable())) {
   4835       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
   4836                  (write_back.GetWriteBackUint32() << 21) |
   4837                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4838                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4839                  GetRegisterListEncoding(registers, 0, 13));
   4840       AdvanceIT();
   4841       return;
   4842     }
   4843   } else {
   4844     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4845     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4846       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4847               (write_back.GetWriteBackUint32() << 21) |
   4848               GetRegisterListEncoding(registers, 0, 16));
   4849       return;
   4850     }
   4851   }
   4852   Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
   4853 }
   4854 
   4855 void Assembler::ldmea(Condition cond,
   4856                       Register rn,
   4857                       WriteBack write_back,
   4858                       RegisterList registers) {
   4859   VIXL_ASSERT(AllowAssembler());
   4860   CheckIT(cond);
   4861   if (IsUsingT32()) {
   4862     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4863     if (((registers.GetList() & ~0xdfff) == 0) &&
   4864         (!rn.IsPC() || AllowUnpredictable())) {
   4865       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
   4866                  (write_back.GetWriteBackUint32() << 21) |
   4867                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4868                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4869                  GetRegisterListEncoding(registers, 0, 13));
   4870       AdvanceIT();
   4871       return;
   4872     }
   4873   } else {
   4874     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4875     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4876       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4877               (write_back.GetWriteBackUint32() << 21) |
   4878               GetRegisterListEncoding(registers, 0, 16));
   4879       return;
   4880     }
   4881   }
   4882   Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
   4883 }
   4884 
   4885 void Assembler::ldmed(Condition cond,
   4886                       Register rn,
   4887                       WriteBack write_back,
   4888                       RegisterList registers) {
   4889   VIXL_ASSERT(AllowAssembler());
   4890   CheckIT(cond);
   4891   if (IsUsingA32()) {
   4892     // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4893     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4894       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4895               (write_back.GetWriteBackUint32() << 21) |
   4896               GetRegisterListEncoding(registers, 0, 16));
   4897       return;
   4898     }
   4899   }
   4900   Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
   4901 }
   4902 
   4903 void Assembler::ldmfa(Condition cond,
   4904                       Register rn,
   4905                       WriteBack write_back,
   4906                       RegisterList registers) {
   4907   VIXL_ASSERT(AllowAssembler());
   4908   CheckIT(cond);
   4909   if (IsUsingA32()) {
   4910     // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4911     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4912       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4913               (write_back.GetWriteBackUint32() << 21) |
   4914               GetRegisterListEncoding(registers, 0, 16));
   4915       return;
   4916     }
   4917   }
   4918   Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
   4919 }
   4920 
   4921 void Assembler::ldmfd(Condition cond,
   4922                       EncodingSize size,
   4923                       Register rn,
   4924                       WriteBack write_back,
   4925                       RegisterList registers) {
   4926   VIXL_ASSERT(AllowAssembler());
   4927   CheckIT(cond);
   4928   if (IsUsingT32()) {
   4929     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
   4930     if (!size.IsWide() && rn.IsLow() &&
   4931         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
   4932          write_back.DoesWriteBack()) &&
   4933         ((registers.GetList() & ~0xff) == 0)) {
   4934       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
   4935                  GetRegisterListEncoding(registers, 0, 8));
   4936       AdvanceIT();
   4937       return;
   4938     }
   4939     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
   4940     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) &&
   4941         (!rn.IsPC() || AllowUnpredictable())) {
   4942       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
   4943                  (write_back.GetWriteBackUint32() << 21) |
   4944                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   4945                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   4946                  GetRegisterListEncoding(registers, 0, 13));
   4947       AdvanceIT();
   4948       return;
   4949     }
   4950   } else {
   4951     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4952     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4953       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4954               (write_back.GetWriteBackUint32() << 21) |
   4955               GetRegisterListEncoding(registers, 0, 16));
   4956       return;
   4957     }
   4958   }
   4959   Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
   4960 }
   4961 
   4962 void Assembler::ldmib(Condition cond,
   4963                       Register rn,
   4964                       WriteBack write_back,
   4965                       RegisterList registers) {
   4966   VIXL_ASSERT(AllowAssembler());
   4967   CheckIT(cond);
   4968   if (IsUsingA32()) {
   4969     // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   4970     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   4971       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   4972               (write_back.GetWriteBackUint32() << 21) |
   4973               GetRegisterListEncoding(registers, 0, 16));
   4974       return;
   4975     }
   4976   }
   4977   Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
   4978 }
   4979 
   4980 void Assembler::ldr(Condition cond,
   4981                     EncodingSize size,
   4982                     Register rt,
   4983                     const MemOperand& operand) {
   4984   VIXL_ASSERT(AllowAssembler());
   4985   CheckIT(cond);
   4986   if (operand.IsImmediate()) {
   4987     Register rn = operand.GetBaseRegister();
   4988     int32_t offset = operand.GetOffsetImmediate();
   4989     if (IsUsingT32()) {
   4990       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   4991       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   4992           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
   4993         int32_t offset_ = offset >> 2;
   4994         EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
   4995                    ((offset_ & 0x1f) << 6));
   4996         AdvanceIT();
   4997         return;
   4998       }
   4999       // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
   5000       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
   5001           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
   5002         int32_t offset_ = offset >> 2;
   5003         EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
   5004         AdvanceIT();
   5005         return;
   5006       }
   5007       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
   5008       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5009           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   5010           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5011            AllowUnpredictable())) {
   5012         EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5013                    (offset & 0xfff));
   5014         AdvanceIT();
   5015         return;
   5016       }
   5017       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
   5018       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5019           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   5020           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5021            AllowUnpredictable())) {
   5022         EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5023                    (-offset & 0xff));
   5024         AdvanceIT();
   5025         return;
   5026       }
   5027       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
   5028       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5029           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   5030           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5031            AllowUnpredictable())) {
   5032         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5033         uint32_t offset_ = abs(offset);
   5034         EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5035                    offset_ | (sign << 9));
   5036         AdvanceIT();
   5037         return;
   5038       }
   5039       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
   5040       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5041           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   5042           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5043            AllowUnpredictable())) {
   5044         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5045         uint32_t offset_ = abs(offset);
   5046         EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5047                    offset_ | (sign << 9));
   5048         AdvanceIT();
   5049         return;
   5050       }
   5051       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
   5052       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   5053           rn.Is(pc) && operand.IsOffset() &&
   5054           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5055            AllowUnpredictable())) {
   5056         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5057         uint32_t offset_ = abs(offset);
   5058         EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   5059         AdvanceIT();
   5060         return;
   5061       }
   5062     } else {
   5063       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   5064       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   5065           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5066         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5067         uint32_t offset_ = abs(offset);
   5068         EmitA32(0x05100000U | (cond.GetCondition() << 28) |
   5069                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5070                 (sign << 23));
   5071         return;
   5072       }
   5073       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   5074       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   5075           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5076         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5077         uint32_t offset_ = abs(offset);
   5078         EmitA32(0x04100000U | (cond.GetCondition() << 28) |
   5079                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5080                 (sign << 23));
   5081         return;
   5082       }
   5083       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   5084       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   5085           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
   5086         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5087         uint32_t offset_ = abs(offset);
   5088         EmitA32(0x05300000U | (cond.GetCondition() << 28) |
   5089                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5090                 (sign << 23));
   5091         return;
   5092       }
   5093       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   5094       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   5095           operand.IsOffset() && cond.IsNotNever()) {
   5096         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5097         uint32_t offset_ = abs(offset);
   5098         EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
   5099                 (rt.GetCode() << 12) | offset_ | (sign << 23));
   5100         return;
   5101       }
   5102     }
   5103   }
   5104   if (operand.IsPlainRegister()) {
   5105     Register rn = operand.GetBaseRegister();
   5106     Sign sign = operand.GetSign();
   5107     Register rm = operand.GetOffsetRegister();
   5108     if (IsUsingT32()) {
   5109       // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   5110       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   5111           sign.IsPlus() && operand.IsOffset()) {
   5112         EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
   5113                    (rm.GetCode() << 6));
   5114         AdvanceIT();
   5115         return;
   5116       }
   5117     }
   5118   }
   5119   if (operand.IsShiftedRegister()) {
   5120     Register rn = operand.GetBaseRegister();
   5121     Sign sign = operand.GetSign();
   5122     Register rm = operand.GetOffsetRegister();
   5123     Shift shift = operand.GetShift();
   5124     uint32_t amount = operand.GetShiftAmount();
   5125     if (IsUsingT32()) {
   5126       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   5127       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   5128           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   5129           ((!rm.IsPC() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) ||
   5130            AllowUnpredictable())) {
   5131         EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5132                    rm.GetCode() | (amount << 4));
   5133         AdvanceIT();
   5134         return;
   5135       }
   5136     } else {
   5137       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   5138       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
   5139           (!rm.IsPC() || AllowUnpredictable())) {
   5140         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5141         uint32_t shift_ = TypeEncodingValue(shift);
   5142         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5143         EmitA32(0x07100000U | (cond.GetCondition() << 28) |
   5144                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5145                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5146         return;
   5147       }
   5148       // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   5149       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   5150           cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
   5151         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5152         uint32_t shift_ = TypeEncodingValue(shift);
   5153         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5154         EmitA32(0x06100000U | (cond.GetCondition() << 28) |
   5155                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5156                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5157         return;
   5158       }
   5159       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   5160       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
   5161           (!rm.IsPC() || AllowUnpredictable())) {
   5162         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5163         uint32_t shift_ = TypeEncodingValue(shift);
   5164         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5165         EmitA32(0x07300000U | (cond.GetCondition() << 28) |
   5166                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5167                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5168         return;
   5169       }
   5170     }
   5171   }
   5172   Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
   5173 }
   5174 
   5175 void Assembler::ldr(Condition cond,
   5176                     EncodingSize size,
   5177                     Register rt,
   5178                     Location* location) {
   5179   VIXL_ASSERT(AllowAssembler());
   5180   CheckIT(cond);
   5181   Location::Offset offset =
   5182       location->IsBound()
   5183           ? location->GetLocation() -
   5184                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5185           : 0;
   5186   if (IsUsingT32()) {
   5187     // LDR{<c>}{<q>} <Rt>, <label> ; T1
   5188     if (!size.IsWide() && rt.IsLow() &&
   5189         ((location->IsBound() && (offset >= 0) && (offset <= 1020) &&
   5190           ((offset & 0x3) == 0)) ||
   5191          (!location->IsBound() && size.IsNarrow()))) {
   5192       static class EmitOp : public Location::EmitOperator {
   5193        public:
   5194         EmitOp() : Location::EmitOperator(T32) {}
   5195         virtual uint32_t Encode(uint32_t instr,
   5196                                 Location::Offset pc,
   5197                                 const Location* location) const VIXL_OVERRIDE {
   5198           pc += kT32PcDelta;
   5199           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   5200           VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
   5201                       ((offset & 0x3) == 0));
   5202           const int32_t target = offset >> 2;
   5203           return instr | (target & 0xff);
   5204         }
   5205       } immop;
   5206       EmitT32_16(
   5207           Link(0x4800 | (rt.GetCode() << 8), location, immop, &kT16DataInfo));
   5208       AdvanceIT();
   5209       return;
   5210     }
   5211     // LDR{<c>}{<q>} <Rt>, <label> ; T2
   5212     if (!size.IsNarrow() &&
   5213         ((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5214          !location->IsBound()) &&
   5215         ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   5216          AllowUnpredictable())) {
   5217       static class EmitOp : public Location::EmitOperator {
   5218        public:
   5219         EmitOp() : Location::EmitOperator(T32) {}
   5220         virtual uint32_t Encode(uint32_t instr,
   5221                                 Location::Offset pc,
   5222                                 const Location* location) const VIXL_OVERRIDE {
   5223           pc += kT32PcDelta;
   5224           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   5225           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   5226           uint32_t U = (offset >= 0);
   5227           int32_t target = abs(offset) | (U << 12);
   5228           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5229         }
   5230       } immop;
   5231       EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12),
   5232                       location,
   5233                       immop,
   5234                       &kT32FarDataInfo));
   5235       AdvanceIT();
   5236       return;
   5237     }
   5238   } else {
   5239     // LDR{<c>}{<q>} <Rt>, <label> ; A1
   5240     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5241          !location->IsBound()) &&
   5242         cond.IsNotNever()) {
   5243       static class EmitOp : public Location::EmitOperator {
   5244        public:
   5245         EmitOp() : Location::EmitOperator(A32) {}
   5246         virtual uint32_t Encode(uint32_t instr,
   5247                                 Location::Offset pc,
   5248                                 const Location* location) const VIXL_OVERRIDE {
   5249           pc += kA32PcDelta;
   5250           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   5251           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   5252           uint32_t U = (offset >= 0);
   5253           int32_t target = abs(offset) | (U << 12);
   5254           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5255         }
   5256       } immop;
   5257       EmitA32(
   5258           Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5259                location,
   5260                immop,
   5261                &kA32FarDataInfo));
   5262       return;
   5263     }
   5264   }
   5265   Delegate(kLdr, &Assembler::ldr, cond, size, rt, location);
   5266 }
   5267 
   5268 bool Assembler::ldr_info(Condition cond,
   5269                          EncodingSize size,
   5270                          Register rt,
   5271                          Location* location,
   5272                          const struct ReferenceInfo** info) {
   5273   VIXL_ASSERT(!location->IsBound());
   5274   USE(location);
   5275   if (IsUsingT32()) {
   5276     // LDR{<c>}{<q>} <Rt>, <label> ; T1
   5277     if (!size.IsWide() && rt.IsLow() && size.IsNarrow()) {
   5278       *info = &kT16DataInfo;
   5279       return true;
   5280     }
   5281     // LDR{<c>}{<q>} <Rt>, <label> ; T2
   5282     if (!size.IsNarrow()) {
   5283       *info = &kT32FarDataInfo;
   5284       return true;
   5285     }
   5286   } else {
   5287     // LDR{<c>}{<q>} <Rt>, <label> ; A1
   5288     if (cond.IsNotNever()) {
   5289       *info = &kA32FarDataInfo;
   5290       return true;
   5291     }
   5292   }
   5293   return false;
   5294 }
   5295 
   5296 void Assembler::ldrb(Condition cond,
   5297                      EncodingSize size,
   5298                      Register rt,
   5299                      const MemOperand& operand) {
   5300   VIXL_ASSERT(AllowAssembler());
   5301   CheckIT(cond);
   5302   if (operand.IsImmediate()) {
   5303     Register rn = operand.GetBaseRegister();
   5304     int32_t offset = operand.GetOffsetImmediate();
   5305     if (IsUsingT32()) {
   5306       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   5307       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   5308           (offset <= 31) && operand.IsOffset()) {
   5309         EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
   5310                    ((offset & 0x1f) << 6));
   5311         AdvanceIT();
   5312         return;
   5313       }
   5314       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   5315       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5316           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5317         EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5318                    (offset & 0xfff));
   5319         AdvanceIT();
   5320         return;
   5321       }
   5322       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   5323       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5324           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5325         EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5326                    (-offset & 0xff));
   5327         AdvanceIT();
   5328         return;
   5329       }
   5330       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   5331       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5332           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5333         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5334         uint32_t offset_ = abs(offset);
   5335         EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5336                    offset_ | (sign << 9));
   5337         AdvanceIT();
   5338         return;
   5339       }
   5340       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   5341       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5342           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5343         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5344         uint32_t offset_ = abs(offset);
   5345         EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5346                    offset_ | (sign << 9));
   5347         AdvanceIT();
   5348         return;
   5349       }
   5350       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   5351       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   5352           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   5353         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5354         uint32_t offset_ = abs(offset);
   5355         EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   5356         AdvanceIT();
   5357         return;
   5358       }
   5359     } else {
   5360       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   5361       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   5362           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5363           (!rt.IsPC() || AllowUnpredictable())) {
   5364         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5365         uint32_t offset_ = abs(offset);
   5366         EmitA32(0x05500000U | (cond.GetCondition() << 28) |
   5367                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5368                 (sign << 23));
   5369         return;
   5370       }
   5371       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   5372       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   5373           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5374           (!rt.IsPC() || AllowUnpredictable())) {
   5375         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5376         uint32_t offset_ = abs(offset);
   5377         EmitA32(0x04500000U | (cond.GetCondition() << 28) |
   5378                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5379                 (sign << 23));
   5380         return;
   5381       }
   5382       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   5383       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   5384           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5385           (!rt.IsPC() || AllowUnpredictable())) {
   5386         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5387         uint32_t offset_ = abs(offset);
   5388         EmitA32(0x05700000U | (cond.GetCondition() << 28) |
   5389                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   5390                 (sign << 23));
   5391         return;
   5392       }
   5393       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   5394       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   5395           operand.IsOffset() && cond.IsNotNever() &&
   5396           (!rt.IsPC() || AllowUnpredictable())) {
   5397         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5398         uint32_t offset_ = abs(offset);
   5399         EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
   5400                 (rt.GetCode() << 12) | offset_ | (sign << 23));
   5401         return;
   5402       }
   5403     }
   5404   }
   5405   if (operand.IsPlainRegister()) {
   5406     Register rn = operand.GetBaseRegister();
   5407     Sign sign = operand.GetSign();
   5408     Register rm = operand.GetOffsetRegister();
   5409     if (IsUsingT32()) {
   5410       // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   5411       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   5412           sign.IsPlus() && operand.IsOffset()) {
   5413         EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
   5414                    (rm.GetCode() << 6));
   5415         AdvanceIT();
   5416         return;
   5417       }
   5418     }
   5419   }
   5420   if (operand.IsShiftedRegister()) {
   5421     Register rn = operand.GetBaseRegister();
   5422     Sign sign = operand.GetSign();
   5423     Register rm = operand.GetOffsetRegister();
   5424     Shift shift = operand.GetShift();
   5425     uint32_t amount = operand.GetShiftAmount();
   5426     if (IsUsingT32()) {
   5427       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   5428       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   5429           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
   5430           (!rm.IsPC() || AllowUnpredictable())) {
   5431         EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5432                    rm.GetCode() | (amount << 4));
   5433         AdvanceIT();
   5434         return;
   5435       }
   5436     } else {
   5437       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   5438       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
   5439           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   5440         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5441         uint32_t shift_ = TypeEncodingValue(shift);
   5442         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5443         EmitA32(0x07500000U | (cond.GetCondition() << 28) |
   5444                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5445                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5446         return;
   5447       }
   5448       // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   5449       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   5450           cond.IsNotNever() &&
   5451           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   5452         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5453         uint32_t shift_ = TypeEncodingValue(shift);
   5454         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5455         EmitA32(0x06500000U | (cond.GetCondition() << 28) |
   5456                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5457                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5458         return;
   5459       }
   5460       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   5461       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
   5462           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   5463         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5464         uint32_t shift_ = TypeEncodingValue(shift);
   5465         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   5466         EmitA32(0x07700000U | (cond.GetCondition() << 28) |
   5467                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5468                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   5469         return;
   5470       }
   5471     }
   5472   }
   5473   Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
   5474 }
   5475 
   5476 void Assembler::ldrb(Condition cond, Register rt, Location* location) {
   5477   VIXL_ASSERT(AllowAssembler());
   5478   CheckIT(cond);
   5479   Location::Offset offset =
   5480       location->IsBound()
   5481           ? location->GetLocation() -
   5482                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5483           : 0;
   5484   if (IsUsingT32()) {
   5485     // LDRB{<c>}{<q>} <Rt>, <label> ; T1
   5486     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5487          !location->IsBound()) &&
   5488         !rt.Is(pc)) {
   5489       static class EmitOp : public Location::EmitOperator {
   5490        public:
   5491         EmitOp() : Location::EmitOperator(T32) {}
   5492         virtual uint32_t Encode(uint32_t instr,
   5493                                 Location::Offset pc,
   5494                                 const Location* location) const VIXL_OVERRIDE {
   5495           pc += kT32PcDelta;
   5496           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   5497           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   5498           uint32_t U = (offset >= 0);
   5499           int32_t target = abs(offset) | (U << 12);
   5500           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5501         }
   5502       } immop;
   5503       EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12),
   5504                       location,
   5505                       immop,
   5506                       &kT32FarDataInfo));
   5507       AdvanceIT();
   5508       return;
   5509     }
   5510   } else {
   5511     // LDRB{<c>}{<q>} <Rt>, <label> ; A1
   5512     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   5513          !location->IsBound()) &&
   5514         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   5515       static class EmitOp : public Location::EmitOperator {
   5516        public:
   5517         EmitOp() : Location::EmitOperator(A32) {}
   5518         virtual uint32_t Encode(uint32_t instr,
   5519                                 Location::Offset pc,
   5520                                 const Location* location) const VIXL_OVERRIDE {
   5521           pc += kA32PcDelta;
   5522           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   5523           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   5524           uint32_t U = (offset >= 0);
   5525           int32_t target = abs(offset) | (U << 12);
   5526           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   5527         }
   5528       } immop;
   5529       EmitA32(
   5530           Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5531                location,
   5532                immop,
   5533                &kA32FarDataInfo));
   5534       return;
   5535     }
   5536   }
   5537   Delegate(kLdrb, &Assembler::ldrb, cond, rt, location);
   5538 }
   5539 
   5540 bool Assembler::ldrb_info(Condition cond,
   5541                           Register rt,
   5542                           Location* location,
   5543                           const struct ReferenceInfo** info) {
   5544   VIXL_ASSERT(!location->IsBound());
   5545   USE(location);
   5546   if (IsUsingT32()) {
   5547     // LDRB{<c>}{<q>} <Rt>, <label> ; T1
   5548     if (!rt.Is(pc)) {
   5549       *info = &kT32FarDataInfo;
   5550       return true;
   5551     }
   5552   } else {
   5553     // LDRB{<c>}{<q>} <Rt>, <label> ; A1
   5554     if (cond.IsNotNever()) {
   5555       *info = &kA32FarDataInfo;
   5556       return true;
   5557     }
   5558   }
   5559   return false;
   5560 }
   5561 
   5562 void Assembler::ldrd(Condition cond,
   5563                      Register rt,
   5564                      Register rt2,
   5565                      const MemOperand& operand) {
   5566   VIXL_ASSERT(AllowAssembler());
   5567   CheckIT(cond);
   5568   if (operand.IsImmediate()) {
   5569     Register rn = operand.GetBaseRegister();
   5570     int32_t offset = operand.GetOffsetImmediate();
   5571     if (IsUsingT32()) {
   5572       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
   5573       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5574           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   5575           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5576         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5577         uint32_t offset_ = abs(offset) >> 2;
   5578         EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5579                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5580         AdvanceIT();
   5581         return;
   5582       }
   5583       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
   5584       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5585           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   5586           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5587         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5588         uint32_t offset_ = abs(offset) >> 2;
   5589         EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5590                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5591         AdvanceIT();
   5592         return;
   5593       }
   5594       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
   5595       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   5596           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   5597           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5598         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5599         uint32_t offset_ = abs(offset) >> 2;
   5600         EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5601                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   5602         AdvanceIT();
   5603         return;
   5604       }
   5605       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
   5606       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5607           operand.IsOffset() &&
   5608           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5609         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5610         uint32_t offset_ = abs(offset);
   5611         EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5612                    offset_ | (sign << 23));
   5613         AdvanceIT();
   5614         return;
   5615       }
   5616     } else {
   5617       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
   5618       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5619           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   5620           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5621           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   5622            AllowUnpredictable())) {
   5623         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5624         uint32_t offset_ = abs(offset);
   5625         EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
   5626                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5627                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5628         return;
   5629       }
   5630       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
   5631       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5632           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   5633           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5634           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   5635            AllowUnpredictable())) {
   5636         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5637         uint32_t offset_ = abs(offset);
   5638         EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
   5639                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5640                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5641         return;
   5642       }
   5643       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
   5644       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5645           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   5646           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5647           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   5648            AllowUnpredictable())) {
   5649         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5650         uint32_t offset_ = abs(offset);
   5651         EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
   5652                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5653                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5654         return;
   5655       }
   5656       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
   5657       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5658           (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   5659           operand.IsOffset() && cond.IsNotNever() &&
   5660           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   5661            AllowUnpredictable())) {
   5662         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5663         uint32_t offset_ = abs(offset);
   5664         EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
   5665                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   5666                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5667         return;
   5668       }
   5669     }
   5670   }
   5671   if (operand.IsPlainRegister()) {
   5672     Register rn = operand.GetBaseRegister();
   5673     Sign sign = operand.GetSign();
   5674     Register rm = operand.GetOffsetRegister();
   5675     if (IsUsingA32()) {
   5676       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
   5677       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5678           operand.IsOffset() && cond.IsNotNever() &&
   5679           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   5680            AllowUnpredictable())) {
   5681         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5682         EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
   5683                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5684                 (sign_ << 23));
   5685         return;
   5686       }
   5687       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
   5688       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5689           operand.IsPostIndex() && cond.IsNotNever() &&
   5690           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   5691            AllowUnpredictable())) {
   5692         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5693         EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
   5694                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5695                 (sign_ << 23));
   5696         return;
   5697       }
   5698       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
   5699       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5700           operand.IsPreIndex() && cond.IsNotNever() &&
   5701           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   5702            AllowUnpredictable())) {
   5703         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   5704         EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
   5705                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   5706                 (sign_ << 23));
   5707         return;
   5708       }
   5709     }
   5710   }
   5711   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
   5712 }
   5713 
   5714 void Assembler::ldrd(Condition cond,
   5715                      Register rt,
   5716                      Register rt2,
   5717                      Location* location) {
   5718   VIXL_ASSERT(AllowAssembler());
   5719   CheckIT(cond);
   5720   Location::Offset offset =
   5721       location->IsBound()
   5722           ? location->GetLocation() -
   5723                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   5724           : 0;
   5725   if (IsUsingT32()) {
   5726     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
   5727     if (((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   5728           ((offset & 0x3) == 0)) ||
   5729          !location->IsBound()) &&
   5730         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   5731       static class EmitOp : public Location::EmitOperator {
   5732        public:
   5733         EmitOp() : Location::EmitOperator(T32) {}
   5734         virtual uint32_t Encode(uint32_t instr,
   5735                                 Location::Offset pc,
   5736                                 const Location* location) const VIXL_OVERRIDE {
   5737           pc += kT32PcDelta;
   5738           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   5739           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   5740                       ((offset & 0x3) == 0));
   5741           int32_t target = offset >> 2;
   5742           uint32_t U = (target >= 0);
   5743           target = abs(target) | (U << 8);
   5744           return instr | (target & 0xff) | ((target & 0x100) << 15);
   5745         }
   5746       } immop;
   5747       EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
   5748                       location,
   5749                       immop,
   5750                       &kT32DataInfo));
   5751       AdvanceIT();
   5752       return;
   5753     }
   5754   } else {
   5755     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
   5756     if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5757         ((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
   5758          !location->IsBound()) &&
   5759         cond.IsNotNever() &&
   5760         ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || AllowUnpredictable())) {
   5761       static class EmitOp : public Location::EmitOperator {
   5762        public:
   5763         EmitOp() : Location::EmitOperator(A32) {}
   5764         virtual uint32_t Encode(uint32_t instr,
   5765                                 Location::Offset pc,
   5766                                 const Location* location) const VIXL_OVERRIDE {
   5767           pc += kA32PcDelta;
   5768           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   5769           VIXL_ASSERT((offset >= -255) && (offset <= 255));
   5770           uint32_t U = (offset >= 0);
   5771           int32_t target = abs(offset) | (U << 8);
   5772           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   5773                  ((target & 0x100) << 15);
   5774         }
   5775       } immop;
   5776       EmitA32(
   5777           Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   5778                location,
   5779                immop,
   5780                &kA32VeryNearDataInfo));
   5781       return;
   5782     }
   5783   }
   5784   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, location);
   5785 }
   5786 
   5787 bool Assembler::ldrd_info(Condition cond,
   5788                           Register rt,
   5789                           Register rt2,
   5790                           Location* location,
   5791                           const struct ReferenceInfo** info) {
   5792   VIXL_ASSERT(!location->IsBound());
   5793   USE(location);
   5794   if (IsUsingT32()) {
   5795     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
   5796     if (true) {
   5797       *info = &kT32DataInfo;
   5798       return true;
   5799     }
   5800   } else {
   5801     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
   5802     if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5803         cond.IsNotNever()) {
   5804       *info = &kA32VeryNearDataInfo;
   5805       return true;
   5806     }
   5807   }
   5808   return false;
   5809 }
   5810 
   5811 void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) {
   5812   VIXL_ASSERT(AllowAssembler());
   5813   CheckIT(cond);
   5814   if (operand.IsImmediate()) {
   5815     Register rn = operand.GetBaseRegister();
   5816     int32_t offset = operand.GetOffsetImmediate();
   5817     if (IsUsingT32()) {
   5818       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
   5819       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
   5820           operand.IsOffset() &&
   5821           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5822         int32_t offset_ = offset >> 2;
   5823         EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5824                    (offset_ & 0xff));
   5825         AdvanceIT();
   5826         return;
   5827       }
   5828     } else {
   5829       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
   5830       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() &&
   5831           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5832         EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
   5833                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5834         return;
   5835       }
   5836     }
   5837   }
   5838   Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
   5839 }
   5840 
   5841 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
   5842   VIXL_ASSERT(AllowAssembler());
   5843   CheckIT(cond);
   5844   if (operand.IsImmediateZero()) {
   5845     Register rn = operand.GetBaseRegister();
   5846     if (IsUsingT32()) {
   5847       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   5848       if (operand.IsOffset() &&
   5849           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5850         EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5851         AdvanceIT();
   5852         return;
   5853       }
   5854     } else {
   5855       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   5856       if (operand.IsOffset() && cond.IsNotNever() &&
   5857           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5858         EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
   5859                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5860         return;
   5861       }
   5862     }
   5863   }
   5864   Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
   5865 }
   5866 
   5867 void Assembler::ldrexd(Condition cond,
   5868                        Register rt,
   5869                        Register rt2,
   5870                        const MemOperand& operand) {
   5871   VIXL_ASSERT(AllowAssembler());
   5872   CheckIT(cond);
   5873   if (operand.IsImmediateZero()) {
   5874     Register rn = operand.GetBaseRegister();
   5875     if (IsUsingT32()) {
   5876       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
   5877       if (operand.IsOffset() &&
   5878           ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5879         EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   5880                    (rn.GetCode() << 16));
   5881         AdvanceIT();
   5882         return;
   5883       }
   5884     } else {
   5885       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
   5886       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   5887           operand.IsOffset() && cond.IsNotNever() &&
   5888           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) ||
   5889            AllowUnpredictable())) {
   5890         EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
   5891                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5892         return;
   5893       }
   5894     }
   5895   }
   5896   Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
   5897 }
   5898 
   5899 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
   5900   VIXL_ASSERT(AllowAssembler());
   5901   CheckIT(cond);
   5902   if (operand.IsImmediateZero()) {
   5903     Register rn = operand.GetBaseRegister();
   5904     if (IsUsingT32()) {
   5905       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   5906       if (operand.IsOffset() &&
   5907           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5908         EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5909         AdvanceIT();
   5910         return;
   5911       }
   5912     } else {
   5913       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   5914       if (operand.IsOffset() && cond.IsNotNever() &&
   5915           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   5916         EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
   5917                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
   5918         return;
   5919       }
   5920     }
   5921   }
   5922   Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
   5923 }
   5924 
   5925 void Assembler::ldrh(Condition cond,
   5926                      EncodingSize size,
   5927                      Register rt,
   5928                      const MemOperand& operand) {
   5929   VIXL_ASSERT(AllowAssembler());
   5930   CheckIT(cond);
   5931   if (operand.IsImmediate()) {
   5932     Register rn = operand.GetBaseRegister();
   5933     int32_t offset = operand.GetOffsetImmediate();
   5934     if (IsUsingT32()) {
   5935       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   5936       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   5937           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
   5938         int32_t offset_ = offset >> 1;
   5939         EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
   5940                    ((offset_ & 0x1f) << 6));
   5941         AdvanceIT();
   5942         return;
   5943       }
   5944       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   5945       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   5946           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5947         EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5948                    (offset & 0xfff));
   5949         AdvanceIT();
   5950         return;
   5951       }
   5952       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   5953       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   5954           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   5955         EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5956                    (-offset & 0xff));
   5957         AdvanceIT();
   5958         return;
   5959       }
   5960       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   5961       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5962           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5963         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5964         uint32_t offset_ = abs(offset);
   5965         EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5966                    offset_ | (sign << 9));
   5967         AdvanceIT();
   5968         return;
   5969       }
   5970       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   5971       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   5972           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   5973         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5974         uint32_t offset_ = abs(offset);
   5975         EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   5976                    offset_ | (sign << 9));
   5977         AdvanceIT();
   5978         return;
   5979       }
   5980       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   5981       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   5982           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   5983         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5984         uint32_t offset_ = abs(offset);
   5985         EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   5986         AdvanceIT();
   5987         return;
   5988       }
   5989     } else {
   5990       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   5991       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   5992           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   5993           (!rt.IsPC() || AllowUnpredictable())) {
   5994         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   5995         uint32_t offset_ = abs(offset);
   5996         EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
   5997                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   5998                 ((offset_ & 0xf0) << 4) | (sign << 23));
   5999         return;
   6000       }
   6001       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   6002       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   6003           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6004           (!rt.IsPC() || AllowUnpredictable())) {
   6005         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6006         uint32_t offset_ = abs(offset);
   6007         EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
   6008                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6009                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6010         return;
   6011       }
   6012       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   6013       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   6014           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6015           (!rt.IsPC() || AllowUnpredictable())) {
   6016         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6017         uint32_t offset_ = abs(offset);
   6018         EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
   6019                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6020                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6021         return;
   6022       }
   6023       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   6024       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   6025           operand.IsOffset() && cond.IsNotNever() &&
   6026           (!rt.IsPC() || AllowUnpredictable())) {
   6027         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6028         uint32_t offset_ = abs(offset);
   6029         EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
   6030                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   6031                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6032         return;
   6033       }
   6034     }
   6035   }
   6036   if (operand.IsPlainRegister()) {
   6037     Register rn = operand.GetBaseRegister();
   6038     Sign sign = operand.GetSign();
   6039     Register rm = operand.GetOffsetRegister();
   6040     if (IsUsingT32()) {
   6041       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   6042       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   6043           sign.IsPlus() && operand.IsOffset()) {
   6044         EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
   6045                    (rm.GetCode() << 6));
   6046         AdvanceIT();
   6047         return;
   6048       }
   6049     } else {
   6050       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   6051       if (operand.IsOffset() && cond.IsNotNever() &&
   6052           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6053         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6054         EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
   6055                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6056                 (sign_ << 23));
   6057         return;
   6058       }
   6059       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   6060       if (operand.IsPostIndex() && cond.IsNotNever() &&
   6061           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6062         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6063         EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
   6064                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6065                 (sign_ << 23));
   6066         return;
   6067       }
   6068       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   6069       if (operand.IsPreIndex() && cond.IsNotNever() &&
   6070           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6071         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6072         EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
   6073                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6074                 (sign_ << 23));
   6075         return;
   6076       }
   6077     }
   6078   }
   6079   if (operand.IsShiftedRegister()) {
   6080     Register rn = operand.GetBaseRegister();
   6081     Sign sign = operand.GetSign();
   6082     Register rm = operand.GetOffsetRegister();
   6083     Shift shift = operand.GetShift();
   6084     uint32_t amount = operand.GetShiftAmount();
   6085     if (IsUsingT32()) {
   6086       // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   6087       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   6088           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
   6089           (!rm.IsPC() || AllowUnpredictable())) {
   6090         EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6091                    rm.GetCode() | (amount << 4));
   6092         AdvanceIT();
   6093         return;
   6094       }
   6095     }
   6096   }
   6097   Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
   6098 }
   6099 
   6100 void Assembler::ldrh(Condition cond, Register rt, Location* location) {
   6101   VIXL_ASSERT(AllowAssembler());
   6102   CheckIT(cond);
   6103   Location::Offset offset =
   6104       location->IsBound()
   6105           ? location->GetLocation() -
   6106                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   6107           : 0;
   6108   if (IsUsingT32()) {
   6109     // LDRH{<c>}{<q>} <Rt>, <label> ; T1
   6110     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   6111          !location->IsBound()) &&
   6112         !rt.Is(pc)) {
   6113       static class EmitOp : public Location::EmitOperator {
   6114        public:
   6115         EmitOp() : Location::EmitOperator(T32) {}
   6116         virtual uint32_t Encode(uint32_t instr,
   6117                                 Location::Offset pc,
   6118                                 const Location* location) const VIXL_OVERRIDE {
   6119           pc += kT32PcDelta;
   6120           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   6121           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   6122           uint32_t U = (offset >= 0);
   6123           int32_t target = abs(offset) | (U << 12);
   6124           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   6125         }
   6126       } immop;
   6127       EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12),
   6128                       location,
   6129                       immop,
   6130                       &kT32FarDataInfo));
   6131       AdvanceIT();
   6132       return;
   6133     }
   6134   } else {
   6135     // LDRH{<c>}{<q>} <Rt>, <label> ; A1
   6136     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
   6137          !location->IsBound()) &&
   6138         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   6139       static class EmitOp : public Location::EmitOperator {
   6140        public:
   6141         EmitOp() : Location::EmitOperator(A32) {}
   6142         virtual uint32_t Encode(uint32_t instr,
   6143                                 Location::Offset pc,
   6144                                 const Location* location) const VIXL_OVERRIDE {
   6145           pc += kA32PcDelta;
   6146           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   6147           VIXL_ASSERT((offset >= -255) && (offset <= 255));
   6148           uint32_t U = (offset >= 0);
   6149           int32_t target = abs(offset) | (U << 8);
   6150           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   6151                  ((target & 0x100) << 15);
   6152         }
   6153       } immop;
   6154       EmitA32(
   6155           Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   6156                location,
   6157                immop,
   6158                &kA32VeryNearDataInfo));
   6159       return;
   6160     }
   6161   }
   6162   Delegate(kLdrh, &Assembler::ldrh, cond, rt, location);
   6163 }
   6164 
   6165 bool Assembler::ldrh_info(Condition cond,
   6166                           Register rt,
   6167                           Location* location,
   6168                           const struct ReferenceInfo** info) {
   6169   VIXL_ASSERT(!location->IsBound());
   6170   USE(location);
   6171   if (IsUsingT32()) {
   6172     // LDRH{<c>}{<q>} <Rt>, <label> ; T1
   6173     if (!rt.Is(pc)) {
   6174       *info = &kT32FarDataInfo;
   6175       return true;
   6176     }
   6177   } else {
   6178     // LDRH{<c>}{<q>} <Rt>, <label> ; A1
   6179     if (cond.IsNotNever()) {
   6180       *info = &kA32VeryNearDataInfo;
   6181       return true;
   6182     }
   6183   }
   6184   return false;
   6185 }
   6186 
   6187 void Assembler::ldrsb(Condition cond,
   6188                       EncodingSize size,
   6189                       Register rt,
   6190                       const MemOperand& operand) {
   6191   VIXL_ASSERT(AllowAssembler());
   6192   CheckIT(cond);
   6193   if (operand.IsImmediate()) {
   6194     Register rn = operand.GetBaseRegister();
   6195     int32_t offset = operand.GetOffsetImmediate();
   6196     if (IsUsingT32()) {
   6197       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   6198       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   6199           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6200         EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6201                    (offset & 0xfff));
   6202         AdvanceIT();
   6203         return;
   6204       }
   6205       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
   6206       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   6207           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6208         EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6209                    (-offset & 0xff));
   6210         AdvanceIT();
   6211         return;
   6212       }
   6213       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
   6214       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   6215           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   6216         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6217         uint32_t offset_ = abs(offset);
   6218         EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6219                    offset_ | (sign << 9));
   6220         AdvanceIT();
   6221         return;
   6222       }
   6223       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
   6224       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   6225           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   6226         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6227         uint32_t offset_ = abs(offset);
   6228         EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6229                    offset_ | (sign << 9));
   6230         AdvanceIT();
   6231         return;
   6232       }
   6233       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   6234       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   6235           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   6236         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6237         uint32_t offset_ = abs(offset);
   6238         EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   6239         AdvanceIT();
   6240         return;
   6241       }
   6242     } else {
   6243       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
   6244       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   6245           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6246           (!rt.IsPC() || AllowUnpredictable())) {
   6247         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6248         uint32_t offset_ = abs(offset);
   6249         EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
   6250                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6251                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6252         return;
   6253       }
   6254       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
   6255       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   6256           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6257           (!rt.IsPC() || AllowUnpredictable())) {
   6258         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6259         uint32_t offset_ = abs(offset);
   6260         EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
   6261                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6262                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6263         return;
   6264       }
   6265       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
   6266       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   6267           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6268           (!rt.IsPC() || AllowUnpredictable())) {
   6269         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6270         uint32_t offset_ = abs(offset);
   6271         EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
   6272                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6273                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6274         return;
   6275       }
   6276       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   6277       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   6278           operand.IsOffset() && cond.IsNotNever() &&
   6279           (!rt.IsPC() || AllowUnpredictable())) {
   6280         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6281         uint32_t offset_ = abs(offset);
   6282         EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
   6283                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   6284                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6285         return;
   6286       }
   6287     }
   6288   }
   6289   if (operand.IsPlainRegister()) {
   6290     Register rn = operand.GetBaseRegister();
   6291     Sign sign = operand.GetSign();
   6292     Register rm = operand.GetOffsetRegister();
   6293     if (IsUsingT32()) {
   6294       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   6295       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   6296           sign.IsPlus() && operand.IsOffset()) {
   6297         EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
   6298                    (rm.GetCode() << 6));
   6299         AdvanceIT();
   6300         return;
   6301       }
   6302     } else {
   6303       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   6304       if (operand.IsOffset() && cond.IsNotNever() &&
   6305           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6306         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6307         EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
   6308                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6309                 (sign_ << 23));
   6310         return;
   6311       }
   6312       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   6313       if (operand.IsPostIndex() && cond.IsNotNever() &&
   6314           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6315         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6316         EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
   6317                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6318                 (sign_ << 23));
   6319         return;
   6320       }
   6321       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   6322       if (operand.IsPreIndex() && cond.IsNotNever() &&
   6323           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6324         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6325         EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
   6326                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6327                 (sign_ << 23));
   6328         return;
   6329       }
   6330     }
   6331   }
   6332   if (operand.IsShiftedRegister()) {
   6333     Register rn = operand.GetBaseRegister();
   6334     Sign sign = operand.GetSign();
   6335     Register rm = operand.GetOffsetRegister();
   6336     Shift shift = operand.GetShift();
   6337     uint32_t amount = operand.GetShiftAmount();
   6338     if (IsUsingT32()) {
   6339       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   6340       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   6341           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
   6342           (!rm.IsPC() || AllowUnpredictable())) {
   6343         EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6344                    rm.GetCode() | (amount << 4));
   6345         AdvanceIT();
   6346         return;
   6347       }
   6348     }
   6349   }
   6350   Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
   6351 }
   6352 
   6353 void Assembler::ldrsb(Condition cond, Register rt, Location* location) {
   6354   VIXL_ASSERT(AllowAssembler());
   6355   CheckIT(cond);
   6356   Location::Offset offset =
   6357       location->IsBound()
   6358           ? location->GetLocation() -
   6359                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   6360           : 0;
   6361   if (IsUsingT32()) {
   6362     // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
   6363     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   6364          !location->IsBound()) &&
   6365         !rt.Is(pc)) {
   6366       static class EmitOp : public Location::EmitOperator {
   6367        public:
   6368         EmitOp() : Location::EmitOperator(T32) {}
   6369         virtual uint32_t Encode(uint32_t instr,
   6370                                 Location::Offset pc,
   6371                                 const Location* location) const VIXL_OVERRIDE {
   6372           pc += kT32PcDelta;
   6373           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   6374           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   6375           uint32_t U = (offset >= 0);
   6376           int32_t target = abs(offset) | (U << 12);
   6377           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   6378         }
   6379       } immop;
   6380       EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12),
   6381                       location,
   6382                       immop,
   6383                       &kT32FarDataInfo));
   6384       AdvanceIT();
   6385       return;
   6386     }
   6387   } else {
   6388     // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
   6389     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
   6390          !location->IsBound()) &&
   6391         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   6392       static class EmitOp : public Location::EmitOperator {
   6393        public:
   6394         EmitOp() : Location::EmitOperator(A32) {}
   6395         virtual uint32_t Encode(uint32_t instr,
   6396                                 Location::Offset pc,
   6397                                 const Location* location) const VIXL_OVERRIDE {
   6398           pc += kA32PcDelta;
   6399           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   6400           VIXL_ASSERT((offset >= -255) && (offset <= 255));
   6401           uint32_t U = (offset >= 0);
   6402           int32_t target = abs(offset) | (U << 8);
   6403           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   6404                  ((target & 0x100) << 15);
   6405         }
   6406       } immop;
   6407       EmitA32(
   6408           Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   6409                location,
   6410                immop,
   6411                &kA32VeryNearDataInfo));
   6412       return;
   6413     }
   6414   }
   6415   Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, location);
   6416 }
   6417 
   6418 bool Assembler::ldrsb_info(Condition cond,
   6419                            Register rt,
   6420                            Location* location,
   6421                            const struct ReferenceInfo** info) {
   6422   VIXL_ASSERT(!location->IsBound());
   6423   USE(location);
   6424   if (IsUsingT32()) {
   6425     // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
   6426     if (!rt.Is(pc)) {
   6427       *info = &kT32FarDataInfo;
   6428       return true;
   6429     }
   6430   } else {
   6431     // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
   6432     if (cond.IsNotNever()) {
   6433       *info = &kA32VeryNearDataInfo;
   6434       return true;
   6435     }
   6436   }
   6437   return false;
   6438 }
   6439 
   6440 void Assembler::ldrsh(Condition cond,
   6441                       EncodingSize size,
   6442                       Register rt,
   6443                       const MemOperand& operand) {
   6444   VIXL_ASSERT(AllowAssembler());
   6445   CheckIT(cond);
   6446   if (operand.IsImmediate()) {
   6447     Register rn = operand.GetBaseRegister();
   6448     int32_t offset = operand.GetOffsetImmediate();
   6449     if (IsUsingT32()) {
   6450       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   6451       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   6452           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6453         EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6454                    (offset & 0xfff));
   6455         AdvanceIT();
   6456         return;
   6457       }
   6458       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
   6459       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   6460           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
   6461         EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6462                    (-offset & 0xff));
   6463         AdvanceIT();
   6464         return;
   6465       }
   6466       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
   6467       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   6468           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   6469         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6470         uint32_t offset_ = abs(offset);
   6471         EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6472                    offset_ | (sign << 9));
   6473         AdvanceIT();
   6474         return;
   6475       }
   6476       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
   6477       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   6478           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
   6479         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6480         uint32_t offset_ = abs(offset);
   6481         EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6482                    offset_ | (sign << 9));
   6483         AdvanceIT();
   6484         return;
   6485       }
   6486       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
   6487       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
   6488           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
   6489         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6490         uint32_t offset_ = abs(offset);
   6491         EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
   6492         AdvanceIT();
   6493         return;
   6494       }
   6495     } else {
   6496       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
   6497       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   6498           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6499           (!rt.IsPC() || AllowUnpredictable())) {
   6500         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6501         uint32_t offset_ = abs(offset);
   6502         EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
   6503                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6504                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6505         return;
   6506       }
   6507       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
   6508       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   6509           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6510           (!rt.IsPC() || AllowUnpredictable())) {
   6511         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6512         uint32_t offset_ = abs(offset);
   6513         EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
   6514                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6515                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6516         return;
   6517       }
   6518       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
   6519       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   6520           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
   6521           (!rt.IsPC() || AllowUnpredictable())) {
   6522         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6523         uint32_t offset_ = abs(offset);
   6524         EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
   6525                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   6526                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6527         return;
   6528       }
   6529       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
   6530       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
   6531           operand.IsOffset() && cond.IsNotNever() &&
   6532           (!rt.IsPC() || AllowUnpredictable())) {
   6533         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   6534         uint32_t offset_ = abs(offset);
   6535         EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
   6536                 (rt.GetCode() << 12) | (offset_ & 0xf) |
   6537                 ((offset_ & 0xf0) << 4) | (sign << 23));
   6538         return;
   6539       }
   6540     }
   6541   }
   6542   if (operand.IsPlainRegister()) {
   6543     Register rn = operand.GetBaseRegister();
   6544     Sign sign = operand.GetSign();
   6545     Register rm = operand.GetOffsetRegister();
   6546     if (IsUsingT32()) {
   6547       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   6548       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   6549           sign.IsPlus() && operand.IsOffset()) {
   6550         EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
   6551                    (rm.GetCode() << 6));
   6552         AdvanceIT();
   6553         return;
   6554       }
   6555     } else {
   6556       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   6557       if (operand.IsOffset() && cond.IsNotNever() &&
   6558           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6559         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6560         EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
   6561                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6562                 (sign_ << 23));
   6563         return;
   6564       }
   6565       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   6566       if (operand.IsPostIndex() && cond.IsNotNever() &&
   6567           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6568         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6569         EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
   6570                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6571                 (sign_ << 23));
   6572         return;
   6573       }
   6574       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   6575       if (operand.IsPreIndex() && cond.IsNotNever() &&
   6576           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6577         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   6578         EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
   6579                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   6580                 (sign_ << 23));
   6581         return;
   6582       }
   6583     }
   6584   }
   6585   if (operand.IsShiftedRegister()) {
   6586     Register rn = operand.GetBaseRegister();
   6587     Sign sign = operand.GetSign();
   6588     Register rm = operand.GetOffsetRegister();
   6589     Shift shift = operand.GetShift();
   6590     uint32_t amount = operand.GetShiftAmount();
   6591     if (IsUsingT32()) {
   6592       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   6593       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   6594           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
   6595           (!rm.IsPC() || AllowUnpredictable())) {
   6596         EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   6597                    rm.GetCode() | (amount << 4));
   6598         AdvanceIT();
   6599         return;
   6600       }
   6601     }
   6602   }
   6603   Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
   6604 }
   6605 
   6606 void Assembler::ldrsh(Condition cond, Register rt, Location* location) {
   6607   VIXL_ASSERT(AllowAssembler());
   6608   CheckIT(cond);
   6609   Location::Offset offset =
   6610       location->IsBound()
   6611           ? location->GetLocation() -
   6612                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   6613           : 0;
   6614   if (IsUsingT32()) {
   6615     // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
   6616     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   6617          !location->IsBound()) &&
   6618         !rt.Is(pc)) {
   6619       static class EmitOp : public Location::EmitOperator {
   6620        public:
   6621         EmitOp() : Location::EmitOperator(T32) {}
   6622         virtual uint32_t Encode(uint32_t instr,
   6623                                 Location::Offset pc,
   6624                                 const Location* location) const VIXL_OVERRIDE {
   6625           pc += kT32PcDelta;
   6626           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   6627           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   6628           uint32_t U = (offset >= 0);
   6629           int32_t target = abs(offset) | (U << 12);
   6630           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   6631         }
   6632       } immop;
   6633       EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12),
   6634                       location,
   6635                       immop,
   6636                       &kT32FarDataInfo));
   6637       AdvanceIT();
   6638       return;
   6639     }
   6640   } else {
   6641     // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
   6642     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
   6643          !location->IsBound()) &&
   6644         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   6645       static class EmitOp : public Location::EmitOperator {
   6646        public:
   6647         EmitOp() : Location::EmitOperator(A32) {}
   6648         virtual uint32_t Encode(uint32_t instr,
   6649                                 Location::Offset pc,
   6650                                 const Location* location) const VIXL_OVERRIDE {
   6651           pc += kA32PcDelta;
   6652           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   6653           VIXL_ASSERT((offset >= -255) && (offset <= 255));
   6654           uint32_t U = (offset >= 0);
   6655           int32_t target = abs(offset) | (U << 8);
   6656           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
   6657                  ((target & 0x100) << 15);
   6658         }
   6659       } immop;
   6660       EmitA32(
   6661           Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
   6662                location,
   6663                immop,
   6664                &kA32VeryNearDataInfo));
   6665       return;
   6666     }
   6667   }
   6668   Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, location);
   6669 }
   6670 
   6671 bool Assembler::ldrsh_info(Condition cond,
   6672                            Register rt,
   6673                            Location* location,
   6674                            const struct ReferenceInfo** info) {
   6675   VIXL_ASSERT(!location->IsBound());
   6676   USE(location);
   6677   if (IsUsingT32()) {
   6678     // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
   6679     if (!rt.Is(pc)) {
   6680       *info = &kT32FarDataInfo;
   6681       return true;
   6682     }
   6683   } else {
   6684     // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
   6685     if (cond.IsNotNever()) {
   6686       *info = &kA32VeryNearDataInfo;
   6687       return true;
   6688     }
   6689   }
   6690   return false;
   6691 }
   6692 
   6693 void Assembler::lsl(Condition cond,
   6694                     EncodingSize size,
   6695                     Register rd,
   6696                     Register rm,
   6697                     const Operand& operand) {
   6698   VIXL_ASSERT(AllowAssembler());
   6699   CheckIT(cond);
   6700   if (operand.IsImmediate()) {
   6701     uint32_t imm = operand.GetImmediate();
   6702     if (IsUsingT32()) {
   6703       // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6704       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6705           (imm >= 1) && (imm <= 31)) {
   6706         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
   6707         AdvanceIT();
   6708         return;
   6709       }
   6710       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6711       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
   6712           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6713         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6714                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   6715         AdvanceIT();
   6716         return;
   6717       }
   6718     } else {
   6719       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6720       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   6721         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
   6722                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   6723         return;
   6724       }
   6725     }
   6726   }
   6727   if (operand.IsPlainRegister()) {
   6728     Register rs = operand.GetBaseRegister();
   6729     if (IsUsingT32()) {
   6730       // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6731       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6732           rs.IsLow()) {
   6733         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   6734         AdvanceIT();
   6735         return;
   6736       }
   6737       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6738       if (!size.IsNarrow() &&
   6739           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6740         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6741                    rs.GetCode());
   6742         AdvanceIT();
   6743         return;
   6744       }
   6745     } else {
   6746       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6747       if (cond.IsNotNever() &&
   6748           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6749         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
   6750                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6751         return;
   6752       }
   6753     }
   6754   }
   6755   Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
   6756 }
   6757 
   6758 void Assembler::lsls(Condition cond,
   6759                      EncodingSize size,
   6760                      Register rd,
   6761                      Register rm,
   6762                      const Operand& operand) {
   6763   VIXL_ASSERT(AllowAssembler());
   6764   CheckIT(cond);
   6765   if (operand.IsImmediate()) {
   6766     uint32_t imm = operand.GetImmediate();
   6767     if (IsUsingT32()) {
   6768       // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6769       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6770           (imm >= 1) && (imm <= 31)) {
   6771         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
   6772         AdvanceIT();
   6773         return;
   6774       }
   6775       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6776       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
   6777           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6778         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   6779                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   6780         AdvanceIT();
   6781         return;
   6782       }
   6783     } else {
   6784       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6785       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   6786         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
   6787                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   6788         return;
   6789       }
   6790     }
   6791   }
   6792   if (operand.IsPlainRegister()) {
   6793     Register rs = operand.GetBaseRegister();
   6794     if (IsUsingT32()) {
   6795       // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6796       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6797           rs.IsLow()) {
   6798         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   6799         AdvanceIT();
   6800         return;
   6801       }
   6802       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6803       if (!size.IsNarrow() &&
   6804           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6805         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6806                    rs.GetCode());
   6807         AdvanceIT();
   6808         return;
   6809       }
   6810     } else {
   6811       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6812       if (cond.IsNotNever() &&
   6813           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6814         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
   6815                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6816         return;
   6817       }
   6818     }
   6819   }
   6820   Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
   6821 }
   6822 
   6823 void Assembler::lsr(Condition cond,
   6824                     EncodingSize size,
   6825                     Register rd,
   6826                     Register rm,
   6827                     const Operand& operand) {
   6828   VIXL_ASSERT(AllowAssembler());
   6829   CheckIT(cond);
   6830   if (operand.IsImmediate()) {
   6831     uint32_t imm = operand.GetImmediate();
   6832     if (IsUsingT32()) {
   6833       // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6834       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6835           (imm >= 1) && (imm <= 32)) {
   6836         uint32_t amount_ = imm % 32;
   6837         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
   6838                    (amount_ << 6));
   6839         AdvanceIT();
   6840         return;
   6841       }
   6842       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6843       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
   6844           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6845         uint32_t amount_ = imm % 32;
   6846         EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
   6847                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6848         AdvanceIT();
   6849         return;
   6850       }
   6851     } else {
   6852       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6853       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   6854         uint32_t amount_ = imm % 32;
   6855         EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
   6856                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   6857         return;
   6858       }
   6859     }
   6860   }
   6861   if (operand.IsPlainRegister()) {
   6862     Register rs = operand.GetBaseRegister();
   6863     if (IsUsingT32()) {
   6864       // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6865       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6866           rs.IsLow()) {
   6867         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   6868         AdvanceIT();
   6869         return;
   6870       }
   6871       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6872       if (!size.IsNarrow() &&
   6873           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6874         EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6875                    rs.GetCode());
   6876         AdvanceIT();
   6877         return;
   6878       }
   6879     } else {
   6880       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6881       if (cond.IsNotNever() &&
   6882           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6883         EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
   6884                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6885         return;
   6886       }
   6887     }
   6888   }
   6889   Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
   6890 }
   6891 
   6892 void Assembler::lsrs(Condition cond,
   6893                      EncodingSize size,
   6894                      Register rd,
   6895                      Register rm,
   6896                      const Operand& operand) {
   6897   VIXL_ASSERT(AllowAssembler());
   6898   CheckIT(cond);
   6899   if (operand.IsImmediate()) {
   6900     uint32_t imm = operand.GetImmediate();
   6901     if (IsUsingT32()) {
   6902       // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
   6903       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
   6904           (imm >= 1) && (imm <= 32)) {
   6905         uint32_t amount_ = imm % 32;
   6906         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
   6907                    (amount_ << 6));
   6908         AdvanceIT();
   6909         return;
   6910       }
   6911       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   6912       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
   6913           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6914         uint32_t amount_ = imm % 32;
   6915         EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
   6916                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   6917         AdvanceIT();
   6918         return;
   6919       }
   6920     } else {
   6921       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   6922       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
   6923         uint32_t amount_ = imm % 32;
   6924         EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
   6925                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
   6926         return;
   6927       }
   6928     }
   6929   }
   6930   if (operand.IsPlainRegister()) {
   6931     Register rs = operand.GetBaseRegister();
   6932     if (IsUsingT32()) {
   6933       // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   6934       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   6935           rs.IsLow()) {
   6936         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   6937         AdvanceIT();
   6938         return;
   6939       }
   6940       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   6941       if (!size.IsNarrow() &&
   6942           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6943         EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   6944                    rs.GetCode());
   6945         AdvanceIT();
   6946         return;
   6947       }
   6948     } else {
   6949       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   6950       if (cond.IsNotNever() &&
   6951           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   6952         EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
   6953                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   6954         return;
   6955       }
   6956     }
   6957   }
   6958   Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
   6959 }
   6960 
   6961 void Assembler::mla(
   6962     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   6963   VIXL_ASSERT(AllowAssembler());
   6964   CheckIT(cond);
   6965   if (IsUsingT32()) {
   6966     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   6967     if (!ra.Is(pc) &&
   6968         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   6969       EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   6970                  rm.GetCode() | (ra.GetCode() << 12));
   6971       AdvanceIT();
   6972       return;
   6973     }
   6974   } else {
   6975     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   6976     if (cond.IsNotNever() &&
   6977         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   6978          AllowUnpredictable())) {
   6979       EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   6980               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   6981       return;
   6982     }
   6983   }
   6984   Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
   6985 }
   6986 
   6987 void Assembler::mlas(
   6988     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   6989   VIXL_ASSERT(AllowAssembler());
   6990   CheckIT(cond);
   6991   if (IsUsingA32()) {
   6992     // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   6993     if (cond.IsNotNever() &&
   6994         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   6995          AllowUnpredictable())) {
   6996       EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   6997               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   6998       return;
   6999     }
   7000   }
   7001   Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
   7002 }
   7003 
   7004 void Assembler::mls(
   7005     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   7006   VIXL_ASSERT(AllowAssembler());
   7007   CheckIT(cond);
   7008   if (IsUsingT32()) {
   7009     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   7010     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   7011          AllowUnpredictable())) {
   7012       EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7013                  rm.GetCode() | (ra.GetCode() << 12));
   7014       AdvanceIT();
   7015       return;
   7016     }
   7017   } else {
   7018     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   7019     if (cond.IsNotNever() &&
   7020         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   7021          AllowUnpredictable())) {
   7022       EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   7023               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   7024       return;
   7025     }
   7026   }
   7027   Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
   7028 }
   7029 
   7030 void Assembler::mov(Condition cond,
   7031                     EncodingSize size,
   7032                     Register rd,
   7033                     const Operand& operand) {
   7034   VIXL_ASSERT(AllowAssembler());
   7035   CheckIT(cond);
   7036   if (operand.IsImmediateShiftedRegister()) {
   7037     Register rm = operand.GetBaseRegister();
   7038     if (operand.IsPlainRegister()) {
   7039       if (IsUsingT32()) {
   7040         // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
   7041         if (!size.IsWide() &&
   7042             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   7043              AllowUnpredictable())) {
   7044           EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
   7045                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
   7046           AdvanceIT();
   7047           return;
   7048         }
   7049       }
   7050     }
   7051     Shift shift = operand.GetShift();
   7052     uint32_t amount = operand.GetShiftAmount();
   7053     if (IsUsingT32()) {
   7054       // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   7055       if (InITBlock() && !size.IsWide() && rd.IsLow() &&
   7056           shift.IsValidAmount(amount) && rm.IsLow() &&
   7057           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) &&
   7058           ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) {
   7059         uint32_t amount_ = amount % 32;
   7060         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
   7061                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
   7062         AdvanceIT();
   7063         return;
   7064       }
   7065       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
   7066       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   7067           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7068         uint32_t amount_ = amount % 32;
   7069         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   7070                    (operand.GetTypeEncodingValue() << 4) |
   7071                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7072         AdvanceIT();
   7073         return;
   7074       }
   7075     } else {
   7076       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   7077       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7078         uint32_t amount_ = amount % 32;
   7079         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
   7080                 (rd.GetCode() << 12) | rm.GetCode() |
   7081                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7082         return;
   7083       }
   7084     }
   7085   }
   7086   if (operand.IsRegisterShiftedRegister()) {
   7087     Register rm = operand.GetBaseRegister();
   7088     Shift shift = operand.GetShift();
   7089     Register rs = operand.GetShiftRegister();
   7090     if (IsUsingT32()) {
   7091       // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
   7092       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7093           shift.IsASR() && rs.IsLow()) {
   7094         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   7095         AdvanceIT();
   7096         return;
   7097       }
   7098       // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
   7099       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7100           shift.IsLSL() && rs.IsLow()) {
   7101         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   7102         AdvanceIT();
   7103         return;
   7104       }
   7105       // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
   7106       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7107           shift.IsLSR() && rs.IsLow()) {
   7108         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   7109         AdvanceIT();
   7110         return;
   7111       }
   7112       // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
   7113       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7114           shift.IsROR() && rs.IsLow()) {
   7115         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   7116         AdvanceIT();
   7117         return;
   7118       }
   7119       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
   7120       if (!size.IsNarrow() &&
   7121           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7122         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   7123                    (shift.GetType() << 21) | rs.GetCode());
   7124         AdvanceIT();
   7125         return;
   7126       }
   7127     } else {
   7128       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7129       if (cond.IsNotNever() &&
   7130           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7131         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
   7132                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7133                 (rs.GetCode() << 8));
   7134         return;
   7135       }
   7136     }
   7137   }
   7138   if (operand.IsImmediate()) {
   7139     uint32_t imm = operand.GetImmediate();
   7140     if (IsUsingT32()) {
   7141       ImmediateT32 immediate_t32(imm);
   7142       // MOV<c>{<q>} <Rd>, #<imm8> ; T1
   7143       if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
   7144         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
   7145         AdvanceIT();
   7146         return;
   7147       }
   7148       // MOV{<c>}{<q>} <Rd>, #<const> ; T2
   7149       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   7150           (!rd.IsPC() || AllowUnpredictable())) {
   7151         EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
   7152                    (immediate_t32.GetEncodingValue() & 0xff) |
   7153                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7154                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7155         AdvanceIT();
   7156         return;
   7157       }
   7158       // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
   7159       if (!size.IsNarrow() && (imm <= 65535) &&
   7160           (!rd.IsPC() || AllowUnpredictable())) {
   7161         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
   7162                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   7163                    ((imm & 0xf000) << 4));
   7164         AdvanceIT();
   7165         return;
   7166       }
   7167     } else {
   7168       ImmediateA32 immediate_a32(imm);
   7169       // MOV{<c>}{<q>} <Rd>, #<const> ; A1
   7170       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7171         EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
   7172                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   7173         return;
   7174       }
   7175       // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
   7176       if ((imm <= 65535) && cond.IsNotNever() &&
   7177           (!rd.IsPC() || AllowUnpredictable())) {
   7178         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
   7179                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   7180         return;
   7181       }
   7182     }
   7183   }
   7184   Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
   7185 }
   7186 
   7187 void Assembler::movs(Condition cond,
   7188                      EncodingSize size,
   7189                      Register rd,
   7190                      const Operand& operand) {
   7191   VIXL_ASSERT(AllowAssembler());
   7192   CheckIT(cond);
   7193   if (operand.IsImmediateShiftedRegister()) {
   7194     Register rm = operand.GetBaseRegister();
   7195     Shift shift = operand.GetShift();
   7196     uint32_t amount = operand.GetShiftAmount();
   7197     if (IsUsingT32()) {
   7198       // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   7199       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
   7200           shift.IsValidAmount(amount) && rm.IsLow() &&
   7201           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
   7202         uint32_t amount_ = amount % 32;
   7203         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
   7204                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
   7205         AdvanceIT();
   7206         return;
   7207       }
   7208       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
   7209       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   7210           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7211         uint32_t amount_ = amount % 32;
   7212         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   7213                    (operand.GetTypeEncodingValue() << 4) |
   7214                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7215         AdvanceIT();
   7216         return;
   7217       }
   7218     } else {
   7219       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   7220       if (shift.IsValidAmount(amount) && cond.IsNotNever() &&
   7221           (!rd.IsPC() || AllowUnpredictable())) {
   7222         uint32_t amount_ = amount % 32;
   7223         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
   7224                 (rd.GetCode() << 12) | rm.GetCode() |
   7225                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7226         return;
   7227       }
   7228     }
   7229   }
   7230   if (operand.IsRegisterShiftedRegister()) {
   7231     Register rm = operand.GetBaseRegister();
   7232     Shift shift = operand.GetShift();
   7233     Register rs = operand.GetShiftRegister();
   7234     if (IsUsingT32()) {
   7235       // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
   7236       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7237           shift.IsASR() && rs.IsLow()) {
   7238         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
   7239         AdvanceIT();
   7240         return;
   7241       }
   7242       // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
   7243       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7244           shift.IsLSL() && rs.IsLow()) {
   7245         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
   7246         AdvanceIT();
   7247         return;
   7248       }
   7249       // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
   7250       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7251           shift.IsLSR() && rs.IsLow()) {
   7252         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
   7253         AdvanceIT();
   7254         return;
   7255       }
   7256       // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
   7257       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   7258           shift.IsROR() && rs.IsLow()) {
   7259         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   7260         AdvanceIT();
   7261         return;
   7262       }
   7263       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
   7264       if (!size.IsNarrow() &&
   7265           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7266         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   7267                    (shift.GetType() << 21) | rs.GetCode());
   7268         AdvanceIT();
   7269         return;
   7270       }
   7271     } else {
   7272       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7273       if (cond.IsNotNever() &&
   7274           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7275         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
   7276                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7277                 (rs.GetCode() << 8));
   7278         return;
   7279       }
   7280     }
   7281   }
   7282   if (operand.IsImmediate()) {
   7283     uint32_t imm = operand.GetImmediate();
   7284     if (IsUsingT32()) {
   7285       ImmediateT32 immediate_t32(imm);
   7286       // MOVS{<q>} <Rd>, #<imm8> ; T1
   7287       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
   7288         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
   7289         AdvanceIT();
   7290         return;
   7291       }
   7292       // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
   7293       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   7294           (!rd.IsPC() || AllowUnpredictable())) {
   7295         EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
   7296                    (immediate_t32.GetEncodingValue() & 0xff) |
   7297                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7298                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7299         AdvanceIT();
   7300         return;
   7301       }
   7302     } else {
   7303       ImmediateA32 immediate_a32(imm);
   7304       // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
   7305       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7306         EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
   7307                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   7308         return;
   7309       }
   7310     }
   7311   }
   7312   Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
   7313 }
   7314 
   7315 void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
   7316   VIXL_ASSERT(AllowAssembler());
   7317   CheckIT(cond);
   7318   if (operand.IsImmediate()) {
   7319     uint32_t imm = operand.GetImmediate();
   7320     if (IsUsingT32()) {
   7321       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
   7322       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
   7323         EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
   7324                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   7325                    ((imm & 0xf000) << 4));
   7326         AdvanceIT();
   7327         return;
   7328       }
   7329     } else {
   7330       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
   7331       if ((imm <= 65535) && cond.IsNotNever() &&
   7332           (!rd.IsPC() || AllowUnpredictable())) {
   7333         EmitA32(0x03400000U | (cond.GetCondition() << 28) |
   7334                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   7335         return;
   7336       }
   7337     }
   7338   }
   7339   Delegate(kMovt, &Assembler::movt, cond, rd, operand);
   7340 }
   7341 
   7342 void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
   7343   VIXL_ASSERT(AllowAssembler());
   7344   CheckIT(cond);
   7345   if (operand.IsImmediate()) {
   7346     uint32_t imm = operand.GetImmediate();
   7347     if (IsUsingT32()) {
   7348       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
   7349       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
   7350         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
   7351                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
   7352                    ((imm & 0xf000) << 4));
   7353         AdvanceIT();
   7354         return;
   7355       }
   7356     } else {
   7357       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
   7358       if ((imm <= 65535) && cond.IsNotNever() &&
   7359           (!rd.IsPC() || AllowUnpredictable())) {
   7360         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
   7361                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
   7362         return;
   7363       }
   7364     }
   7365   }
   7366   Delegate(kMovw, &Assembler::movw, cond, rd, operand);
   7367 }
   7368 
   7369 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
   7370   VIXL_ASSERT(AllowAssembler());
   7371   CheckIT(cond);
   7372   if (IsUsingT32()) {
   7373     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
   7374     if ((!rd.IsPC() || AllowUnpredictable())) {
   7375       EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
   7376       AdvanceIT();
   7377       return;
   7378     }
   7379   } else {
   7380     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
   7381     if (cond.IsNotNever() && (!rd.IsPC() || AllowUnpredictable())) {
   7382       EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   7383               (spec_reg.GetReg() << 22));
   7384       return;
   7385     }
   7386   }
   7387   Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
   7388 }
   7389 
   7390 void Assembler::msr(Condition cond,
   7391                     MaskedSpecialRegister spec_reg,
   7392                     const Operand& operand) {
   7393   VIXL_ASSERT(AllowAssembler());
   7394   CheckIT(cond);
   7395   if (operand.IsImmediate()) {
   7396     uint32_t imm = operand.GetImmediate();
   7397     if (IsUsingA32()) {
   7398       ImmediateA32 immediate_a32(imm);
   7399       // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
   7400       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7401         EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
   7402                 ((spec_reg.GetReg() & 0xf) << 16) |
   7403                 ((spec_reg.GetReg() & 0x10) << 18) |
   7404                 immediate_a32.GetEncodingValue());
   7405         return;
   7406       }
   7407     }
   7408   }
   7409   if (operand.IsPlainRegister()) {
   7410     Register rn = operand.GetBaseRegister();
   7411     if (IsUsingT32()) {
   7412       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
   7413       if ((!rn.IsPC() || AllowUnpredictable())) {
   7414         EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
   7415                    ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
   7416         AdvanceIT();
   7417         return;
   7418       }
   7419     } else {
   7420       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
   7421       if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   7422         EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
   7423                 ((spec_reg.GetReg() & 0xf) << 16) |
   7424                 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
   7425         return;
   7426       }
   7427     }
   7428   }
   7429   Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
   7430 }
   7431 
   7432 void Assembler::mul(
   7433     Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
   7434   VIXL_ASSERT(AllowAssembler());
   7435   CheckIT(cond);
   7436   if (IsUsingT32()) {
   7437     // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
   7438     if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
   7439         rm.IsLow()) {
   7440       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
   7441       AdvanceIT();
   7442       return;
   7443     }
   7444     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
   7445     if (!size.IsNarrow() &&
   7446         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7447       EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7448                  rm.GetCode());
   7449       AdvanceIT();
   7450       return;
   7451     }
   7452   } else {
   7453     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
   7454     if (cond.IsNotNever() &&
   7455         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7456       EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   7457               rn.GetCode() | (rm.GetCode() << 8));
   7458       return;
   7459     }
   7460   }
   7461   Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
   7462 }
   7463 
   7464 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
   7465   VIXL_ASSERT(AllowAssembler());
   7466   CheckIT(cond);
   7467   if (IsUsingT32()) {
   7468     // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
   7469     if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
   7470       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
   7471       AdvanceIT();
   7472       return;
   7473     }
   7474   } else {
   7475     // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
   7476     if (cond.IsNotNever() &&
   7477         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7478       EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   7479               rn.GetCode() | (rm.GetCode() << 8));
   7480       return;
   7481     }
   7482   }
   7483   Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
   7484 }
   7485 
   7486 void Assembler::mvn(Condition cond,
   7487                     EncodingSize size,
   7488                     Register rd,
   7489                     const Operand& operand) {
   7490   VIXL_ASSERT(AllowAssembler());
   7491   CheckIT(cond);
   7492   if (operand.IsImmediate()) {
   7493     uint32_t imm = operand.GetImmediate();
   7494     if (IsUsingT32()) {
   7495       ImmediateT32 immediate_t32(imm);
   7496       // MVN{<c>}{<q>} <Rd>, #<const> ; T1
   7497       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   7498           (!rd.IsPC() || AllowUnpredictable())) {
   7499         EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
   7500                    (immediate_t32.GetEncodingValue() & 0xff) |
   7501                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7502                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7503         AdvanceIT();
   7504         return;
   7505       }
   7506     } else {
   7507       ImmediateA32 immediate_a32(imm);
   7508       // MVN{<c>}{<q>} <Rd>, #<const> ; A1
   7509       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7510         EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
   7511                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   7512         return;
   7513       }
   7514     }
   7515   }
   7516   if (operand.IsImmediateShiftedRegister()) {
   7517     Register rm = operand.GetBaseRegister();
   7518     if (operand.IsPlainRegister()) {
   7519       if (IsUsingT32()) {
   7520         // MVN<c>{<q>} <Rd>, <Rm> ; T1
   7521         if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
   7522           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
   7523           AdvanceIT();
   7524           return;
   7525         }
   7526       }
   7527     }
   7528     Shift shift = operand.GetShift();
   7529     uint32_t amount = operand.GetShiftAmount();
   7530     if (IsUsingT32()) {
   7531       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   7532       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   7533           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7534         uint32_t amount_ = amount % 32;
   7535         EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   7536                    (operand.GetTypeEncodingValue() << 4) |
   7537                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7538         AdvanceIT();
   7539         return;
   7540       }
   7541     } else {
   7542       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   7543       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7544         uint32_t amount_ = amount % 32;
   7545         EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
   7546                 (rd.GetCode() << 12) | rm.GetCode() |
   7547                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7548         return;
   7549       }
   7550     }
   7551   }
   7552   if (operand.IsRegisterShiftedRegister()) {
   7553     Register rm = operand.GetBaseRegister();
   7554     Shift shift = operand.GetShift();
   7555     Register rs = operand.GetShiftRegister();
   7556     if (IsUsingA32()) {
   7557       // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7558       if (cond.IsNotNever() &&
   7559           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7560         EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
   7561                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7562                 (rs.GetCode() << 8));
   7563         return;
   7564       }
   7565     }
   7566   }
   7567   Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
   7568 }
   7569 
   7570 void Assembler::mvns(Condition cond,
   7571                      EncodingSize size,
   7572                      Register rd,
   7573                      const Operand& operand) {
   7574   VIXL_ASSERT(AllowAssembler());
   7575   CheckIT(cond);
   7576   if (operand.IsImmediate()) {
   7577     uint32_t imm = operand.GetImmediate();
   7578     if (IsUsingT32()) {
   7579       ImmediateT32 immediate_t32(imm);
   7580       // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
   7581       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   7582           (!rd.IsPC() || AllowUnpredictable())) {
   7583         EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
   7584                    (immediate_t32.GetEncodingValue() & 0xff) |
   7585                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7586                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7587         AdvanceIT();
   7588         return;
   7589       }
   7590     } else {
   7591       ImmediateA32 immediate_a32(imm);
   7592       // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
   7593       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7594         EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
   7595                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   7596         return;
   7597       }
   7598     }
   7599   }
   7600   if (operand.IsImmediateShiftedRegister()) {
   7601     Register rm = operand.GetBaseRegister();
   7602     if (operand.IsPlainRegister()) {
   7603       if (IsUsingT32()) {
   7604         // MVNS{<q>} <Rd>, <Rm> ; T1
   7605         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
   7606           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
   7607           AdvanceIT();
   7608           return;
   7609         }
   7610       }
   7611     }
   7612     Shift shift = operand.GetShift();
   7613     uint32_t amount = operand.GetShiftAmount();
   7614     if (IsUsingT32()) {
   7615       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
   7616       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   7617           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7618         uint32_t amount_ = amount % 32;
   7619         EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
   7620                    (operand.GetTypeEncodingValue() << 4) |
   7621                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7622         AdvanceIT();
   7623         return;
   7624       }
   7625     } else {
   7626       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
   7627       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7628         uint32_t amount_ = amount % 32;
   7629         EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
   7630                 (rd.GetCode() << 12) | rm.GetCode() |
   7631                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7632         return;
   7633       }
   7634     }
   7635   }
   7636   if (operand.IsRegisterShiftedRegister()) {
   7637     Register rm = operand.GetBaseRegister();
   7638     Shift shift = operand.GetShift();
   7639     Register rs = operand.GetShiftRegister();
   7640     if (IsUsingA32()) {
   7641       // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
   7642       if (cond.IsNotNever() &&
   7643           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   7644         EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
   7645                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
   7646                 (rs.GetCode() << 8));
   7647         return;
   7648       }
   7649     }
   7650   }
   7651   Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
   7652 }
   7653 
   7654 void Assembler::nop(Condition cond, EncodingSize size) {
   7655   VIXL_ASSERT(AllowAssembler());
   7656   CheckIT(cond);
   7657   if (IsUsingT32()) {
   7658     // NOP{<c>}{<q>} ; T1
   7659     if (!size.IsWide()) {
   7660       EmitT32_16(0xbf00);
   7661       AdvanceIT();
   7662       return;
   7663     }
   7664     // NOP{<c>}.W ; T2
   7665     if (!size.IsNarrow()) {
   7666       EmitT32_32(0xf3af8000U);
   7667       AdvanceIT();
   7668       return;
   7669     }
   7670   } else {
   7671     // NOP{<c>}{<q>} ; A1
   7672     if (cond.IsNotNever()) {
   7673       EmitA32(0x0320f000U | (cond.GetCondition() << 28));
   7674       return;
   7675     }
   7676   }
   7677   Delegate(kNop, &Assembler::nop, cond, size);
   7678 }
   7679 
   7680 void Assembler::orn(Condition cond,
   7681                     Register rd,
   7682                     Register rn,
   7683                     const Operand& operand) {
   7684   VIXL_ASSERT(AllowAssembler());
   7685   CheckIT(cond);
   7686   if (operand.IsImmediate()) {
   7687     uint32_t imm = operand.GetImmediate();
   7688     if (IsUsingT32()) {
   7689       ImmediateT32 immediate_t32(imm);
   7690       // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7691       if (immediate_t32.IsValid() && !rn.Is(pc) &&
   7692           (!rd.IsPC() || AllowUnpredictable())) {
   7693         EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7694                    (immediate_t32.GetEncodingValue() & 0xff) |
   7695                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7696                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7697         AdvanceIT();
   7698         return;
   7699       }
   7700     }
   7701   }
   7702   if (operand.IsImmediateShiftedRegister()) {
   7703     Register rm = operand.GetBaseRegister();
   7704     Shift shift = operand.GetShift();
   7705     uint32_t amount = operand.GetShiftAmount();
   7706     if (IsUsingT32()) {
   7707       // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   7708       if (shift.IsValidAmount(amount) && !rn.Is(pc) &&
   7709           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7710         uint32_t amount_ = amount % 32;
   7711         EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7712                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7713                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7714         AdvanceIT();
   7715         return;
   7716       }
   7717     }
   7718   }
   7719   Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
   7720 }
   7721 
   7722 void Assembler::orns(Condition cond,
   7723                      Register rd,
   7724                      Register rn,
   7725                      const Operand& operand) {
   7726   VIXL_ASSERT(AllowAssembler());
   7727   CheckIT(cond);
   7728   if (operand.IsImmediate()) {
   7729     uint32_t imm = operand.GetImmediate();
   7730     if (IsUsingT32()) {
   7731       ImmediateT32 immediate_t32(imm);
   7732       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7733       if (immediate_t32.IsValid() && !rn.Is(pc) &&
   7734           (!rd.IsPC() || AllowUnpredictable())) {
   7735         EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7736                    (immediate_t32.GetEncodingValue() & 0xff) |
   7737                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7738                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7739         AdvanceIT();
   7740         return;
   7741       }
   7742     }
   7743   }
   7744   if (operand.IsImmediateShiftedRegister()) {
   7745     Register rm = operand.GetBaseRegister();
   7746     Shift shift = operand.GetShift();
   7747     uint32_t amount = operand.GetShiftAmount();
   7748     if (IsUsingT32()) {
   7749       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   7750       if (shift.IsValidAmount(amount) && !rn.Is(pc) &&
   7751           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7752         uint32_t amount_ = amount % 32;
   7753         EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7754                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7755                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7756         AdvanceIT();
   7757         return;
   7758       }
   7759     }
   7760   }
   7761   Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
   7762 }
   7763 
   7764 void Assembler::orr(Condition cond,
   7765                     EncodingSize size,
   7766                     Register rd,
   7767                     Register rn,
   7768                     const Operand& operand) {
   7769   VIXL_ASSERT(AllowAssembler());
   7770   CheckIT(cond);
   7771   if (operand.IsImmediate()) {
   7772     uint32_t imm = operand.GetImmediate();
   7773     if (IsUsingT32()) {
   7774       ImmediateT32 immediate_t32(imm);
   7775       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7776       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) &&
   7777           (!rd.IsPC() || AllowUnpredictable())) {
   7778         EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7779                    (immediate_t32.GetEncodingValue() & 0xff) |
   7780                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7781                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7782         AdvanceIT();
   7783         return;
   7784       }
   7785     } else {
   7786       ImmediateA32 immediate_a32(imm);
   7787       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   7788       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7789         EmitA32(0x03800000U | (cond.GetCondition() << 28) |
   7790                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   7791                 immediate_a32.GetEncodingValue());
   7792         return;
   7793       }
   7794     }
   7795   }
   7796   if (operand.IsImmediateShiftedRegister()) {
   7797     Register rm = operand.GetBaseRegister();
   7798     if (operand.IsPlainRegister()) {
   7799       if (IsUsingT32()) {
   7800         // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   7801         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   7802             rm.IsLow()) {
   7803           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
   7804           AdvanceIT();
   7805           return;
   7806         }
   7807       }
   7808     }
   7809     Shift shift = operand.GetShift();
   7810     uint32_t amount = operand.GetShiftAmount();
   7811     if (IsUsingT32()) {
   7812       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   7813       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) &&
   7814           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7815         uint32_t amount_ = amount % 32;
   7816         EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7817                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7818                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7819         AdvanceIT();
   7820         return;
   7821       }
   7822     } else {
   7823       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   7824       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7825         uint32_t amount_ = amount % 32;
   7826         EmitA32(0x01800000U | (cond.GetCondition() << 28) |
   7827                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7828                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7829         return;
   7830       }
   7831     }
   7832   }
   7833   if (operand.IsRegisterShiftedRegister()) {
   7834     Register rm = operand.GetBaseRegister();
   7835     Shift shift = operand.GetShift();
   7836     Register rs = operand.GetShiftRegister();
   7837     if (IsUsingA32()) {
   7838       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   7839       if (cond.IsNotNever() &&
   7840           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   7841            AllowUnpredictable())) {
   7842         EmitA32(0x01800010U | (cond.GetCondition() << 28) |
   7843                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7844                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   7845         return;
   7846       }
   7847     }
   7848   }
   7849   Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
   7850 }
   7851 
   7852 void Assembler::orrs(Condition cond,
   7853                      EncodingSize size,
   7854                      Register rd,
   7855                      Register rn,
   7856                      const Operand& operand) {
   7857   VIXL_ASSERT(AllowAssembler());
   7858   CheckIT(cond);
   7859   if (operand.IsImmediate()) {
   7860     uint32_t imm = operand.GetImmediate();
   7861     if (IsUsingT32()) {
   7862       ImmediateT32 immediate_t32(imm);
   7863       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   7864       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) &&
   7865           (!rd.IsPC() || AllowUnpredictable())) {
   7866         EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7867                    (immediate_t32.GetEncodingValue() & 0xff) |
   7868                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   7869                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   7870         AdvanceIT();
   7871         return;
   7872       }
   7873     } else {
   7874       ImmediateA32 immediate_a32(imm);
   7875       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   7876       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   7877         EmitA32(0x03900000U | (cond.GetCondition() << 28) |
   7878                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   7879                 immediate_a32.GetEncodingValue());
   7880         return;
   7881       }
   7882     }
   7883   }
   7884   if (operand.IsImmediateShiftedRegister()) {
   7885     Register rm = operand.GetBaseRegister();
   7886     if (operand.IsPlainRegister()) {
   7887       if (IsUsingT32()) {
   7888         // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   7889         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   7890             rm.IsLow()) {
   7891           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
   7892           AdvanceIT();
   7893           return;
   7894         }
   7895       }
   7896     }
   7897     Shift shift = operand.GetShift();
   7898     uint32_t amount = operand.GetShiftAmount();
   7899     if (IsUsingT32()) {
   7900       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   7901       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) &&
   7902           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7903         uint32_t amount_ = amount % 32;
   7904         EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7905                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   7906                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   7907         AdvanceIT();
   7908         return;
   7909       }
   7910     } else {
   7911       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   7912       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   7913         uint32_t amount_ = amount % 32;
   7914         EmitA32(0x01900000U | (cond.GetCondition() << 28) |
   7915                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7916                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   7917         return;
   7918       }
   7919     }
   7920   }
   7921   if (operand.IsRegisterShiftedRegister()) {
   7922     Register rm = operand.GetBaseRegister();
   7923     Shift shift = operand.GetShift();
   7924     Register rs = operand.GetShiftRegister();
   7925     if (IsUsingA32()) {
   7926       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   7927       if (cond.IsNotNever() &&
   7928           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   7929            AllowUnpredictable())) {
   7930         EmitA32(0x01900010U | (cond.GetCondition() << 28) |
   7931                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7932                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   7933         return;
   7934       }
   7935     }
   7936   }
   7937   Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
   7938 }
   7939 
   7940 void Assembler::pkhbt(Condition cond,
   7941                       Register rd,
   7942                       Register rn,
   7943                       const Operand& operand) {
   7944   VIXL_ASSERT(AllowAssembler());
   7945   CheckIT(cond);
   7946   if (operand.IsImmediateShiftedRegister()) {
   7947     Register rm = operand.GetBaseRegister();
   7948     Shift shift = operand.GetShift();
   7949     uint32_t amount = operand.GetShiftAmount();
   7950     if (IsUsingT32()) {
   7951       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
   7952       if (shift.IsLSL() && shift.IsValidAmount(amount) &&
   7953           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7954         EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7955                    rm.GetCode() | ((amount & 0x3) << 6) |
   7956                    ((amount & 0x1c) << 10));
   7957         AdvanceIT();
   7958         return;
   7959       }
   7960     } else {
   7961       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
   7962       if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever() &&
   7963           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7964         EmitA32(0x06800010U | (cond.GetCondition() << 28) |
   7965                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   7966                 (amount << 7));
   7967         return;
   7968       }
   7969     }
   7970   }
   7971   Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
   7972 }
   7973 
   7974 void Assembler::pkhtb(Condition cond,
   7975                       Register rd,
   7976                       Register rn,
   7977                       const Operand& operand) {
   7978   VIXL_ASSERT(AllowAssembler());
   7979   CheckIT(cond);
   7980   if (operand.IsImmediateShiftedRegister()) {
   7981     Register rm = operand.GetBaseRegister();
   7982     Shift shift = operand.GetShift();
   7983     uint32_t amount = operand.GetShiftAmount();
   7984     if (IsUsingT32()) {
   7985       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
   7986       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
   7987           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   7988         uint32_t amount_ = amount % 32;
   7989         EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   7990                    rm.GetCode() | ((amount_ & 0x3) << 6) |
   7991                    ((amount_ & 0x1c) << 10));
   7992         AdvanceIT();
   7993         return;
   7994       }
   7995     } else {
   7996       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
   7997       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
   7998           cond.IsNotNever() &&
   7999           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8000         uint32_t amount_ = amount % 32;
   8001         EmitA32(0x06800050U | (cond.GetCondition() << 28) |
   8002                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   8003                 (amount_ << 7));
   8004         return;
   8005       }
   8006     }
   8007   }
   8008   Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
   8009 }
   8010 
   8011 void Assembler::pld(Condition cond, Location* location) {
   8012   VIXL_ASSERT(AllowAssembler());
   8013   CheckIT(cond);
   8014   Location::Offset offset =
   8015       location->IsBound()
   8016           ? location->GetLocation() -
   8017                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   8018           : 0;
   8019   if (IsUsingT32()) {
   8020     // PLD{<c>}{<q>} <label> ; T1
   8021     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   8022          !location->IsBound())) {
   8023       static class EmitOp : public Location::EmitOperator {
   8024        public:
   8025         EmitOp() : Location::EmitOperator(T32) {}
   8026         virtual uint32_t Encode(uint32_t instr,
   8027                                 Location::Offset pc,
   8028                                 const Location* location) const VIXL_OVERRIDE {
   8029           pc += kT32PcDelta;
   8030           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   8031           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   8032           uint32_t U = (offset >= 0);
   8033           int32_t target = abs(offset) | (U << 12);
   8034           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   8035         }
   8036       } immop;
   8037       EmitT32_32(Link(0xf81ff000U, location, immop, &kT32FarDataInfo));
   8038       AdvanceIT();
   8039       return;
   8040     }
   8041   } else {
   8042     // PLD{<c>}{<q>} <label> ; A1
   8043     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   8044          !location->IsBound())) {
   8045       if (cond.Is(al)) {
   8046         static class EmitOp : public Location::EmitOperator {
   8047          public:
   8048           EmitOp() : Location::EmitOperator(A32) {}
   8049           virtual uint32_t Encode(uint32_t instr,
   8050                                   Location::Offset pc,
   8051                                   const Location* location) const
   8052               VIXL_OVERRIDE {
   8053             pc += kA32PcDelta;
   8054             Location::Offset offset =
   8055                 location->GetLocation() - AlignDown(pc, 4);
   8056             VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   8057             uint32_t U = (offset >= 0);
   8058             int32_t target = abs(offset) | (U << 12);
   8059             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   8060           }
   8061         } immop;
   8062         EmitA32(Link(0xf55ff000U, location, immop, &kA32FarDataInfo));
   8063         return;
   8064       }
   8065     }
   8066   }
   8067   Delegate(kPld, &Assembler::pld, cond, location);
   8068 }
   8069 
   8070 bool Assembler::pld_info(Condition cond,
   8071                          Location* location,
   8072                          const struct ReferenceInfo** info) {
   8073   VIXL_ASSERT(!location->IsBound());
   8074   USE(location);
   8075   USE(cond);
   8076   if (IsUsingT32()) {
   8077     // PLD{<c>}{<q>} <label> ; T1
   8078     if (true) {
   8079       *info = &kT32FarDataInfo;
   8080       return true;
   8081     }
   8082   } else {
   8083     // PLD{<c>}{<q>} <label> ; A1
   8084     if (true) {
   8085       *info = &kA32FarDataInfo;
   8086       return true;
   8087     }
   8088   }
   8089   return false;
   8090 }
   8091 
   8092 void Assembler::pld(Condition cond, const MemOperand& operand) {
   8093   VIXL_ASSERT(AllowAssembler());
   8094   CheckIT(cond);
   8095   if (operand.IsImmediate()) {
   8096     Register rn = operand.GetBaseRegister();
   8097     int32_t offset = operand.GetOffsetImmediate();
   8098     if (IsUsingT32()) {
   8099       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
   8100       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   8101           operand.IsOffset()) {
   8102         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8103         uint32_t offset_ = abs(offset);
   8104         EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
   8105         AdvanceIT();
   8106         return;
   8107       }
   8108     } else {
   8109       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
   8110       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   8111           operand.IsOffset()) {
   8112         if (cond.Is(al)) {
   8113           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8114           uint32_t offset_ = abs(offset);
   8115           EmitA32(0xf55ff000U | offset_ | (sign << 23));
   8116           return;
   8117         }
   8118       }
   8119     }
   8120   }
   8121   if (operand.IsImmediate()) {
   8122     Register rn = operand.GetBaseRegister();
   8123     int32_t offset = operand.GetOffsetImmediate();
   8124     if (IsUsingT32()) {
   8125       // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   8126       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   8127           ((rn.GetCode() & 0xf) != 0xf)) {
   8128         EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   8129         AdvanceIT();
   8130         return;
   8131       }
   8132       // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   8133       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   8134           ((rn.GetCode() & 0xf) != 0xf)) {
   8135         EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   8136         AdvanceIT();
   8137         return;
   8138       }
   8139     } else {
   8140       // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
   8141       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   8142           ((rn.GetCode() & 0xf) != 0xf)) {
   8143         if (cond.Is(al)) {
   8144           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8145           uint32_t offset_ = abs(offset);
   8146           EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   8147           return;
   8148         }
   8149       }
   8150     }
   8151   }
   8152   if (operand.IsShiftedRegister()) {
   8153     Register rn = operand.GetBaseRegister();
   8154     Sign sign = operand.GetSign();
   8155     Register rm = operand.GetOffsetRegister();
   8156     Shift shift = operand.GetShift();
   8157     uint32_t amount = operand.GetShiftAmount();
   8158     if (IsUsingT32()) {
   8159       // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   8160       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   8161           ((rn.GetCode() & 0xf) != 0xf) &&
   8162           (!rm.IsPC() || AllowUnpredictable())) {
   8163         EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8164                    (amount << 4));
   8165         AdvanceIT();
   8166         return;
   8167       }
   8168     } else {
   8169       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   8170       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
   8171           (!rm.IsPC() || AllowUnpredictable())) {
   8172         if (cond.Is(al)) {
   8173           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8174           uint32_t amount_ = amount % 32;
   8175           EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8176                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   8177           return;
   8178         }
   8179       }
   8180       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   8181       if (shift.IsRRX() && operand.IsOffset() &&
   8182           (!rm.IsPC() || AllowUnpredictable())) {
   8183         if (cond.Is(al)) {
   8184           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8185           EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
   8186                   (sign_ << 23));
   8187           return;
   8188         }
   8189       }
   8190     }
   8191   }
   8192   Delegate(kPld, &Assembler::pld, cond, operand);
   8193 }
   8194 
   8195 void Assembler::pldw(Condition cond, const MemOperand& operand) {
   8196   VIXL_ASSERT(AllowAssembler());
   8197   CheckIT(cond);
   8198   if (operand.IsImmediate()) {
   8199     Register rn = operand.GetBaseRegister();
   8200     int32_t offset = operand.GetOffsetImmediate();
   8201     if (IsUsingT32()) {
   8202       // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   8203       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   8204           ((rn.GetCode() & 0xf) != 0xf)) {
   8205         EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   8206         AdvanceIT();
   8207         return;
   8208       }
   8209       // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   8210       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   8211           ((rn.GetCode() & 0xf) != 0xf)) {
   8212         EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   8213         AdvanceIT();
   8214         return;
   8215       }
   8216     } else {
   8217       // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
   8218       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   8219           ((rn.GetCode() & 0xf) != 0xf)) {
   8220         if (cond.Is(al)) {
   8221           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8222           uint32_t offset_ = abs(offset);
   8223           EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   8224           return;
   8225         }
   8226       }
   8227     }
   8228   }
   8229   if (operand.IsShiftedRegister()) {
   8230     Register rn = operand.GetBaseRegister();
   8231     Sign sign = operand.GetSign();
   8232     Register rm = operand.GetOffsetRegister();
   8233     Shift shift = operand.GetShift();
   8234     uint32_t amount = operand.GetShiftAmount();
   8235     if (IsUsingT32()) {
   8236       // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   8237       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   8238           ((rn.GetCode() & 0xf) != 0xf) &&
   8239           (!rm.IsPC() || AllowUnpredictable())) {
   8240         EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8241                    (amount << 4));
   8242         AdvanceIT();
   8243         return;
   8244       }
   8245     } else {
   8246       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   8247       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
   8248           (!rm.IsPC() || AllowUnpredictable())) {
   8249         if (cond.Is(al)) {
   8250           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8251           uint32_t amount_ = amount % 32;
   8252           EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8253                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   8254           return;
   8255         }
   8256       }
   8257       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   8258       if (shift.IsRRX() && operand.IsOffset() &&
   8259           (!rm.IsPC() || AllowUnpredictable())) {
   8260         if (cond.Is(al)) {
   8261           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8262           EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
   8263                   (sign_ << 23));
   8264           return;
   8265         }
   8266       }
   8267     }
   8268   }
   8269   Delegate(kPldw, &Assembler::pldw, cond, operand);
   8270 }
   8271 
   8272 void Assembler::pli(Condition cond, const MemOperand& operand) {
   8273   VIXL_ASSERT(AllowAssembler());
   8274   CheckIT(cond);
   8275   if (operand.IsImmediate()) {
   8276     Register rn = operand.GetBaseRegister();
   8277     int32_t offset = operand.GetOffsetImmediate();
   8278     if (IsUsingT32()) {
   8279       // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
   8280       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
   8281           ((rn.GetCode() & 0xf) != 0xf)) {
   8282         EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
   8283         AdvanceIT();
   8284         return;
   8285       }
   8286       // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
   8287       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
   8288           ((rn.GetCode() & 0xf) != 0xf)) {
   8289         EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
   8290         AdvanceIT();
   8291         return;
   8292       }
   8293     } else {
   8294       // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
   8295       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   8296           ((rn.GetCode() & 0xf) != 0xf)) {
   8297         if (cond.Is(al)) {
   8298           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8299           uint32_t offset_ = abs(offset);
   8300           EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
   8301           return;
   8302         }
   8303       }
   8304     }
   8305   }
   8306   if (operand.IsImmediate()) {
   8307     Register rn = operand.GetBaseRegister();
   8308     int32_t offset = operand.GetOffsetImmediate();
   8309     if (IsUsingT32()) {
   8310       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
   8311       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   8312           operand.IsOffset()) {
   8313         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8314         uint32_t offset_ = abs(offset);
   8315         EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
   8316         AdvanceIT();
   8317         return;
   8318       }
   8319     } else {
   8320       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
   8321       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
   8322           operand.IsOffset()) {
   8323         if (cond.Is(al)) {
   8324           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   8325           uint32_t offset_ = abs(offset);
   8326           EmitA32(0xf45ff000U | offset_ | (sign << 23));
   8327           return;
   8328         }
   8329       }
   8330     }
   8331   }
   8332   if (operand.IsShiftedRegister()) {
   8333     Register rn = operand.GetBaseRegister();
   8334     Sign sign = operand.GetSign();
   8335     Register rm = operand.GetOffsetRegister();
   8336     Shift shift = operand.GetShift();
   8337     uint32_t amount = operand.GetShiftAmount();
   8338     if (IsUsingT32()) {
   8339       // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
   8340       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
   8341           ((rn.GetCode() & 0xf) != 0xf) &&
   8342           (!rm.IsPC() || AllowUnpredictable())) {
   8343         EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8344                    (amount << 4));
   8345         AdvanceIT();
   8346         return;
   8347       }
   8348     } else {
   8349       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
   8350       if (shift.IsRRX() && operand.IsOffset() &&
   8351           (!rm.IsPC() || AllowUnpredictable())) {
   8352         if (cond.Is(al)) {
   8353           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8354           EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
   8355                   (sign_ << 23));
   8356           return;
   8357         }
   8358       }
   8359       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
   8360       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
   8361           (!rm.IsPC() || AllowUnpredictable())) {
   8362         if (cond.Is(al)) {
   8363           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   8364           uint32_t amount_ = amount % 32;
   8365           EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
   8366                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
   8367           return;
   8368         }
   8369       }
   8370     }
   8371   }
   8372   Delegate(kPli, &Assembler::pli, cond, operand);
   8373 }
   8374 
   8375 void Assembler::pli(Condition cond, Location* location) {
   8376   VIXL_ASSERT(AllowAssembler());
   8377   CheckIT(cond);
   8378   Location::Offset offset =
   8379       location->IsBound()
   8380           ? location->GetLocation() -
   8381                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   8382           : 0;
   8383   if (IsUsingT32()) {
   8384     // PLI{<c>}{<q>} <label> ; T3
   8385     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   8386          !location->IsBound())) {
   8387       static class EmitOp : public Location::EmitOperator {
   8388        public:
   8389         EmitOp() : Location::EmitOperator(T32) {}
   8390         virtual uint32_t Encode(uint32_t instr,
   8391                                 Location::Offset pc,
   8392                                 const Location* location) const VIXL_OVERRIDE {
   8393           pc += kT32PcDelta;
   8394           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   8395           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   8396           uint32_t U = (offset >= 0);
   8397           int32_t target = abs(offset) | (U << 12);
   8398           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   8399         }
   8400       } immop;
   8401       EmitT32_32(Link(0xf91ff000U, location, immop, &kT32FarDataInfo));
   8402       AdvanceIT();
   8403       return;
   8404     }
   8405   } else {
   8406     // PLI{<c>}{<q>} <label> ; A1
   8407     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
   8408          !location->IsBound())) {
   8409       if (cond.Is(al)) {
   8410         static class EmitOp : public Location::EmitOperator {
   8411          public:
   8412           EmitOp() : Location::EmitOperator(A32) {}
   8413           virtual uint32_t Encode(uint32_t instr,
   8414                                   Location::Offset pc,
   8415                                   const Location* location) const
   8416               VIXL_OVERRIDE {
   8417             pc += kA32PcDelta;
   8418             Location::Offset offset =
   8419                 location->GetLocation() - AlignDown(pc, 4);
   8420             VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
   8421             uint32_t U = (offset >= 0);
   8422             int32_t target = abs(offset) | (U << 12);
   8423             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
   8424           }
   8425         } immop;
   8426         EmitA32(Link(0xf45ff000U, location, immop, &kA32FarDataInfo));
   8427         return;
   8428       }
   8429     }
   8430   }
   8431   Delegate(kPli, &Assembler::pli, cond, location);
   8432 }
   8433 
   8434 bool Assembler::pli_info(Condition cond,
   8435                          Location* location,
   8436                          const struct ReferenceInfo** info) {
   8437   VIXL_ASSERT(!location->IsBound());
   8438   USE(location);
   8439   USE(cond);
   8440   if (IsUsingT32()) {
   8441     // PLI{<c>}{<q>} <label> ; T3
   8442     if (true) {
   8443       *info = &kT32FarDataInfo;
   8444       return true;
   8445     }
   8446   } else {
   8447     // PLI{<c>}{<q>} <label> ; A1
   8448     if (true) {
   8449       *info = &kA32FarDataInfo;
   8450       return true;
   8451     }
   8452   }
   8453   return false;
   8454 }
   8455 
   8456 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
   8457   VIXL_ASSERT(AllowAssembler());
   8458   CheckIT(cond);
   8459   if (IsUsingT32()) {
   8460     // POP{<c>}{<q>} <registers> ; T1
   8461     if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) {
   8462       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
   8463                  GetRegisterListEncoding(registers, 0, 8));
   8464       AdvanceIT();
   8465       return;
   8466     }
   8467     // POP{<c>}{<q>} <registers> ; T2
   8468     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
   8469       EmitT32_32(0xe8bd0000U |
   8470                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
   8471                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   8472                  GetRegisterListEncoding(registers, 0, 13));
   8473       AdvanceIT();
   8474       return;
   8475     }
   8476   } else {
   8477     // POP{<c>}{<q>} <registers> ; A1
   8478     if (cond.IsNotNever()) {
   8479       EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
   8480               GetRegisterListEncoding(registers, 0, 16));
   8481       return;
   8482     }
   8483   }
   8484   Delegate(kPop, &Assembler::pop, cond, size, registers);
   8485 }
   8486 
   8487 void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
   8488   VIXL_ASSERT(AllowAssembler());
   8489   CheckIT(cond);
   8490   if (IsUsingT32()) {
   8491     // POP{<c>}{<q>} <single_register_list> ; T4
   8492     if (!size.IsNarrow() && ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
   8493                              AllowUnpredictable())) {
   8494       EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
   8495       AdvanceIT();
   8496       return;
   8497     }
   8498   } else {
   8499     // POP{<c>}{<q>} <single_register_list> ; A1
   8500     if (cond.IsNotNever()) {
   8501       EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
   8502       return;
   8503     }
   8504   }
   8505   Delegate(kPop, &Assembler::pop, cond, size, rt);
   8506 }
   8507 
   8508 void Assembler::push(Condition cond,
   8509                      EncodingSize size,
   8510                      RegisterList registers) {
   8511   VIXL_ASSERT(AllowAssembler());
   8512   CheckIT(cond);
   8513   if (IsUsingT32()) {
   8514     // PUSH{<c>}{<q>} <registers> ; T1
   8515     if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) {
   8516       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
   8517                  GetRegisterListEncoding(registers, 0, 8));
   8518       AdvanceIT();
   8519       return;
   8520     }
   8521     // PUSH{<c>}{<q>} <registers> ; T1
   8522     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
   8523       EmitT32_32(0xe92d0000U |
   8524                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   8525                  GetRegisterListEncoding(registers, 0, 13));
   8526       AdvanceIT();
   8527       return;
   8528     }
   8529   } else {
   8530     // PUSH{<c>}{<q>} <registers> ; A1
   8531     if (cond.IsNotNever()) {
   8532       EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
   8533               GetRegisterListEncoding(registers, 0, 16));
   8534       return;
   8535     }
   8536   }
   8537   Delegate(kPush, &Assembler::push, cond, size, registers);
   8538 }
   8539 
   8540 void Assembler::push(Condition cond, EncodingSize size, Register rt) {
   8541   VIXL_ASSERT(AllowAssembler());
   8542   CheckIT(cond);
   8543   if (IsUsingT32()) {
   8544     // PUSH{<c>}{<q>} <single_register_list> ; T4
   8545     if (!size.IsNarrow() && (!rt.IsPC() || AllowUnpredictable())) {
   8546       EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
   8547       AdvanceIT();
   8548       return;
   8549     }
   8550   } else {
   8551     // PUSH{<c>}{<q>} <single_register_list> ; A1
   8552     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   8553       EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
   8554       return;
   8555     }
   8556   }
   8557   Delegate(kPush, &Assembler::push, cond, size, rt);
   8558 }
   8559 
   8560 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
   8561   VIXL_ASSERT(AllowAssembler());
   8562   CheckIT(cond);
   8563   if (IsUsingT32()) {
   8564     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   8565     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8566       EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
   8567                  (rn.GetCode() << 16));
   8568       AdvanceIT();
   8569       return;
   8570     }
   8571   } else {
   8572     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   8573     if (cond.IsNotNever() &&
   8574         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8575       EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8576               rm.GetCode() | (rn.GetCode() << 16));
   8577       return;
   8578     }
   8579   }
   8580   Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
   8581 }
   8582 
   8583 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
   8584   VIXL_ASSERT(AllowAssembler());
   8585   CheckIT(cond);
   8586   if (IsUsingT32()) {
   8587     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8588     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8589       EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8590                  rm.GetCode());
   8591       AdvanceIT();
   8592       return;
   8593     }
   8594   } else {
   8595     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8596     if (cond.IsNotNever() &&
   8597         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8598       EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8599               (rn.GetCode() << 16) | rm.GetCode());
   8600       return;
   8601     }
   8602   }
   8603   Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
   8604 }
   8605 
   8606 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
   8607   VIXL_ASSERT(AllowAssembler());
   8608   CheckIT(cond);
   8609   if (IsUsingT32()) {
   8610     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8611     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8612       EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8613                  rm.GetCode());
   8614       AdvanceIT();
   8615       return;
   8616     }
   8617   } else {
   8618     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8619     if (cond.IsNotNever() &&
   8620         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8621       EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8622               (rn.GetCode() << 16) | rm.GetCode());
   8623       return;
   8624     }
   8625   }
   8626   Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
   8627 }
   8628 
   8629 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
   8630   VIXL_ASSERT(AllowAssembler());
   8631   CheckIT(cond);
   8632   if (IsUsingT32()) {
   8633     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8634     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8635       EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8636                  rm.GetCode());
   8637       AdvanceIT();
   8638       return;
   8639     }
   8640   } else {
   8641     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8642     if (cond.IsNotNever() &&
   8643         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8644       EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8645               (rn.GetCode() << 16) | rm.GetCode());
   8646       return;
   8647     }
   8648   }
   8649   Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
   8650 }
   8651 
   8652 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
   8653   VIXL_ASSERT(AllowAssembler());
   8654   CheckIT(cond);
   8655   if (IsUsingT32()) {
   8656     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   8657     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8658       EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
   8659                  (rn.GetCode() << 16));
   8660       AdvanceIT();
   8661       return;
   8662     }
   8663   } else {
   8664     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   8665     if (cond.IsNotNever() &&
   8666         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8667       EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8668               rm.GetCode() | (rn.GetCode() << 16));
   8669       return;
   8670     }
   8671   }
   8672   Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
   8673 }
   8674 
   8675 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
   8676   VIXL_ASSERT(AllowAssembler());
   8677   CheckIT(cond);
   8678   if (IsUsingT32()) {
   8679     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   8680     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8681       EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
   8682                  (rn.GetCode() << 16));
   8683       AdvanceIT();
   8684       return;
   8685     }
   8686   } else {
   8687     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   8688     if (cond.IsNotNever() &&
   8689         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8690       EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8691               rm.GetCode() | (rn.GetCode() << 16));
   8692       return;
   8693     }
   8694   }
   8695   Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
   8696 }
   8697 
   8698 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
   8699   VIXL_ASSERT(AllowAssembler());
   8700   CheckIT(cond);
   8701   if (IsUsingT32()) {
   8702     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8703     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8704       EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8705                  rm.GetCode());
   8706       AdvanceIT();
   8707       return;
   8708     }
   8709   } else {
   8710     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8711     if (cond.IsNotNever() &&
   8712         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8713       EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8714               (rn.GetCode() << 16) | rm.GetCode());
   8715       return;
   8716     }
   8717   }
   8718   Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
   8719 }
   8720 
   8721 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
   8722   VIXL_ASSERT(AllowAssembler());
   8723   CheckIT(cond);
   8724   if (IsUsingT32()) {
   8725     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
   8726     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8727       EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
   8728                  (rn.GetCode() << 16));
   8729       AdvanceIT();
   8730       return;
   8731     }
   8732   } else {
   8733     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
   8734     if (cond.IsNotNever() &&
   8735         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8736       EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8737               rm.GetCode() | (rn.GetCode() << 16));
   8738       return;
   8739     }
   8740   }
   8741   Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
   8742 }
   8743 
   8744 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
   8745   VIXL_ASSERT(AllowAssembler());
   8746   CheckIT(cond);
   8747   if (IsUsingT32()) {
   8748     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8749     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8750       EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8751                  rm.GetCode());
   8752       AdvanceIT();
   8753       return;
   8754     }
   8755   } else {
   8756     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8757     if (cond.IsNotNever() &&
   8758         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8759       EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8760               (rn.GetCode() << 16) | rm.GetCode());
   8761       return;
   8762     }
   8763   }
   8764   Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
   8765 }
   8766 
   8767 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
   8768   VIXL_ASSERT(AllowAssembler());
   8769   CheckIT(cond);
   8770   if (IsUsingT32()) {
   8771     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   8772     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8773       EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   8774                  rm.GetCode());
   8775       AdvanceIT();
   8776       return;
   8777     }
   8778   } else {
   8779     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   8780     if (cond.IsNotNever() &&
   8781         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8782       EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8783               (rn.GetCode() << 16) | rm.GetCode());
   8784       return;
   8785     }
   8786   }
   8787   Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
   8788 }
   8789 
   8790 void Assembler::rbit(Condition cond, Register rd, Register rm) {
   8791   VIXL_ASSERT(AllowAssembler());
   8792   CheckIT(cond);
   8793   if (IsUsingT32()) {
   8794     // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
   8795     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8796       EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
   8797                  (rm.GetCode() << 16));
   8798       AdvanceIT();
   8799       return;
   8800     }
   8801   } else {
   8802     // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
   8803     if (cond.IsNotNever() &&
   8804         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8805       EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8806               rm.GetCode());
   8807       return;
   8808     }
   8809   }
   8810   Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
   8811 }
   8812 
   8813 void Assembler::rev(Condition cond,
   8814                     EncodingSize size,
   8815                     Register rd,
   8816                     Register rm) {
   8817   VIXL_ASSERT(AllowAssembler());
   8818   CheckIT(cond);
   8819   if (IsUsingT32()) {
   8820     // REV{<c>}{<q>} <Rd>, <Rm> ; T1
   8821     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8822       EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
   8823       AdvanceIT();
   8824       return;
   8825     }
   8826     // REV{<c>}{<q>} <Rd>, <Rm> ; T2
   8827     if (!size.IsNarrow() &&
   8828         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8829       EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
   8830                  (rm.GetCode() << 16));
   8831       AdvanceIT();
   8832       return;
   8833     }
   8834   } else {
   8835     // REV{<c>}{<q>} <Rd>, <Rm> ; A1
   8836     if (cond.IsNotNever() &&
   8837         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8838       EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8839               rm.GetCode());
   8840       return;
   8841     }
   8842   }
   8843   Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
   8844 }
   8845 
   8846 void Assembler::rev16(Condition cond,
   8847                       EncodingSize size,
   8848                       Register rd,
   8849                       Register rm) {
   8850   VIXL_ASSERT(AllowAssembler());
   8851   CheckIT(cond);
   8852   if (IsUsingT32()) {
   8853     // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
   8854     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8855       EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
   8856       AdvanceIT();
   8857       return;
   8858     }
   8859     // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
   8860     if (!size.IsNarrow() &&
   8861         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8862       EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
   8863                  (rm.GetCode() << 16));
   8864       AdvanceIT();
   8865       return;
   8866     }
   8867   } else {
   8868     // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
   8869     if (cond.IsNotNever() &&
   8870         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8871       EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8872               rm.GetCode());
   8873       return;
   8874     }
   8875   }
   8876   Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
   8877 }
   8878 
   8879 void Assembler::revsh(Condition cond,
   8880                       EncodingSize size,
   8881                       Register rd,
   8882                       Register rm) {
   8883   VIXL_ASSERT(AllowAssembler());
   8884   CheckIT(cond);
   8885   if (IsUsingT32()) {
   8886     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
   8887     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   8888       EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
   8889       AdvanceIT();
   8890       return;
   8891     }
   8892     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
   8893     if (!size.IsNarrow() &&
   8894         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8895       EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
   8896                  (rm.GetCode() << 16));
   8897       AdvanceIT();
   8898       return;
   8899     }
   8900   } else {
   8901     // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
   8902     if (cond.IsNotNever() &&
   8903         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8904       EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   8905               rm.GetCode());
   8906       return;
   8907     }
   8908   }
   8909   Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
   8910 }
   8911 
   8912 void Assembler::ror(Condition cond,
   8913                     EncodingSize size,
   8914                     Register rd,
   8915                     Register rm,
   8916                     const Operand& operand) {
   8917   VIXL_ASSERT(AllowAssembler());
   8918   CheckIT(cond);
   8919   if (operand.IsImmediate()) {
   8920     uint32_t imm = operand.GetImmediate();
   8921     if (IsUsingT32()) {
   8922       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   8923       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
   8924           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8925         EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
   8926                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   8927         AdvanceIT();
   8928         return;
   8929       }
   8930     } else {
   8931       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   8932       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   8933         EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
   8934                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   8935         return;
   8936       }
   8937     }
   8938   }
   8939   if (operand.IsPlainRegister()) {
   8940     Register rs = operand.GetBaseRegister();
   8941     if (IsUsingT32()) {
   8942       // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   8943       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   8944           rs.IsLow()) {
   8945         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   8946         AdvanceIT();
   8947         return;
   8948       }
   8949       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   8950       if (!size.IsNarrow() &&
   8951           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   8952         EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   8953                    rs.GetCode());
   8954         AdvanceIT();
   8955         return;
   8956       }
   8957     } else {
   8958       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   8959       if (cond.IsNotNever() &&
   8960           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   8961         EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
   8962                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   8963         return;
   8964       }
   8965     }
   8966   }
   8967   Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
   8968 }
   8969 
   8970 void Assembler::rors(Condition cond,
   8971                      EncodingSize size,
   8972                      Register rd,
   8973                      Register rm,
   8974                      const Operand& operand) {
   8975   VIXL_ASSERT(AllowAssembler());
   8976   CheckIT(cond);
   8977   if (operand.IsImmediate()) {
   8978     uint32_t imm = operand.GetImmediate();
   8979     if (IsUsingT32()) {
   8980       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
   8981       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
   8982           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   8983         EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
   8984                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
   8985         AdvanceIT();
   8986         return;
   8987       }
   8988     } else {
   8989       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
   8990       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
   8991         EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
   8992                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
   8993         return;
   8994       }
   8995     }
   8996   }
   8997   if (operand.IsPlainRegister()) {
   8998     Register rs = operand.GetBaseRegister();
   8999     if (IsUsingT32()) {
   9000       // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
   9001       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
   9002           rs.IsLow()) {
   9003         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
   9004         AdvanceIT();
   9005         return;
   9006       }
   9007       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
   9008       if (!size.IsNarrow() &&
   9009           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   9010         EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
   9011                    rs.GetCode());
   9012         AdvanceIT();
   9013         return;
   9014       }
   9015     } else {
   9016       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
   9017       if (cond.IsNotNever() &&
   9018           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   9019         EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
   9020                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
   9021         return;
   9022       }
   9023     }
   9024   }
   9025   Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
   9026 }
   9027 
   9028 void Assembler::rrx(Condition cond, Register rd, Register rm) {
   9029   VIXL_ASSERT(AllowAssembler());
   9030   CheckIT(cond);
   9031   if (IsUsingT32()) {
   9032     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
   9033     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9034       EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
   9035       AdvanceIT();
   9036       return;
   9037     }
   9038   } else {
   9039     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
   9040     if (cond.IsNotNever()) {
   9041       EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9042               rm.GetCode());
   9043       return;
   9044     }
   9045   }
   9046   Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
   9047 }
   9048 
   9049 void Assembler::rrxs(Condition cond, Register rd, Register rm) {
   9050   VIXL_ASSERT(AllowAssembler());
   9051   CheckIT(cond);
   9052   if (IsUsingT32()) {
   9053     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
   9054     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9055       EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
   9056       AdvanceIT();
   9057       return;
   9058     }
   9059   } else {
   9060     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
   9061     if (cond.IsNotNever()) {
   9062       EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9063               rm.GetCode());
   9064       return;
   9065     }
   9066   }
   9067   Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
   9068 }
   9069 
   9070 void Assembler::rsb(Condition cond,
   9071                     EncodingSize size,
   9072                     Register rd,
   9073                     Register rn,
   9074                     const Operand& operand) {
   9075   VIXL_ASSERT(AllowAssembler());
   9076   CheckIT(cond);
   9077   if (operand.IsImmediate()) {
   9078     uint32_t imm = operand.GetImmediate();
   9079     if (IsUsingT32()) {
   9080       ImmediateT32 immediate_t32(imm);
   9081       // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
   9082       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   9083           (imm == 0)) {
   9084         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
   9085         AdvanceIT();
   9086         return;
   9087       }
   9088       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
   9089       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   9090           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   9091         EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9092                    (immediate_t32.GetEncodingValue() & 0xff) |
   9093                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   9094                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   9095         AdvanceIT();
   9096         return;
   9097       }
   9098     } else {
   9099       ImmediateA32 immediate_a32(imm);
   9100       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9101       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9102         EmitA32(0x02600000U | (cond.GetCondition() << 28) |
   9103                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9104                 immediate_a32.GetEncodingValue());
   9105         return;
   9106       }
   9107     }
   9108   }
   9109   if (operand.IsImmediateShiftedRegister()) {
   9110     Register rm = operand.GetBaseRegister();
   9111     Shift shift = operand.GetShift();
   9112     uint32_t amount = operand.GetShiftAmount();
   9113     if (IsUsingT32()) {
   9114       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   9115       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   9116           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9117         uint32_t amount_ = amount % 32;
   9118         EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9119                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   9120                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   9121         AdvanceIT();
   9122         return;
   9123       }
   9124     } else {
   9125       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9126       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9127         uint32_t amount_ = amount % 32;
   9128         EmitA32(0x00600000U | (cond.GetCondition() << 28) |
   9129                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9130                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9131         return;
   9132       }
   9133     }
   9134   }
   9135   if (operand.IsRegisterShiftedRegister()) {
   9136     Register rm = operand.GetBaseRegister();
   9137     Shift shift = operand.GetShift();
   9138     Register rs = operand.GetShiftRegister();
   9139     if (IsUsingA32()) {
   9140       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9141       if (cond.IsNotNever() &&
   9142           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9143            AllowUnpredictable())) {
   9144         EmitA32(0x00600010U | (cond.GetCondition() << 28) |
   9145                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9146                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9147         return;
   9148       }
   9149     }
   9150   }
   9151   Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
   9152 }
   9153 
   9154 void Assembler::rsbs(Condition cond,
   9155                      EncodingSize size,
   9156                      Register rd,
   9157                      Register rn,
   9158                      const Operand& operand) {
   9159   VIXL_ASSERT(AllowAssembler());
   9160   CheckIT(cond);
   9161   if (operand.IsImmediate()) {
   9162     uint32_t imm = operand.GetImmediate();
   9163     if (IsUsingT32()) {
   9164       ImmediateT32 immediate_t32(imm);
   9165       // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
   9166       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   9167           (imm == 0)) {
   9168         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
   9169         AdvanceIT();
   9170         return;
   9171       }
   9172       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
   9173       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   9174           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   9175         EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9176                    (immediate_t32.GetEncodingValue() & 0xff) |
   9177                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   9178                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   9179         AdvanceIT();
   9180         return;
   9181       }
   9182     } else {
   9183       ImmediateA32 immediate_a32(imm);
   9184       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9185       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9186         EmitA32(0x02700000U | (cond.GetCondition() << 28) |
   9187                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9188                 immediate_a32.GetEncodingValue());
   9189         return;
   9190       }
   9191     }
   9192   }
   9193   if (operand.IsImmediateShiftedRegister()) {
   9194     Register rm = operand.GetBaseRegister();
   9195     Shift shift = operand.GetShift();
   9196     uint32_t amount = operand.GetShiftAmount();
   9197     if (IsUsingT32()) {
   9198       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
   9199       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   9200           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9201         uint32_t amount_ = amount % 32;
   9202         EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9203                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   9204                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   9205         AdvanceIT();
   9206         return;
   9207       }
   9208     } else {
   9209       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9210       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9211         uint32_t amount_ = amount % 32;
   9212         EmitA32(0x00700000U | (cond.GetCondition() << 28) |
   9213                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9214                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9215         return;
   9216       }
   9217     }
   9218   }
   9219   if (operand.IsRegisterShiftedRegister()) {
   9220     Register rm = operand.GetBaseRegister();
   9221     Shift shift = operand.GetShift();
   9222     Register rs = operand.GetShiftRegister();
   9223     if (IsUsingA32()) {
   9224       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9225       if (cond.IsNotNever() &&
   9226           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9227            AllowUnpredictable())) {
   9228         EmitA32(0x00700010U | (cond.GetCondition() << 28) |
   9229                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9230                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9231         return;
   9232       }
   9233     }
   9234   }
   9235   Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
   9236 }
   9237 
   9238 void Assembler::rsc(Condition cond,
   9239                     Register rd,
   9240                     Register rn,
   9241                     const Operand& operand) {
   9242   VIXL_ASSERT(AllowAssembler());
   9243   CheckIT(cond);
   9244   if (operand.IsImmediate()) {
   9245     uint32_t imm = operand.GetImmediate();
   9246     if (IsUsingA32()) {
   9247       ImmediateA32 immediate_a32(imm);
   9248       // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9249       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9250         EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
   9251                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9252                 immediate_a32.GetEncodingValue());
   9253         return;
   9254       }
   9255     }
   9256   }
   9257   if (operand.IsImmediateShiftedRegister()) {
   9258     Register rm = operand.GetBaseRegister();
   9259     Shift shift = operand.GetShift();
   9260     uint32_t amount = operand.GetShiftAmount();
   9261     if (IsUsingA32()) {
   9262       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9263       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9264         uint32_t amount_ = amount % 32;
   9265         EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
   9266                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9267                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9268         return;
   9269       }
   9270     }
   9271   }
   9272   if (operand.IsRegisterShiftedRegister()) {
   9273     Register rm = operand.GetBaseRegister();
   9274     Shift shift = operand.GetShift();
   9275     Register rs = operand.GetShiftRegister();
   9276     if (IsUsingA32()) {
   9277       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9278       if (cond.IsNotNever() &&
   9279           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9280            AllowUnpredictable())) {
   9281         EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
   9282                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9283                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9284         return;
   9285       }
   9286     }
   9287   }
   9288   Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
   9289 }
   9290 
   9291 void Assembler::rscs(Condition cond,
   9292                      Register rd,
   9293                      Register rn,
   9294                      const Operand& operand) {
   9295   VIXL_ASSERT(AllowAssembler());
   9296   CheckIT(cond);
   9297   if (operand.IsImmediate()) {
   9298     uint32_t imm = operand.GetImmediate();
   9299     if (IsUsingA32()) {
   9300       ImmediateA32 immediate_a32(imm);
   9301       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9302       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9303         EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
   9304                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9305                 immediate_a32.GetEncodingValue());
   9306         return;
   9307       }
   9308     }
   9309   }
   9310   if (operand.IsImmediateShiftedRegister()) {
   9311     Register rm = operand.GetBaseRegister();
   9312     Shift shift = operand.GetShift();
   9313     uint32_t amount = operand.GetShiftAmount();
   9314     if (IsUsingA32()) {
   9315       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9316       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9317         uint32_t amount_ = amount % 32;
   9318         EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
   9319                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9320                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9321         return;
   9322       }
   9323     }
   9324   }
   9325   if (operand.IsRegisterShiftedRegister()) {
   9326     Register rm = operand.GetBaseRegister();
   9327     Shift shift = operand.GetShift();
   9328     Register rs = operand.GetShiftRegister();
   9329     if (IsUsingA32()) {
   9330       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9331       if (cond.IsNotNever() &&
   9332           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9333            AllowUnpredictable())) {
   9334         EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
   9335                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9336                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9337         return;
   9338       }
   9339     }
   9340   }
   9341   Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
   9342 }
   9343 
   9344 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
   9345   VIXL_ASSERT(AllowAssembler());
   9346   CheckIT(cond);
   9347   if (IsUsingT32()) {
   9348     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9349     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9350       EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9351                  rm.GetCode());
   9352       AdvanceIT();
   9353       return;
   9354     }
   9355   } else {
   9356     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9357     if (cond.IsNotNever() &&
   9358         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9359       EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9360               (rn.GetCode() << 16) | rm.GetCode());
   9361       return;
   9362     }
   9363   }
   9364   Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
   9365 }
   9366 
   9367 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
   9368   VIXL_ASSERT(AllowAssembler());
   9369   CheckIT(cond);
   9370   if (IsUsingT32()) {
   9371     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9372     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9373       EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9374                  rm.GetCode());
   9375       AdvanceIT();
   9376       return;
   9377     }
   9378   } else {
   9379     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9380     if (cond.IsNotNever() &&
   9381         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9382       EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9383               (rn.GetCode() << 16) | rm.GetCode());
   9384       return;
   9385     }
   9386   }
   9387   Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
   9388 }
   9389 
   9390 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
   9391   VIXL_ASSERT(AllowAssembler());
   9392   CheckIT(cond);
   9393   if (IsUsingT32()) {
   9394     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9395     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9396       EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9397                  rm.GetCode());
   9398       AdvanceIT();
   9399       return;
   9400     }
   9401   } else {
   9402     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9403     if (cond.IsNotNever() &&
   9404         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9405       EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9406               (rn.GetCode() << 16) | rm.GetCode());
   9407       return;
   9408     }
   9409   }
   9410   Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
   9411 }
   9412 
   9413 void Assembler::sbc(Condition cond,
   9414                     EncodingSize size,
   9415                     Register rd,
   9416                     Register rn,
   9417                     const Operand& operand) {
   9418   VIXL_ASSERT(AllowAssembler());
   9419   CheckIT(cond);
   9420   if (operand.IsImmediate()) {
   9421     uint32_t imm = operand.GetImmediate();
   9422     if (IsUsingT32()) {
   9423       ImmediateT32 immediate_t32(imm);
   9424       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   9425       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   9426           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   9427         EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9428                    (immediate_t32.GetEncodingValue() & 0xff) |
   9429                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   9430                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   9431         AdvanceIT();
   9432         return;
   9433       }
   9434     } else {
   9435       ImmediateA32 immediate_a32(imm);
   9436       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9437       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9438         EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
   9439                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9440                 immediate_a32.GetEncodingValue());
   9441         return;
   9442       }
   9443     }
   9444   }
   9445   if (operand.IsImmediateShiftedRegister()) {
   9446     Register rm = operand.GetBaseRegister();
   9447     if (operand.IsPlainRegister()) {
   9448       if (IsUsingT32()) {
   9449         // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   9450         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   9451             rm.IsLow()) {
   9452           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
   9453           AdvanceIT();
   9454           return;
   9455         }
   9456       }
   9457     }
   9458     Shift shift = operand.GetShift();
   9459     uint32_t amount = operand.GetShiftAmount();
   9460     if (IsUsingT32()) {
   9461       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   9462       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   9463           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9464         uint32_t amount_ = amount % 32;
   9465         EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9466                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   9467                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   9468         AdvanceIT();
   9469         return;
   9470       }
   9471     } else {
   9472       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9473       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9474         uint32_t amount_ = amount % 32;
   9475         EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
   9476                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9477                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9478         return;
   9479       }
   9480     }
   9481   }
   9482   if (operand.IsRegisterShiftedRegister()) {
   9483     Register rm = operand.GetBaseRegister();
   9484     Shift shift = operand.GetShift();
   9485     Register rs = operand.GetShiftRegister();
   9486     if (IsUsingA32()) {
   9487       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9488       if (cond.IsNotNever() &&
   9489           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9490            AllowUnpredictable())) {
   9491         EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
   9492                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9493                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9494         return;
   9495       }
   9496     }
   9497   }
   9498   Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
   9499 }
   9500 
   9501 void Assembler::sbcs(Condition cond,
   9502                      EncodingSize size,
   9503                      Register rd,
   9504                      Register rn,
   9505                      const Operand& operand) {
   9506   VIXL_ASSERT(AllowAssembler());
   9507   CheckIT(cond);
   9508   if (operand.IsImmediate()) {
   9509     uint32_t imm = operand.GetImmediate();
   9510     if (IsUsingT32()) {
   9511       ImmediateT32 immediate_t32(imm);
   9512       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
   9513       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   9514           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   9515         EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9516                    (immediate_t32.GetEncodingValue() & 0xff) |
   9517                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   9518                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   9519         AdvanceIT();
   9520         return;
   9521       }
   9522     } else {
   9523       ImmediateA32 immediate_a32(imm);
   9524       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   9525       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   9526         EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
   9527                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   9528                 immediate_a32.GetEncodingValue());
   9529         return;
   9530       }
   9531     }
   9532   }
   9533   if (operand.IsImmediateShiftedRegister()) {
   9534     Register rm = operand.GetBaseRegister();
   9535     if (operand.IsPlainRegister()) {
   9536       if (IsUsingT32()) {
   9537         // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
   9538         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   9539             rm.IsLow()) {
   9540           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
   9541           AdvanceIT();
   9542           return;
   9543         }
   9544       }
   9545     }
   9546     Shift shift = operand.GetShift();
   9547     uint32_t amount = operand.GetShiftAmount();
   9548     if (IsUsingT32()) {
   9549       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   9550       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   9551           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9552         uint32_t amount_ = amount % 32;
   9553         EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9554                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   9555                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   9556         AdvanceIT();
   9557         return;
   9558       }
   9559     } else {
   9560       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   9561       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   9562         uint32_t amount_ = amount % 32;
   9563         EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
   9564                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9565                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   9566         return;
   9567       }
   9568     }
   9569   }
   9570   if (operand.IsRegisterShiftedRegister()) {
   9571     Register rm = operand.GetBaseRegister();
   9572     Shift shift = operand.GetShift();
   9573     Register rs = operand.GetShiftRegister();
   9574     if (IsUsingA32()) {
   9575       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   9576       if (cond.IsNotNever() &&
   9577           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   9578            AllowUnpredictable())) {
   9579         EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
   9580                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   9581                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   9582         return;
   9583       }
   9584     }
   9585   }
   9586   Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
   9587 }
   9588 
   9589 void Assembler::sbfx(
   9590     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
   9591   VIXL_ASSERT(AllowAssembler());
   9592   CheckIT(cond);
   9593   if (IsUsingT32()) {
   9594     // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
   9595     if ((lsb <= 31) &&
   9596         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
   9597          AllowUnpredictable())) {
   9598       uint32_t widthm1 = width - 1;
   9599       EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9600                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
   9601       AdvanceIT();
   9602       return;
   9603     }
   9604   } else {
   9605     // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
   9606     if ((lsb <= 31) && cond.IsNotNever() &&
   9607         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
   9608          AllowUnpredictable())) {
   9609       uint32_t widthm1 = width - 1;
   9610       EmitA32(0x07a00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9611               rn.GetCode() | (lsb << 7) | (widthm1 << 16));
   9612       return;
   9613     }
   9614   }
   9615   Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, width);
   9616 }
   9617 
   9618 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
   9619   VIXL_ASSERT(AllowAssembler());
   9620   CheckIT(cond);
   9621   if (IsUsingT32()) {
   9622     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9623     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9624       EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9625                  rm.GetCode());
   9626       AdvanceIT();
   9627       return;
   9628     }
   9629   } else {
   9630     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9631     if (cond.IsNotNever() &&
   9632         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9633       EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9634               rn.GetCode() | (rm.GetCode() << 8));
   9635       return;
   9636     }
   9637   }
   9638   Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
   9639 }
   9640 
   9641 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
   9642   VIXL_ASSERT(AllowAssembler());
   9643   CheckIT(cond);
   9644   if (IsUsingT32()) {
   9645     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9646     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9647       EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9648                  rm.GetCode());
   9649       AdvanceIT();
   9650       return;
   9651     }
   9652   } else {
   9653     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9654     if (cond.IsNotNever() &&
   9655         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9656       EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9657               (rn.GetCode() << 16) | rm.GetCode());
   9658       return;
   9659     }
   9660   }
   9661   Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
   9662 }
   9663 
   9664 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
   9665   VIXL_ASSERT(AllowAssembler());
   9666   CheckIT(cond);
   9667   if (IsUsingT32()) {
   9668     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9669     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9670       EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9671                  rm.GetCode());
   9672       AdvanceIT();
   9673       return;
   9674     }
   9675   } else {
   9676     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9677     if (cond.IsNotNever() &&
   9678         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9679       EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9680               (rn.GetCode() << 16) | rm.GetCode());
   9681       return;
   9682     }
   9683   }
   9684   Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
   9685 }
   9686 
   9687 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
   9688   VIXL_ASSERT(AllowAssembler());
   9689   CheckIT(cond);
   9690   if (IsUsingT32()) {
   9691     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9692     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9693       EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9694                  rm.GetCode());
   9695       AdvanceIT();
   9696       return;
   9697     }
   9698   } else {
   9699     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9700     if (cond.IsNotNever() &&
   9701         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9702       EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9703               (rn.GetCode() << 16) | rm.GetCode());
   9704       return;
   9705     }
   9706   }
   9707   Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
   9708 }
   9709 
   9710 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
   9711   VIXL_ASSERT(AllowAssembler());
   9712   CheckIT(cond);
   9713   if (IsUsingT32()) {
   9714     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9715     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9716       EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9717                  rm.GetCode());
   9718       AdvanceIT();
   9719       return;
   9720     }
   9721   } else {
   9722     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9723     if (cond.IsNotNever() &&
   9724         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9725       EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9726               (rn.GetCode() << 16) | rm.GetCode());
   9727       return;
   9728     }
   9729   }
   9730   Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
   9731 }
   9732 
   9733 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
   9734   VIXL_ASSERT(AllowAssembler());
   9735   CheckIT(cond);
   9736   if (IsUsingT32()) {
   9737     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9738     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9739       EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9740                  rm.GetCode());
   9741       AdvanceIT();
   9742       return;
   9743     }
   9744   } else {
   9745     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9746     if (cond.IsNotNever() &&
   9747         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9748       EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9749               (rn.GetCode() << 16) | rm.GetCode());
   9750       return;
   9751     }
   9752   }
   9753   Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
   9754 }
   9755 
   9756 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
   9757   VIXL_ASSERT(AllowAssembler());
   9758   CheckIT(cond);
   9759   if (IsUsingT32()) {
   9760     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9761     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9762       EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9763                  rm.GetCode());
   9764       AdvanceIT();
   9765       return;
   9766     }
   9767   } else {
   9768     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9769     if (cond.IsNotNever() &&
   9770         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9771       EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9772               (rn.GetCode() << 16) | rm.GetCode());
   9773       return;
   9774     }
   9775   }
   9776   Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
   9777 }
   9778 
   9779 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
   9780   VIXL_ASSERT(AllowAssembler());
   9781   CheckIT(cond);
   9782   if (IsUsingT32()) {
   9783     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   9784     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9785       EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9786                  rm.GetCode());
   9787       AdvanceIT();
   9788       return;
   9789     }
   9790   } else {
   9791     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   9792     if (cond.IsNotNever() &&
   9793         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9794       EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   9795               (rn.GetCode() << 16) | rm.GetCode());
   9796       return;
   9797     }
   9798   }
   9799   Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
   9800 }
   9801 
   9802 void Assembler::smlabb(
   9803     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9804   VIXL_ASSERT(AllowAssembler());
   9805   CheckIT(cond);
   9806   if (IsUsingT32()) {
   9807     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9808     if (!ra.Is(pc) &&
   9809         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9810       EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9811                  rm.GetCode() | (ra.GetCode() << 12));
   9812       AdvanceIT();
   9813       return;
   9814     }
   9815   } else {
   9816     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9817     if (cond.IsNotNever() &&
   9818         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   9819          AllowUnpredictable())) {
   9820       EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9821               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9822       return;
   9823     }
   9824   }
   9825   Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
   9826 }
   9827 
   9828 void Assembler::smlabt(
   9829     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9830   VIXL_ASSERT(AllowAssembler());
   9831   CheckIT(cond);
   9832   if (IsUsingT32()) {
   9833     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9834     if (!ra.Is(pc) &&
   9835         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9836       EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9837                  rm.GetCode() | (ra.GetCode() << 12));
   9838       AdvanceIT();
   9839       return;
   9840     }
   9841   } else {
   9842     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9843     if (cond.IsNotNever() &&
   9844         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   9845          AllowUnpredictable())) {
   9846       EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9847               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9848       return;
   9849     }
   9850   }
   9851   Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
   9852 }
   9853 
   9854 void Assembler::smlad(
   9855     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9856   VIXL_ASSERT(AllowAssembler());
   9857   CheckIT(cond);
   9858   if (IsUsingT32()) {
   9859     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9860     if (!ra.Is(pc) &&
   9861         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9862       EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9863                  rm.GetCode() | (ra.GetCode() << 12));
   9864       AdvanceIT();
   9865       return;
   9866     }
   9867   } else {
   9868     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9869     if (cond.IsNotNever() && !ra.Is(pc) &&
   9870         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9871       EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9872               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9873       return;
   9874     }
   9875   }
   9876   Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
   9877 }
   9878 
   9879 void Assembler::smladx(
   9880     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   9881   VIXL_ASSERT(AllowAssembler());
   9882   CheckIT(cond);
   9883   if (IsUsingT32()) {
   9884     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   9885     if (!ra.Is(pc) &&
   9886         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9887       EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   9888                  rm.GetCode() | (ra.GetCode() << 12));
   9889       AdvanceIT();
   9890       return;
   9891     }
   9892   } else {
   9893     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   9894     if (cond.IsNotNever() && !ra.Is(pc) &&
   9895         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   9896       EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   9897               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   9898       return;
   9899     }
   9900   }
   9901   Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
   9902 }
   9903 
   9904 void Assembler::smlal(
   9905     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9906   VIXL_ASSERT(AllowAssembler());
   9907   CheckIT(cond);
   9908   if (IsUsingT32()) {
   9909     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9910     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9911          AllowUnpredictable())) {
   9912       EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9913                  (rn.GetCode() << 16) | rm.GetCode());
   9914       AdvanceIT();
   9915       return;
   9916     }
   9917   } else {
   9918     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9919     if (cond.IsNotNever() &&
   9920         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9921          AllowUnpredictable())) {
   9922       EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
   9923               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9924               (rm.GetCode() << 8));
   9925       return;
   9926     }
   9927   }
   9928   Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
   9929 }
   9930 
   9931 void Assembler::smlalbb(
   9932     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9933   VIXL_ASSERT(AllowAssembler());
   9934   CheckIT(cond);
   9935   if (IsUsingT32()) {
   9936     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9937     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9938          AllowUnpredictable())) {
   9939       EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9940                  (rn.GetCode() << 16) | rm.GetCode());
   9941       AdvanceIT();
   9942       return;
   9943     }
   9944   } else {
   9945     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9946     if (cond.IsNotNever() &&
   9947         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9948          AllowUnpredictable())) {
   9949       EmitA32(0x01400080U | (cond.GetCondition() << 28) |
   9950               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9951               (rm.GetCode() << 8));
   9952       return;
   9953     }
   9954   }
   9955   Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
   9956 }
   9957 
   9958 void Assembler::smlalbt(
   9959     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9960   VIXL_ASSERT(AllowAssembler());
   9961   CheckIT(cond);
   9962   if (IsUsingT32()) {
   9963     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9964     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9965          AllowUnpredictable())) {
   9966       EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9967                  (rn.GetCode() << 16) | rm.GetCode());
   9968       AdvanceIT();
   9969       return;
   9970     }
   9971   } else {
   9972     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   9973     if (cond.IsNotNever() &&
   9974         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9975          AllowUnpredictable())) {
   9976       EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
   9977               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   9978               (rm.GetCode() << 8));
   9979       return;
   9980     }
   9981   }
   9982   Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
   9983 }
   9984 
   9985 void Assembler::smlald(
   9986     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   9987   VIXL_ASSERT(AllowAssembler());
   9988   CheckIT(cond);
   9989   if (IsUsingT32()) {
   9990     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   9991     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   9992          AllowUnpredictable())) {
   9993       EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   9994                  (rn.GetCode() << 16) | rm.GetCode());
   9995       AdvanceIT();
   9996       return;
   9997     }
   9998   } else {
   9999     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10000     if (cond.IsNotNever() &&
   10001         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10002          AllowUnpredictable())) {
   10003       EmitA32(0x07400010U | (cond.GetCondition() << 28) |
   10004               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10005               (rm.GetCode() << 8));
   10006       return;
   10007     }
   10008   }
   10009   Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
   10010 }
   10011 
   10012 void Assembler::smlaldx(
   10013     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   10014   VIXL_ASSERT(AllowAssembler());
   10015   CheckIT(cond);
   10016   if (IsUsingT32()) {
   10017     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   10018     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10019          AllowUnpredictable())) {
   10020       EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   10021                  (rn.GetCode() << 16) | rm.GetCode());
   10022       AdvanceIT();
   10023       return;
   10024     }
   10025   } else {
   10026     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10027     if (cond.IsNotNever() &&
   10028         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10029          AllowUnpredictable())) {
   10030       EmitA32(0x07400030U | (cond.GetCondition() << 28) |
   10031               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10032               (rm.GetCode() << 8));
   10033       return;
   10034     }
   10035   }
   10036   Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
   10037 }
   10038 
   10039 void Assembler::smlals(
   10040     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   10041   VIXL_ASSERT(AllowAssembler());
   10042   CheckIT(cond);
   10043   if (IsUsingA32()) {
   10044     // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10045     if (cond.IsNotNever() &&
   10046         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10047          AllowUnpredictable())) {
   10048       EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
   10049               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10050               (rm.GetCode() << 8));
   10051       return;
   10052     }
   10053   }
   10054   Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
   10055 }
   10056 
   10057 void Assembler::smlaltb(
   10058     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   10059   VIXL_ASSERT(AllowAssembler());
   10060   CheckIT(cond);
   10061   if (IsUsingT32()) {
   10062     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   10063     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10064          AllowUnpredictable())) {
   10065       EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   10066                  (rn.GetCode() << 16) | rm.GetCode());
   10067       AdvanceIT();
   10068       return;
   10069     }
   10070   } else {
   10071     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10072     if (cond.IsNotNever() &&
   10073         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10074          AllowUnpredictable())) {
   10075       EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
   10076               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10077               (rm.GetCode() << 8));
   10078       return;
   10079     }
   10080   }
   10081   Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
   10082 }
   10083 
   10084 void Assembler::smlaltt(
   10085     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   10086   VIXL_ASSERT(AllowAssembler());
   10087   CheckIT(cond);
   10088   if (IsUsingT32()) {
   10089     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   10090     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10091          AllowUnpredictable())) {
   10092       EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   10093                  (rn.GetCode() << 16) | rm.GetCode());
   10094       AdvanceIT();
   10095       return;
   10096     }
   10097   } else {
   10098     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10099     if (cond.IsNotNever() &&
   10100         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10101          AllowUnpredictable())) {
   10102       EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
   10103               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10104               (rm.GetCode() << 8));
   10105       return;
   10106     }
   10107   }
   10108   Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
   10109 }
   10110 
   10111 void Assembler::smlatb(
   10112     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10113   VIXL_ASSERT(AllowAssembler());
   10114   CheckIT(cond);
   10115   if (IsUsingT32()) {
   10116     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10117     if (!ra.Is(pc) &&
   10118         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10119       EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10120                  rm.GetCode() | (ra.GetCode() << 12));
   10121       AdvanceIT();
   10122       return;
   10123     }
   10124   } else {
   10125     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10126     if (cond.IsNotNever() &&
   10127         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   10128          AllowUnpredictable())) {
   10129       EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10130               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10131       return;
   10132     }
   10133   }
   10134   Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
   10135 }
   10136 
   10137 void Assembler::smlatt(
   10138     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10139   VIXL_ASSERT(AllowAssembler());
   10140   CheckIT(cond);
   10141   if (IsUsingT32()) {
   10142     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10143     if (!ra.Is(pc) &&
   10144         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10145       EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10146                  rm.GetCode() | (ra.GetCode() << 12));
   10147       AdvanceIT();
   10148       return;
   10149     }
   10150   } else {
   10151     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10152     if (cond.IsNotNever() &&
   10153         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   10154          AllowUnpredictable())) {
   10155       EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10156               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10157       return;
   10158     }
   10159   }
   10160   Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
   10161 }
   10162 
   10163 void Assembler::smlawb(
   10164     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10165   VIXL_ASSERT(AllowAssembler());
   10166   CheckIT(cond);
   10167   if (IsUsingT32()) {
   10168     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10169     if (!ra.Is(pc) &&
   10170         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10171       EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10172                  rm.GetCode() | (ra.GetCode() << 12));
   10173       AdvanceIT();
   10174       return;
   10175     }
   10176   } else {
   10177     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10178     if (cond.IsNotNever() &&
   10179         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   10180          AllowUnpredictable())) {
   10181       EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10182               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10183       return;
   10184     }
   10185   }
   10186   Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
   10187 }
   10188 
   10189 void Assembler::smlawt(
   10190     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10191   VIXL_ASSERT(AllowAssembler());
   10192   CheckIT(cond);
   10193   if (IsUsingT32()) {
   10194     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10195     if (!ra.Is(pc) &&
   10196         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10197       EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10198                  rm.GetCode() | (ra.GetCode() << 12));
   10199       AdvanceIT();
   10200       return;
   10201     }
   10202   } else {
   10203     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10204     if (cond.IsNotNever() &&
   10205         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   10206          AllowUnpredictable())) {
   10207       EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10208               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10209       return;
   10210     }
   10211   }
   10212   Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
   10213 }
   10214 
   10215 void Assembler::smlsd(
   10216     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10217   VIXL_ASSERT(AllowAssembler());
   10218   CheckIT(cond);
   10219   if (IsUsingT32()) {
   10220     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10221     if (!ra.Is(pc) &&
   10222         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10223       EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10224                  rm.GetCode() | (ra.GetCode() << 12));
   10225       AdvanceIT();
   10226       return;
   10227     }
   10228   } else {
   10229     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10230     if (cond.IsNotNever() && !ra.Is(pc) &&
   10231         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10232       EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10233               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10234       return;
   10235     }
   10236   }
   10237   Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
   10238 }
   10239 
   10240 void Assembler::smlsdx(
   10241     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10242   VIXL_ASSERT(AllowAssembler());
   10243   CheckIT(cond);
   10244   if (IsUsingT32()) {
   10245     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10246     if (!ra.Is(pc) &&
   10247         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10248       EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10249                  rm.GetCode() | (ra.GetCode() << 12));
   10250       AdvanceIT();
   10251       return;
   10252     }
   10253   } else {
   10254     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10255     if (cond.IsNotNever() && !ra.Is(pc) &&
   10256         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10257       EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10258               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10259       return;
   10260     }
   10261   }
   10262   Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
   10263 }
   10264 
   10265 void Assembler::smlsld(
   10266     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   10267   VIXL_ASSERT(AllowAssembler());
   10268   CheckIT(cond);
   10269   if (IsUsingT32()) {
   10270     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   10271     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10272          AllowUnpredictable())) {
   10273       EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   10274                  (rn.GetCode() << 16) | rm.GetCode());
   10275       AdvanceIT();
   10276       return;
   10277     }
   10278   } else {
   10279     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10280     if (cond.IsNotNever() &&
   10281         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10282          AllowUnpredictable())) {
   10283       EmitA32(0x07400050U | (cond.GetCondition() << 28) |
   10284               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10285               (rm.GetCode() << 8));
   10286       return;
   10287     }
   10288   }
   10289   Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
   10290 }
   10291 
   10292 void Assembler::smlsldx(
   10293     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   10294   VIXL_ASSERT(AllowAssembler());
   10295   CheckIT(cond);
   10296   if (IsUsingT32()) {
   10297     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   10298     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10299          AllowUnpredictable())) {
   10300       EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   10301                  (rn.GetCode() << 16) | rm.GetCode());
   10302       AdvanceIT();
   10303       return;
   10304     }
   10305   } else {
   10306     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10307     if (cond.IsNotNever() &&
   10308         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10309          AllowUnpredictable())) {
   10310       EmitA32(0x07400070U | (cond.GetCondition() << 28) |
   10311               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10312               (rm.GetCode() << 8));
   10313       return;
   10314     }
   10315   }
   10316   Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
   10317 }
   10318 
   10319 void Assembler::smmla(
   10320     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10321   VIXL_ASSERT(AllowAssembler());
   10322   CheckIT(cond);
   10323   if (IsUsingT32()) {
   10324     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10325     if (!ra.Is(pc) &&
   10326         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10327       EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10328                  rm.GetCode() | (ra.GetCode() << 12));
   10329       AdvanceIT();
   10330       return;
   10331     }
   10332   } else {
   10333     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10334     if (cond.IsNotNever() && !ra.Is(pc) &&
   10335         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10336       EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10337               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10338       return;
   10339     }
   10340   }
   10341   Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
   10342 }
   10343 
   10344 void Assembler::smmlar(
   10345     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10346   VIXL_ASSERT(AllowAssembler());
   10347   CheckIT(cond);
   10348   if (IsUsingT32()) {
   10349     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10350     if (!ra.Is(pc) &&
   10351         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10352       EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10353                  rm.GetCode() | (ra.GetCode() << 12));
   10354       AdvanceIT();
   10355       return;
   10356     }
   10357   } else {
   10358     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10359     if (cond.IsNotNever() && !ra.Is(pc) &&
   10360         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10361       EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10362               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10363       return;
   10364     }
   10365   }
   10366   Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
   10367 }
   10368 
   10369 void Assembler::smmls(
   10370     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10371   VIXL_ASSERT(AllowAssembler());
   10372   CheckIT(cond);
   10373   if (IsUsingT32()) {
   10374     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10375     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   10376          AllowUnpredictable())) {
   10377       EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10378                  rm.GetCode() | (ra.GetCode() << 12));
   10379       AdvanceIT();
   10380       return;
   10381     }
   10382   } else {
   10383     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10384     if (cond.IsNotNever() &&
   10385         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   10386          AllowUnpredictable())) {
   10387       EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10388               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10389       return;
   10390     }
   10391   }
   10392   Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
   10393 }
   10394 
   10395 void Assembler::smmlsr(
   10396     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   10397   VIXL_ASSERT(AllowAssembler());
   10398   CheckIT(cond);
   10399   if (IsUsingT32()) {
   10400     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   10401     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   10402          AllowUnpredictable())) {
   10403       EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10404                  rm.GetCode() | (ra.GetCode() << 12));
   10405       AdvanceIT();
   10406       return;
   10407     }
   10408   } else {
   10409     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   10410     if (cond.IsNotNever() &&
   10411         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
   10412          AllowUnpredictable())) {
   10413       EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10414               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   10415       return;
   10416     }
   10417   }
   10418   Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
   10419 }
   10420 
   10421 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
   10422   VIXL_ASSERT(AllowAssembler());
   10423   CheckIT(cond);
   10424   if (IsUsingT32()) {
   10425     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10426     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10427       EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10428                  rm.GetCode());
   10429       AdvanceIT();
   10430       return;
   10431     }
   10432   } else {
   10433     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10434     if (cond.IsNotNever() &&
   10435         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10436       EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10437               rn.GetCode() | (rm.GetCode() << 8));
   10438       return;
   10439     }
   10440   }
   10441   Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
   10442 }
   10443 
   10444 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
   10445   VIXL_ASSERT(AllowAssembler());
   10446   CheckIT(cond);
   10447   if (IsUsingT32()) {
   10448     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10449     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10450       EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10451                  rm.GetCode());
   10452       AdvanceIT();
   10453       return;
   10454     }
   10455   } else {
   10456     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10457     if (cond.IsNotNever() &&
   10458         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10459       EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10460               rn.GetCode() | (rm.GetCode() << 8));
   10461       return;
   10462     }
   10463   }
   10464   Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
   10465 }
   10466 
   10467 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
   10468   VIXL_ASSERT(AllowAssembler());
   10469   CheckIT(cond);
   10470   if (IsUsingT32()) {
   10471     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10472     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10473       EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10474                  rm.GetCode());
   10475       AdvanceIT();
   10476       return;
   10477     }
   10478   } else {
   10479     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10480     if (cond.IsNotNever() &&
   10481         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10482       EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10483               rn.GetCode() | (rm.GetCode() << 8));
   10484       return;
   10485     }
   10486   }
   10487   Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
   10488 }
   10489 
   10490 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
   10491   VIXL_ASSERT(AllowAssembler());
   10492   CheckIT(cond);
   10493   if (IsUsingT32()) {
   10494     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10495     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10496       EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10497                  rm.GetCode());
   10498       AdvanceIT();
   10499       return;
   10500     }
   10501   } else {
   10502     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10503     if (cond.IsNotNever() &&
   10504         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10505       EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10506               rn.GetCode() | (rm.GetCode() << 8));
   10507       return;
   10508     }
   10509   }
   10510   Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
   10511 }
   10512 
   10513 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
   10514   VIXL_ASSERT(AllowAssembler());
   10515   CheckIT(cond);
   10516   if (IsUsingT32()) {
   10517     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10518     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10519       EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10520                  rm.GetCode());
   10521       AdvanceIT();
   10522       return;
   10523     }
   10524   } else {
   10525     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10526     if (cond.IsNotNever() &&
   10527         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10528       EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10529               rn.GetCode() | (rm.GetCode() << 8));
   10530       return;
   10531     }
   10532   }
   10533   Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
   10534 }
   10535 
   10536 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
   10537   VIXL_ASSERT(AllowAssembler());
   10538   CheckIT(cond);
   10539   if (IsUsingT32()) {
   10540     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10541     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10542       EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10543                  rm.GetCode());
   10544       AdvanceIT();
   10545       return;
   10546     }
   10547   } else {
   10548     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10549     if (cond.IsNotNever() &&
   10550         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10551       EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10552               rn.GetCode() | (rm.GetCode() << 8));
   10553       return;
   10554     }
   10555   }
   10556   Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
   10557 }
   10558 
   10559 void Assembler::smull(
   10560     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   10561   VIXL_ASSERT(AllowAssembler());
   10562   CheckIT(cond);
   10563   if (IsUsingT32()) {
   10564     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   10565     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10566          AllowUnpredictable())) {
   10567       EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   10568                  (rn.GetCode() << 16) | rm.GetCode());
   10569       AdvanceIT();
   10570       return;
   10571     }
   10572   } else {
   10573     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10574     if (cond.IsNotNever() &&
   10575         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10576          AllowUnpredictable())) {
   10577       EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
   10578               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10579               (rm.GetCode() << 8));
   10580       return;
   10581     }
   10582   }
   10583   Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
   10584 }
   10585 
   10586 void Assembler::smulls(
   10587     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   10588   VIXL_ASSERT(AllowAssembler());
   10589   CheckIT(cond);
   10590   if (IsUsingA32()) {
   10591     // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   10592     if (cond.IsNotNever() &&
   10593         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   10594          AllowUnpredictable())) {
   10595       EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
   10596               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   10597               (rm.GetCode() << 8));
   10598       return;
   10599     }
   10600   }
   10601   Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
   10602 }
   10603 
   10604 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
   10605   VIXL_ASSERT(AllowAssembler());
   10606   CheckIT(cond);
   10607   if (IsUsingT32()) {
   10608     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10609     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10610       EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10611                  rm.GetCode());
   10612       AdvanceIT();
   10613       return;
   10614     }
   10615   } else {
   10616     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10617     if (cond.IsNotNever() &&
   10618         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10619       EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10620               rn.GetCode() | (rm.GetCode() << 8));
   10621       return;
   10622     }
   10623   }
   10624   Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
   10625 }
   10626 
   10627 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
   10628   VIXL_ASSERT(AllowAssembler());
   10629   CheckIT(cond);
   10630   if (IsUsingT32()) {
   10631     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10632     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10633       EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10634                  rm.GetCode());
   10635       AdvanceIT();
   10636       return;
   10637     }
   10638   } else {
   10639     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10640     if (cond.IsNotNever() &&
   10641         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10642       EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10643               rn.GetCode() | (rm.GetCode() << 8));
   10644       return;
   10645     }
   10646   }
   10647   Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
   10648 }
   10649 
   10650 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
   10651   VIXL_ASSERT(AllowAssembler());
   10652   CheckIT(cond);
   10653   if (IsUsingT32()) {
   10654     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10655     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10656       EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10657                  rm.GetCode());
   10658       AdvanceIT();
   10659       return;
   10660     }
   10661   } else {
   10662     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10663     if (cond.IsNotNever() &&
   10664         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10665       EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10666               rn.GetCode() | (rm.GetCode() << 8));
   10667       return;
   10668     }
   10669   }
   10670   Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
   10671 }
   10672 
   10673 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
   10674   VIXL_ASSERT(AllowAssembler());
   10675   CheckIT(cond);
   10676   if (IsUsingT32()) {
   10677     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10678     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10679       EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10680                  rm.GetCode());
   10681       AdvanceIT();
   10682       return;
   10683     }
   10684   } else {
   10685     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10686     if (cond.IsNotNever() &&
   10687         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10688       EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10689               rn.GetCode() | (rm.GetCode() << 8));
   10690       return;
   10691     }
   10692   }
   10693   Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
   10694 }
   10695 
   10696 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
   10697   VIXL_ASSERT(AllowAssembler());
   10698   CheckIT(cond);
   10699   if (IsUsingT32()) {
   10700     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10701     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10702       EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10703                  rm.GetCode());
   10704       AdvanceIT();
   10705       return;
   10706     }
   10707   } else {
   10708     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10709     if (cond.IsNotNever() &&
   10710         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10711       EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10712               rn.GetCode() | (rm.GetCode() << 8));
   10713       return;
   10714     }
   10715   }
   10716   Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
   10717 }
   10718 
   10719 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
   10720   VIXL_ASSERT(AllowAssembler());
   10721   CheckIT(cond);
   10722   if (IsUsingT32()) {
   10723     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10724     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10725       EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10726                  rm.GetCode());
   10727       AdvanceIT();
   10728       return;
   10729     }
   10730   } else {
   10731     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10732     if (cond.IsNotNever() &&
   10733         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10734       EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   10735               rn.GetCode() | (rm.GetCode() << 8));
   10736       return;
   10737     }
   10738   }
   10739   Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
   10740 }
   10741 
   10742 void Assembler::ssat(Condition cond,
   10743                      Register rd,
   10744                      uint32_t imm,
   10745                      const Operand& operand) {
   10746   VIXL_ASSERT(AllowAssembler());
   10747   CheckIT(cond);
   10748   if (operand.IsImmediateShiftedRegister()) {
   10749     Register rn = operand.GetBaseRegister();
   10750     Shift shift = operand.GetShift();
   10751     uint32_t amount = operand.GetShiftAmount();
   10752     if (IsUsingT32()) {
   10753       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
   10754       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
   10755           (amount <= 31) &&
   10756           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10757         uint32_t imm_ = imm - 1;
   10758         EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
   10759                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
   10760                    ((amount & 0x1c) << 10));
   10761         AdvanceIT();
   10762         return;
   10763       }
   10764       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
   10765       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
   10766           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10767         uint32_t imm_ = imm - 1;
   10768         EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
   10769                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
   10770                    ((amount & 0x1c) << 10));
   10771         AdvanceIT();
   10772         return;
   10773       }
   10774     } else {
   10775       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
   10776       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
   10777           (amount <= 32) && cond.IsNotNever() &&
   10778           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10779         uint32_t imm_ = imm - 1;
   10780         uint32_t amount_ = amount % 32;
   10781         EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
   10782                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
   10783                 (amount_ << 7));
   10784         return;
   10785       }
   10786       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
   10787       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
   10788           cond.IsNotNever() &&
   10789           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10790         uint32_t imm_ = imm - 1;
   10791         EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
   10792                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
   10793                 (amount << 7));
   10794         return;
   10795       }
   10796     }
   10797   }
   10798   Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
   10799 }
   10800 
   10801 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
   10802   VIXL_ASSERT(AllowAssembler());
   10803   CheckIT(cond);
   10804   if (IsUsingT32()) {
   10805     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
   10806     if ((imm >= 1) && (imm <= 16) &&
   10807         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10808       uint32_t imm_ = imm - 1;
   10809       EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
   10810                  (rn.GetCode() << 16));
   10811       AdvanceIT();
   10812       return;
   10813     }
   10814   } else {
   10815     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
   10816     if ((imm >= 1) && (imm <= 16) && cond.IsNotNever() &&
   10817         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10818       uint32_t imm_ = imm - 1;
   10819       EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   10820               (imm_ << 16) | rn.GetCode());
   10821       return;
   10822     }
   10823   }
   10824   Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
   10825 }
   10826 
   10827 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
   10828   VIXL_ASSERT(AllowAssembler());
   10829   CheckIT(cond);
   10830   if (IsUsingT32()) {
   10831     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10832     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10833       EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10834                  rm.GetCode());
   10835       AdvanceIT();
   10836       return;
   10837     }
   10838   } else {
   10839     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10840     if (cond.IsNotNever() &&
   10841         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10842       EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   10843               (rn.GetCode() << 16) | rm.GetCode());
   10844       return;
   10845     }
   10846   }
   10847   Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
   10848 }
   10849 
   10850 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
   10851   VIXL_ASSERT(AllowAssembler());
   10852   CheckIT(cond);
   10853   if (IsUsingT32()) {
   10854     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10855     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10856       EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10857                  rm.GetCode());
   10858       AdvanceIT();
   10859       return;
   10860     }
   10861   } else {
   10862     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10863     if (cond.IsNotNever() &&
   10864         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10865       EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   10866               (rn.GetCode() << 16) | rm.GetCode());
   10867       return;
   10868     }
   10869   }
   10870   Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
   10871 }
   10872 
   10873 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
   10874   VIXL_ASSERT(AllowAssembler());
   10875   CheckIT(cond);
   10876   if (IsUsingT32()) {
   10877     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   10878     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10879       EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   10880                  rm.GetCode());
   10881       AdvanceIT();
   10882       return;
   10883     }
   10884   } else {
   10885     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   10886     if (cond.IsNotNever() &&
   10887         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   10888       EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   10889               (rn.GetCode() << 16) | rm.GetCode());
   10890       return;
   10891     }
   10892   }
   10893   Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
   10894 }
   10895 
   10896 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
   10897   VIXL_ASSERT(AllowAssembler());
   10898   CheckIT(cond);
   10899   if (operand.IsImmediateZero()) {
   10900     Register rn = operand.GetBaseRegister();
   10901     if (IsUsingT32()) {
   10902       // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
   10903       if (operand.IsOffset() &&
   10904           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10905         EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   10906         AdvanceIT();
   10907         return;
   10908       }
   10909     } else {
   10910       // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
   10911       if (operand.IsOffset() && cond.IsNotNever() &&
   10912           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10913         EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
   10914                 (rn.GetCode() << 16));
   10915         return;
   10916       }
   10917     }
   10918   }
   10919   Delegate(kStl, &Assembler::stl, cond, rt, operand);
   10920 }
   10921 
   10922 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
   10923   VIXL_ASSERT(AllowAssembler());
   10924   CheckIT(cond);
   10925   if (operand.IsImmediateZero()) {
   10926     Register rn = operand.GetBaseRegister();
   10927     if (IsUsingT32()) {
   10928       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
   10929       if (operand.IsOffset() &&
   10930           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10931         EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   10932         AdvanceIT();
   10933         return;
   10934       }
   10935     } else {
   10936       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
   10937       if (operand.IsOffset() && cond.IsNotNever() &&
   10938           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10939         EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
   10940                 (rn.GetCode() << 16));
   10941         return;
   10942       }
   10943     }
   10944   }
   10945   Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
   10946 }
   10947 
   10948 void Assembler::stlex(Condition cond,
   10949                       Register rd,
   10950                       Register rt,
   10951                       const MemOperand& operand) {
   10952   VIXL_ASSERT(AllowAssembler());
   10953   CheckIT(cond);
   10954   if (operand.IsImmediateZero()) {
   10955     Register rn = operand.GetBaseRegister();
   10956     if (IsUsingT32()) {
   10957       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   10958       if (operand.IsOffset() &&
   10959           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10960         EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
   10961                    (rn.GetCode() << 16));
   10962         AdvanceIT();
   10963         return;
   10964       }
   10965     } else {
   10966       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   10967       if (operand.IsOffset() && cond.IsNotNever() &&
   10968           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10969         EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
   10970                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   10971         return;
   10972       }
   10973     }
   10974   }
   10975   Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
   10976 }
   10977 
   10978 void Assembler::stlexb(Condition cond,
   10979                        Register rd,
   10980                        Register rt,
   10981                        const MemOperand& operand) {
   10982   VIXL_ASSERT(AllowAssembler());
   10983   CheckIT(cond);
   10984   if (operand.IsImmediateZero()) {
   10985     Register rn = operand.GetBaseRegister();
   10986     if (IsUsingT32()) {
   10987       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   10988       if (operand.IsOffset() &&
   10989           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10990         EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
   10991                    (rn.GetCode() << 16));
   10992         AdvanceIT();
   10993         return;
   10994       }
   10995     } else {
   10996       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   10997       if (operand.IsOffset() && cond.IsNotNever() &&
   10998           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   10999         EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
   11000                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   11001         return;
   11002       }
   11003     }
   11004   }
   11005   Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
   11006 }
   11007 
   11008 void Assembler::stlexd(Condition cond,
   11009                        Register rd,
   11010                        Register rt,
   11011                        Register rt2,
   11012                        const MemOperand& operand) {
   11013   VIXL_ASSERT(AllowAssembler());
   11014   CheckIT(cond);
   11015   if (operand.IsImmediateZero()) {
   11016     Register rn = operand.GetBaseRegister();
   11017     if (IsUsingT32()) {
   11018       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
   11019       if (operand.IsOffset() &&
   11020           ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) ||
   11021            AllowUnpredictable())) {
   11022         EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
   11023                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
   11024         AdvanceIT();
   11025         return;
   11026       }
   11027     } else {
   11028       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
   11029       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   11030           operand.IsOffset() && cond.IsNotNever() &&
   11031           ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() &&
   11032             !rn.IsPC()) ||
   11033            AllowUnpredictable())) {
   11034         EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
   11035                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   11036         return;
   11037       }
   11038     }
   11039   }
   11040   Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
   11041 }
   11042 
   11043 void Assembler::stlexh(Condition cond,
   11044                        Register rd,
   11045                        Register rt,
   11046                        const MemOperand& operand) {
   11047   VIXL_ASSERT(AllowAssembler());
   11048   CheckIT(cond);
   11049   if (operand.IsImmediateZero()) {
   11050     Register rn = operand.GetBaseRegister();
   11051     if (IsUsingT32()) {
   11052       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   11053       if (operand.IsOffset() &&
   11054           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11055         EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
   11056                    (rn.GetCode() << 16));
   11057         AdvanceIT();
   11058         return;
   11059       }
   11060     } else {
   11061       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   11062       if (operand.IsOffset() && cond.IsNotNever() &&
   11063           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11064         EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
   11065                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   11066         return;
   11067       }
   11068     }
   11069   }
   11070   Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
   11071 }
   11072 
   11073 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
   11074   VIXL_ASSERT(AllowAssembler());
   11075   CheckIT(cond);
   11076   if (operand.IsImmediateZero()) {
   11077     Register rn = operand.GetBaseRegister();
   11078     if (IsUsingT32()) {
   11079       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
   11080       if (operand.IsOffset() &&
   11081           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11082         EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
   11083         AdvanceIT();
   11084         return;
   11085       }
   11086     } else {
   11087       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
   11088       if (operand.IsOffset() && cond.IsNotNever() &&
   11089           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11090         EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
   11091                 (rn.GetCode() << 16));
   11092         return;
   11093       }
   11094     }
   11095   }
   11096   Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
   11097 }
   11098 
   11099 void Assembler::stm(Condition cond,
   11100                     EncodingSize size,
   11101                     Register rn,
   11102                     WriteBack write_back,
   11103                     RegisterList registers) {
   11104   VIXL_ASSERT(AllowAssembler());
   11105   CheckIT(cond);
   11106   if (IsUsingT32()) {
   11107     // STM{<c>}{<q>} <Rn>!, <registers> ; T1
   11108     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
   11109         ((registers.GetList() & ~0xff) == 0)) {
   11110       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
   11111                  GetRegisterListEncoding(registers, 0, 8));
   11112       AdvanceIT();
   11113       return;
   11114     }
   11115     // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
   11116     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
   11117         (!rn.IsPC() || AllowUnpredictable())) {
   11118       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
   11119                  (write_back.GetWriteBackUint32() << 21) |
   11120                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   11121                  GetRegisterListEncoding(registers, 0, 13));
   11122       AdvanceIT();
   11123       return;
   11124     }
   11125   } else {
   11126     // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
   11127     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   11128       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   11129               (write_back.GetWriteBackUint32() << 21) |
   11130               GetRegisterListEncoding(registers, 0, 16));
   11131       return;
   11132     }
   11133   }
   11134   Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
   11135 }
   11136 
   11137 void Assembler::stmda(Condition cond,
   11138                       Register rn,
   11139                       WriteBack write_back,
   11140                       RegisterList registers) {
   11141   VIXL_ASSERT(AllowAssembler());
   11142   CheckIT(cond);
   11143   if (IsUsingA32()) {
   11144     // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   11145     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   11146       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   11147               (write_back.GetWriteBackUint32() << 21) |
   11148               GetRegisterListEncoding(registers, 0, 16));
   11149       return;
   11150     }
   11151   }
   11152   Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
   11153 }
   11154 
   11155 void Assembler::stmdb(Condition cond,
   11156                       EncodingSize size,
   11157                       Register rn,
   11158                       WriteBack write_back,
   11159                       RegisterList registers) {
   11160   VIXL_ASSERT(AllowAssembler());
   11161   CheckIT(cond);
   11162   if (IsUsingT32()) {
   11163     // STMDB{<c>}{<q>} SP!, <registers> ; T1
   11164     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
   11165         ((registers.GetList() & ~0x40ff) == 0)) {
   11166       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
   11167                  GetRegisterListEncoding(registers, 0, 8));
   11168       AdvanceIT();
   11169       return;
   11170     }
   11171     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
   11172     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
   11173         (!rn.IsPC() || AllowUnpredictable())) {
   11174       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
   11175                  (write_back.GetWriteBackUint32() << 21) |
   11176                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   11177                  GetRegisterListEncoding(registers, 0, 13));
   11178       AdvanceIT();
   11179       return;
   11180     }
   11181   } else {
   11182     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   11183     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   11184       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   11185               (write_back.GetWriteBackUint32() << 21) |
   11186               GetRegisterListEncoding(registers, 0, 16));
   11187       return;
   11188     }
   11189   }
   11190   Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
   11191 }
   11192 
   11193 void Assembler::stmea(Condition cond,
   11194                       EncodingSize size,
   11195                       Register rn,
   11196                       WriteBack write_back,
   11197                       RegisterList registers) {
   11198   VIXL_ASSERT(AllowAssembler());
   11199   CheckIT(cond);
   11200   if (IsUsingT32()) {
   11201     // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
   11202     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
   11203         ((registers.GetList() & ~0xff) == 0)) {
   11204       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
   11205                  GetRegisterListEncoding(registers, 0, 8));
   11206       AdvanceIT();
   11207       return;
   11208     }
   11209     // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
   11210     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
   11211         (!rn.IsPC() || AllowUnpredictable())) {
   11212       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
   11213                  (write_back.GetWriteBackUint32() << 21) |
   11214                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   11215                  GetRegisterListEncoding(registers, 0, 13));
   11216       AdvanceIT();
   11217       return;
   11218     }
   11219     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
   11220     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
   11221         (!rn.IsPC() || AllowUnpredictable())) {
   11222       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
   11223                  (write_back.GetWriteBackUint32() << 21) |
   11224                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   11225                  GetRegisterListEncoding(registers, 0, 13));
   11226       AdvanceIT();
   11227       return;
   11228     }
   11229   } else {
   11230     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   11231     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   11232       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   11233               (write_back.GetWriteBackUint32() << 21) |
   11234               GetRegisterListEncoding(registers, 0, 16));
   11235       return;
   11236     }
   11237   }
   11238   Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
   11239 }
   11240 
   11241 void Assembler::stmed(Condition cond,
   11242                       Register rn,
   11243                       WriteBack write_back,
   11244                       RegisterList registers) {
   11245   VIXL_ASSERT(AllowAssembler());
   11246   CheckIT(cond);
   11247   if (IsUsingA32()) {
   11248     // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
   11249     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   11250       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   11251               (write_back.GetWriteBackUint32() << 21) |
   11252               GetRegisterListEncoding(registers, 0, 16));
   11253       return;
   11254     }
   11255   }
   11256   Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
   11257 }
   11258 
   11259 void Assembler::stmfa(Condition cond,
   11260                       Register rn,
   11261                       WriteBack write_back,
   11262                       RegisterList registers) {
   11263   VIXL_ASSERT(AllowAssembler());
   11264   CheckIT(cond);
   11265   if (IsUsingA32()) {
   11266     // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
   11267     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   11268       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   11269               (write_back.GetWriteBackUint32() << 21) |
   11270               GetRegisterListEncoding(registers, 0, 16));
   11271       return;
   11272     }
   11273   }
   11274   Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
   11275 }
   11276 
   11277 void Assembler::stmfd(Condition cond,
   11278                       Register rn,
   11279                       WriteBack write_back,
   11280                       RegisterList registers) {
   11281   VIXL_ASSERT(AllowAssembler());
   11282   CheckIT(cond);
   11283   if (IsUsingT32()) {
   11284     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
   11285     if (((registers.GetList() & ~0x5fff) == 0) &&
   11286         (!rn.IsPC() || AllowUnpredictable())) {
   11287       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
   11288                  (write_back.GetWriteBackUint32() << 21) |
   11289                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
   11290                  GetRegisterListEncoding(registers, 0, 13));
   11291       AdvanceIT();
   11292       return;
   11293     }
   11294   } else {
   11295     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
   11296     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   11297       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   11298               (write_back.GetWriteBackUint32() << 21) |
   11299               GetRegisterListEncoding(registers, 0, 16));
   11300       return;
   11301     }
   11302   }
   11303   Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
   11304 }
   11305 
   11306 void Assembler::stmib(Condition cond,
   11307                       Register rn,
   11308                       WriteBack write_back,
   11309                       RegisterList registers) {
   11310   VIXL_ASSERT(AllowAssembler());
   11311   CheckIT(cond);
   11312   if (IsUsingA32()) {
   11313     // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
   11314     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
   11315       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   11316               (write_back.GetWriteBackUint32() << 21) |
   11317               GetRegisterListEncoding(registers, 0, 16));
   11318       return;
   11319     }
   11320   }
   11321   Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
   11322 }
   11323 
   11324 void Assembler::str(Condition cond,
   11325                     EncodingSize size,
   11326                     Register rt,
   11327                     const MemOperand& operand) {
   11328   VIXL_ASSERT(AllowAssembler());
   11329   CheckIT(cond);
   11330   if (operand.IsImmediate()) {
   11331     Register rn = operand.GetBaseRegister();
   11332     int32_t offset = operand.GetOffsetImmediate();
   11333     if (IsUsingT32()) {
   11334       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   11335       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   11336           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
   11337         int32_t offset_ = offset >> 2;
   11338         EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
   11339                    ((offset_ & 0x1f) << 6));
   11340         AdvanceIT();
   11341         return;
   11342       }
   11343       // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
   11344       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
   11345           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
   11346         int32_t offset_ = offset >> 2;
   11347         EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
   11348         AdvanceIT();
   11349         return;
   11350       }
   11351       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
   11352       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   11353           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11354           (!rt.IsPC() || AllowUnpredictable())) {
   11355         EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11356                    (offset & 0xfff));
   11357         AdvanceIT();
   11358         return;
   11359       }
   11360       // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
   11361       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   11362           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11363           (!rt.IsPC() || AllowUnpredictable())) {
   11364         EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11365                    (-offset & 0xff));
   11366         AdvanceIT();
   11367         return;
   11368       }
   11369       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
   11370       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   11371           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   11372           (!rt.IsPC() || AllowUnpredictable())) {
   11373         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11374         uint32_t offset_ = abs(offset);
   11375         EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11376                    offset_ | (sign << 9));
   11377         AdvanceIT();
   11378         return;
   11379       }
   11380       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
   11381       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   11382           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   11383           (!rt.IsPC() || AllowUnpredictable())) {
   11384         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11385         uint32_t offset_ = abs(offset);
   11386         EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11387                    offset_ | (sign << 9));
   11388         AdvanceIT();
   11389         return;
   11390       }
   11391     } else {
   11392       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   11393       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   11394           cond.IsNotNever()) {
   11395         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11396         uint32_t offset_ = abs(offset);
   11397         EmitA32(0x05000000U | (cond.GetCondition() << 28) |
   11398                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   11399                 (sign << 23));
   11400         return;
   11401       }
   11402       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   11403       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   11404           cond.IsNotNever()) {
   11405         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11406         uint32_t offset_ = abs(offset);
   11407         EmitA32(0x04000000U | (cond.GetCondition() << 28) |
   11408                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   11409                 (sign << 23));
   11410         return;
   11411       }
   11412       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   11413       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   11414           cond.IsNotNever()) {
   11415         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11416         uint32_t offset_ = abs(offset);
   11417         EmitA32(0x05200000U | (cond.GetCondition() << 28) |
   11418                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   11419                 (sign << 23));
   11420         return;
   11421       }
   11422     }
   11423   }
   11424   if (operand.IsPlainRegister()) {
   11425     Register rn = operand.GetBaseRegister();
   11426     Sign sign = operand.GetSign();
   11427     Register rm = operand.GetOffsetRegister();
   11428     if (IsUsingT32()) {
   11429       // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   11430       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   11431           sign.IsPlus() && operand.IsOffset()) {
   11432         EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
   11433                    (rm.GetCode() << 6));
   11434         AdvanceIT();
   11435         return;
   11436       }
   11437     }
   11438   }
   11439   if (operand.IsShiftedRegister()) {
   11440     Register rn = operand.GetBaseRegister();
   11441     Sign sign = operand.GetSign();
   11442     Register rm = operand.GetOffsetRegister();
   11443     Shift shift = operand.GetShift();
   11444     uint32_t amount = operand.GetShiftAmount();
   11445     if (IsUsingT32()) {
   11446       // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   11447       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   11448           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11449           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   11450         EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11451                    rm.GetCode() | (amount << 4));
   11452         AdvanceIT();
   11453         return;
   11454       }
   11455     } else {
   11456       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   11457       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
   11458           (!rm.IsPC() || AllowUnpredictable())) {
   11459         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11460         uint32_t shift_ = TypeEncodingValue(shift);
   11461         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   11462         EmitA32(0x07000000U | (cond.GetCondition() << 28) |
   11463                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11464                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   11465         return;
   11466       }
   11467       // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   11468       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   11469           cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
   11470         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11471         uint32_t shift_ = TypeEncodingValue(shift);
   11472         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   11473         EmitA32(0x06000000U | (cond.GetCondition() << 28) |
   11474                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11475                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   11476         return;
   11477       }
   11478       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   11479       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
   11480           (!rm.IsPC() || AllowUnpredictable())) {
   11481         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11482         uint32_t shift_ = TypeEncodingValue(shift);
   11483         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   11484         EmitA32(0x07200000U | (cond.GetCondition() << 28) |
   11485                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11486                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   11487         return;
   11488       }
   11489     }
   11490   }
   11491   Delegate(kStr, &Assembler::str, cond, size, rt, operand);
   11492 }
   11493 
   11494 void Assembler::strb(Condition cond,
   11495                      EncodingSize size,
   11496                      Register rt,
   11497                      const MemOperand& operand) {
   11498   VIXL_ASSERT(AllowAssembler());
   11499   CheckIT(cond);
   11500   if (operand.IsImmediate()) {
   11501     Register rn = operand.GetBaseRegister();
   11502     int32_t offset = operand.GetOffsetImmediate();
   11503     if (IsUsingT32()) {
   11504       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   11505       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   11506           (offset <= 31) && operand.IsOffset()) {
   11507         EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
   11508                    ((offset & 0x1f) << 6));
   11509         AdvanceIT();
   11510         return;
   11511       }
   11512       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   11513       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   11514           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11515           (!rt.IsPC() || AllowUnpredictable())) {
   11516         EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11517                    (offset & 0xfff));
   11518         AdvanceIT();
   11519         return;
   11520       }
   11521       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   11522       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   11523           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11524           (!rt.IsPC() || AllowUnpredictable())) {
   11525         EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11526                    (-offset & 0xff));
   11527         AdvanceIT();
   11528         return;
   11529       }
   11530       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   11531       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   11532           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   11533           (!rt.IsPC() || AllowUnpredictable())) {
   11534         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11535         uint32_t offset_ = abs(offset);
   11536         EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11537                    offset_ | (sign << 9));
   11538         AdvanceIT();
   11539         return;
   11540       }
   11541       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   11542       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   11543           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   11544           (!rt.IsPC() || AllowUnpredictable())) {
   11545         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11546         uint32_t offset_ = abs(offset);
   11547         EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11548                    offset_ | (sign << 9));
   11549         AdvanceIT();
   11550         return;
   11551       }
   11552     } else {
   11553       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   11554       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
   11555           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   11556         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11557         uint32_t offset_ = abs(offset);
   11558         EmitA32(0x05400000U | (cond.GetCondition() << 28) |
   11559                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   11560                 (sign << 23));
   11561         return;
   11562       }
   11563       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   11564       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
   11565           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   11566         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11567         uint32_t offset_ = abs(offset);
   11568         EmitA32(0x04400000U | (cond.GetCondition() << 28) |
   11569                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   11570                 (sign << 23));
   11571         return;
   11572       }
   11573       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   11574       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
   11575           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   11576         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11577         uint32_t offset_ = abs(offset);
   11578         EmitA32(0x05600000U | (cond.GetCondition() << 28) |
   11579                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
   11580                 (sign << 23));
   11581         return;
   11582       }
   11583     }
   11584   }
   11585   if (operand.IsPlainRegister()) {
   11586     Register rn = operand.GetBaseRegister();
   11587     Sign sign = operand.GetSign();
   11588     Register rm = operand.GetOffsetRegister();
   11589     if (IsUsingT32()) {
   11590       // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   11591       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   11592           sign.IsPlus() && operand.IsOffset()) {
   11593         EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
   11594                    (rm.GetCode() << 6));
   11595         AdvanceIT();
   11596         return;
   11597       }
   11598     }
   11599   }
   11600   if (operand.IsShiftedRegister()) {
   11601     Register rn = operand.GetBaseRegister();
   11602     Sign sign = operand.GetSign();
   11603     Register rm = operand.GetOffsetRegister();
   11604     Shift shift = operand.GetShift();
   11605     uint32_t amount = operand.GetShiftAmount();
   11606     if (IsUsingT32()) {
   11607       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   11608       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   11609           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11610           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   11611         EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11612                    rm.GetCode() | (amount << 4));
   11613         AdvanceIT();
   11614         return;
   11615       }
   11616     } else {
   11617       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
   11618       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
   11619           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   11620         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11621         uint32_t shift_ = TypeEncodingValue(shift);
   11622         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   11623         EmitA32(0x07400000U | (cond.GetCondition() << 28) |
   11624                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11625                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   11626         return;
   11627       }
   11628       // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
   11629       if (operand.IsShiftValid() && operand.IsPostIndex() &&
   11630           cond.IsNotNever() &&
   11631           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   11632         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11633         uint32_t shift_ = TypeEncodingValue(shift);
   11634         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   11635         EmitA32(0x06400000U | (cond.GetCondition() << 28) |
   11636                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11637                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   11638         return;
   11639       }
   11640       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
   11641       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
   11642           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   11643         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11644         uint32_t shift_ = TypeEncodingValue(shift);
   11645         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
   11646         EmitA32(0x07600000U | (cond.GetCondition() << 28) |
   11647                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11648                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
   11649         return;
   11650       }
   11651     }
   11652   }
   11653   Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
   11654 }
   11655 
   11656 void Assembler::strd(Condition cond,
   11657                      Register rt,
   11658                      Register rt2,
   11659                      const MemOperand& operand) {
   11660   VIXL_ASSERT(AllowAssembler());
   11661   CheckIT(cond);
   11662   if (operand.IsImmediate()) {
   11663     Register rn = operand.GetBaseRegister();
   11664     int32_t offset = operand.GetOffsetImmediate();
   11665     if (IsUsingT32()) {
   11666       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
   11667       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   11668           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11669           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   11670         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11671         uint32_t offset_ = abs(offset) >> 2;
   11672         EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   11673                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   11674         AdvanceIT();
   11675         return;
   11676       }
   11677       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
   11678       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   11679           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   11680           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   11681         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11682         uint32_t offset_ = abs(offset) >> 2;
   11683         EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   11684                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   11685         AdvanceIT();
   11686         return;
   11687       }
   11688       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
   11689       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
   11690           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   11691           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   11692         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11693         uint32_t offset_ = abs(offset) >> 2;
   11694         EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
   11695                    (rn.GetCode() << 16) | offset_ | (sign << 23));
   11696         AdvanceIT();
   11697         return;
   11698       }
   11699     } else {
   11700       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
   11701       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   11702           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   11703           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   11704                                 AllowUnpredictable())) {
   11705         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11706         uint32_t offset_ = abs(offset);
   11707         EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
   11708                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   11709                 ((offset_ & 0xf0) << 4) | (sign << 23));
   11710         return;
   11711       }
   11712       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
   11713       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   11714           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   11715           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   11716                                 AllowUnpredictable())) {
   11717         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11718         uint32_t offset_ = abs(offset);
   11719         EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
   11720                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   11721                 ((offset_ & 0xf0) << 4) | (sign << 23));
   11722         return;
   11723       }
   11724       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
   11725       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   11726           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   11727           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
   11728                                 AllowUnpredictable())) {
   11729         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11730         uint32_t offset_ = abs(offset);
   11731         EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
   11732                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   11733                 ((offset_ & 0xf0) << 4) | (sign << 23));
   11734         return;
   11735       }
   11736     }
   11737   }
   11738   if (operand.IsPlainRegister()) {
   11739     Register rn = operand.GetBaseRegister();
   11740     Sign sign = operand.GetSign();
   11741     Register rm = operand.GetOffsetRegister();
   11742     if (IsUsingA32()) {
   11743       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
   11744       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   11745           operand.IsOffset() && cond.IsNotNever() &&
   11746           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   11747            AllowUnpredictable())) {
   11748         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11749         EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
   11750                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11751                 (sign_ << 23));
   11752         return;
   11753       }
   11754       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
   11755       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   11756           operand.IsPostIndex() && cond.IsNotNever() &&
   11757           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   11758            AllowUnpredictable())) {
   11759         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11760         EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
   11761                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11762                 (sign_ << 23));
   11763         return;
   11764       }
   11765       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
   11766       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   11767           operand.IsPreIndex() && cond.IsNotNever() &&
   11768           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
   11769            AllowUnpredictable())) {
   11770         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   11771         EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
   11772                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   11773                 (sign_ << 23));
   11774         return;
   11775       }
   11776     }
   11777   }
   11778   Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
   11779 }
   11780 
   11781 void Assembler::strex(Condition cond,
   11782                       Register rd,
   11783                       Register rt,
   11784                       const MemOperand& operand) {
   11785   VIXL_ASSERT(AllowAssembler());
   11786   CheckIT(cond);
   11787   if (operand.IsImmediate()) {
   11788     Register rn = operand.GetBaseRegister();
   11789     int32_t offset = operand.GetOffsetImmediate();
   11790     if (IsUsingT32()) {
   11791       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
   11792       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
   11793           operand.IsOffset() &&
   11794           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11795         int32_t offset_ = offset >> 2;
   11796         EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
   11797                    (rn.GetCode() << 16) | (offset_ & 0xff));
   11798         AdvanceIT();
   11799         return;
   11800       }
   11801     } else {
   11802       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
   11803       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() &&
   11804           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11805         EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
   11806                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   11807         return;
   11808       }
   11809     }
   11810   }
   11811   Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
   11812 }
   11813 
   11814 void Assembler::strexb(Condition cond,
   11815                        Register rd,
   11816                        Register rt,
   11817                        const MemOperand& operand) {
   11818   VIXL_ASSERT(AllowAssembler());
   11819   CheckIT(cond);
   11820   if (operand.IsImmediateZero()) {
   11821     Register rn = operand.GetBaseRegister();
   11822     if (IsUsingT32()) {
   11823       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   11824       if (operand.IsOffset() &&
   11825           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11826         EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
   11827                    (rn.GetCode() << 16));
   11828         AdvanceIT();
   11829         return;
   11830       }
   11831     } else {
   11832       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   11833       if (operand.IsOffset() && cond.IsNotNever() &&
   11834           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11835         EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
   11836                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   11837         return;
   11838       }
   11839     }
   11840   }
   11841   Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
   11842 }
   11843 
   11844 void Assembler::strexd(Condition cond,
   11845                        Register rd,
   11846                        Register rt,
   11847                        Register rt2,
   11848                        const MemOperand& operand) {
   11849   VIXL_ASSERT(AllowAssembler());
   11850   CheckIT(cond);
   11851   if (operand.IsImmediateZero()) {
   11852     Register rn = operand.GetBaseRegister();
   11853     if (IsUsingT32()) {
   11854       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
   11855       if (operand.IsOffset() &&
   11856           ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) ||
   11857            AllowUnpredictable())) {
   11858         EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
   11859                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
   11860         AdvanceIT();
   11861         return;
   11862       }
   11863     } else {
   11864       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
   11865       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
   11866           operand.IsOffset() && cond.IsNotNever() &&
   11867           ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() &&
   11868             !rn.IsPC()) ||
   11869            AllowUnpredictable())) {
   11870         EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
   11871                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   11872         return;
   11873       }
   11874     }
   11875   }
   11876   Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
   11877 }
   11878 
   11879 void Assembler::strexh(Condition cond,
   11880                        Register rd,
   11881                        Register rt,
   11882                        const MemOperand& operand) {
   11883   VIXL_ASSERT(AllowAssembler());
   11884   CheckIT(cond);
   11885   if (operand.IsImmediateZero()) {
   11886     Register rn = operand.GetBaseRegister();
   11887     if (IsUsingT32()) {
   11888       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
   11889       if (operand.IsOffset() &&
   11890           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11891         EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
   11892                    (rn.GetCode() << 16));
   11893         AdvanceIT();
   11894         return;
   11895       }
   11896     } else {
   11897       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
   11898       if (operand.IsOffset() && cond.IsNotNever() &&
   11899           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   11900         EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
   11901                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
   11902         return;
   11903       }
   11904     }
   11905   }
   11906   Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
   11907 }
   11908 
   11909 void Assembler::strh(Condition cond,
   11910                      EncodingSize size,
   11911                      Register rt,
   11912                      const MemOperand& operand) {
   11913   VIXL_ASSERT(AllowAssembler());
   11914   CheckIT(cond);
   11915   if (operand.IsImmediate()) {
   11916     Register rn = operand.GetBaseRegister();
   11917     int32_t offset = operand.GetOffsetImmediate();
   11918     if (IsUsingT32()) {
   11919       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
   11920       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
   11921           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
   11922         int32_t offset_ = offset >> 1;
   11923         EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
   11924                    ((offset_ & 0x1f) << 6));
   11925         AdvanceIT();
   11926         return;
   11927       }
   11928       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
   11929       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
   11930           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11931           (!rt.IsPC() || AllowUnpredictable())) {
   11932         EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11933                    (offset & 0xfff));
   11934         AdvanceIT();
   11935         return;
   11936       }
   11937       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
   11938       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
   11939           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   11940           (!rt.IsPC() || AllowUnpredictable())) {
   11941         EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11942                    (-offset & 0xff));
   11943         AdvanceIT();
   11944         return;
   11945       }
   11946       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
   11947       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   11948           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   11949           (!rt.IsPC() || AllowUnpredictable())) {
   11950         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11951         uint32_t offset_ = abs(offset);
   11952         EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11953                    offset_ | (sign << 9));
   11954         AdvanceIT();
   11955         return;
   11956       }
   11957       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
   11958       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
   11959           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
   11960           (!rt.IsPC() || AllowUnpredictable())) {
   11961         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11962         uint32_t offset_ = abs(offset);
   11963         EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   11964                    offset_ | (sign << 9));
   11965         AdvanceIT();
   11966         return;
   11967       }
   11968     } else {
   11969       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
   11970       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
   11971           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   11972         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11973         uint32_t offset_ = abs(offset);
   11974         EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
   11975                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   11976                 ((offset_ & 0xf0) << 4) | (sign << 23));
   11977         return;
   11978       }
   11979       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
   11980       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
   11981           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   11982         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11983         uint32_t offset_ = abs(offset);
   11984         EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
   11985                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   11986                 ((offset_ & 0xf0) << 4) | (sign << 23));
   11987         return;
   11988       }
   11989       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
   11990       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
   11991           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   11992         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   11993         uint32_t offset_ = abs(offset);
   11994         EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
   11995                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
   11996                 ((offset_ & 0xf0) << 4) | (sign << 23));
   11997         return;
   11998       }
   11999     }
   12000   }
   12001   if (operand.IsPlainRegister()) {
   12002     Register rn = operand.GetBaseRegister();
   12003     Sign sign = operand.GetSign();
   12004     Register rm = operand.GetOffsetRegister();
   12005     if (IsUsingT32()) {
   12006       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
   12007       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
   12008           sign.IsPlus() && operand.IsOffset()) {
   12009         EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
   12010                    (rm.GetCode() << 6));
   12011         AdvanceIT();
   12012         return;
   12013       }
   12014     } else {
   12015       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
   12016       if (operand.IsOffset() && cond.IsNotNever() &&
   12017           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12018         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   12019         EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
   12020                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12021                 (sign_ << 23));
   12022         return;
   12023       }
   12024       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
   12025       if (operand.IsPostIndex() && cond.IsNotNever() &&
   12026           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12027         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   12028         EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
   12029                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12030                 (sign_ << 23));
   12031         return;
   12032       }
   12033       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
   12034       if (operand.IsPreIndex() && cond.IsNotNever() &&
   12035           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12036         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
   12037         EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
   12038                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12039                 (sign_ << 23));
   12040         return;
   12041       }
   12042     }
   12043   }
   12044   if (operand.IsShiftedRegister()) {
   12045     Register rn = operand.GetBaseRegister();
   12046     Sign sign = operand.GetSign();
   12047     Register rm = operand.GetOffsetRegister();
   12048     Shift shift = operand.GetShift();
   12049     uint32_t amount = operand.GetShiftAmount();
   12050     if (IsUsingT32()) {
   12051       // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
   12052       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
   12053           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
   12054           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12055         EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
   12056                    rm.GetCode() | (amount << 4));
   12057         AdvanceIT();
   12058         return;
   12059       }
   12060     }
   12061   }
   12062   Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
   12063 }
   12064 
   12065 void Assembler::sub(Condition cond,
   12066                     EncodingSize size,
   12067                     Register rd,
   12068                     Register rn,
   12069                     const Operand& operand) {
   12070   VIXL_ASSERT(AllowAssembler());
   12071   CheckIT(cond);
   12072   if (operand.IsImmediate()) {
   12073     uint32_t imm = operand.GetImmediate();
   12074     if (IsUsingT32()) {
   12075       ImmediateT32 immediate_t32(imm);
   12076       // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
   12077       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   12078           (imm <= 7)) {
   12079         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   12080         AdvanceIT();
   12081         return;
   12082       }
   12083       // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   12084       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   12085           (imm <= 255)) {
   12086         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
   12087         AdvanceIT();
   12088         return;
   12089       }
   12090       // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
   12091       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
   12092           ((imm % 4) == 0)) {
   12093         uint32_t imm_ = imm >> 2;
   12094         EmitT32_16(0xb080 | imm_);
   12095         AdvanceIT();
   12096         return;
   12097       }
   12098       // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
   12099       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
   12100           (!rd.IsPC() || AllowUnpredictable())) {
   12101         EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   12102                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   12103         AdvanceIT();
   12104         return;
   12105       }
   12106       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   12107       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   12108           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   12109         EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12110                    (immediate_t32.GetEncodingValue() & 0xff) |
   12111                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   12112                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   12113         AdvanceIT();
   12114         return;
   12115       }
   12116       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   12117       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
   12118           (!rd.IsPC() || AllowUnpredictable())) {
   12119         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12120                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   12121         AdvanceIT();
   12122         return;
   12123       }
   12124       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
   12125       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   12126           (!rd.IsPC() || AllowUnpredictable())) {
   12127         EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
   12128                    (immediate_t32.GetEncodingValue() & 0xff) |
   12129                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   12130                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   12131         AdvanceIT();
   12132         return;
   12133       }
   12134       // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
   12135       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
   12136           (!rd.IsPC() || AllowUnpredictable())) {
   12137         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   12138                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   12139         AdvanceIT();
   12140         return;
   12141       }
   12142     } else {
   12143       ImmediateA32 immediate_a32(imm);
   12144       // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
   12145       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
   12146         EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
   12147                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   12148         return;
   12149       }
   12150       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   12151       if (immediate_a32.IsValid() && cond.IsNotNever() &&
   12152           ((rn.GetCode() & 0xd) != 0xd)) {
   12153         EmitA32(0x02400000U | (cond.GetCondition() << 28) |
   12154                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   12155                 immediate_a32.GetEncodingValue());
   12156         return;
   12157       }
   12158       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   12159       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   12160         EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
   12161                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   12162         return;
   12163       }
   12164     }
   12165   }
   12166   if (operand.IsImmediateShiftedRegister()) {
   12167     Register rm = operand.GetBaseRegister();
   12168     if (operand.IsPlainRegister()) {
   12169       if (IsUsingT32()) {
   12170         // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
   12171         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   12172             rm.IsLow()) {
   12173           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
   12174                      (rm.GetCode() << 6));
   12175           AdvanceIT();
   12176           return;
   12177         }
   12178         // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
   12179         if (rn.Is(sp) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12180           EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
   12181           AdvanceIT();
   12182           return;
   12183         }
   12184       }
   12185     }
   12186     Shift shift = operand.GetShift();
   12187     uint32_t amount = operand.GetShiftAmount();
   12188     if (IsUsingT32()) {
   12189       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   12190       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   12191           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12192         uint32_t amount_ = amount % 32;
   12193         EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12194                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   12195                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   12196         AdvanceIT();
   12197         return;
   12198       }
   12199       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
   12200       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   12201           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12202         uint32_t amount_ = amount % 32;
   12203         EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
   12204                    (operand.GetTypeEncodingValue() << 4) |
   12205                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   12206         AdvanceIT();
   12207         return;
   12208       }
   12209     } else {
   12210       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   12211       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   12212         uint32_t amount_ = amount % 32;
   12213         EmitA32(0x00400000U | (cond.GetCondition() << 28) |
   12214                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12215                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   12216         return;
   12217       }
   12218       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   12219       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   12220         uint32_t amount_ = amount % 32;
   12221         EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
   12222                 (rd.GetCode() << 12) | rm.GetCode() |
   12223                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   12224         return;
   12225       }
   12226     }
   12227   }
   12228   if (operand.IsRegisterShiftedRegister()) {
   12229     Register rm = operand.GetBaseRegister();
   12230     Shift shift = operand.GetShift();
   12231     Register rs = operand.GetShiftRegister();
   12232     if (IsUsingA32()) {
   12233       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   12234       if (cond.IsNotNever() &&
   12235           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   12236            AllowUnpredictable())) {
   12237         EmitA32(0x00400010U | (cond.GetCondition() << 28) |
   12238                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12239                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   12240         return;
   12241       }
   12242     }
   12243   }
   12244   Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
   12245 }
   12246 
   12247 void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
   12248   VIXL_ASSERT(AllowAssembler());
   12249   CheckIT(cond);
   12250   if (operand.IsImmediate()) {
   12251     uint32_t imm = operand.GetImmediate();
   12252     if (IsUsingT32()) {
   12253       // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
   12254       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
   12255         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
   12256         AdvanceIT();
   12257         return;
   12258       }
   12259     }
   12260   }
   12261   Delegate(kSub, &Assembler::sub, cond, rd, operand);
   12262 }
   12263 
   12264 void Assembler::subs(Condition cond,
   12265                      EncodingSize size,
   12266                      Register rd,
   12267                      Register rn,
   12268                      const Operand& operand) {
   12269   VIXL_ASSERT(AllowAssembler());
   12270   CheckIT(cond);
   12271   if (operand.IsImmediate()) {
   12272     uint32_t imm = operand.GetImmediate();
   12273     if (IsUsingT32()) {
   12274       ImmediateT32 immediate_t32(imm);
   12275       // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
   12276       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   12277           (imm <= 7)) {
   12278         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
   12279         AdvanceIT();
   12280         return;
   12281       }
   12282       // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
   12283       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
   12284           (imm <= 255)) {
   12285         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
   12286         AdvanceIT();
   12287         return;
   12288       }
   12289       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
   12290       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
   12291           !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
   12292         EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12293                    (immediate_t32.GetEncodingValue() & 0xff) |
   12294                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   12295                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   12296         AdvanceIT();
   12297         return;
   12298       }
   12299       // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
   12300       if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255) &&
   12301           (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
   12302         EmitT32_32(0xf3de8f00U | imm);
   12303         AdvanceIT();
   12304         return;
   12305       }
   12306       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
   12307       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
   12308           !rd.Is(pc)) {
   12309         EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
   12310                    (immediate_t32.GetEncodingValue() & 0xff) |
   12311                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   12312                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   12313         AdvanceIT();
   12314         return;
   12315       }
   12316     } else {
   12317       ImmediateA32 immediate_a32(imm);
   12318       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
   12319       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
   12320         EmitA32(0x02500000U | (cond.GetCondition() << 28) |
   12321                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
   12322                 immediate_a32.GetEncodingValue());
   12323         return;
   12324       }
   12325       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
   12326       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
   12327         EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
   12328                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
   12329         return;
   12330       }
   12331     }
   12332   }
   12333   if (operand.IsImmediateShiftedRegister()) {
   12334     Register rm = operand.GetBaseRegister();
   12335     if (operand.IsPlainRegister()) {
   12336       if (IsUsingT32()) {
   12337         // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12338         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
   12339             rm.IsLow()) {
   12340           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
   12341                      (rm.GetCode() << 6));
   12342           AdvanceIT();
   12343           return;
   12344         }
   12345       }
   12346     }
   12347     Shift shift = operand.GetShift();
   12348     uint32_t amount = operand.GetShiftAmount();
   12349     if (IsUsingT32()) {
   12350       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
   12351       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
   12352           !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12353         uint32_t amount_ = amount % 32;
   12354         EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12355                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
   12356                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   12357         AdvanceIT();
   12358         return;
   12359       }
   12360       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
   12361       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
   12362           !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
   12363         uint32_t amount_ = amount % 32;
   12364         EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
   12365                    (operand.GetTypeEncodingValue() << 4) |
   12366                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   12367         AdvanceIT();
   12368         return;
   12369       }
   12370     } else {
   12371       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
   12372       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
   12373         uint32_t amount_ = amount % 32;
   12374         EmitA32(0x00500000U | (cond.GetCondition() << 28) |
   12375                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12376                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   12377         return;
   12378       }
   12379       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
   12380       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
   12381         uint32_t amount_ = amount % 32;
   12382         EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
   12383                 (rd.GetCode() << 12) | rm.GetCode() |
   12384                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   12385         return;
   12386       }
   12387     }
   12388   }
   12389   if (operand.IsRegisterShiftedRegister()) {
   12390     Register rm = operand.GetBaseRegister();
   12391     Shift shift = operand.GetShift();
   12392     Register rs = operand.GetShiftRegister();
   12393     if (IsUsingA32()) {
   12394       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
   12395       if (cond.IsNotNever() &&
   12396           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
   12397            AllowUnpredictable())) {
   12398         EmitA32(0x00500010U | (cond.GetCondition() << 28) |
   12399                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12400                 (shift.GetType() << 5) | (rs.GetCode() << 8));
   12401         return;
   12402       }
   12403     }
   12404   }
   12405   Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
   12406 }
   12407 
   12408 void Assembler::subs(Register rd, const Operand& operand) {
   12409   VIXL_ASSERT(AllowAssembler());
   12410   CheckIT(al);
   12411   if (operand.IsImmediate()) {
   12412     uint32_t imm = operand.GetImmediate();
   12413     if (IsUsingT32()) {
   12414       // SUBS{<q>} <Rdn>, #<imm8> ; T2
   12415       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
   12416         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
   12417         AdvanceIT();
   12418         return;
   12419       }
   12420     }
   12421   }
   12422   Delegate(kSubs, &Assembler::subs, rd, operand);
   12423 }
   12424 
   12425 void Assembler::subw(Condition cond,
   12426                      Register rd,
   12427                      Register rn,
   12428                      const Operand& operand) {
   12429   VIXL_ASSERT(AllowAssembler());
   12430   CheckIT(cond);
   12431   if (operand.IsImmediate()) {
   12432     uint32_t imm = operand.GetImmediate();
   12433     if (IsUsingT32()) {
   12434       // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
   12435       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
   12436           (!rd.IsPC() || AllowUnpredictable())) {
   12437         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12438                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   12439         AdvanceIT();
   12440         return;
   12441       }
   12442       // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
   12443       if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
   12444         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
   12445                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
   12446         AdvanceIT();
   12447         return;
   12448       }
   12449     }
   12450   }
   12451   Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
   12452 }
   12453 
   12454 void Assembler::svc(Condition cond, uint32_t imm) {
   12455   VIXL_ASSERT(AllowAssembler());
   12456   CheckIT(cond);
   12457   if (IsUsingT32()) {
   12458     // SVC{<c>}{<q>} {#}<imm> ; T1
   12459     if ((imm <= 255)) {
   12460       EmitT32_16(0xdf00 | imm);
   12461       AdvanceIT();
   12462       return;
   12463     }
   12464   } else {
   12465     // SVC{<c>}{<q>} {#}<imm> ; A1
   12466     if ((imm <= 16777215) && cond.IsNotNever()) {
   12467       EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
   12468       return;
   12469     }
   12470   }
   12471   Delegate(kSvc, &Assembler::svc, cond, imm);
   12472 }
   12473 
   12474 void Assembler::sxtab(Condition cond,
   12475                       Register rd,
   12476                       Register rn,
   12477                       const Operand& operand) {
   12478   VIXL_ASSERT(AllowAssembler());
   12479   CheckIT(cond);
   12480   if (operand.IsImmediateShiftedRegister()) {
   12481     Register rm = operand.GetBaseRegister();
   12482     Shift shift = operand.GetShift();
   12483     uint32_t amount = operand.GetShiftAmount();
   12484     if (IsUsingT32()) {
   12485       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   12486       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12487           ((amount % 8) == 0) && !rn.Is(pc) &&
   12488           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12489         uint32_t amount_ = amount / 8;
   12490         EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12491                    rm.GetCode() | (amount_ << 4));
   12492         AdvanceIT();
   12493         return;
   12494       }
   12495     } else {
   12496       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   12497       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12498           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
   12499           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12500         uint32_t amount_ = amount / 8;
   12501         EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
   12502                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12503                 (amount_ << 10));
   12504         return;
   12505       }
   12506     }
   12507   }
   12508   Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
   12509 }
   12510 
   12511 void Assembler::sxtab16(Condition cond,
   12512                         Register rd,
   12513                         Register rn,
   12514                         const Operand& operand) {
   12515   VIXL_ASSERT(AllowAssembler());
   12516   CheckIT(cond);
   12517   if (operand.IsImmediateShiftedRegister()) {
   12518     Register rm = operand.GetBaseRegister();
   12519     Shift shift = operand.GetShift();
   12520     uint32_t amount = operand.GetShiftAmount();
   12521     if (IsUsingT32()) {
   12522       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   12523       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12524           ((amount % 8) == 0) && !rn.Is(pc) &&
   12525           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12526         uint32_t amount_ = amount / 8;
   12527         EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12528                    rm.GetCode() | (amount_ << 4));
   12529         AdvanceIT();
   12530         return;
   12531       }
   12532     } else {
   12533       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   12534       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12535           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
   12536           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12537         uint32_t amount_ = amount / 8;
   12538         EmitA32(0x06800070U | (cond.GetCondition() << 28) |
   12539                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12540                 (amount_ << 10));
   12541         return;
   12542       }
   12543     }
   12544   }
   12545   Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
   12546 }
   12547 
   12548 void Assembler::sxtah(Condition cond,
   12549                       Register rd,
   12550                       Register rn,
   12551                       const Operand& operand) {
   12552   VIXL_ASSERT(AllowAssembler());
   12553   CheckIT(cond);
   12554   if (operand.IsImmediateShiftedRegister()) {
   12555     Register rm = operand.GetBaseRegister();
   12556     Shift shift = operand.GetShift();
   12557     uint32_t amount = operand.GetShiftAmount();
   12558     if (IsUsingT32()) {
   12559       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   12560       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12561           ((amount % 8) == 0) && !rn.Is(pc) &&
   12562           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12563         uint32_t amount_ = amount / 8;
   12564         EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12565                    rm.GetCode() | (amount_ << 4));
   12566         AdvanceIT();
   12567         return;
   12568       }
   12569     } else {
   12570       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   12571       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12572           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
   12573           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12574         uint32_t amount_ = amount / 8;
   12575         EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
   12576                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   12577                 (amount_ << 10));
   12578         return;
   12579       }
   12580     }
   12581   }
   12582   Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
   12583 }
   12584 
   12585 void Assembler::sxtb(Condition cond,
   12586                      EncodingSize size,
   12587                      Register rd,
   12588                      const Operand& operand) {
   12589   VIXL_ASSERT(AllowAssembler());
   12590   CheckIT(cond);
   12591   if (operand.IsImmediateShiftedRegister()) {
   12592     Register rm = operand.GetBaseRegister();
   12593     if (operand.IsPlainRegister()) {
   12594       if (IsUsingT32()) {
   12595         // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
   12596         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   12597           EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
   12598           AdvanceIT();
   12599           return;
   12600         }
   12601       }
   12602     }
   12603     Shift shift = operand.GetShift();
   12604     uint32_t amount = operand.GetShiftAmount();
   12605     if (IsUsingT32()) {
   12606       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
   12607       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
   12608           (amount <= 24) && ((amount % 8) == 0) &&
   12609           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12610         uint32_t amount_ = amount / 8;
   12611         EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   12612                    (amount_ << 4));
   12613         AdvanceIT();
   12614         return;
   12615       }
   12616     } else {
   12617       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   12618       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12619           ((amount % 8) == 0) && cond.IsNotNever() &&
   12620           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12621         uint32_t amount_ = amount / 8;
   12622         EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
   12623                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   12624         return;
   12625       }
   12626     }
   12627   }
   12628   Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
   12629 }
   12630 
   12631 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
   12632   VIXL_ASSERT(AllowAssembler());
   12633   CheckIT(cond);
   12634   if (operand.IsImmediateShiftedRegister()) {
   12635     Register rm = operand.GetBaseRegister();
   12636     Shift shift = operand.GetShift();
   12637     uint32_t amount = operand.GetShiftAmount();
   12638     if (IsUsingT32()) {
   12639       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
   12640       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12641           ((amount % 8) == 0) &&
   12642           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12643         uint32_t amount_ = amount / 8;
   12644         EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   12645                    (amount_ << 4));
   12646         AdvanceIT();
   12647         return;
   12648       }
   12649     } else {
   12650       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   12651       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12652           ((amount % 8) == 0) && cond.IsNotNever() &&
   12653           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12654         uint32_t amount_ = amount / 8;
   12655         EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
   12656                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   12657         return;
   12658       }
   12659     }
   12660   }
   12661   Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
   12662 }
   12663 
   12664 void Assembler::sxth(Condition cond,
   12665                      EncodingSize size,
   12666                      Register rd,
   12667                      const Operand& operand) {
   12668   VIXL_ASSERT(AllowAssembler());
   12669   CheckIT(cond);
   12670   if (operand.IsImmediateShiftedRegister()) {
   12671     Register rm = operand.GetBaseRegister();
   12672     if (operand.IsPlainRegister()) {
   12673       if (IsUsingT32()) {
   12674         // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
   12675         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   12676           EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
   12677           AdvanceIT();
   12678           return;
   12679         }
   12680       }
   12681     }
   12682     Shift shift = operand.GetShift();
   12683     uint32_t amount = operand.GetShiftAmount();
   12684     if (IsUsingT32()) {
   12685       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
   12686       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
   12687           (amount <= 24) && ((amount % 8) == 0) &&
   12688           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12689         uint32_t amount_ = amount / 8;
   12690         EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   12691                    (amount_ << 4));
   12692         AdvanceIT();
   12693         return;
   12694       }
   12695     } else {
   12696       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   12697       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   12698           ((amount % 8) == 0) && cond.IsNotNever() &&
   12699           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12700         uint32_t amount_ = amount / 8;
   12701         EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
   12702                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   12703         return;
   12704       }
   12705     }
   12706   }
   12707   Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
   12708 }
   12709 
   12710 void Assembler::tbb(Condition cond, Register rn, Register rm) {
   12711   VIXL_ASSERT(AllowAssembler());
   12712   CheckIT(cond);
   12713   if (IsUsingT32()) {
   12714     // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
   12715     if (OutsideITBlockAndAlOrLast(cond) &&
   12716         (!rm.IsPC() || AllowUnpredictable())) {
   12717       EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
   12718       AdvanceIT();
   12719       return;
   12720     }
   12721   }
   12722   Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
   12723 }
   12724 
   12725 void Assembler::tbh(Condition cond, Register rn, Register rm) {
   12726   VIXL_ASSERT(AllowAssembler());
   12727   CheckIT(cond);
   12728   if (IsUsingT32()) {
   12729     // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
   12730     if (OutsideITBlockAndAlOrLast(cond) &&
   12731         (!rm.IsPC() || AllowUnpredictable())) {
   12732       EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
   12733       AdvanceIT();
   12734       return;
   12735     }
   12736   }
   12737   Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
   12738 }
   12739 
   12740 void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
   12741   VIXL_ASSERT(AllowAssembler());
   12742   CheckIT(cond);
   12743   if (operand.IsImmediate()) {
   12744     uint32_t imm = operand.GetImmediate();
   12745     if (IsUsingT32()) {
   12746       ImmediateT32 immediate_t32(imm);
   12747       // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
   12748       if (immediate_t32.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   12749         EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
   12750                    (immediate_t32.GetEncodingValue() & 0xff) |
   12751                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   12752                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   12753         AdvanceIT();
   12754         return;
   12755       }
   12756     } else {
   12757       ImmediateA32 immediate_a32(imm);
   12758       // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
   12759       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   12760         EmitA32(0x03300000U | (cond.GetCondition() << 28) |
   12761                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   12762         return;
   12763       }
   12764     }
   12765   }
   12766   if (operand.IsImmediateShiftedRegister()) {
   12767     Register rm = operand.GetBaseRegister();
   12768     Shift shift = operand.GetShift();
   12769     uint32_t amount = operand.GetShiftAmount();
   12770     if (IsUsingT32()) {
   12771       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
   12772       if (shift.IsValidAmount(amount) &&
   12773           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12774         uint32_t amount_ = amount % 32;
   12775         EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
   12776                    (operand.GetTypeEncodingValue() << 4) |
   12777                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   12778         AdvanceIT();
   12779         return;
   12780       }
   12781     } else {
   12782       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   12783       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   12784         uint32_t amount_ = amount % 32;
   12785         EmitA32(0x01300000U | (cond.GetCondition() << 28) |
   12786                 (rn.GetCode() << 16) | rm.GetCode() |
   12787                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   12788         return;
   12789       }
   12790     }
   12791   }
   12792   if (operand.IsRegisterShiftedRegister()) {
   12793     Register rm = operand.GetBaseRegister();
   12794     Shift shift = operand.GetShift();
   12795     Register rs = operand.GetShiftRegister();
   12796     if (IsUsingA32()) {
   12797       // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   12798       if (cond.IsNotNever() &&
   12799           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   12800         EmitA32(0x01300010U | (cond.GetCondition() << 28) |
   12801                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   12802                 (rs.GetCode() << 8));
   12803         return;
   12804       }
   12805     }
   12806   }
   12807   Delegate(kTeq, &Assembler::teq, cond, rn, operand);
   12808 }
   12809 
   12810 void Assembler::tst(Condition cond,
   12811                     EncodingSize size,
   12812                     Register rn,
   12813                     const Operand& operand) {
   12814   VIXL_ASSERT(AllowAssembler());
   12815   CheckIT(cond);
   12816   if (operand.IsImmediate()) {
   12817     uint32_t imm = operand.GetImmediate();
   12818     if (IsUsingT32()) {
   12819       ImmediateT32 immediate_t32(imm);
   12820       // TST{<c>}{<q>} <Rn>, #<const> ; T1
   12821       if (!size.IsNarrow() && immediate_t32.IsValid() &&
   12822           (!rn.IsPC() || AllowUnpredictable())) {
   12823         EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
   12824                    (immediate_t32.GetEncodingValue() & 0xff) |
   12825                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
   12826                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
   12827         AdvanceIT();
   12828         return;
   12829       }
   12830     } else {
   12831       ImmediateA32 immediate_a32(imm);
   12832       // TST{<c>}{<q>} <Rn>, #<const> ; A1
   12833       if (immediate_a32.IsValid() && cond.IsNotNever()) {
   12834         EmitA32(0x03100000U | (cond.GetCondition() << 28) |
   12835                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
   12836         return;
   12837       }
   12838     }
   12839   }
   12840   if (operand.IsImmediateShiftedRegister()) {
   12841     Register rm = operand.GetBaseRegister();
   12842     if (operand.IsPlainRegister()) {
   12843       if (IsUsingT32()) {
   12844         // TST{<c>}{<q>} <Rn>, <Rm> ; T1
   12845         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
   12846           EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
   12847           AdvanceIT();
   12848           return;
   12849         }
   12850       }
   12851     }
   12852     Shift shift = operand.GetShift();
   12853     uint32_t amount = operand.GetShiftAmount();
   12854     if (IsUsingT32()) {
   12855       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
   12856       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
   12857           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12858         uint32_t amount_ = amount % 32;
   12859         EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
   12860                    (operand.GetTypeEncodingValue() << 4) |
   12861                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
   12862         AdvanceIT();
   12863         return;
   12864       }
   12865     } else {
   12866       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
   12867       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
   12868         uint32_t amount_ = amount % 32;
   12869         EmitA32(0x01100000U | (cond.GetCondition() << 28) |
   12870                 (rn.GetCode() << 16) | rm.GetCode() |
   12871                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
   12872         return;
   12873       }
   12874     }
   12875   }
   12876   if (operand.IsRegisterShiftedRegister()) {
   12877     Register rm = operand.GetBaseRegister();
   12878     Shift shift = operand.GetShift();
   12879     Register rs = operand.GetShiftRegister();
   12880     if (IsUsingA32()) {
   12881       // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
   12882       if (cond.IsNotNever() &&
   12883           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
   12884         EmitA32(0x01100010U | (cond.GetCondition() << 28) |
   12885                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
   12886                 (rs.GetCode() << 8));
   12887         return;
   12888       }
   12889     }
   12890   }
   12891   Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
   12892 }
   12893 
   12894 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
   12895   VIXL_ASSERT(AllowAssembler());
   12896   CheckIT(cond);
   12897   if (IsUsingT32()) {
   12898     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12899     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12900       EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12901                  rm.GetCode());
   12902       AdvanceIT();
   12903       return;
   12904     }
   12905   } else {
   12906     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12907     if (cond.IsNotNever() &&
   12908         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12909       EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12910               (rn.GetCode() << 16) | rm.GetCode());
   12911       return;
   12912     }
   12913   }
   12914   Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
   12915 }
   12916 
   12917 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
   12918   VIXL_ASSERT(AllowAssembler());
   12919   CheckIT(cond);
   12920   if (IsUsingT32()) {
   12921     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12922     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12923       EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12924                  rm.GetCode());
   12925       AdvanceIT();
   12926       return;
   12927     }
   12928   } else {
   12929     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12930     if (cond.IsNotNever() &&
   12931         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12932       EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12933               (rn.GetCode() << 16) | rm.GetCode());
   12934       return;
   12935     }
   12936   }
   12937   Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
   12938 }
   12939 
   12940 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
   12941   VIXL_ASSERT(AllowAssembler());
   12942   CheckIT(cond);
   12943   if (IsUsingT32()) {
   12944     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   12945     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12946       EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12947                  rm.GetCode());
   12948       AdvanceIT();
   12949       return;
   12950     }
   12951   } else {
   12952     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   12953     if (cond.IsNotNever() &&
   12954         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   12955       EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12956               (rn.GetCode() << 16) | rm.GetCode());
   12957       return;
   12958     }
   12959   }
   12960   Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
   12961 }
   12962 
   12963 void Assembler::ubfx(
   12964     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
   12965   VIXL_ASSERT(AllowAssembler());
   12966   CheckIT(cond);
   12967   if (IsUsingT32()) {
   12968     // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
   12969     if ((lsb <= 31) &&
   12970         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
   12971          AllowUnpredictable())) {
   12972       uint32_t widthm1 = width - 1;
   12973       EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   12974                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
   12975       AdvanceIT();
   12976       return;
   12977     }
   12978   } else {
   12979     // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
   12980     if ((lsb <= 31) && cond.IsNotNever() &&
   12981         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
   12982          AllowUnpredictable())) {
   12983       uint32_t widthm1 = width - 1;
   12984       EmitA32(0x07e00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   12985               rn.GetCode() | (lsb << 7) | (widthm1 << 16));
   12986       return;
   12987     }
   12988   }
   12989   Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, width);
   12990 }
   12991 
   12992 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
   12993   VIXL_ASSERT(AllowAssembler());
   12994   CheckIT(cond);
   12995   if (IsUsingT32()) {
   12996     // UDF{<c>}{<q>} {#}<imm> ; T1
   12997     if (!size.IsWide() && (imm <= 255)) {
   12998       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   12999         EmitT32_16(0xde00 | imm);
   13000         AdvanceIT();
   13001         return;
   13002       }
   13003     }
   13004     // UDF{<c>}{<q>} {#}<imm> ; T2
   13005     if (!size.IsNarrow() && (imm <= 65535)) {
   13006       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13007         EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
   13008         AdvanceIT();
   13009         return;
   13010       }
   13011     }
   13012   } else {
   13013     // UDF{<c>}{<q>} {#}<imm> ; A1
   13014     if ((imm <= 65535)) {
   13015       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13016         EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
   13017         return;
   13018       }
   13019     }
   13020   }
   13021   Delegate(kUdf, &Assembler::udf, cond, size, imm);
   13022 }
   13023 
   13024 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
   13025   VIXL_ASSERT(AllowAssembler());
   13026   CheckIT(cond);
   13027   if (IsUsingT32()) {
   13028     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13029     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13030       EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13031                  rm.GetCode());
   13032       AdvanceIT();
   13033       return;
   13034     }
   13035   } else {
   13036     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13037     if (cond.IsNotNever() &&
   13038         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13039       EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   13040               rn.GetCode() | (rm.GetCode() << 8));
   13041       return;
   13042     }
   13043   }
   13044   Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
   13045 }
   13046 
   13047 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
   13048   VIXL_ASSERT(AllowAssembler());
   13049   CheckIT(cond);
   13050   if (IsUsingT32()) {
   13051     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13052     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13053       EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13054                  rm.GetCode());
   13055       AdvanceIT();
   13056       return;
   13057     }
   13058   } else {
   13059     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13060     if (cond.IsNotNever() &&
   13061         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13062       EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13063               (rn.GetCode() << 16) | rm.GetCode());
   13064       return;
   13065     }
   13066   }
   13067   Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
   13068 }
   13069 
   13070 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
   13071   VIXL_ASSERT(AllowAssembler());
   13072   CheckIT(cond);
   13073   if (IsUsingT32()) {
   13074     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13075     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13076       EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13077                  rm.GetCode());
   13078       AdvanceIT();
   13079       return;
   13080     }
   13081   } else {
   13082     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13083     if (cond.IsNotNever() &&
   13084         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13085       EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13086               (rn.GetCode() << 16) | rm.GetCode());
   13087       return;
   13088     }
   13089   }
   13090   Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
   13091 }
   13092 
   13093 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
   13094   VIXL_ASSERT(AllowAssembler());
   13095   CheckIT(cond);
   13096   if (IsUsingT32()) {
   13097     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13098     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13099       EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13100                  rm.GetCode());
   13101       AdvanceIT();
   13102       return;
   13103     }
   13104   } else {
   13105     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13106     if (cond.IsNotNever() &&
   13107         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13108       EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13109               (rn.GetCode() << 16) | rm.GetCode());
   13110       return;
   13111     }
   13112   }
   13113   Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
   13114 }
   13115 
   13116 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
   13117   VIXL_ASSERT(AllowAssembler());
   13118   CheckIT(cond);
   13119   if (IsUsingT32()) {
   13120     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13121     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13122       EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13123                  rm.GetCode());
   13124       AdvanceIT();
   13125       return;
   13126     }
   13127   } else {
   13128     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13129     if (cond.IsNotNever() &&
   13130         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13131       EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13132               (rn.GetCode() << 16) | rm.GetCode());
   13133       return;
   13134     }
   13135   }
   13136   Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
   13137 }
   13138 
   13139 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
   13140   VIXL_ASSERT(AllowAssembler());
   13141   CheckIT(cond);
   13142   if (IsUsingT32()) {
   13143     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13144     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13145       EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13146                  rm.GetCode());
   13147       AdvanceIT();
   13148       return;
   13149     }
   13150   } else {
   13151     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13152     if (cond.IsNotNever() &&
   13153         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13154       EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13155               (rn.GetCode() << 16) | rm.GetCode());
   13156       return;
   13157     }
   13158   }
   13159   Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
   13160 }
   13161 
   13162 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
   13163   VIXL_ASSERT(AllowAssembler());
   13164   CheckIT(cond);
   13165   if (IsUsingT32()) {
   13166     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13167     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13168       EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13169                  rm.GetCode());
   13170       AdvanceIT();
   13171       return;
   13172     }
   13173   } else {
   13174     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13175     if (cond.IsNotNever() &&
   13176         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13177       EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13178               (rn.GetCode() << 16) | rm.GetCode());
   13179       return;
   13180     }
   13181   }
   13182   Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
   13183 }
   13184 
   13185 void Assembler::umaal(
   13186     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   13187   VIXL_ASSERT(AllowAssembler());
   13188   CheckIT(cond);
   13189   if (IsUsingT32()) {
   13190     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   13191     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   13192          AllowUnpredictable())) {
   13193       EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   13194                  (rn.GetCode() << 16) | rm.GetCode());
   13195       AdvanceIT();
   13196       return;
   13197     }
   13198   } else {
   13199     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   13200     if (cond.IsNotNever() &&
   13201         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   13202          AllowUnpredictable())) {
   13203       EmitA32(0x00400090U | (cond.GetCondition() << 28) |
   13204               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   13205               (rm.GetCode() << 8));
   13206       return;
   13207     }
   13208   }
   13209   Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
   13210 }
   13211 
   13212 void Assembler::umlal(
   13213     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   13214   VIXL_ASSERT(AllowAssembler());
   13215   CheckIT(cond);
   13216   if (IsUsingT32()) {
   13217     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   13218     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   13219          AllowUnpredictable())) {
   13220       EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   13221                  (rn.GetCode() << 16) | rm.GetCode());
   13222       AdvanceIT();
   13223       return;
   13224     }
   13225   } else {
   13226     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   13227     if (cond.IsNotNever() &&
   13228         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   13229          AllowUnpredictable())) {
   13230       EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
   13231               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   13232               (rm.GetCode() << 8));
   13233       return;
   13234     }
   13235   }
   13236   Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
   13237 }
   13238 
   13239 void Assembler::umlals(
   13240     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   13241   VIXL_ASSERT(AllowAssembler());
   13242   CheckIT(cond);
   13243   if (IsUsingA32()) {
   13244     // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   13245     if (cond.IsNotNever() &&
   13246         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   13247          AllowUnpredictable())) {
   13248       EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
   13249               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   13250               (rm.GetCode() << 8));
   13251       return;
   13252     }
   13253   }
   13254   Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
   13255 }
   13256 
   13257 void Assembler::umull(
   13258     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   13259   VIXL_ASSERT(AllowAssembler());
   13260   CheckIT(cond);
   13261   if (IsUsingT32()) {
   13262     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
   13263     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   13264          AllowUnpredictable())) {
   13265       EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
   13266                  (rn.GetCode() << 16) | rm.GetCode());
   13267       AdvanceIT();
   13268       return;
   13269     }
   13270   } else {
   13271     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   13272     if (cond.IsNotNever() &&
   13273         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   13274          AllowUnpredictable())) {
   13275       EmitA32(0x00800090U | (cond.GetCondition() << 28) |
   13276               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   13277               (rm.GetCode() << 8));
   13278       return;
   13279     }
   13280   }
   13281   Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
   13282 }
   13283 
   13284 void Assembler::umulls(
   13285     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
   13286   VIXL_ASSERT(AllowAssembler());
   13287   CheckIT(cond);
   13288   if (IsUsingA32()) {
   13289     // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
   13290     if (cond.IsNotNever() &&
   13291         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
   13292          AllowUnpredictable())) {
   13293       EmitA32(0x00900090U | (cond.GetCondition() << 28) |
   13294               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
   13295               (rm.GetCode() << 8));
   13296       return;
   13297     }
   13298   }
   13299   Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
   13300 }
   13301 
   13302 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
   13303   VIXL_ASSERT(AllowAssembler());
   13304   CheckIT(cond);
   13305   if (IsUsingT32()) {
   13306     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13307     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13308       EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13309                  rm.GetCode());
   13310       AdvanceIT();
   13311       return;
   13312     }
   13313   } else {
   13314     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13315     if (cond.IsNotNever() &&
   13316         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13317       EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13318               (rn.GetCode() << 16) | rm.GetCode());
   13319       return;
   13320     }
   13321   }
   13322   Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
   13323 }
   13324 
   13325 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
   13326   VIXL_ASSERT(AllowAssembler());
   13327   CheckIT(cond);
   13328   if (IsUsingT32()) {
   13329     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13330     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13331       EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13332                  rm.GetCode());
   13333       AdvanceIT();
   13334       return;
   13335     }
   13336   } else {
   13337     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13338     if (cond.IsNotNever() &&
   13339         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13340       EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13341               (rn.GetCode() << 16) | rm.GetCode());
   13342       return;
   13343     }
   13344   }
   13345   Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
   13346 }
   13347 
   13348 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
   13349   VIXL_ASSERT(AllowAssembler());
   13350   CheckIT(cond);
   13351   if (IsUsingT32()) {
   13352     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13353     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13354       EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13355                  rm.GetCode());
   13356       AdvanceIT();
   13357       return;
   13358     }
   13359   } else {
   13360     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13361     if (cond.IsNotNever() &&
   13362         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13363       EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13364               (rn.GetCode() << 16) | rm.GetCode());
   13365       return;
   13366     }
   13367   }
   13368   Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
   13369 }
   13370 
   13371 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
   13372   VIXL_ASSERT(AllowAssembler());
   13373   CheckIT(cond);
   13374   if (IsUsingT32()) {
   13375     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13376     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13377       EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13378                  rm.GetCode());
   13379       AdvanceIT();
   13380       return;
   13381     }
   13382   } else {
   13383     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13384     if (cond.IsNotNever() &&
   13385         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13386       EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13387               (rn.GetCode() << 16) | rm.GetCode());
   13388       return;
   13389     }
   13390   }
   13391   Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
   13392 }
   13393 
   13394 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
   13395   VIXL_ASSERT(AllowAssembler());
   13396   CheckIT(cond);
   13397   if (IsUsingT32()) {
   13398     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13399     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13400       EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13401                  rm.GetCode());
   13402       AdvanceIT();
   13403       return;
   13404     }
   13405   } else {
   13406     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13407     if (cond.IsNotNever() &&
   13408         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13409       EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13410               (rn.GetCode() << 16) | rm.GetCode());
   13411       return;
   13412     }
   13413   }
   13414   Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
   13415 }
   13416 
   13417 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
   13418   VIXL_ASSERT(AllowAssembler());
   13419   CheckIT(cond);
   13420   if (IsUsingT32()) {
   13421     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13422     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13423       EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13424                  rm.GetCode());
   13425       AdvanceIT();
   13426       return;
   13427     }
   13428   } else {
   13429     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13430     if (cond.IsNotNever() &&
   13431         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13432       EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13433               (rn.GetCode() << 16) | rm.GetCode());
   13434       return;
   13435     }
   13436   }
   13437   Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
   13438 }
   13439 
   13440 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
   13441   VIXL_ASSERT(AllowAssembler());
   13442   CheckIT(cond);
   13443   if (IsUsingT32()) {
   13444     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13445     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13446       EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13447                  rm.GetCode());
   13448       AdvanceIT();
   13449       return;
   13450     }
   13451   } else {
   13452     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13453     if (cond.IsNotNever() &&
   13454         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13455       EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   13456               rn.GetCode() | (rm.GetCode() << 8));
   13457       return;
   13458     }
   13459   }
   13460   Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
   13461 }
   13462 
   13463 void Assembler::usada8(
   13464     Condition cond, Register rd, Register rn, Register rm, Register ra) {
   13465   VIXL_ASSERT(AllowAssembler());
   13466   CheckIT(cond);
   13467   if (IsUsingT32()) {
   13468     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
   13469     if (!ra.Is(pc) &&
   13470         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13471       EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13472                  rm.GetCode() | (ra.GetCode() << 12));
   13473       AdvanceIT();
   13474       return;
   13475     }
   13476   } else {
   13477     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
   13478     if (cond.IsNotNever() && !ra.Is(pc) &&
   13479         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13480       EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
   13481               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
   13482       return;
   13483     }
   13484   }
   13485   Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
   13486 }
   13487 
   13488 void Assembler::usat(Condition cond,
   13489                      Register rd,
   13490                      uint32_t imm,
   13491                      const Operand& operand) {
   13492   VIXL_ASSERT(AllowAssembler());
   13493   CheckIT(cond);
   13494   if (operand.IsImmediateShiftedRegister()) {
   13495     Register rn = operand.GetBaseRegister();
   13496     Shift shift = operand.GetShift();
   13497     uint32_t amount = operand.GetShiftAmount();
   13498     if (IsUsingT32()) {
   13499       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
   13500       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31) &&
   13501           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   13502         EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
   13503                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
   13504                    ((amount & 0x1c) << 10));
   13505         AdvanceIT();
   13506         return;
   13507       }
   13508       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
   13509       if ((imm <= 31) && shift.IsLSL() && (amount <= 31) &&
   13510           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   13511         EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
   13512                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
   13513                    ((amount & 0x1c) << 10));
   13514         AdvanceIT();
   13515         return;
   13516       }
   13517     } else {
   13518       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
   13519       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
   13520           cond.IsNotNever() &&
   13521           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   13522         uint32_t amount_ = amount % 32;
   13523         EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
   13524                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
   13525                 (amount_ << 7));
   13526         return;
   13527       }
   13528       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
   13529       if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever() &&
   13530           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   13531         EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
   13532                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
   13533                 (amount << 7));
   13534         return;
   13535       }
   13536     }
   13537   }
   13538   Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
   13539 }
   13540 
   13541 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
   13542   VIXL_ASSERT(AllowAssembler());
   13543   CheckIT(cond);
   13544   if (IsUsingT32()) {
   13545     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
   13546     if ((imm <= 15) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   13547       EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
   13548                  (rn.GetCode() << 16));
   13549       AdvanceIT();
   13550       return;
   13551     }
   13552   } else {
   13553     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
   13554     if ((imm <= 15) && cond.IsNotNever() &&
   13555         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
   13556       EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13557               (imm << 16) | rn.GetCode());
   13558       return;
   13559     }
   13560   }
   13561   Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
   13562 }
   13563 
   13564 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
   13565   VIXL_ASSERT(AllowAssembler());
   13566   CheckIT(cond);
   13567   if (IsUsingT32()) {
   13568     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13569     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13570       EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13571                  rm.GetCode());
   13572       AdvanceIT();
   13573       return;
   13574     }
   13575   } else {
   13576     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13577     if (cond.IsNotNever() &&
   13578         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13579       EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13580               (rn.GetCode() << 16) | rm.GetCode());
   13581       return;
   13582     }
   13583   }
   13584   Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
   13585 }
   13586 
   13587 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
   13588   VIXL_ASSERT(AllowAssembler());
   13589   CheckIT(cond);
   13590   if (IsUsingT32()) {
   13591     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13592     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13593       EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13594                  rm.GetCode());
   13595       AdvanceIT();
   13596       return;
   13597     }
   13598   } else {
   13599     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13600     if (cond.IsNotNever() &&
   13601         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13602       EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13603               (rn.GetCode() << 16) | rm.GetCode());
   13604       return;
   13605     }
   13606   }
   13607   Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
   13608 }
   13609 
   13610 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
   13611   VIXL_ASSERT(AllowAssembler());
   13612   CheckIT(cond);
   13613   if (IsUsingT32()) {
   13614     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
   13615     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13616       EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13617                  rm.GetCode());
   13618       AdvanceIT();
   13619       return;
   13620     }
   13621   } else {
   13622     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
   13623     if (cond.IsNotNever() &&
   13624         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13625       EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
   13626               (rn.GetCode() << 16) | rm.GetCode());
   13627       return;
   13628     }
   13629   }
   13630   Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
   13631 }
   13632 
   13633 void Assembler::uxtab(Condition cond,
   13634                       Register rd,
   13635                       Register rn,
   13636                       const Operand& operand) {
   13637   VIXL_ASSERT(AllowAssembler());
   13638   CheckIT(cond);
   13639   if (operand.IsImmediateShiftedRegister()) {
   13640     Register rm = operand.GetBaseRegister();
   13641     Shift shift = operand.GetShift();
   13642     uint32_t amount = operand.GetShiftAmount();
   13643     if (IsUsingT32()) {
   13644       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   13645       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13646           ((amount % 8) == 0) && !rn.Is(pc) &&
   13647           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13648         uint32_t amount_ = amount / 8;
   13649         EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13650                    rm.GetCode() | (amount_ << 4));
   13651         AdvanceIT();
   13652         return;
   13653       }
   13654     } else {
   13655       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   13656       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13657           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
   13658           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13659         uint32_t amount_ = amount / 8;
   13660         EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
   13661                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   13662                 (amount_ << 10));
   13663         return;
   13664       }
   13665     }
   13666   }
   13667   Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
   13668 }
   13669 
   13670 void Assembler::uxtab16(Condition cond,
   13671                         Register rd,
   13672                         Register rn,
   13673                         const Operand& operand) {
   13674   VIXL_ASSERT(AllowAssembler());
   13675   CheckIT(cond);
   13676   if (operand.IsImmediateShiftedRegister()) {
   13677     Register rm = operand.GetBaseRegister();
   13678     Shift shift = operand.GetShift();
   13679     uint32_t amount = operand.GetShiftAmount();
   13680     if (IsUsingT32()) {
   13681       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   13682       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13683           ((amount % 8) == 0) && !rn.Is(pc) &&
   13684           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13685         uint32_t amount_ = amount / 8;
   13686         EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13687                    rm.GetCode() | (amount_ << 4));
   13688         AdvanceIT();
   13689         return;
   13690       }
   13691     } else {
   13692       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   13693       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13694           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
   13695           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13696         uint32_t amount_ = amount / 8;
   13697         EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
   13698                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   13699                 (amount_ << 10));
   13700         return;
   13701       }
   13702     }
   13703   }
   13704   Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
   13705 }
   13706 
   13707 void Assembler::uxtah(Condition cond,
   13708                       Register rd,
   13709                       Register rn,
   13710                       const Operand& operand) {
   13711   VIXL_ASSERT(AllowAssembler());
   13712   CheckIT(cond);
   13713   if (operand.IsImmediateShiftedRegister()) {
   13714     Register rm = operand.GetBaseRegister();
   13715     Shift shift = operand.GetShift();
   13716     uint32_t amount = operand.GetShiftAmount();
   13717     if (IsUsingT32()) {
   13718       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
   13719       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13720           ((amount % 8) == 0) && !rn.Is(pc) &&
   13721           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13722         uint32_t amount_ = amount / 8;
   13723         EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
   13724                    rm.GetCode() | (amount_ << 4));
   13725         AdvanceIT();
   13726         return;
   13727       }
   13728     } else {
   13729       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
   13730       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13731           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
   13732           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13733         uint32_t amount_ = amount / 8;
   13734         EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
   13735                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
   13736                 (amount_ << 10));
   13737         return;
   13738       }
   13739     }
   13740   }
   13741   Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
   13742 }
   13743 
   13744 void Assembler::uxtb(Condition cond,
   13745                      EncodingSize size,
   13746                      Register rd,
   13747                      const Operand& operand) {
   13748   VIXL_ASSERT(AllowAssembler());
   13749   CheckIT(cond);
   13750   if (operand.IsImmediateShiftedRegister()) {
   13751     Register rm = operand.GetBaseRegister();
   13752     if (operand.IsPlainRegister()) {
   13753       if (IsUsingT32()) {
   13754         // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
   13755         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   13756           EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
   13757           AdvanceIT();
   13758           return;
   13759         }
   13760       }
   13761     }
   13762     Shift shift = operand.GetShift();
   13763     uint32_t amount = operand.GetShiftAmount();
   13764     if (IsUsingT32()) {
   13765       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
   13766       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
   13767           (amount <= 24) && ((amount % 8) == 0) &&
   13768           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13769         uint32_t amount_ = amount / 8;
   13770         EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   13771                    (amount_ << 4));
   13772         AdvanceIT();
   13773         return;
   13774       }
   13775     } else {
   13776       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   13777       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13778           ((amount % 8) == 0) && cond.IsNotNever() &&
   13779           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13780         uint32_t amount_ = amount / 8;
   13781         EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
   13782                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   13783         return;
   13784       }
   13785     }
   13786   }
   13787   Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
   13788 }
   13789 
   13790 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
   13791   VIXL_ASSERT(AllowAssembler());
   13792   CheckIT(cond);
   13793   if (operand.IsImmediateShiftedRegister()) {
   13794     Register rm = operand.GetBaseRegister();
   13795     Shift shift = operand.GetShift();
   13796     uint32_t amount = operand.GetShiftAmount();
   13797     if (IsUsingT32()) {
   13798       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
   13799       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13800           ((amount % 8) == 0) &&
   13801           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13802         uint32_t amount_ = amount / 8;
   13803         EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   13804                    (amount_ << 4));
   13805         AdvanceIT();
   13806         return;
   13807       }
   13808     } else {
   13809       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   13810       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13811           ((amount % 8) == 0) && cond.IsNotNever() &&
   13812           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13813         uint32_t amount_ = amount / 8;
   13814         EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
   13815                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   13816         return;
   13817       }
   13818     }
   13819   }
   13820   Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
   13821 }
   13822 
   13823 void Assembler::uxth(Condition cond,
   13824                      EncodingSize size,
   13825                      Register rd,
   13826                      const Operand& operand) {
   13827   VIXL_ASSERT(AllowAssembler());
   13828   CheckIT(cond);
   13829   if (operand.IsImmediateShiftedRegister()) {
   13830     Register rm = operand.GetBaseRegister();
   13831     if (operand.IsPlainRegister()) {
   13832       if (IsUsingT32()) {
   13833         // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
   13834         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
   13835           EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
   13836           AdvanceIT();
   13837           return;
   13838         }
   13839       }
   13840     }
   13841     Shift shift = operand.GetShift();
   13842     uint32_t amount = operand.GetShiftAmount();
   13843     if (IsUsingT32()) {
   13844       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
   13845       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
   13846           (amount <= 24) && ((amount % 8) == 0) &&
   13847           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13848         uint32_t amount_ = amount / 8;
   13849         EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
   13850                    (amount_ << 4));
   13851         AdvanceIT();
   13852         return;
   13853       }
   13854     } else {
   13855       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
   13856       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
   13857           ((amount % 8) == 0) && cond.IsNotNever() &&
   13858           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
   13859         uint32_t amount_ = amount / 8;
   13860         EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
   13861                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
   13862         return;
   13863       }
   13864     }
   13865   }
   13866   Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
   13867 }
   13868 
   13869 void Assembler::vaba(
   13870     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13871   VIXL_ASSERT(AllowAssembler());
   13872   CheckIT(cond);
   13873   Dt_U_size_1 encoded_dt(dt);
   13874   if (IsUsingT32()) {
   13875     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
   13876     if (encoded_dt.IsValid()) {
   13877       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13878         EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13879                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   13880                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13881         AdvanceIT();
   13882         return;
   13883       }
   13884     }
   13885   } else {
   13886     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
   13887     if (encoded_dt.IsValid()) {
   13888       if (cond.Is(al)) {
   13889         EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13890                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   13891                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13892         return;
   13893       }
   13894     }
   13895   }
   13896   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
   13897 }
   13898 
   13899 void Assembler::vaba(
   13900     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   13901   VIXL_ASSERT(AllowAssembler());
   13902   CheckIT(cond);
   13903   Dt_U_size_1 encoded_dt(dt);
   13904   if (IsUsingT32()) {
   13905     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
   13906     if (encoded_dt.IsValid()) {
   13907       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13908         EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13909                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   13910                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13911         AdvanceIT();
   13912         return;
   13913       }
   13914     }
   13915   } else {
   13916     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
   13917     if (encoded_dt.IsValid()) {
   13918       if (cond.Is(al)) {
   13919         EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13920                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   13921                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13922         return;
   13923       }
   13924     }
   13925   }
   13926   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
   13927 }
   13928 
   13929 void Assembler::vabal(
   13930     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   13931   VIXL_ASSERT(AllowAssembler());
   13932   CheckIT(cond);
   13933   Dt_U_size_1 encoded_dt(dt);
   13934   if (IsUsingT32()) {
   13935     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   13936     if (encoded_dt.IsValid()) {
   13937       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13938         EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13939                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   13940                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13941         AdvanceIT();
   13942         return;
   13943       }
   13944     }
   13945   } else {
   13946     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   13947     if (encoded_dt.IsValid()) {
   13948       if (cond.Is(al)) {
   13949         EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13950                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   13951                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13952         return;
   13953       }
   13954     }
   13955   }
   13956   Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
   13957 }
   13958 
   13959 void Assembler::vabd(
   13960     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   13961   VIXL_ASSERT(AllowAssembler());
   13962   CheckIT(cond);
   13963   Dt_U_size_1 encoded_dt(dt);
   13964   if (IsUsingT32()) {
   13965     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   13966     if (dt.Is(F32)) {
   13967       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13968         EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13969                    rm.Encode(5, 0));
   13970         AdvanceIT();
   13971         return;
   13972       }
   13973     }
   13974     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   13975     if (encoded_dt.IsValid()) {
   13976       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   13977         EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13978                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   13979                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13980         AdvanceIT();
   13981         return;
   13982       }
   13983     }
   13984   } else {
   13985     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   13986     if (dt.Is(F32)) {
   13987       if (cond.Is(al)) {
   13988         EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   13989                 rm.Encode(5, 0));
   13990         return;
   13991       }
   13992     }
   13993     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   13994     if (encoded_dt.IsValid()) {
   13995       if (cond.Is(al)) {
   13996         EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   13997                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   13998                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   13999         return;
   14000       }
   14001     }
   14002   }
   14003   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
   14004 }
   14005 
   14006 void Assembler::vabd(
   14007     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14008   VIXL_ASSERT(AllowAssembler());
   14009   CheckIT(cond);
   14010   Dt_U_size_1 encoded_dt(dt);
   14011   if (IsUsingT32()) {
   14012     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   14013     if (dt.Is(F32)) {
   14014       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14015         EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14016                    rm.Encode(5, 0));
   14017         AdvanceIT();
   14018         return;
   14019       }
   14020     }
   14021     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   14022     if (encoded_dt.IsValid()) {
   14023       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14024         EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14025                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14026                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14027         AdvanceIT();
   14028         return;
   14029       }
   14030     }
   14031   } else {
   14032     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   14033     if (dt.Is(F32)) {
   14034       if (cond.Is(al)) {
   14035         EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14036                 rm.Encode(5, 0));
   14037         return;
   14038       }
   14039     }
   14040     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   14041     if (encoded_dt.IsValid()) {
   14042       if (cond.Is(al)) {
   14043         EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14044                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14045                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14046         return;
   14047       }
   14048     }
   14049   }
   14050   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
   14051 }
   14052 
   14053 void Assembler::vabdl(
   14054     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   14055   VIXL_ASSERT(AllowAssembler());
   14056   CheckIT(cond);
   14057   Dt_U_size_1 encoded_dt(dt);
   14058   if (IsUsingT32()) {
   14059     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   14060     if (encoded_dt.IsValid()) {
   14061       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14062         EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14063                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14064                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14065         AdvanceIT();
   14066         return;
   14067       }
   14068     }
   14069   } else {
   14070     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   14071     if (encoded_dt.IsValid()) {
   14072       if (cond.Is(al)) {
   14073         EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14074                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14075                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14076         return;
   14077       }
   14078     }
   14079   }
   14080   Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
   14081 }
   14082 
   14083 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   14084   VIXL_ASSERT(AllowAssembler());
   14085   CheckIT(cond);
   14086   Dt_F_size_1 encoded_dt(dt);
   14087   if (IsUsingT32()) {
   14088     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   14089     if (encoded_dt.IsValid()) {
   14090       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14091         EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14092                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14093                    rd.Encode(22, 12) | rm.Encode(5, 0));
   14094         AdvanceIT();
   14095         return;
   14096       }
   14097     }
   14098     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
   14099     if (dt.Is(F64)) {
   14100       EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   14101       AdvanceIT();
   14102       return;
   14103     }
   14104   } else {
   14105     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   14106     if (encoded_dt.IsValid()) {
   14107       if (cond.Is(al)) {
   14108         EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14109                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14110                 rd.Encode(22, 12) | rm.Encode(5, 0));
   14111         return;
   14112       }
   14113     }
   14114     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
   14115     if (dt.Is(F64) && cond.IsNotNever()) {
   14116       EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   14117               rm.Encode(5, 0));
   14118       return;
   14119     }
   14120   }
   14121   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
   14122 }
   14123 
   14124 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   14125   VIXL_ASSERT(AllowAssembler());
   14126   CheckIT(cond);
   14127   Dt_F_size_1 encoded_dt(dt);
   14128   if (IsUsingT32()) {
   14129     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   14130     if (encoded_dt.IsValid()) {
   14131       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14132         EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14133                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14134                    rd.Encode(22, 12) | rm.Encode(5, 0));
   14135         AdvanceIT();
   14136         return;
   14137       }
   14138     }
   14139   } else {
   14140     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   14141     if (encoded_dt.IsValid()) {
   14142       if (cond.Is(al)) {
   14143         EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14144                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14145                 rd.Encode(22, 12) | rm.Encode(5, 0));
   14146         return;
   14147       }
   14148     }
   14149   }
   14150   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
   14151 }
   14152 
   14153 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
   14154   VIXL_ASSERT(AllowAssembler());
   14155   CheckIT(cond);
   14156   if (IsUsingT32()) {
   14157     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
   14158     if (dt.Is(F32)) {
   14159       EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   14160       AdvanceIT();
   14161       return;
   14162     }
   14163   } else {
   14164     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
   14165     if (dt.Is(F32) && cond.IsNotNever()) {
   14166       EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   14167               rm.Encode(5, 0));
   14168       return;
   14169     }
   14170   }
   14171   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
   14172 }
   14173 
   14174 void Assembler::vacge(
   14175     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14176   VIXL_ASSERT(AllowAssembler());
   14177   CheckIT(cond);
   14178   if (IsUsingT32()) {
   14179     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   14180     if (dt.Is(F32)) {
   14181       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14182         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14183                    rm.Encode(5, 0));
   14184         AdvanceIT();
   14185         return;
   14186       }
   14187     }
   14188   } else {
   14189     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   14190     if (dt.Is(F32)) {
   14191       if (cond.Is(al)) {
   14192         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14193                 rm.Encode(5, 0));
   14194         return;
   14195       }
   14196     }
   14197   }
   14198   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
   14199 }
   14200 
   14201 void Assembler::vacge(
   14202     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14203   VIXL_ASSERT(AllowAssembler());
   14204   CheckIT(cond);
   14205   if (IsUsingT32()) {
   14206     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   14207     if (dt.Is(F32)) {
   14208       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14209         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14210                    rm.Encode(5, 0));
   14211         AdvanceIT();
   14212         return;
   14213       }
   14214     }
   14215   } else {
   14216     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   14217     if (dt.Is(F32)) {
   14218       if (cond.Is(al)) {
   14219         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14220                 rm.Encode(5, 0));
   14221         return;
   14222       }
   14223     }
   14224   }
   14225   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
   14226 }
   14227 
   14228 void Assembler::vacgt(
   14229     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14230   VIXL_ASSERT(AllowAssembler());
   14231   CheckIT(cond);
   14232   if (IsUsingT32()) {
   14233     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   14234     if (dt.Is(F32)) {
   14235       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14236         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14237                    rm.Encode(5, 0));
   14238         AdvanceIT();
   14239         return;
   14240       }
   14241     }
   14242   } else {
   14243     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   14244     if (dt.Is(F32)) {
   14245       if (cond.Is(al)) {
   14246         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14247                 rm.Encode(5, 0));
   14248         return;
   14249       }
   14250     }
   14251   }
   14252   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
   14253 }
   14254 
   14255 void Assembler::vacgt(
   14256     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14257   VIXL_ASSERT(AllowAssembler());
   14258   CheckIT(cond);
   14259   if (IsUsingT32()) {
   14260     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   14261     if (dt.Is(F32)) {
   14262       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14263         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14264                    rm.Encode(5, 0));
   14265         AdvanceIT();
   14266         return;
   14267       }
   14268     }
   14269   } else {
   14270     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   14271     if (dt.Is(F32)) {
   14272       if (cond.Is(al)) {
   14273         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14274                 rm.Encode(5, 0));
   14275         return;
   14276       }
   14277     }
   14278   }
   14279   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
   14280 }
   14281 
   14282 void Assembler::vacle(
   14283     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14284   VIXL_ASSERT(AllowAssembler());
   14285   CheckIT(cond);
   14286   if (IsUsingT32()) {
   14287     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   14288     if (dt.Is(F32)) {
   14289       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14290         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14291                    rm.Encode(5, 0));
   14292         AdvanceIT();
   14293         return;
   14294       }
   14295     }
   14296   } else {
   14297     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   14298     if (dt.Is(F32)) {
   14299       if (cond.Is(al)) {
   14300         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14301                 rm.Encode(5, 0));
   14302         return;
   14303       }
   14304     }
   14305   }
   14306   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
   14307 }
   14308 
   14309 void Assembler::vacle(
   14310     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14311   VIXL_ASSERT(AllowAssembler());
   14312   CheckIT(cond);
   14313   if (IsUsingT32()) {
   14314     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   14315     if (dt.Is(F32)) {
   14316       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14317         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14318                    rm.Encode(5, 0));
   14319         AdvanceIT();
   14320         return;
   14321       }
   14322     }
   14323   } else {
   14324     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   14325     if (dt.Is(F32)) {
   14326       if (cond.Is(al)) {
   14327         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14328                 rm.Encode(5, 0));
   14329         return;
   14330       }
   14331     }
   14332   }
   14333   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
   14334 }
   14335 
   14336 void Assembler::vaclt(
   14337     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14338   VIXL_ASSERT(AllowAssembler());
   14339   CheckIT(cond);
   14340   if (IsUsingT32()) {
   14341     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   14342     if (dt.Is(F32)) {
   14343       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14344         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14345                    rm.Encode(5, 0));
   14346         AdvanceIT();
   14347         return;
   14348       }
   14349     }
   14350   } else {
   14351     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   14352     if (dt.Is(F32)) {
   14353       if (cond.Is(al)) {
   14354         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14355                 rm.Encode(5, 0));
   14356         return;
   14357       }
   14358     }
   14359   }
   14360   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
   14361 }
   14362 
   14363 void Assembler::vaclt(
   14364     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14365   VIXL_ASSERT(AllowAssembler());
   14366   CheckIT(cond);
   14367   if (IsUsingT32()) {
   14368     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   14369     if (dt.Is(F32)) {
   14370       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14371         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14372                    rm.Encode(5, 0));
   14373         AdvanceIT();
   14374         return;
   14375       }
   14376     }
   14377   } else {
   14378     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   14379     if (dt.Is(F32)) {
   14380       if (cond.Is(al)) {
   14381         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14382                 rm.Encode(5, 0));
   14383         return;
   14384       }
   14385     }
   14386   }
   14387   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
   14388 }
   14389 
   14390 void Assembler::vadd(
   14391     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14392   VIXL_ASSERT(AllowAssembler());
   14393   CheckIT(cond);
   14394   Dt_size_2 encoded_dt(dt);
   14395   if (IsUsingT32()) {
   14396     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   14397     if (dt.Is(F32)) {
   14398       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14399         EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14400                    rm.Encode(5, 0));
   14401         AdvanceIT();
   14402         return;
   14403       }
   14404     }
   14405     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
   14406     if (dt.Is(F64)) {
   14407       EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14408                  rm.Encode(5, 0));
   14409       AdvanceIT();
   14410       return;
   14411     }
   14412     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   14413     if (encoded_dt.IsValid()) {
   14414       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14415         EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
   14416                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14417         AdvanceIT();
   14418         return;
   14419       }
   14420     }
   14421   } else {
   14422     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   14423     if (dt.Is(F32)) {
   14424       if (cond.Is(al)) {
   14425         EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14426                 rm.Encode(5, 0));
   14427         return;
   14428       }
   14429     }
   14430     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
   14431     if (dt.Is(F64) && cond.IsNotNever()) {
   14432       EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   14433               rn.Encode(7, 16) | rm.Encode(5, 0));
   14434       return;
   14435     }
   14436     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   14437     if (encoded_dt.IsValid()) {
   14438       if (cond.Is(al)) {
   14439         EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
   14440                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14441         return;
   14442       }
   14443     }
   14444   }
   14445   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
   14446 }
   14447 
   14448 void Assembler::vadd(
   14449     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14450   VIXL_ASSERT(AllowAssembler());
   14451   CheckIT(cond);
   14452   Dt_size_2 encoded_dt(dt);
   14453   if (IsUsingT32()) {
   14454     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   14455     if (dt.Is(F32)) {
   14456       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14457         EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14458                    rm.Encode(5, 0));
   14459         AdvanceIT();
   14460         return;
   14461       }
   14462     }
   14463     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   14464     if (encoded_dt.IsValid()) {
   14465       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14466         EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
   14467                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14468         AdvanceIT();
   14469         return;
   14470       }
   14471     }
   14472   } else {
   14473     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   14474     if (dt.Is(F32)) {
   14475       if (cond.Is(al)) {
   14476         EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14477                 rm.Encode(5, 0));
   14478         return;
   14479       }
   14480     }
   14481     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   14482     if (encoded_dt.IsValid()) {
   14483       if (cond.Is(al)) {
   14484         EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
   14485                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14486         return;
   14487       }
   14488     }
   14489   }
   14490   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
   14491 }
   14492 
   14493 void Assembler::vadd(
   14494     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   14495   VIXL_ASSERT(AllowAssembler());
   14496   CheckIT(cond);
   14497   if (IsUsingT32()) {
   14498     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
   14499     if (dt.Is(F32)) {
   14500       EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14501                  rm.Encode(5, 0));
   14502       AdvanceIT();
   14503       return;
   14504     }
   14505   } else {
   14506     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
   14507     if (dt.Is(F32) && cond.IsNotNever()) {
   14508       EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   14509               rn.Encode(7, 16) | rm.Encode(5, 0));
   14510       return;
   14511     }
   14512   }
   14513   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
   14514 }
   14515 
   14516 void Assembler::vaddhn(
   14517     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
   14518   VIXL_ASSERT(AllowAssembler());
   14519   CheckIT(cond);
   14520   Dt_size_3 encoded_dt(dt);
   14521   if (IsUsingT32()) {
   14522     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
   14523     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   14524       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14525         EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
   14526                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14527         AdvanceIT();
   14528         return;
   14529       }
   14530     }
   14531   } else {
   14532     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
   14533     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   14534       if (cond.Is(al)) {
   14535         EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
   14536                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14537         return;
   14538       }
   14539     }
   14540   }
   14541   Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
   14542 }
   14543 
   14544 void Assembler::vaddl(
   14545     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   14546   VIXL_ASSERT(AllowAssembler());
   14547   CheckIT(cond);
   14548   Dt_U_size_1 encoded_dt(dt);
   14549   if (IsUsingT32()) {
   14550     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   14551     if (encoded_dt.IsValid()) {
   14552       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14553         EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14554                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14555                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14556         AdvanceIT();
   14557         return;
   14558       }
   14559     }
   14560   } else {
   14561     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   14562     if (encoded_dt.IsValid()) {
   14563       if (cond.Is(al)) {
   14564         EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14565                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14566                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14567         return;
   14568       }
   14569     }
   14570   }
   14571   Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
   14572 }
   14573 
   14574 void Assembler::vaddw(
   14575     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
   14576   VIXL_ASSERT(AllowAssembler());
   14577   CheckIT(cond);
   14578   Dt_U_size_1 encoded_dt(dt);
   14579   if (IsUsingT32()) {
   14580     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
   14581     if (encoded_dt.IsValid()) {
   14582       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14583         EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14584                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   14585                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14586         AdvanceIT();
   14587         return;
   14588       }
   14589     }
   14590   } else {
   14591     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
   14592     if (encoded_dt.IsValid()) {
   14593       if (cond.Is(al)) {
   14594         EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   14595                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   14596                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   14597         return;
   14598       }
   14599     }
   14600   }
   14601   Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
   14602 }
   14603 
   14604 void Assembler::vand(Condition cond,
   14605                      DataType dt,
   14606                      DRegister rd,
   14607                      DRegister rn,
   14608                      const DOperand& operand) {
   14609   VIXL_ASSERT(AllowAssembler());
   14610   CheckIT(cond);
   14611   if (operand.IsImmediate()) {
   14612     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
   14613     if (IsUsingT32()) {
   14614       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
   14615       if (encoded_dt.IsValid() && rd.Is(rn)) {
   14616         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14617           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
   14618                      rd.Encode(22, 12) |
   14619                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   14620                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   14621                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   14622           AdvanceIT();
   14623           return;
   14624         }
   14625       }
   14626     } else {
   14627       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
   14628       if (encoded_dt.IsValid() && rd.Is(rn)) {
   14629         if (cond.Is(al)) {
   14630           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
   14631                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   14632                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   14633                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   14634           return;
   14635         }
   14636       }
   14637     }
   14638   }
   14639   if (operand.IsRegister()) {
   14640     DRegister rm = operand.GetRegister();
   14641     USE(dt);
   14642     if (IsUsingT32()) {
   14643       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   14644       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14645         EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14646                    rm.Encode(5, 0));
   14647         AdvanceIT();
   14648         return;
   14649       }
   14650     } else {
   14651       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   14652       if (cond.Is(al)) {
   14653         EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14654                 rm.Encode(5, 0));
   14655         return;
   14656       }
   14657     }
   14658   }
   14659   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
   14660 }
   14661 
   14662 void Assembler::vand(Condition cond,
   14663                      DataType dt,
   14664                      QRegister rd,
   14665                      QRegister rn,
   14666                      const QOperand& operand) {
   14667   VIXL_ASSERT(AllowAssembler());
   14668   CheckIT(cond);
   14669   if (operand.IsImmediate()) {
   14670     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
   14671     if (IsUsingT32()) {
   14672       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
   14673       if (encoded_dt.IsValid() && rd.Is(rn)) {
   14674         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14675           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
   14676                      rd.Encode(22, 12) |
   14677                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   14678                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   14679                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   14680           AdvanceIT();
   14681           return;
   14682         }
   14683       }
   14684     } else {
   14685       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
   14686       if (encoded_dt.IsValid() && rd.Is(rn)) {
   14687         if (cond.Is(al)) {
   14688           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
   14689                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   14690                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   14691                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   14692           return;
   14693         }
   14694       }
   14695     }
   14696   }
   14697   if (operand.IsRegister()) {
   14698     QRegister rm = operand.GetRegister();
   14699     USE(dt);
   14700     if (IsUsingT32()) {
   14701       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   14702       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14703         EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14704                    rm.Encode(5, 0));
   14705         AdvanceIT();
   14706         return;
   14707       }
   14708     } else {
   14709       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   14710       if (cond.Is(al)) {
   14711         EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14712                 rm.Encode(5, 0));
   14713         return;
   14714       }
   14715     }
   14716   }
   14717   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
   14718 }
   14719 
   14720 void Assembler::vbic(Condition cond,
   14721                      DataType dt,
   14722                      DRegister rd,
   14723                      DRegister rn,
   14724                      const DOperand& operand) {
   14725   VIXL_ASSERT(AllowAssembler());
   14726   CheckIT(cond);
   14727   if (operand.IsImmediate()) {
   14728     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
   14729     if (IsUsingT32()) {
   14730       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
   14731       if (encoded_dt.IsValid() && rd.Is(rn)) {
   14732         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14733           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
   14734                      rd.Encode(22, 12) |
   14735                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   14736                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   14737                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   14738           AdvanceIT();
   14739           return;
   14740         }
   14741       }
   14742     } else {
   14743       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
   14744       if (encoded_dt.IsValid() && rd.Is(rn)) {
   14745         if (cond.Is(al)) {
   14746           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
   14747                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   14748                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   14749                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   14750           return;
   14751         }
   14752       }
   14753     }
   14754   }
   14755   if (operand.IsRegister()) {
   14756     DRegister rm = operand.GetRegister();
   14757     USE(dt);
   14758     if (IsUsingT32()) {
   14759       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   14760       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14761         EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14762                    rm.Encode(5, 0));
   14763         AdvanceIT();
   14764         return;
   14765       }
   14766     } else {
   14767       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   14768       if (cond.Is(al)) {
   14769         EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14770                 rm.Encode(5, 0));
   14771         return;
   14772       }
   14773     }
   14774   }
   14775   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
   14776 }
   14777 
   14778 void Assembler::vbic(Condition cond,
   14779                      DataType dt,
   14780                      QRegister rd,
   14781                      QRegister rn,
   14782                      const QOperand& operand) {
   14783   VIXL_ASSERT(AllowAssembler());
   14784   CheckIT(cond);
   14785   if (operand.IsImmediate()) {
   14786     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
   14787     if (IsUsingT32()) {
   14788       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
   14789       if (encoded_dt.IsValid() && rd.Is(rn)) {
   14790         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14791           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
   14792                      rd.Encode(22, 12) |
   14793                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   14794                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   14795                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   14796           AdvanceIT();
   14797           return;
   14798         }
   14799       }
   14800     } else {
   14801       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
   14802       if (encoded_dt.IsValid() && rd.Is(rn)) {
   14803         if (cond.Is(al)) {
   14804           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
   14805                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   14806                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   14807                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   14808           return;
   14809         }
   14810       }
   14811     }
   14812   }
   14813   if (operand.IsRegister()) {
   14814     QRegister rm = operand.GetRegister();
   14815     USE(dt);
   14816     if (IsUsingT32()) {
   14817       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   14818       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14819         EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14820                    rm.Encode(5, 0));
   14821         AdvanceIT();
   14822         return;
   14823       }
   14824     } else {
   14825       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   14826       if (cond.Is(al)) {
   14827         EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14828                 rm.Encode(5, 0));
   14829         return;
   14830       }
   14831     }
   14832   }
   14833   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
   14834 }
   14835 
   14836 void Assembler::vbif(
   14837     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14838   VIXL_ASSERT(AllowAssembler());
   14839   CheckIT(cond);
   14840   USE(dt);
   14841   if (IsUsingT32()) {
   14842     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   14843     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14844       EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14845                  rm.Encode(5, 0));
   14846       AdvanceIT();
   14847       return;
   14848     }
   14849   } else {
   14850     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   14851     if (cond.Is(al)) {
   14852       EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14853               rm.Encode(5, 0));
   14854       return;
   14855     }
   14856   }
   14857   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
   14858 }
   14859 
   14860 void Assembler::vbif(
   14861     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14862   VIXL_ASSERT(AllowAssembler());
   14863   CheckIT(cond);
   14864   USE(dt);
   14865   if (IsUsingT32()) {
   14866     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   14867     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14868       EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14869                  rm.Encode(5, 0));
   14870       AdvanceIT();
   14871       return;
   14872     }
   14873   } else {
   14874     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   14875     if (cond.Is(al)) {
   14876       EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14877               rm.Encode(5, 0));
   14878       return;
   14879     }
   14880   }
   14881   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
   14882 }
   14883 
   14884 void Assembler::vbit(
   14885     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14886   VIXL_ASSERT(AllowAssembler());
   14887   CheckIT(cond);
   14888   USE(dt);
   14889   if (IsUsingT32()) {
   14890     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   14891     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14892       EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14893                  rm.Encode(5, 0));
   14894       AdvanceIT();
   14895       return;
   14896     }
   14897   } else {
   14898     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   14899     if (cond.Is(al)) {
   14900       EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14901               rm.Encode(5, 0));
   14902       return;
   14903     }
   14904   }
   14905   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
   14906 }
   14907 
   14908 void Assembler::vbit(
   14909     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14910   VIXL_ASSERT(AllowAssembler());
   14911   CheckIT(cond);
   14912   USE(dt);
   14913   if (IsUsingT32()) {
   14914     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   14915     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14916       EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14917                  rm.Encode(5, 0));
   14918       AdvanceIT();
   14919       return;
   14920     }
   14921   } else {
   14922     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   14923     if (cond.Is(al)) {
   14924       EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14925               rm.Encode(5, 0));
   14926       return;
   14927     }
   14928   }
   14929   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
   14930 }
   14931 
   14932 void Assembler::vbsl(
   14933     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   14934   VIXL_ASSERT(AllowAssembler());
   14935   CheckIT(cond);
   14936   USE(dt);
   14937   if (IsUsingT32()) {
   14938     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   14939     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14940       EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14941                  rm.Encode(5, 0));
   14942       AdvanceIT();
   14943       return;
   14944     }
   14945   } else {
   14946     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   14947     if (cond.Is(al)) {
   14948       EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14949               rm.Encode(5, 0));
   14950       return;
   14951     }
   14952   }
   14953   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
   14954 }
   14955 
   14956 void Assembler::vbsl(
   14957     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   14958   VIXL_ASSERT(AllowAssembler());
   14959   CheckIT(cond);
   14960   USE(dt);
   14961   if (IsUsingT32()) {
   14962     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   14963     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14964       EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14965                  rm.Encode(5, 0));
   14966       AdvanceIT();
   14967       return;
   14968     }
   14969   } else {
   14970     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   14971     if (cond.Is(al)) {
   14972       EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   14973               rm.Encode(5, 0));
   14974       return;
   14975     }
   14976   }
   14977   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
   14978 }
   14979 
   14980 void Assembler::vceq(Condition cond,
   14981                      DataType dt,
   14982                      DRegister rd,
   14983                      DRegister rm,
   14984                      const DOperand& operand) {
   14985   VIXL_ASSERT(AllowAssembler());
   14986   CheckIT(cond);
   14987   if (operand.IsImmediate()) {
   14988     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   14989       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   14990       Dt_F_size_2 encoded_dt(dt);
   14991       if (IsUsingT32()) {
   14992         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   14993         if (encoded_dt.IsValid() && (imm == 0)) {
   14994           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   14995             EmitT32_32(0xffb10100U |
   14996                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   14997                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   14998                        rd.Encode(22, 12) | rm.Encode(5, 0));
   14999             AdvanceIT();
   15000             return;
   15001           }
   15002         }
   15003       } else {
   15004         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   15005         if (encoded_dt.IsValid() && (imm == 0)) {
   15006           if (cond.Is(al)) {
   15007             EmitA32(0xf3b10100U |
   15008                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15009                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15010                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15011             return;
   15012           }
   15013         }
   15014       }
   15015     }
   15016   }
   15017   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
   15018 }
   15019 
   15020 void Assembler::vceq(Condition cond,
   15021                      DataType dt,
   15022                      QRegister rd,
   15023                      QRegister rm,
   15024                      const QOperand& operand) {
   15025   VIXL_ASSERT(AllowAssembler());
   15026   CheckIT(cond);
   15027   if (operand.IsImmediate()) {
   15028     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15029       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15030       Dt_F_size_2 encoded_dt(dt);
   15031       if (IsUsingT32()) {
   15032         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   15033         if (encoded_dt.IsValid() && (imm == 0)) {
   15034           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15035             EmitT32_32(0xffb10140U |
   15036                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15037                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15038                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15039             AdvanceIT();
   15040             return;
   15041           }
   15042         }
   15043       } else {
   15044         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   15045         if (encoded_dt.IsValid() && (imm == 0)) {
   15046           if (cond.Is(al)) {
   15047             EmitA32(0xf3b10140U |
   15048                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15049                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15050                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15051             return;
   15052           }
   15053         }
   15054       }
   15055     }
   15056   }
   15057   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
   15058 }
   15059 
   15060 void Assembler::vceq(
   15061     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   15062   VIXL_ASSERT(AllowAssembler());
   15063   CheckIT(cond);
   15064   Dt_size_4 encoded_dt(dt);
   15065   Dt_sz_1 encoded_dt_2(dt);
   15066   if (IsUsingT32()) {
   15067     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   15068     if (encoded_dt.IsValid()) {
   15069       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15070         EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
   15071                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15072         AdvanceIT();
   15073         return;
   15074       }
   15075     }
   15076     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
   15077     if (encoded_dt_2.IsValid()) {
   15078       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15079         EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
   15080                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15081         AdvanceIT();
   15082         return;
   15083       }
   15084     }
   15085   } else {
   15086     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   15087     if (encoded_dt.IsValid()) {
   15088       if (cond.Is(al)) {
   15089         EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
   15090                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15091         return;
   15092       }
   15093     }
   15094     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
   15095     if (encoded_dt_2.IsValid()) {
   15096       if (cond.Is(al)) {
   15097         EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
   15098                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15099         return;
   15100       }
   15101     }
   15102   }
   15103   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
   15104 }
   15105 
   15106 void Assembler::vceq(
   15107     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   15108   VIXL_ASSERT(AllowAssembler());
   15109   CheckIT(cond);
   15110   Dt_size_4 encoded_dt(dt);
   15111   Dt_sz_1 encoded_dt_2(dt);
   15112   if (IsUsingT32()) {
   15113     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   15114     if (encoded_dt.IsValid()) {
   15115       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15116         EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
   15117                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15118         AdvanceIT();
   15119         return;
   15120       }
   15121     }
   15122     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
   15123     if (encoded_dt_2.IsValid()) {
   15124       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15125         EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
   15126                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15127         AdvanceIT();
   15128         return;
   15129       }
   15130     }
   15131   } else {
   15132     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   15133     if (encoded_dt.IsValid()) {
   15134       if (cond.Is(al)) {
   15135         EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
   15136                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15137         return;
   15138       }
   15139     }
   15140     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
   15141     if (encoded_dt_2.IsValid()) {
   15142       if (cond.Is(al)) {
   15143         EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
   15144                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15145         return;
   15146       }
   15147     }
   15148   }
   15149   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
   15150 }
   15151 
   15152 void Assembler::vcge(Condition cond,
   15153                      DataType dt,
   15154                      DRegister rd,
   15155                      DRegister rm,
   15156                      const DOperand& operand) {
   15157   VIXL_ASSERT(AllowAssembler());
   15158   CheckIT(cond);
   15159   if (operand.IsImmediate()) {
   15160     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15161       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15162       Dt_F_size_1 encoded_dt(dt);
   15163       if (IsUsingT32()) {
   15164         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   15165         if (encoded_dt.IsValid() && (imm == 0)) {
   15166           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15167             EmitT32_32(0xffb10080U |
   15168                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15169                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15170                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15171             AdvanceIT();
   15172             return;
   15173           }
   15174         }
   15175       } else {
   15176         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   15177         if (encoded_dt.IsValid() && (imm == 0)) {
   15178           if (cond.Is(al)) {
   15179             EmitA32(0xf3b10080U |
   15180                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15181                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15182                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15183             return;
   15184           }
   15185         }
   15186       }
   15187     }
   15188   }
   15189   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
   15190 }
   15191 
   15192 void Assembler::vcge(Condition cond,
   15193                      DataType dt,
   15194                      QRegister rd,
   15195                      QRegister rm,
   15196                      const QOperand& operand) {
   15197   VIXL_ASSERT(AllowAssembler());
   15198   CheckIT(cond);
   15199   if (operand.IsImmediate()) {
   15200     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15201       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15202       Dt_F_size_1 encoded_dt(dt);
   15203       if (IsUsingT32()) {
   15204         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   15205         if (encoded_dt.IsValid() && (imm == 0)) {
   15206           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15207             EmitT32_32(0xffb100c0U |
   15208                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15209                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15210                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15211             AdvanceIT();
   15212             return;
   15213           }
   15214         }
   15215       } else {
   15216         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   15217         if (encoded_dt.IsValid() && (imm == 0)) {
   15218           if (cond.Is(al)) {
   15219             EmitA32(0xf3b100c0U |
   15220                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15221                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15222                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15223             return;
   15224           }
   15225         }
   15226       }
   15227     }
   15228   }
   15229   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
   15230 }
   15231 
   15232 void Assembler::vcge(
   15233     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   15234   VIXL_ASSERT(AllowAssembler());
   15235   CheckIT(cond);
   15236   Dt_U_size_1 encoded_dt(dt);
   15237   if (IsUsingT32()) {
   15238     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   15239     if (encoded_dt.IsValid()) {
   15240       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15241         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15242                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   15243                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15244         AdvanceIT();
   15245         return;
   15246       }
   15247     }
   15248     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
   15249     if (dt.Is(F32)) {
   15250       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15251         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   15252                    rm.Encode(5, 0));
   15253         AdvanceIT();
   15254         return;
   15255       }
   15256     }
   15257   } else {
   15258     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   15259     if (encoded_dt.IsValid()) {
   15260       if (cond.Is(al)) {
   15261         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15262                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   15263                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15264         return;
   15265       }
   15266     }
   15267     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
   15268     if (dt.Is(F32)) {
   15269       if (cond.Is(al)) {
   15270         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   15271                 rm.Encode(5, 0));
   15272         return;
   15273       }
   15274     }
   15275   }
   15276   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
   15277 }
   15278 
   15279 void Assembler::vcge(
   15280     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   15281   VIXL_ASSERT(AllowAssembler());
   15282   CheckIT(cond);
   15283   Dt_U_size_1 encoded_dt(dt);
   15284   if (IsUsingT32()) {
   15285     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   15286     if (encoded_dt.IsValid()) {
   15287       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15288         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15289                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   15290                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15291         AdvanceIT();
   15292         return;
   15293       }
   15294     }
   15295     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
   15296     if (dt.Is(F32)) {
   15297       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15298         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   15299                    rm.Encode(5, 0));
   15300         AdvanceIT();
   15301         return;
   15302       }
   15303     }
   15304   } else {
   15305     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   15306     if (encoded_dt.IsValid()) {
   15307       if (cond.Is(al)) {
   15308         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15309                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   15310                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15311         return;
   15312       }
   15313     }
   15314     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
   15315     if (dt.Is(F32)) {
   15316       if (cond.Is(al)) {
   15317         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   15318                 rm.Encode(5, 0));
   15319         return;
   15320       }
   15321     }
   15322   }
   15323   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
   15324 }
   15325 
   15326 void Assembler::vcgt(Condition cond,
   15327                      DataType dt,
   15328                      DRegister rd,
   15329                      DRegister rm,
   15330                      const DOperand& operand) {
   15331   VIXL_ASSERT(AllowAssembler());
   15332   CheckIT(cond);
   15333   if (operand.IsImmediate()) {
   15334     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15335       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15336       Dt_F_size_1 encoded_dt(dt);
   15337       if (IsUsingT32()) {
   15338         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   15339         if (encoded_dt.IsValid() && (imm == 0)) {
   15340           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15341             EmitT32_32(0xffb10000U |
   15342                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15343                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15344                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15345             AdvanceIT();
   15346             return;
   15347           }
   15348         }
   15349       } else {
   15350         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   15351         if (encoded_dt.IsValid() && (imm == 0)) {
   15352           if (cond.Is(al)) {
   15353             EmitA32(0xf3b10000U |
   15354                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15355                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15356                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15357             return;
   15358           }
   15359         }
   15360       }
   15361     }
   15362   }
   15363   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
   15364 }
   15365 
   15366 void Assembler::vcgt(Condition cond,
   15367                      DataType dt,
   15368                      QRegister rd,
   15369                      QRegister rm,
   15370                      const QOperand& operand) {
   15371   VIXL_ASSERT(AllowAssembler());
   15372   CheckIT(cond);
   15373   if (operand.IsImmediate()) {
   15374     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15375       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15376       Dt_F_size_1 encoded_dt(dt);
   15377       if (IsUsingT32()) {
   15378         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   15379         if (encoded_dt.IsValid() && (imm == 0)) {
   15380           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15381             EmitT32_32(0xffb10040U |
   15382                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15383                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15384                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15385             AdvanceIT();
   15386             return;
   15387           }
   15388         }
   15389       } else {
   15390         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   15391         if (encoded_dt.IsValid() && (imm == 0)) {
   15392           if (cond.Is(al)) {
   15393             EmitA32(0xf3b10040U |
   15394                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15395                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15396                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15397             return;
   15398           }
   15399         }
   15400       }
   15401     }
   15402   }
   15403   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
   15404 }
   15405 
   15406 void Assembler::vcgt(
   15407     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   15408   VIXL_ASSERT(AllowAssembler());
   15409   CheckIT(cond);
   15410   Dt_U_size_1 encoded_dt(dt);
   15411   if (IsUsingT32()) {
   15412     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   15413     if (encoded_dt.IsValid()) {
   15414       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15415         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15416                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   15417                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15418         AdvanceIT();
   15419         return;
   15420       }
   15421     }
   15422     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
   15423     if (dt.Is(F32)) {
   15424       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15425         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   15426                    rm.Encode(5, 0));
   15427         AdvanceIT();
   15428         return;
   15429       }
   15430     }
   15431   } else {
   15432     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   15433     if (encoded_dt.IsValid()) {
   15434       if (cond.Is(al)) {
   15435         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15436                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   15437                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15438         return;
   15439       }
   15440     }
   15441     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
   15442     if (dt.Is(F32)) {
   15443       if (cond.Is(al)) {
   15444         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   15445                 rm.Encode(5, 0));
   15446         return;
   15447       }
   15448     }
   15449   }
   15450   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
   15451 }
   15452 
   15453 void Assembler::vcgt(
   15454     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   15455   VIXL_ASSERT(AllowAssembler());
   15456   CheckIT(cond);
   15457   Dt_U_size_1 encoded_dt(dt);
   15458   if (IsUsingT32()) {
   15459     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   15460     if (encoded_dt.IsValid()) {
   15461       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15462         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15463                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   15464                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15465         AdvanceIT();
   15466         return;
   15467       }
   15468     }
   15469     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
   15470     if (dt.Is(F32)) {
   15471       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15472         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   15473                    rm.Encode(5, 0));
   15474         AdvanceIT();
   15475         return;
   15476       }
   15477     }
   15478   } else {
   15479     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   15480     if (encoded_dt.IsValid()) {
   15481       if (cond.Is(al)) {
   15482         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15483                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   15484                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   15485         return;
   15486       }
   15487     }
   15488     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
   15489     if (dt.Is(F32)) {
   15490       if (cond.Is(al)) {
   15491         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   15492                 rm.Encode(5, 0));
   15493         return;
   15494       }
   15495     }
   15496   }
   15497   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
   15498 }
   15499 
   15500 void Assembler::vcle(Condition cond,
   15501                      DataType dt,
   15502                      DRegister rd,
   15503                      DRegister rm,
   15504                      const DOperand& operand) {
   15505   VIXL_ASSERT(AllowAssembler());
   15506   CheckIT(cond);
   15507   if (operand.IsImmediate()) {
   15508     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15509       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15510       Dt_F_size_1 encoded_dt(dt);
   15511       if (IsUsingT32()) {
   15512         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   15513         if (encoded_dt.IsValid() && (imm == 0)) {
   15514           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15515             EmitT32_32(0xffb10180U |
   15516                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15517                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15518                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15519             AdvanceIT();
   15520             return;
   15521           }
   15522         }
   15523       } else {
   15524         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   15525         if (encoded_dt.IsValid() && (imm == 0)) {
   15526           if (cond.Is(al)) {
   15527             EmitA32(0xf3b10180U |
   15528                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15529                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15530                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15531             return;
   15532           }
   15533         }
   15534       }
   15535     }
   15536   }
   15537   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
   15538 }
   15539 
   15540 void Assembler::vcle(Condition cond,
   15541                      DataType dt,
   15542                      QRegister rd,
   15543                      QRegister rm,
   15544                      const QOperand& operand) {
   15545   VIXL_ASSERT(AllowAssembler());
   15546   CheckIT(cond);
   15547   if (operand.IsImmediate()) {
   15548     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15549       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15550       Dt_F_size_1 encoded_dt(dt);
   15551       if (IsUsingT32()) {
   15552         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   15553         if (encoded_dt.IsValid() && (imm == 0)) {
   15554           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15555             EmitT32_32(0xffb101c0U |
   15556                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15557                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15558                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15559             AdvanceIT();
   15560             return;
   15561           }
   15562         }
   15563       } else {
   15564         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   15565         if (encoded_dt.IsValid() && (imm == 0)) {
   15566           if (cond.Is(al)) {
   15567             EmitA32(0xf3b101c0U |
   15568                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15569                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15570                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15571             return;
   15572           }
   15573         }
   15574       }
   15575     }
   15576   }
   15577   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
   15578 }
   15579 
   15580 void Assembler::vcle(
   15581     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   15582   VIXL_ASSERT(AllowAssembler());
   15583   CheckIT(cond);
   15584   Dt_U_size_1 encoded_dt(dt);
   15585   if (IsUsingT32()) {
   15586     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   15587     if (encoded_dt.IsValid()) {
   15588       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15589         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15590                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   15591                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   15592         AdvanceIT();
   15593         return;
   15594       }
   15595     }
   15596     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
   15597     if (dt.Is(F32)) {
   15598       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15599         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   15600                    rm.Encode(7, 16));
   15601         AdvanceIT();
   15602         return;
   15603       }
   15604     }
   15605   } else {
   15606     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   15607     if (encoded_dt.IsValid()) {
   15608       if (cond.Is(al)) {
   15609         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15610                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   15611                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   15612         return;
   15613       }
   15614     }
   15615     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
   15616     if (dt.Is(F32)) {
   15617       if (cond.Is(al)) {
   15618         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   15619                 rm.Encode(7, 16));
   15620         return;
   15621       }
   15622     }
   15623   }
   15624   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
   15625 }
   15626 
   15627 void Assembler::vcle(
   15628     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   15629   VIXL_ASSERT(AllowAssembler());
   15630   CheckIT(cond);
   15631   Dt_U_size_1 encoded_dt(dt);
   15632   if (IsUsingT32()) {
   15633     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   15634     if (encoded_dt.IsValid()) {
   15635       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15636         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15637                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   15638                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   15639         AdvanceIT();
   15640         return;
   15641       }
   15642     }
   15643     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
   15644     if (dt.Is(F32)) {
   15645       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15646         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   15647                    rm.Encode(7, 16));
   15648         AdvanceIT();
   15649         return;
   15650       }
   15651     }
   15652   } else {
   15653     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   15654     if (encoded_dt.IsValid()) {
   15655       if (cond.Is(al)) {
   15656         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15657                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   15658                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   15659         return;
   15660       }
   15661     }
   15662     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
   15663     if (dt.Is(F32)) {
   15664       if (cond.Is(al)) {
   15665         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   15666                 rm.Encode(7, 16));
   15667         return;
   15668       }
   15669     }
   15670   }
   15671   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
   15672 }
   15673 
   15674 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   15675   VIXL_ASSERT(AllowAssembler());
   15676   CheckIT(cond);
   15677   Dt_size_5 encoded_dt(dt);
   15678   if (IsUsingT32()) {
   15679     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   15680     if (encoded_dt.IsValid()) {
   15681       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15682         EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
   15683                    rd.Encode(22, 12) | rm.Encode(5, 0));
   15684         AdvanceIT();
   15685         return;
   15686       }
   15687     }
   15688   } else {
   15689     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   15690     if (encoded_dt.IsValid()) {
   15691       if (cond.Is(al)) {
   15692         EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
   15693                 rd.Encode(22, 12) | rm.Encode(5, 0));
   15694         return;
   15695       }
   15696     }
   15697   }
   15698   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
   15699 }
   15700 
   15701 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   15702   VIXL_ASSERT(AllowAssembler());
   15703   CheckIT(cond);
   15704   Dt_size_5 encoded_dt(dt);
   15705   if (IsUsingT32()) {
   15706     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   15707     if (encoded_dt.IsValid()) {
   15708       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15709         EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
   15710                    rd.Encode(22, 12) | rm.Encode(5, 0));
   15711         AdvanceIT();
   15712         return;
   15713       }
   15714     }
   15715   } else {
   15716     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   15717     if (encoded_dt.IsValid()) {
   15718       if (cond.Is(al)) {
   15719         EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
   15720                 rd.Encode(22, 12) | rm.Encode(5, 0));
   15721         return;
   15722       }
   15723     }
   15724   }
   15725   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
   15726 }
   15727 
   15728 void Assembler::vclt(Condition cond,
   15729                      DataType dt,
   15730                      DRegister rd,
   15731                      DRegister rm,
   15732                      const DOperand& operand) {
   15733   VIXL_ASSERT(AllowAssembler());
   15734   CheckIT(cond);
   15735   if (operand.IsImmediate()) {
   15736     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15737       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15738       Dt_F_size_1 encoded_dt(dt);
   15739       if (IsUsingT32()) {
   15740         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
   15741         if (encoded_dt.IsValid() && (imm == 0)) {
   15742           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15743             EmitT32_32(0xffb10200U |
   15744                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15745                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15746                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15747             AdvanceIT();
   15748             return;
   15749           }
   15750         }
   15751       } else {
   15752         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
   15753         if (encoded_dt.IsValid() && (imm == 0)) {
   15754           if (cond.Is(al)) {
   15755             EmitA32(0xf3b10200U |
   15756                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15757                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15758                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15759             return;
   15760           }
   15761         }
   15762       }
   15763     }
   15764   }
   15765   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
   15766 }
   15767 
   15768 void Assembler::vclt(Condition cond,
   15769                      DataType dt,
   15770                      QRegister rd,
   15771                      QRegister rm,
   15772                      const QOperand& operand) {
   15773   VIXL_ASSERT(AllowAssembler());
   15774   CheckIT(cond);
   15775   if (operand.IsImmediate()) {
   15776     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   15777       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   15778       Dt_F_size_1 encoded_dt(dt);
   15779       if (IsUsingT32()) {
   15780         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
   15781         if (encoded_dt.IsValid() && (imm == 0)) {
   15782           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15783             EmitT32_32(0xffb10240U |
   15784                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15785                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15786                        rd.Encode(22, 12) | rm.Encode(5, 0));
   15787             AdvanceIT();
   15788             return;
   15789           }
   15790         }
   15791       } else {
   15792         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
   15793         if (encoded_dt.IsValid() && (imm == 0)) {
   15794           if (cond.Is(al)) {
   15795             EmitA32(0xf3b10240U |
   15796                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   15797                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   15798                     rd.Encode(22, 12) | rm.Encode(5, 0));
   15799             return;
   15800           }
   15801         }
   15802       }
   15803     }
   15804   }
   15805   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
   15806 }
   15807 
   15808 void Assembler::vclt(
   15809     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   15810   VIXL_ASSERT(AllowAssembler());
   15811   CheckIT(cond);
   15812   Dt_U_size_1 encoded_dt(dt);
   15813   if (IsUsingT32()) {
   15814     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   15815     if (encoded_dt.IsValid()) {
   15816       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15817         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15818                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   15819                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   15820         AdvanceIT();
   15821         return;
   15822       }
   15823     }
   15824     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
   15825     if (dt.Is(F32)) {
   15826       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15827         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   15828                    rm.Encode(7, 16));
   15829         AdvanceIT();
   15830         return;
   15831       }
   15832     }
   15833   } else {
   15834     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   15835     if (encoded_dt.IsValid()) {
   15836       if (cond.Is(al)) {
   15837         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15838                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   15839                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   15840         return;
   15841       }
   15842     }
   15843     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
   15844     if (dt.Is(F32)) {
   15845       if (cond.Is(al)) {
   15846         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   15847                 rm.Encode(7, 16));
   15848         return;
   15849       }
   15850     }
   15851   }
   15852   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
   15853 }
   15854 
   15855 void Assembler::vclt(
   15856     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   15857   VIXL_ASSERT(AllowAssembler());
   15858   CheckIT(cond);
   15859   Dt_U_size_1 encoded_dt(dt);
   15860   if (IsUsingT32()) {
   15861     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   15862     if (encoded_dt.IsValid()) {
   15863       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15864         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15865                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   15866                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   15867         AdvanceIT();
   15868         return;
   15869       }
   15870     }
   15871     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
   15872     if (dt.Is(F32)) {
   15873       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15874         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   15875                    rm.Encode(7, 16));
   15876         AdvanceIT();
   15877         return;
   15878       }
   15879     }
   15880   } else {
   15881     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   15882     if (encoded_dt.IsValid()) {
   15883       if (cond.Is(al)) {
   15884         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   15885                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   15886                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
   15887         return;
   15888       }
   15889     }
   15890     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
   15891     if (dt.Is(F32)) {
   15892       if (cond.Is(al)) {
   15893         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
   15894                 rm.Encode(7, 16));
   15895         return;
   15896       }
   15897     }
   15898   }
   15899   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
   15900 }
   15901 
   15902 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   15903   VIXL_ASSERT(AllowAssembler());
   15904   CheckIT(cond);
   15905   Dt_size_4 encoded_dt(dt);
   15906   if (IsUsingT32()) {
   15907     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   15908     if (encoded_dt.IsValid()) {
   15909       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15910         EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
   15911                    rd.Encode(22, 12) | rm.Encode(5, 0));
   15912         AdvanceIT();
   15913         return;
   15914       }
   15915     }
   15916   } else {
   15917     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   15918     if (encoded_dt.IsValid()) {
   15919       if (cond.Is(al)) {
   15920         EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
   15921                 rd.Encode(22, 12) | rm.Encode(5, 0));
   15922         return;
   15923       }
   15924     }
   15925   }
   15926   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
   15927 }
   15928 
   15929 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   15930   VIXL_ASSERT(AllowAssembler());
   15931   CheckIT(cond);
   15932   Dt_size_4 encoded_dt(dt);
   15933   if (IsUsingT32()) {
   15934     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   15935     if (encoded_dt.IsValid()) {
   15936       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   15937         EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
   15938                    rd.Encode(22, 12) | rm.Encode(5, 0));
   15939         AdvanceIT();
   15940         return;
   15941       }
   15942     }
   15943   } else {
   15944     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   15945     if (encoded_dt.IsValid()) {
   15946       if (cond.Is(al)) {
   15947         EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
   15948                 rd.Encode(22, 12) | rm.Encode(5, 0));
   15949         return;
   15950       }
   15951     }
   15952   }
   15953   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
   15954 }
   15955 
   15956 void Assembler::vcmp(Condition cond,
   15957                      DataType dt,
   15958                      SRegister rd,
   15959                      const SOperand& operand) {
   15960   VIXL_ASSERT(AllowAssembler());
   15961   CheckIT(cond);
   15962   if (operand.IsRegister()) {
   15963     SRegister rm = operand.GetRegister();
   15964     if (IsUsingT32()) {
   15965       // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
   15966       if (dt.Is(F32)) {
   15967         EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   15968         AdvanceIT();
   15969         return;
   15970       }
   15971     } else {
   15972       // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
   15973       if (dt.Is(F32) && cond.IsNotNever()) {
   15974         EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   15975                 rm.Encode(5, 0));
   15976         return;
   15977       }
   15978     }
   15979   }
   15980   if (operand.IsImmediate()) {
   15981     if (IsUsingT32()) {
   15982       // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
   15983       if (dt.Is(F32) && (operand.IsFloatZero())) {
   15984         EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
   15985         AdvanceIT();
   15986         return;
   15987       }
   15988     } else {
   15989       // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
   15990       if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) {
   15991         EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
   15992         return;
   15993       }
   15994     }
   15995   }
   15996   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand);
   15997 }
   15998 
   15999 void Assembler::vcmp(Condition cond,
   16000                      DataType dt,
   16001                      DRegister rd,
   16002                      const DOperand& operand) {
   16003   VIXL_ASSERT(AllowAssembler());
   16004   CheckIT(cond);
   16005   if (operand.IsRegister()) {
   16006     DRegister rm = operand.GetRegister();
   16007     if (IsUsingT32()) {
   16008       // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
   16009       if (dt.Is(F64)) {
   16010         EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16011         AdvanceIT();
   16012         return;
   16013       }
   16014     } else {
   16015       // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
   16016       if (dt.Is(F64) && cond.IsNotNever()) {
   16017         EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16018                 rm.Encode(5, 0));
   16019         return;
   16020       }
   16021     }
   16022   }
   16023   if (operand.IsImmediate()) {
   16024     if (IsUsingT32()) {
   16025       // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
   16026       if (dt.Is(F64) && (operand.IsFloatZero())) {
   16027         EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
   16028         AdvanceIT();
   16029         return;
   16030       }
   16031     } else {
   16032       // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
   16033       if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) {
   16034         EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
   16035         return;
   16036       }
   16037     }
   16038   }
   16039   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand);
   16040 }
   16041 
   16042 void Assembler::vcmpe(Condition cond,
   16043                       DataType dt,
   16044                       SRegister rd,
   16045                       const SOperand& operand) {
   16046   VIXL_ASSERT(AllowAssembler());
   16047   CheckIT(cond);
   16048   if (operand.IsRegister()) {
   16049     SRegister rm = operand.GetRegister();
   16050     if (IsUsingT32()) {
   16051       // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
   16052       if (dt.Is(F32)) {
   16053         EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16054         AdvanceIT();
   16055         return;
   16056       }
   16057     } else {
   16058       // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
   16059       if (dt.Is(F32) && cond.IsNotNever()) {
   16060         EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16061                 rm.Encode(5, 0));
   16062         return;
   16063       }
   16064     }
   16065   }
   16066   if (operand.IsImmediate()) {
   16067     if (IsUsingT32()) {
   16068       // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
   16069       if (dt.Is(F32) && (operand.IsFloatZero())) {
   16070         EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
   16071         AdvanceIT();
   16072         return;
   16073       }
   16074     } else {
   16075       // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
   16076       if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) {
   16077         EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
   16078         return;
   16079       }
   16080     }
   16081   }
   16082   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand);
   16083 }
   16084 
   16085 void Assembler::vcmpe(Condition cond,
   16086                       DataType dt,
   16087                       DRegister rd,
   16088                       const DOperand& operand) {
   16089   VIXL_ASSERT(AllowAssembler());
   16090   CheckIT(cond);
   16091   if (operand.IsRegister()) {
   16092     DRegister rm = operand.GetRegister();
   16093     if (IsUsingT32()) {
   16094       // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
   16095       if (dt.Is(F64)) {
   16096         EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16097         AdvanceIT();
   16098         return;
   16099       }
   16100     } else {
   16101       // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
   16102       if (dt.Is(F64) && cond.IsNotNever()) {
   16103         EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16104                 rm.Encode(5, 0));
   16105         return;
   16106       }
   16107     }
   16108   }
   16109   if (operand.IsImmediate()) {
   16110     if (IsUsingT32()) {
   16111       // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
   16112       if (dt.Is(F64) && (operand.IsFloatZero())) {
   16113         EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
   16114         AdvanceIT();
   16115         return;
   16116       }
   16117     } else {
   16118       // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
   16119       if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) {
   16120         EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
   16121         return;
   16122       }
   16123     }
   16124   }
   16125   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand);
   16126 }
   16127 
   16128 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   16129   VIXL_ASSERT(AllowAssembler());
   16130   CheckIT(cond);
   16131   if (IsUsingT32()) {
   16132     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
   16133     if (dt.Is(Untyped8)) {
   16134       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16135         EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16136         AdvanceIT();
   16137         return;
   16138       }
   16139     }
   16140   } else {
   16141     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
   16142     if (dt.Is(Untyped8)) {
   16143       if (cond.Is(al)) {
   16144         EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16145         return;
   16146       }
   16147     }
   16148   }
   16149   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
   16150 }
   16151 
   16152 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   16153   VIXL_ASSERT(AllowAssembler());
   16154   CheckIT(cond);
   16155   if (IsUsingT32()) {
   16156     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
   16157     if (dt.Is(Untyped8)) {
   16158       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16159         EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16160         AdvanceIT();
   16161         return;
   16162       }
   16163     }
   16164   } else {
   16165     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
   16166     if (dt.Is(Untyped8)) {
   16167       if (cond.Is(al)) {
   16168         EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16169         return;
   16170       }
   16171     }
   16172   }
   16173   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
   16174 }
   16175 
   16176 void Assembler::vcvt(
   16177     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
   16178   VIXL_ASSERT(AllowAssembler());
   16179   CheckIT(cond);
   16180   Dt_op_2 encoded_dt(dt2);
   16181   if (IsUsingT32()) {
   16182     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
   16183     if (dt1.Is(F64) && dt2.Is(F32)) {
   16184       EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16185       AdvanceIT();
   16186       return;
   16187     }
   16188     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
   16189     if (dt1.Is(F64) && encoded_dt.IsValid()) {
   16190       EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
   16191                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16192       AdvanceIT();
   16193       return;
   16194     }
   16195   } else {
   16196     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
   16197     if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
   16198       EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16199               rm.Encode(5, 0));
   16200       return;
   16201     }
   16202     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
   16203     if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
   16204       EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
   16205               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
   16206               rm.Encode(5, 0));
   16207       return;
   16208     }
   16209   }
   16210   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   16211 }
   16212 
   16213 void Assembler::vcvt(
   16214     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   16215   VIXL_ASSERT(AllowAssembler());
   16216   CheckIT(cond);
   16217   if (IsUsingT32()) {
   16218     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
   16219     if (dt1.Is(F32) && dt2.Is(F64)) {
   16220       EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16221       AdvanceIT();
   16222       return;
   16223     }
   16224     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
   16225     if (dt1.Is(U32) && dt2.Is(F64)) {
   16226       EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16227       AdvanceIT();
   16228       return;
   16229     }
   16230     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
   16231     if (dt1.Is(S32) && dt2.Is(F64)) {
   16232       EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16233       AdvanceIT();
   16234       return;
   16235     }
   16236   } else {
   16237     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
   16238     if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
   16239       EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16240               rm.Encode(5, 0));
   16241       return;
   16242     }
   16243     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
   16244     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
   16245       EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16246               rm.Encode(5, 0));
   16247       return;
   16248     }
   16249     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
   16250     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
   16251       EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16252               rm.Encode(5, 0));
   16253       return;
   16254     }
   16255   }
   16256   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   16257 }
   16258 
   16259 void Assembler::vcvt(Condition cond,
   16260                      DataType dt1,
   16261                      DataType dt2,
   16262                      DRegister rd,
   16263                      DRegister rm,
   16264                      int32_t fbits) {
   16265   VIXL_ASSERT(AllowAssembler());
   16266   CheckIT(cond);
   16267   Dt_op_U_1 encoded_dt(dt1, dt2);
   16268   Dt_U_sx_1 encoded_dt_2(dt2);
   16269   Dt_U_sx_1 encoded_dt_3(dt1);
   16270   if (IsUsingT32()) {
   16271     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
   16272     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
   16273       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16274         uint32_t fbits_ = 64 - fbits;
   16275         EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
   16276                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
   16277                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
   16278         AdvanceIT();
   16279         return;
   16280       }
   16281     }
   16282     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
   16283     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
   16284         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
   16285          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
   16286       unsigned offset = 32;
   16287       if (dt2.Is(S16) || dt2.Is(U16)) {
   16288         offset = 16;
   16289       }
   16290       uint32_t fbits_ = offset - fbits;
   16291       EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
   16292                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
   16293                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   16294                  ((fbits_ & 0x1e) >> 1));
   16295       AdvanceIT();
   16296       return;
   16297     }
   16298     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
   16299     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
   16300         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
   16301          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
   16302       unsigned offset = 32;
   16303       if (dt1.Is(S16) || dt1.Is(U16)) {
   16304         offset = 16;
   16305       }
   16306       uint32_t fbits_ = offset - fbits;
   16307       EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
   16308                  ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
   16309                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   16310                  ((fbits_ & 0x1e) >> 1));
   16311       AdvanceIT();
   16312       return;
   16313     }
   16314   } else {
   16315     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
   16316     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
   16317       if (cond.Is(al)) {
   16318         uint32_t fbits_ = 64 - fbits;
   16319         EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
   16320                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
   16321                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
   16322         return;
   16323       }
   16324     }
   16325     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
   16326     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
   16327         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
   16328          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
   16329         cond.IsNotNever()) {
   16330       unsigned offset = 32;
   16331       if (dt2.Is(S16) || dt2.Is(U16)) {
   16332         offset = 16;
   16333       }
   16334       uint32_t fbits_ = offset - fbits;
   16335       EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
   16336               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
   16337               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
   16338               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   16339               ((fbits_ & 0x1e) >> 1));
   16340       return;
   16341     }
   16342     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
   16343     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
   16344         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
   16345          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
   16346         cond.IsNotNever()) {
   16347       unsigned offset = 32;
   16348       if (dt1.Is(S16) || dt1.Is(U16)) {
   16349         offset = 16;
   16350       }
   16351       uint32_t fbits_ = offset - fbits;
   16352       EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
   16353               ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
   16354               ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
   16355               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   16356               ((fbits_ & 0x1e) >> 1));
   16357       return;
   16358     }
   16359   }
   16360   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
   16361 }
   16362 
   16363 void Assembler::vcvt(Condition cond,
   16364                      DataType dt1,
   16365                      DataType dt2,
   16366                      QRegister rd,
   16367                      QRegister rm,
   16368                      int32_t fbits) {
   16369   VIXL_ASSERT(AllowAssembler());
   16370   CheckIT(cond);
   16371   Dt_op_U_1 encoded_dt(dt1, dt2);
   16372   if (IsUsingT32()) {
   16373     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
   16374     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
   16375       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16376         uint32_t fbits_ = 64 - fbits;
   16377         EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
   16378                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
   16379                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
   16380         AdvanceIT();
   16381         return;
   16382       }
   16383     }
   16384   } else {
   16385     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
   16386     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
   16387       if (cond.Is(al)) {
   16388         uint32_t fbits_ = 64 - fbits;
   16389         EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
   16390                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
   16391                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
   16392         return;
   16393       }
   16394     }
   16395   }
   16396   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
   16397 }
   16398 
   16399 void Assembler::vcvt(Condition cond,
   16400                      DataType dt1,
   16401                      DataType dt2,
   16402                      SRegister rd,
   16403                      SRegister rm,
   16404                      int32_t fbits) {
   16405   VIXL_ASSERT(AllowAssembler());
   16406   CheckIT(cond);
   16407   Dt_U_sx_1 encoded_dt(dt2);
   16408   Dt_U_sx_1 encoded_dt_2(dt1);
   16409   if (IsUsingT32()) {
   16410     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
   16411     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
   16412         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
   16413          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
   16414       unsigned offset = 32;
   16415       if (dt2.Is(S16) || dt2.Is(U16)) {
   16416         offset = 16;
   16417       }
   16418       uint32_t fbits_ = offset - fbits;
   16419       EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
   16420                  ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
   16421                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   16422                  ((fbits_ & 0x1e) >> 1));
   16423       AdvanceIT();
   16424       return;
   16425     }
   16426     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
   16427     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
   16428         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
   16429          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
   16430       unsigned offset = 32;
   16431       if (dt1.Is(S16) || dt1.Is(U16)) {
   16432         offset = 16;
   16433       }
   16434       uint32_t fbits_ = offset - fbits;
   16435       EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
   16436                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
   16437                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   16438                  ((fbits_ & 0x1e) >> 1));
   16439       AdvanceIT();
   16440       return;
   16441     }
   16442   } else {
   16443     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
   16444     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
   16445         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
   16446          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
   16447         cond.IsNotNever()) {
   16448       unsigned offset = 32;
   16449       if (dt2.Is(S16) || dt2.Is(U16)) {
   16450         offset = 16;
   16451       }
   16452       uint32_t fbits_ = offset - fbits;
   16453       EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
   16454               ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
   16455               ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
   16456               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   16457               ((fbits_ & 0x1e) >> 1));
   16458       return;
   16459     }
   16460     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
   16461     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
   16462         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
   16463          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
   16464         cond.IsNotNever()) {
   16465       unsigned offset = 32;
   16466       if (dt1.Is(S16) || dt1.Is(U16)) {
   16467         offset = 16;
   16468       }
   16469       uint32_t fbits_ = offset - fbits;
   16470       EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
   16471               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
   16472               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
   16473               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
   16474               ((fbits_ & 0x1e) >> 1));
   16475       return;
   16476     }
   16477   }
   16478   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
   16479 }
   16480 
   16481 void Assembler::vcvt(
   16482     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   16483   VIXL_ASSERT(AllowAssembler());
   16484   CheckIT(cond);
   16485   Dt_op_1 encoded_dt(dt1, dt2);
   16486   if (IsUsingT32()) {
   16487     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
   16488     if (encoded_dt.IsValid()) {
   16489       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16490         EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
   16491                    rd.Encode(22, 12) | rm.Encode(5, 0));
   16492         AdvanceIT();
   16493         return;
   16494       }
   16495     }
   16496   } else {
   16497     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
   16498     if (encoded_dt.IsValid()) {
   16499       if (cond.Is(al)) {
   16500         EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
   16501                 rd.Encode(22, 12) | rm.Encode(5, 0));
   16502         return;
   16503       }
   16504     }
   16505   }
   16506   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   16507 }
   16508 
   16509 void Assembler::vcvt(
   16510     Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   16511   VIXL_ASSERT(AllowAssembler());
   16512   CheckIT(cond);
   16513   Dt_op_1 encoded_dt(dt1, dt2);
   16514   if (IsUsingT32()) {
   16515     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
   16516     if (encoded_dt.IsValid()) {
   16517       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16518         EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
   16519                    rd.Encode(22, 12) | rm.Encode(5, 0));
   16520         AdvanceIT();
   16521         return;
   16522       }
   16523     }
   16524   } else {
   16525     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
   16526     if (encoded_dt.IsValid()) {
   16527       if (cond.Is(al)) {
   16528         EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
   16529                 rd.Encode(22, 12) | rm.Encode(5, 0));
   16530         return;
   16531       }
   16532     }
   16533   }
   16534   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   16535 }
   16536 
   16537 void Assembler::vcvt(
   16538     Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
   16539   VIXL_ASSERT(AllowAssembler());
   16540   CheckIT(cond);
   16541   if (IsUsingT32()) {
   16542     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
   16543     if (dt1.Is(F16) && dt2.Is(F32)) {
   16544       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16545         EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16546         AdvanceIT();
   16547         return;
   16548       }
   16549     }
   16550   } else {
   16551     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
   16552     if (dt1.Is(F16) && dt2.Is(F32)) {
   16553       if (cond.Is(al)) {
   16554         EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16555         return;
   16556       }
   16557     }
   16558   }
   16559   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   16560 }
   16561 
   16562 void Assembler::vcvt(
   16563     Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
   16564   VIXL_ASSERT(AllowAssembler());
   16565   CheckIT(cond);
   16566   if (IsUsingT32()) {
   16567     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
   16568     if (dt1.Is(F32) && dt2.Is(F16)) {
   16569       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   16570         EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16571         AdvanceIT();
   16572         return;
   16573       }
   16574     }
   16575   } else {
   16576     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
   16577     if (dt1.Is(F32) && dt2.Is(F16)) {
   16578       if (cond.Is(al)) {
   16579         EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16580         return;
   16581       }
   16582     }
   16583   }
   16584   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   16585 }
   16586 
   16587 void Assembler::vcvt(
   16588     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   16589   VIXL_ASSERT(AllowAssembler());
   16590   CheckIT(cond);
   16591   Dt_op_2 encoded_dt(dt2);
   16592   if (IsUsingT32()) {
   16593     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
   16594     if (dt1.Is(U32) && dt2.Is(F32)) {
   16595       EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16596       AdvanceIT();
   16597       return;
   16598     }
   16599     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
   16600     if (dt1.Is(S32) && dt2.Is(F32)) {
   16601       EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16602       AdvanceIT();
   16603       return;
   16604     }
   16605     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
   16606     if (dt1.Is(F32) && encoded_dt.IsValid()) {
   16607       EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
   16608                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16609       AdvanceIT();
   16610       return;
   16611     }
   16612   } else {
   16613     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
   16614     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
   16615       EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16616               rm.Encode(5, 0));
   16617       return;
   16618     }
   16619     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
   16620     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
   16621       EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16622               rm.Encode(5, 0));
   16623       return;
   16624     }
   16625     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
   16626     if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
   16627       EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
   16628               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
   16629               rm.Encode(5, 0));
   16630       return;
   16631     }
   16632   }
   16633   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
   16634 }
   16635 
   16636 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   16637   VIXL_ASSERT(AllowAssembler());
   16638   CheckIT(al);
   16639   Dt_op_3 encoded_dt(dt1);
   16640   if (IsUsingT32()) {
   16641     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
   16642     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16643       EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
   16644                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16645       AdvanceIT();
   16646       return;
   16647     }
   16648   } else {
   16649     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
   16650     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16651       EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
   16652               rd.Encode(22, 12) | rm.Encode(5, 0));
   16653       return;
   16654     }
   16655   }
   16656   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
   16657 }
   16658 
   16659 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   16660   VIXL_ASSERT(AllowAssembler());
   16661   CheckIT(al);
   16662   Dt_op_3 encoded_dt(dt1);
   16663   if (IsUsingT32()) {
   16664     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
   16665     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16666       EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
   16667                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16668       AdvanceIT();
   16669       return;
   16670     }
   16671   } else {
   16672     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
   16673     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16674       EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
   16675               rd.Encode(22, 12) | rm.Encode(5, 0));
   16676       return;
   16677     }
   16678   }
   16679   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
   16680 }
   16681 
   16682 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   16683   VIXL_ASSERT(AllowAssembler());
   16684   CheckIT(al);
   16685   Dt_op_2 encoded_dt(dt1);
   16686   if (IsUsingT32()) {
   16687     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
   16688     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16689       EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
   16690                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16691       AdvanceIT();
   16692       return;
   16693     }
   16694   } else {
   16695     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
   16696     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16697       EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
   16698               rd.Encode(22, 12) | rm.Encode(5, 0));
   16699       return;
   16700     }
   16701   }
   16702   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
   16703 }
   16704 
   16705 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   16706   VIXL_ASSERT(AllowAssembler());
   16707   CheckIT(al);
   16708   Dt_op_2 encoded_dt(dt1);
   16709   if (IsUsingT32()) {
   16710     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
   16711     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   16712       EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
   16713                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16714       AdvanceIT();
   16715       return;
   16716     }
   16717   } else {
   16718     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
   16719     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   16720       EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
   16721               rd.Encode(22, 12) | rm.Encode(5, 0));
   16722       return;
   16723     }
   16724   }
   16725   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
   16726 }
   16727 
   16728 void Assembler::vcvtb(
   16729     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   16730   VIXL_ASSERT(AllowAssembler());
   16731   CheckIT(cond);
   16732   if (IsUsingT32()) {
   16733     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
   16734     if (dt1.Is(F32) && dt2.Is(F16)) {
   16735       EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16736       AdvanceIT();
   16737       return;
   16738     }
   16739     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
   16740     if (dt1.Is(F16) && dt2.Is(F32)) {
   16741       EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16742       AdvanceIT();
   16743       return;
   16744     }
   16745   } else {
   16746     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
   16747     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
   16748       EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16749               rm.Encode(5, 0));
   16750       return;
   16751     }
   16752     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
   16753     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
   16754       EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16755               rm.Encode(5, 0));
   16756       return;
   16757     }
   16758   }
   16759   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
   16760 }
   16761 
   16762 void Assembler::vcvtb(
   16763     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
   16764   VIXL_ASSERT(AllowAssembler());
   16765   CheckIT(cond);
   16766   if (IsUsingT32()) {
   16767     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
   16768     if (dt1.Is(F64) && dt2.Is(F16)) {
   16769       EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16770       AdvanceIT();
   16771       return;
   16772     }
   16773   } else {
   16774     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
   16775     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
   16776       EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16777               rm.Encode(5, 0));
   16778       return;
   16779     }
   16780   }
   16781   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
   16782 }
   16783 
   16784 void Assembler::vcvtb(
   16785     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   16786   VIXL_ASSERT(AllowAssembler());
   16787   CheckIT(cond);
   16788   if (IsUsingT32()) {
   16789     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
   16790     if (dt1.Is(F16) && dt2.Is(F64)) {
   16791       EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   16792       AdvanceIT();
   16793       return;
   16794     }
   16795   } else {
   16796     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
   16797     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
   16798       EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   16799               rm.Encode(5, 0));
   16800       return;
   16801     }
   16802   }
   16803   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
   16804 }
   16805 
   16806 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   16807   VIXL_ASSERT(AllowAssembler());
   16808   CheckIT(al);
   16809   Dt_op_3 encoded_dt(dt1);
   16810   if (IsUsingT32()) {
   16811     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
   16812     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16813       EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
   16814                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16815       AdvanceIT();
   16816       return;
   16817     }
   16818   } else {
   16819     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
   16820     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16821       EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
   16822               rd.Encode(22, 12) | rm.Encode(5, 0));
   16823       return;
   16824     }
   16825   }
   16826   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
   16827 }
   16828 
   16829 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   16830   VIXL_ASSERT(AllowAssembler());
   16831   CheckIT(al);
   16832   Dt_op_3 encoded_dt(dt1);
   16833   if (IsUsingT32()) {
   16834     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
   16835     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16836       EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
   16837                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16838       AdvanceIT();
   16839       return;
   16840     }
   16841   } else {
   16842     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
   16843     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16844       EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
   16845               rd.Encode(22, 12) | rm.Encode(5, 0));
   16846       return;
   16847     }
   16848   }
   16849   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
   16850 }
   16851 
   16852 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   16853   VIXL_ASSERT(AllowAssembler());
   16854   CheckIT(al);
   16855   Dt_op_2 encoded_dt(dt1);
   16856   if (IsUsingT32()) {
   16857     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
   16858     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16859       EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
   16860                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16861       AdvanceIT();
   16862       return;
   16863     }
   16864   } else {
   16865     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
   16866     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16867       EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
   16868               rd.Encode(22, 12) | rm.Encode(5, 0));
   16869       return;
   16870     }
   16871   }
   16872   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
   16873 }
   16874 
   16875 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   16876   VIXL_ASSERT(AllowAssembler());
   16877   CheckIT(al);
   16878   Dt_op_2 encoded_dt(dt1);
   16879   if (IsUsingT32()) {
   16880     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
   16881     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   16882       EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
   16883                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16884       AdvanceIT();
   16885       return;
   16886     }
   16887   } else {
   16888     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
   16889     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   16890       EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
   16891               rd.Encode(22, 12) | rm.Encode(5, 0));
   16892       return;
   16893     }
   16894   }
   16895   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
   16896 }
   16897 
   16898 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   16899   VIXL_ASSERT(AllowAssembler());
   16900   CheckIT(al);
   16901   Dt_op_3 encoded_dt(dt1);
   16902   if (IsUsingT32()) {
   16903     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
   16904     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16905       EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
   16906                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16907       AdvanceIT();
   16908       return;
   16909     }
   16910   } else {
   16911     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
   16912     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16913       EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
   16914               rd.Encode(22, 12) | rm.Encode(5, 0));
   16915       return;
   16916     }
   16917   }
   16918   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
   16919 }
   16920 
   16921 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   16922   VIXL_ASSERT(AllowAssembler());
   16923   CheckIT(al);
   16924   Dt_op_3 encoded_dt(dt1);
   16925   if (IsUsingT32()) {
   16926     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
   16927     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16928       EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
   16929                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16930       AdvanceIT();
   16931       return;
   16932     }
   16933   } else {
   16934     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
   16935     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16936       EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
   16937               rd.Encode(22, 12) | rm.Encode(5, 0));
   16938       return;
   16939     }
   16940   }
   16941   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
   16942 }
   16943 
   16944 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   16945   VIXL_ASSERT(AllowAssembler());
   16946   CheckIT(al);
   16947   Dt_op_2 encoded_dt(dt1);
   16948   if (IsUsingT32()) {
   16949     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
   16950     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16951       EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
   16952                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16953       AdvanceIT();
   16954       return;
   16955     }
   16956   } else {
   16957     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
   16958     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16959       EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
   16960               rd.Encode(22, 12) | rm.Encode(5, 0));
   16961       return;
   16962     }
   16963   }
   16964   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
   16965 }
   16966 
   16967 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   16968   VIXL_ASSERT(AllowAssembler());
   16969   CheckIT(al);
   16970   Dt_op_2 encoded_dt(dt1);
   16971   if (IsUsingT32()) {
   16972     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
   16973     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   16974       EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
   16975                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16976       AdvanceIT();
   16977       return;
   16978     }
   16979   } else {
   16980     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
   16981     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   16982       EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
   16983               rd.Encode(22, 12) | rm.Encode(5, 0));
   16984       return;
   16985     }
   16986   }
   16987   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
   16988 }
   16989 
   16990 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   16991   VIXL_ASSERT(AllowAssembler());
   16992   CheckIT(al);
   16993   Dt_op_3 encoded_dt(dt1);
   16994   if (IsUsingT32()) {
   16995     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
   16996     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   16997       EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
   16998                  rd.Encode(22, 12) | rm.Encode(5, 0));
   16999       AdvanceIT();
   17000       return;
   17001     }
   17002   } else {
   17003     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
   17004     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   17005       EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
   17006               rd.Encode(22, 12) | rm.Encode(5, 0));
   17007       return;
   17008     }
   17009   }
   17010   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
   17011 }
   17012 
   17013 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   17014   VIXL_ASSERT(AllowAssembler());
   17015   CheckIT(al);
   17016   Dt_op_3 encoded_dt(dt1);
   17017   if (IsUsingT32()) {
   17018     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
   17019     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   17020       EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
   17021                  rd.Encode(22, 12) | rm.Encode(5, 0));
   17022       AdvanceIT();
   17023       return;
   17024     }
   17025   } else {
   17026     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
   17027     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   17028       EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
   17029               rd.Encode(22, 12) | rm.Encode(5, 0));
   17030       return;
   17031     }
   17032   }
   17033   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
   17034 }
   17035 
   17036 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   17037   VIXL_ASSERT(AllowAssembler());
   17038   CheckIT(al);
   17039   Dt_op_2 encoded_dt(dt1);
   17040   if (IsUsingT32()) {
   17041     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
   17042     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   17043       EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
   17044                  rd.Encode(22, 12) | rm.Encode(5, 0));
   17045       AdvanceIT();
   17046       return;
   17047     }
   17048   } else {
   17049     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
   17050     if (encoded_dt.IsValid() && dt2.Is(F32)) {
   17051       EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
   17052               rd.Encode(22, 12) | rm.Encode(5, 0));
   17053       return;
   17054     }
   17055   }
   17056   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
   17057 }
   17058 
   17059 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   17060   VIXL_ASSERT(AllowAssembler());
   17061   CheckIT(al);
   17062   Dt_op_2 encoded_dt(dt1);
   17063   if (IsUsingT32()) {
   17064     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
   17065     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   17066       EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
   17067                  rd.Encode(22, 12) | rm.Encode(5, 0));
   17068       AdvanceIT();
   17069       return;
   17070     }
   17071   } else {
   17072     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
   17073     if (encoded_dt.IsValid() && dt2.Is(F64)) {
   17074       EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
   17075               rd.Encode(22, 12) | rm.Encode(5, 0));
   17076       return;
   17077     }
   17078   }
   17079   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
   17080 }
   17081 
   17082 void Assembler::vcvtr(
   17083     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   17084   VIXL_ASSERT(AllowAssembler());
   17085   CheckIT(cond);
   17086   if (IsUsingT32()) {
   17087     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
   17088     if (dt1.Is(U32) && dt2.Is(F32)) {
   17089       EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   17090       AdvanceIT();
   17091       return;
   17092     }
   17093     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
   17094     if (dt1.Is(S32) && dt2.Is(F32)) {
   17095       EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   17096       AdvanceIT();
   17097       return;
   17098     }
   17099   } else {
   17100     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
   17101     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
   17102       EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17103               rm.Encode(5, 0));
   17104       return;
   17105     }
   17106     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
   17107     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
   17108       EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17109               rm.Encode(5, 0));
   17110       return;
   17111     }
   17112   }
   17113   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
   17114 }
   17115 
   17116 void Assembler::vcvtr(
   17117     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   17118   VIXL_ASSERT(AllowAssembler());
   17119   CheckIT(cond);
   17120   if (IsUsingT32()) {
   17121     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
   17122     if (dt1.Is(U32) && dt2.Is(F64)) {
   17123       EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   17124       AdvanceIT();
   17125       return;
   17126     }
   17127     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
   17128     if (dt1.Is(S32) && dt2.Is(F64)) {
   17129       EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   17130       AdvanceIT();
   17131       return;
   17132     }
   17133   } else {
   17134     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
   17135     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
   17136       EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17137               rm.Encode(5, 0));
   17138       return;
   17139     }
   17140     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
   17141     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
   17142       EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17143               rm.Encode(5, 0));
   17144       return;
   17145     }
   17146   }
   17147   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
   17148 }
   17149 
   17150 void Assembler::vcvtt(
   17151     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   17152   VIXL_ASSERT(AllowAssembler());
   17153   CheckIT(cond);
   17154   if (IsUsingT32()) {
   17155     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
   17156     if (dt1.Is(F32) && dt2.Is(F16)) {
   17157       EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   17158       AdvanceIT();
   17159       return;
   17160     }
   17161     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
   17162     if (dt1.Is(F16) && dt2.Is(F32)) {
   17163       EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   17164       AdvanceIT();
   17165       return;
   17166     }
   17167   } else {
   17168     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
   17169     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
   17170       EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17171               rm.Encode(5, 0));
   17172       return;
   17173     }
   17174     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
   17175     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
   17176       EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17177               rm.Encode(5, 0));
   17178       return;
   17179     }
   17180   }
   17181   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
   17182 }
   17183 
   17184 void Assembler::vcvtt(
   17185     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
   17186   VIXL_ASSERT(AllowAssembler());
   17187   CheckIT(cond);
   17188   if (IsUsingT32()) {
   17189     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
   17190     if (dt1.Is(F64) && dt2.Is(F16)) {
   17191       EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   17192       AdvanceIT();
   17193       return;
   17194     }
   17195   } else {
   17196     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
   17197     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
   17198       EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17199               rm.Encode(5, 0));
   17200       return;
   17201     }
   17202   }
   17203   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
   17204 }
   17205 
   17206 void Assembler::vcvtt(
   17207     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
   17208   VIXL_ASSERT(AllowAssembler());
   17209   CheckIT(cond);
   17210   if (IsUsingT32()) {
   17211     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
   17212     if (dt1.Is(F16) && dt2.Is(F64)) {
   17213       EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   17214       AdvanceIT();
   17215       return;
   17216     }
   17217   } else {
   17218     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
   17219     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
   17220       EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17221               rm.Encode(5, 0));
   17222       return;
   17223     }
   17224   }
   17225   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
   17226 }
   17227 
   17228 void Assembler::vdiv(
   17229     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   17230   VIXL_ASSERT(AllowAssembler());
   17231   CheckIT(cond);
   17232   if (IsUsingT32()) {
   17233     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
   17234     if (dt.Is(F32)) {
   17235       EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17236                  rm.Encode(5, 0));
   17237       AdvanceIT();
   17238       return;
   17239     }
   17240   } else {
   17241     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
   17242     if (dt.Is(F32) && cond.IsNotNever()) {
   17243       EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17244               rn.Encode(7, 16) | rm.Encode(5, 0));
   17245       return;
   17246     }
   17247   }
   17248   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
   17249 }
   17250 
   17251 void Assembler::vdiv(
   17252     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   17253   VIXL_ASSERT(AllowAssembler());
   17254   CheckIT(cond);
   17255   if (IsUsingT32()) {
   17256     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
   17257     if (dt.Is(F64)) {
   17258       EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17259                  rm.Encode(5, 0));
   17260       AdvanceIT();
   17261       return;
   17262     }
   17263   } else {
   17264     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
   17265     if (dt.Is(F64) && cond.IsNotNever()) {
   17266       EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17267               rn.Encode(7, 16) | rm.Encode(5, 0));
   17268       return;
   17269     }
   17270   }
   17271   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
   17272 }
   17273 
   17274 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
   17275   VIXL_ASSERT(AllowAssembler());
   17276   CheckIT(cond);
   17277   Dt_B_E_1 encoded_dt(dt);
   17278   if (IsUsingT32()) {
   17279     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
   17280     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
   17281       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17282         EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
   17283                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
   17284                    rd.Encode(7, 16) | (rt.GetCode() << 12));
   17285         AdvanceIT();
   17286         return;
   17287       }
   17288     }
   17289   } else {
   17290     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
   17291     if (encoded_dt.IsValid() && cond.IsNotNever() &&
   17292         (!rt.IsPC() || AllowUnpredictable())) {
   17293       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17294         EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
   17295                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
   17296                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
   17297                 rd.Encode(7, 16) | (rt.GetCode() << 12));
   17298         return;
   17299       }
   17300     }
   17301   }
   17302   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
   17303 }
   17304 
   17305 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
   17306   VIXL_ASSERT(AllowAssembler());
   17307   CheckIT(cond);
   17308   Dt_B_E_1 encoded_dt(dt);
   17309   if (IsUsingT32()) {
   17310     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
   17311     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
   17312       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17313         EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
   17314                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
   17315                    rd.Encode(7, 16) | (rt.GetCode() << 12));
   17316         AdvanceIT();
   17317         return;
   17318       }
   17319     }
   17320   } else {
   17321     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
   17322     if (encoded_dt.IsValid() && cond.IsNotNever() &&
   17323         (!rt.IsPC() || AllowUnpredictable())) {
   17324       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17325         EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
   17326                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
   17327                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
   17328                 rd.Encode(7, 16) | (rt.GetCode() << 12));
   17329         return;
   17330       }
   17331     }
   17332   }
   17333   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
   17334 }
   17335 
   17336 void Assembler::vdup(Condition cond,
   17337                      DataType dt,
   17338                      DRegister rd,
   17339                      DRegisterLane rm) {
   17340   VIXL_ASSERT(AllowAssembler());
   17341   CheckIT(cond);
   17342   Dt_imm4_1 encoded_dt(dt, rm);
   17343   if (IsUsingT32()) {
   17344     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
   17345     if (encoded_dt.IsValid()) {
   17346       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17347         EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
   17348                    rd.Encode(22, 12) | rm.Encode(5, 0));
   17349         AdvanceIT();
   17350         return;
   17351       }
   17352     }
   17353   } else {
   17354     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
   17355     if (encoded_dt.IsValid()) {
   17356       if (cond.Is(al)) {
   17357         EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
   17358                 rd.Encode(22, 12) | rm.Encode(5, 0));
   17359         return;
   17360       }
   17361     }
   17362   }
   17363   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
   17364 }
   17365 
   17366 void Assembler::vdup(Condition cond,
   17367                      DataType dt,
   17368                      QRegister rd,
   17369                      DRegisterLane rm) {
   17370   VIXL_ASSERT(AllowAssembler());
   17371   CheckIT(cond);
   17372   Dt_imm4_1 encoded_dt(dt, rm);
   17373   if (IsUsingT32()) {
   17374     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
   17375     if (encoded_dt.IsValid()) {
   17376       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17377         EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
   17378                    rd.Encode(22, 12) | rm.Encode(5, 0));
   17379         AdvanceIT();
   17380         return;
   17381       }
   17382     }
   17383   } else {
   17384     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
   17385     if (encoded_dt.IsValid()) {
   17386       if (cond.Is(al)) {
   17387         EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
   17388                 rd.Encode(22, 12) | rm.Encode(5, 0));
   17389         return;
   17390       }
   17391     }
   17392   }
   17393   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
   17394 }
   17395 
   17396 void Assembler::veor(
   17397     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   17398   VIXL_ASSERT(AllowAssembler());
   17399   CheckIT(cond);
   17400   USE(dt);
   17401   if (IsUsingT32()) {
   17402     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   17403     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17404       EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17405                  rm.Encode(5, 0));
   17406       AdvanceIT();
   17407       return;
   17408     }
   17409   } else {
   17410     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   17411     if (cond.Is(al)) {
   17412       EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17413               rm.Encode(5, 0));
   17414       return;
   17415     }
   17416   }
   17417   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
   17418 }
   17419 
   17420 void Assembler::veor(
   17421     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   17422   VIXL_ASSERT(AllowAssembler());
   17423   CheckIT(cond);
   17424   USE(dt);
   17425   if (IsUsingT32()) {
   17426     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   17427     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17428       EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17429                  rm.Encode(5, 0));
   17430       AdvanceIT();
   17431       return;
   17432     }
   17433   } else {
   17434     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   17435     if (cond.Is(al)) {
   17436       EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17437               rm.Encode(5, 0));
   17438       return;
   17439     }
   17440   }
   17441   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
   17442 }
   17443 
   17444 void Assembler::vext(Condition cond,
   17445                      DataType dt,
   17446                      DRegister rd,
   17447                      DRegister rn,
   17448                      DRegister rm,
   17449                      const DOperand& operand) {
   17450   VIXL_ASSERT(AllowAssembler());
   17451   CheckIT(cond);
   17452   if (operand.IsImmediate()) {
   17453     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   17454       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   17455       if (IsUsingT32()) {
   17456         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
   17457         if (dt.Is(Untyped8) && (imm <= 7)) {
   17458           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17459             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17460                        rm.Encode(5, 0) | (imm << 8));
   17461             AdvanceIT();
   17462             return;
   17463           }
   17464         }
   17465         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
   17466         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
   17467             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
   17468           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17469             uint32_t imm4 = imm / dt.GetSize();
   17470             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17471                        rm.Encode(5, 0) | (imm4 << 8));
   17472             AdvanceIT();
   17473             return;
   17474           }
   17475         }
   17476       } else {
   17477         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
   17478         if (dt.Is(Untyped8) && (imm <= 7)) {
   17479           if (cond.Is(al)) {
   17480             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17481                     rm.Encode(5, 0) | (imm << 8));
   17482             return;
   17483           }
   17484         }
   17485         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
   17486         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
   17487             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
   17488           if (cond.Is(al)) {
   17489             uint32_t imm4 = imm / dt.GetSize();
   17490             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17491                     rm.Encode(5, 0) | (imm4 << 8));
   17492             return;
   17493           }
   17494         }
   17495       }
   17496     }
   17497   }
   17498   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
   17499 }
   17500 
   17501 void Assembler::vext(Condition cond,
   17502                      DataType dt,
   17503                      QRegister rd,
   17504                      QRegister rn,
   17505                      QRegister rm,
   17506                      const QOperand& operand) {
   17507   VIXL_ASSERT(AllowAssembler());
   17508   CheckIT(cond);
   17509   if (operand.IsImmediate()) {
   17510     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   17511       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   17512       if (IsUsingT32()) {
   17513         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
   17514         if (dt.Is(Untyped8) && (imm <= 15)) {
   17515           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17516             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17517                        rm.Encode(5, 0) | (imm << 8));
   17518             AdvanceIT();
   17519             return;
   17520           }
   17521         }
   17522         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
   17523         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
   17524             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
   17525           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17526             uint32_t imm4 = imm / dt.GetSize();
   17527             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17528                        rm.Encode(5, 0) | (imm4 << 8));
   17529             AdvanceIT();
   17530             return;
   17531           }
   17532         }
   17533       } else {
   17534         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
   17535         if (dt.Is(Untyped8) && (imm <= 15)) {
   17536           if (cond.Is(al)) {
   17537             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17538                     rm.Encode(5, 0) | (imm << 8));
   17539             return;
   17540           }
   17541         }
   17542         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
   17543         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
   17544             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
   17545           if (cond.Is(al)) {
   17546             uint32_t imm4 = imm / dt.GetSize();
   17547             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17548                     rm.Encode(5, 0) | (imm4 << 8));
   17549             return;
   17550           }
   17551         }
   17552       }
   17553     }
   17554   }
   17555   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
   17556 }
   17557 
   17558 void Assembler::vfma(
   17559     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   17560   VIXL_ASSERT(AllowAssembler());
   17561   CheckIT(cond);
   17562   if (IsUsingT32()) {
   17563     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   17564     if (dt.Is(F32)) {
   17565       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17566         EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17567                    rm.Encode(5, 0));
   17568         AdvanceIT();
   17569         return;
   17570       }
   17571     }
   17572     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   17573     if (dt.Is(F64)) {
   17574       EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17575                  rm.Encode(5, 0));
   17576       AdvanceIT();
   17577       return;
   17578     }
   17579   } else {
   17580     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   17581     if (dt.Is(F32)) {
   17582       if (cond.Is(al)) {
   17583         EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17584                 rm.Encode(5, 0));
   17585         return;
   17586       }
   17587     }
   17588     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   17589     if (dt.Is(F64) && cond.IsNotNever()) {
   17590       EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17591               rn.Encode(7, 16) | rm.Encode(5, 0));
   17592       return;
   17593     }
   17594   }
   17595   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
   17596 }
   17597 
   17598 void Assembler::vfma(
   17599     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   17600   VIXL_ASSERT(AllowAssembler());
   17601   CheckIT(cond);
   17602   if (IsUsingT32()) {
   17603     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   17604     if (dt.Is(F32)) {
   17605       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17606         EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17607                    rm.Encode(5, 0));
   17608         AdvanceIT();
   17609         return;
   17610       }
   17611     }
   17612   } else {
   17613     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   17614     if (dt.Is(F32)) {
   17615       if (cond.Is(al)) {
   17616         EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17617                 rm.Encode(5, 0));
   17618         return;
   17619       }
   17620     }
   17621   }
   17622   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
   17623 }
   17624 
   17625 void Assembler::vfma(
   17626     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   17627   VIXL_ASSERT(AllowAssembler());
   17628   CheckIT(cond);
   17629   if (IsUsingT32()) {
   17630     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   17631     if (dt.Is(F32)) {
   17632       EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17633                  rm.Encode(5, 0));
   17634       AdvanceIT();
   17635       return;
   17636     }
   17637   } else {
   17638     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   17639     if (dt.Is(F32) && cond.IsNotNever()) {
   17640       EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17641               rn.Encode(7, 16) | rm.Encode(5, 0));
   17642       return;
   17643     }
   17644   }
   17645   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
   17646 }
   17647 
   17648 void Assembler::vfms(
   17649     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   17650   VIXL_ASSERT(AllowAssembler());
   17651   CheckIT(cond);
   17652   if (IsUsingT32()) {
   17653     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   17654     if (dt.Is(F32)) {
   17655       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17656         EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17657                    rm.Encode(5, 0));
   17658         AdvanceIT();
   17659         return;
   17660       }
   17661     }
   17662     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   17663     if (dt.Is(F64)) {
   17664       EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17665                  rm.Encode(5, 0));
   17666       AdvanceIT();
   17667       return;
   17668     }
   17669   } else {
   17670     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   17671     if (dt.Is(F32)) {
   17672       if (cond.Is(al)) {
   17673         EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17674                 rm.Encode(5, 0));
   17675         return;
   17676       }
   17677     }
   17678     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   17679     if (dt.Is(F64) && cond.IsNotNever()) {
   17680       EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17681               rn.Encode(7, 16) | rm.Encode(5, 0));
   17682       return;
   17683     }
   17684   }
   17685   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
   17686 }
   17687 
   17688 void Assembler::vfms(
   17689     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   17690   VIXL_ASSERT(AllowAssembler());
   17691   CheckIT(cond);
   17692   if (IsUsingT32()) {
   17693     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   17694     if (dt.Is(F32)) {
   17695       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17696         EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17697                    rm.Encode(5, 0));
   17698         AdvanceIT();
   17699         return;
   17700       }
   17701     }
   17702   } else {
   17703     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   17704     if (dt.Is(F32)) {
   17705       if (cond.Is(al)) {
   17706         EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17707                 rm.Encode(5, 0));
   17708         return;
   17709       }
   17710     }
   17711   }
   17712   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
   17713 }
   17714 
   17715 void Assembler::vfms(
   17716     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   17717   VIXL_ASSERT(AllowAssembler());
   17718   CheckIT(cond);
   17719   if (IsUsingT32()) {
   17720     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   17721     if (dt.Is(F32)) {
   17722       EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17723                  rm.Encode(5, 0));
   17724       AdvanceIT();
   17725       return;
   17726     }
   17727   } else {
   17728     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   17729     if (dt.Is(F32) && cond.IsNotNever()) {
   17730       EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17731               rn.Encode(7, 16) | rm.Encode(5, 0));
   17732       return;
   17733     }
   17734   }
   17735   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
   17736 }
   17737 
   17738 void Assembler::vfnma(
   17739     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   17740   VIXL_ASSERT(AllowAssembler());
   17741   CheckIT(cond);
   17742   if (IsUsingT32()) {
   17743     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
   17744     if (dt.Is(F32)) {
   17745       EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17746                  rm.Encode(5, 0));
   17747       AdvanceIT();
   17748       return;
   17749     }
   17750   } else {
   17751     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
   17752     if (dt.Is(F32) && cond.IsNotNever()) {
   17753       EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17754               rn.Encode(7, 16) | rm.Encode(5, 0));
   17755       return;
   17756     }
   17757   }
   17758   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
   17759 }
   17760 
   17761 void Assembler::vfnma(
   17762     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   17763   VIXL_ASSERT(AllowAssembler());
   17764   CheckIT(cond);
   17765   if (IsUsingT32()) {
   17766     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
   17767     if (dt.Is(F64)) {
   17768       EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17769                  rm.Encode(5, 0));
   17770       AdvanceIT();
   17771       return;
   17772     }
   17773   } else {
   17774     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
   17775     if (dt.Is(F64) && cond.IsNotNever()) {
   17776       EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17777               rn.Encode(7, 16) | rm.Encode(5, 0));
   17778       return;
   17779     }
   17780   }
   17781   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
   17782 }
   17783 
   17784 void Assembler::vfnms(
   17785     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   17786   VIXL_ASSERT(AllowAssembler());
   17787   CheckIT(cond);
   17788   if (IsUsingT32()) {
   17789     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
   17790     if (dt.Is(F32)) {
   17791       EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17792                  rm.Encode(5, 0));
   17793       AdvanceIT();
   17794       return;
   17795     }
   17796   } else {
   17797     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
   17798     if (dt.Is(F32) && cond.IsNotNever()) {
   17799       EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17800               rn.Encode(7, 16) | rm.Encode(5, 0));
   17801       return;
   17802     }
   17803   }
   17804   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
   17805 }
   17806 
   17807 void Assembler::vfnms(
   17808     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   17809   VIXL_ASSERT(AllowAssembler());
   17810   CheckIT(cond);
   17811   if (IsUsingT32()) {
   17812     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
   17813     if (dt.Is(F64)) {
   17814       EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   17815                  rm.Encode(5, 0));
   17816       AdvanceIT();
   17817       return;
   17818     }
   17819   } else {
   17820     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
   17821     if (dt.Is(F64) && cond.IsNotNever()) {
   17822       EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   17823               rn.Encode(7, 16) | rm.Encode(5, 0));
   17824       return;
   17825     }
   17826   }
   17827   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
   17828 }
   17829 
   17830 void Assembler::vhadd(
   17831     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   17832   VIXL_ASSERT(AllowAssembler());
   17833   CheckIT(cond);
   17834   Dt_U_size_1 encoded_dt(dt);
   17835   if (IsUsingT32()) {
   17836     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   17837     if (encoded_dt.IsValid()) {
   17838       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17839         EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   17840                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   17841                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   17842         AdvanceIT();
   17843         return;
   17844       }
   17845     }
   17846   } else {
   17847     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   17848     if (encoded_dt.IsValid()) {
   17849       if (cond.Is(al)) {
   17850         EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   17851                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   17852                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   17853         return;
   17854       }
   17855     }
   17856   }
   17857   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
   17858 }
   17859 
   17860 void Assembler::vhadd(
   17861     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   17862   VIXL_ASSERT(AllowAssembler());
   17863   CheckIT(cond);
   17864   Dt_U_size_1 encoded_dt(dt);
   17865   if (IsUsingT32()) {
   17866     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   17867     if (encoded_dt.IsValid()) {
   17868       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17869         EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   17870                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   17871                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   17872         AdvanceIT();
   17873         return;
   17874       }
   17875     }
   17876   } else {
   17877     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   17878     if (encoded_dt.IsValid()) {
   17879       if (cond.Is(al)) {
   17880         EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   17881                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   17882                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   17883         return;
   17884       }
   17885     }
   17886   }
   17887   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
   17888 }
   17889 
   17890 void Assembler::vhsub(
   17891     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   17892   VIXL_ASSERT(AllowAssembler());
   17893   CheckIT(cond);
   17894   Dt_U_size_1 encoded_dt(dt);
   17895   if (IsUsingT32()) {
   17896     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   17897     if (encoded_dt.IsValid()) {
   17898       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17899         EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   17900                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   17901                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   17902         AdvanceIT();
   17903         return;
   17904       }
   17905     }
   17906   } else {
   17907     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   17908     if (encoded_dt.IsValid()) {
   17909       if (cond.Is(al)) {
   17910         EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   17911                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   17912                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   17913         return;
   17914       }
   17915     }
   17916   }
   17917   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
   17918 }
   17919 
   17920 void Assembler::vhsub(
   17921     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   17922   VIXL_ASSERT(AllowAssembler());
   17923   CheckIT(cond);
   17924   Dt_U_size_1 encoded_dt(dt);
   17925   if (IsUsingT32()) {
   17926     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   17927     if (encoded_dt.IsValid()) {
   17928       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17929         EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   17930                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   17931                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   17932         AdvanceIT();
   17933         return;
   17934       }
   17935     }
   17936   } else {
   17937     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   17938     if (encoded_dt.IsValid()) {
   17939       if (cond.Is(al)) {
   17940         EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   17941                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   17942                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   17943         return;
   17944       }
   17945     }
   17946   }
   17947   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
   17948 }
   17949 
   17950 void Assembler::vld1(Condition cond,
   17951                      DataType dt,
   17952                      const NeonRegisterList& nreglist,
   17953                      const AlignedMemOperand& operand) {
   17954   VIXL_ASSERT(AllowAssembler());
   17955   CheckIT(cond);
   17956   if (operand.IsImmediateZero()) {
   17957     Register rn = operand.GetBaseRegister();
   17958     Alignment align = operand.GetAlignment();
   17959     Dt_size_6 encoded_dt(dt);
   17960     Dt_size_7 encoded_dt_2(dt);
   17961     Align_align_1 encoded_align_1(align, nreglist);
   17962     Align_a_1 encoded_align_2(align, dt);
   17963     Align_index_align_1 encoded_align_3(align, nreglist, dt);
   17964     if (IsUsingT32()) {
   17965       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   17966       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17967           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   17968           operand.IsOffset() && encoded_align_1.IsValid() &&
   17969           (!rn.IsPC() || AllowUnpredictable())) {
   17970         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   17971           const DRegister& first = nreglist.GetFirstDRegister();
   17972           uint32_t len_encoding;
   17973           switch (nreglist.GetLength()) {
   17974             default:
   17975               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   17976             case 1:
   17977               len_encoding = 0x7;
   17978               break;
   17979             case 2:
   17980               len_encoding = 0xa;
   17981               break;
   17982             case 3:
   17983               len_encoding = 0x6;
   17984               break;
   17985             case 4:
   17986               len_encoding = 0x2;
   17987               break;
   17988           }
   17989           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
   17990                      (encoded_align_1.GetEncodingValue() << 4) |
   17991                      first.Encode(22, 12) | (len_encoding << 8) |
   17992                      (rn.GetCode() << 16));
   17993           AdvanceIT();
   17994           return;
   17995         }
   17996       }
   17997       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   17998       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   17999           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   18000           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   18001           (!rn.IsPC() || AllowUnpredictable())) {
   18002         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18003           const DRegister& first = nreglist.GetFirstDRegister();
   18004           uint32_t len_encoding;
   18005           switch (nreglist.GetLength()) {
   18006             default:
   18007               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   18008             case 1:
   18009               len_encoding = 0x7;
   18010               break;
   18011             case 2:
   18012               len_encoding = 0xa;
   18013               break;
   18014             case 3:
   18015               len_encoding = 0x6;
   18016               break;
   18017             case 4:
   18018               len_encoding = 0x2;
   18019               break;
   18020           }
   18021           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
   18022                      (encoded_align_1.GetEncodingValue() << 4) |
   18023                      first.Encode(22, 12) | (len_encoding << 8) |
   18024                      (rn.GetCode() << 16));
   18025           AdvanceIT();
   18026           return;
   18027         }
   18028       }
   18029       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   18030       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18031           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   18032           operand.IsOffset() && encoded_align_2.IsValid() &&
   18033           (!rn.IsPC() || AllowUnpredictable())) {
   18034         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18035           const DRegister& first = nreglist.GetFirstDRegister();
   18036           uint32_t len_encoding = nreglist.GetLength() - 1;
   18037           EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
   18038                      (encoded_align_2.GetEncodingValue() << 4) |
   18039                      first.Encode(22, 12) | (len_encoding << 5) |
   18040                      (rn.GetCode() << 16));
   18041           AdvanceIT();
   18042           return;
   18043         }
   18044       }
   18045       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   18046       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18047           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   18048           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   18049           (!rn.IsPC() || AllowUnpredictable())) {
   18050         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18051           const DRegister& first = nreglist.GetFirstDRegister();
   18052           uint32_t len_encoding = nreglist.GetLength() - 1;
   18053           EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
   18054                      (encoded_align_2.GetEncodingValue() << 4) |
   18055                      first.Encode(22, 12) | (len_encoding << 5) |
   18056                      (rn.GetCode() << 16));
   18057           AdvanceIT();
   18058           return;
   18059         }
   18060       }
   18061       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   18062       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   18063           (nreglist.GetLength() == 1) && operand.IsOffset() &&
   18064           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   18065         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18066           const DRegister& first = nreglist.GetFirstDRegister();
   18067           EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
   18068                      (encoded_align_3.GetEncodingValue() << 4) |
   18069                      first.Encode(22, 12) | (rn.GetCode() << 16));
   18070           AdvanceIT();
   18071           return;
   18072         }
   18073       }
   18074       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   18075       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   18076           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
   18077           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   18078         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18079           const DRegister& first = nreglist.GetFirstDRegister();
   18080           EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
   18081                      (encoded_align_3.GetEncodingValue() << 4) |
   18082                      first.Encode(22, 12) | (rn.GetCode() << 16));
   18083           AdvanceIT();
   18084           return;
   18085         }
   18086       }
   18087     } else {
   18088       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18089       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18090           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   18091           operand.IsOffset() && encoded_align_1.IsValid() &&
   18092           (!rn.IsPC() || AllowUnpredictable())) {
   18093         if (cond.Is(al)) {
   18094           const DRegister& first = nreglist.GetFirstDRegister();
   18095           uint32_t len_encoding;
   18096           switch (nreglist.GetLength()) {
   18097             default:
   18098               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   18099             case 1:
   18100               len_encoding = 0x7;
   18101               break;
   18102             case 2:
   18103               len_encoding = 0xa;
   18104               break;
   18105             case 3:
   18106               len_encoding = 0x6;
   18107               break;
   18108             case 4:
   18109               len_encoding = 0x2;
   18110               break;
   18111           }
   18112           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
   18113                   (encoded_align_1.GetEncodingValue() << 4) |
   18114                   first.Encode(22, 12) | (len_encoding << 8) |
   18115                   (rn.GetCode() << 16));
   18116           return;
   18117         }
   18118       }
   18119       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18120       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18121           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   18122           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   18123           (!rn.IsPC() || AllowUnpredictable())) {
   18124         if (cond.Is(al)) {
   18125           const DRegister& first = nreglist.GetFirstDRegister();
   18126           uint32_t len_encoding;
   18127           switch (nreglist.GetLength()) {
   18128             default:
   18129               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   18130             case 1:
   18131               len_encoding = 0x7;
   18132               break;
   18133             case 2:
   18134               len_encoding = 0xa;
   18135               break;
   18136             case 3:
   18137               len_encoding = 0x6;
   18138               break;
   18139             case 4:
   18140               len_encoding = 0x2;
   18141               break;
   18142           }
   18143           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
   18144                   (encoded_align_1.GetEncodingValue() << 4) |
   18145                   first.Encode(22, 12) | (len_encoding << 8) |
   18146                   (rn.GetCode() << 16));
   18147           return;
   18148         }
   18149       }
   18150       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18151       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18152           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   18153           operand.IsOffset() && encoded_align_2.IsValid() &&
   18154           (!rn.IsPC() || AllowUnpredictable())) {
   18155         if (cond.Is(al)) {
   18156           const DRegister& first = nreglist.GetFirstDRegister();
   18157           uint32_t len_encoding = nreglist.GetLength() - 1;
   18158           EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
   18159                   (encoded_align_2.GetEncodingValue() << 4) |
   18160                   first.Encode(22, 12) | (len_encoding << 5) |
   18161                   (rn.GetCode() << 16));
   18162           return;
   18163         }
   18164       }
   18165       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18166       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18167           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   18168           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   18169           (!rn.IsPC() || AllowUnpredictable())) {
   18170         if (cond.Is(al)) {
   18171           const DRegister& first = nreglist.GetFirstDRegister();
   18172           uint32_t len_encoding = nreglist.GetLength() - 1;
   18173           EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
   18174                   (encoded_align_2.GetEncodingValue() << 4) |
   18175                   first.Encode(22, 12) | (len_encoding << 5) |
   18176                   (rn.GetCode() << 16));
   18177           return;
   18178         }
   18179       }
   18180       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18181       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   18182           (nreglist.GetLength() == 1) && operand.IsOffset() &&
   18183           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   18184         if (cond.Is(al)) {
   18185           const DRegister& first = nreglist.GetFirstDRegister();
   18186           EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
   18187                   (encoded_align_3.GetEncodingValue() << 4) |
   18188                   first.Encode(22, 12) | (rn.GetCode() << 16));
   18189           return;
   18190         }
   18191       }
   18192       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18193       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   18194           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
   18195           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   18196         if (cond.Is(al)) {
   18197           const DRegister& first = nreglist.GetFirstDRegister();
   18198           EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
   18199                   (encoded_align_3.GetEncodingValue() << 4) |
   18200                   first.Encode(22, 12) | (rn.GetCode() << 16));
   18201           return;
   18202         }
   18203       }
   18204     }
   18205   }
   18206   if (operand.IsPlainRegister()) {
   18207     Register rn = operand.GetBaseRegister();
   18208     Alignment align = operand.GetAlignment();
   18209     Register rm = operand.GetOffsetRegister();
   18210     Dt_size_6 encoded_dt(dt);
   18211     Dt_size_7 encoded_dt_2(dt);
   18212     Align_align_1 encoded_align_1(align, nreglist);
   18213     Align_a_1 encoded_align_2(align, dt);
   18214     Align_index_align_1 encoded_align_3(align, nreglist, dt);
   18215     if (IsUsingT32()) {
   18216       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18217       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18218           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   18219           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18220         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18221           const DRegister& first = nreglist.GetFirstDRegister();
   18222           uint32_t len_encoding;
   18223           switch (nreglist.GetLength()) {
   18224             default:
   18225               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   18226             case 1:
   18227               len_encoding = 0x7;
   18228               break;
   18229             case 2:
   18230               len_encoding = 0xa;
   18231               break;
   18232             case 3:
   18233               len_encoding = 0x6;
   18234               break;
   18235             case 4:
   18236               len_encoding = 0x2;
   18237               break;
   18238           }
   18239           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
   18240                      (encoded_align_1.GetEncodingValue() << 4) |
   18241                      first.Encode(22, 12) | (len_encoding << 8) |
   18242                      (rn.GetCode() << 16) | rm.GetCode());
   18243           AdvanceIT();
   18244           return;
   18245         }
   18246       }
   18247       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18248       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18249           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   18250           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18251         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18252           const DRegister& first = nreglist.GetFirstDRegister();
   18253           uint32_t len_encoding = nreglist.GetLength() - 1;
   18254           EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
   18255                      (encoded_align_2.GetEncodingValue() << 4) |
   18256                      first.Encode(22, 12) | (len_encoding << 5) |
   18257                      (rn.GetCode() << 16) | rm.GetCode());
   18258           AdvanceIT();
   18259           return;
   18260         }
   18261       }
   18262       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18263       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   18264           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
   18265           (!rn.IsPC() || AllowUnpredictable())) {
   18266         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18267           const DRegister& first = nreglist.GetFirstDRegister();
   18268           EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
   18269                      (encoded_align_3.GetEncodingValue() << 4) |
   18270                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   18271                      rm.GetCode());
   18272           AdvanceIT();
   18273           return;
   18274         }
   18275       }
   18276     } else {
   18277       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18278       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18279           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   18280           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18281         if (cond.Is(al)) {
   18282           const DRegister& first = nreglist.GetFirstDRegister();
   18283           uint32_t len_encoding;
   18284           switch (nreglist.GetLength()) {
   18285             default:
   18286               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   18287             case 1:
   18288               len_encoding = 0x7;
   18289               break;
   18290             case 2:
   18291               len_encoding = 0xa;
   18292               break;
   18293             case 3:
   18294               len_encoding = 0x6;
   18295               break;
   18296             case 4:
   18297               len_encoding = 0x2;
   18298               break;
   18299           }
   18300           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
   18301                   (encoded_align_1.GetEncodingValue() << 4) |
   18302                   first.Encode(22, 12) | (len_encoding << 8) |
   18303                   (rn.GetCode() << 16) | rm.GetCode());
   18304           return;
   18305         }
   18306       }
   18307       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18308       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   18309           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
   18310           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18311         if (cond.Is(al)) {
   18312           const DRegister& first = nreglist.GetFirstDRegister();
   18313           uint32_t len_encoding = nreglist.GetLength() - 1;
   18314           EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
   18315                   (encoded_align_2.GetEncodingValue() << 4) |
   18316                   first.Encode(22, 12) | (len_encoding << 5) |
   18317                   (rn.GetCode() << 16) | rm.GetCode());
   18318           return;
   18319         }
   18320       }
   18321       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18322       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   18323           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
   18324           (!rn.IsPC() || AllowUnpredictable())) {
   18325         if (cond.Is(al)) {
   18326           const DRegister& first = nreglist.GetFirstDRegister();
   18327           EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
   18328                   (encoded_align_3.GetEncodingValue() << 4) |
   18329                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   18330           return;
   18331         }
   18332       }
   18333     }
   18334   }
   18335   Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
   18336 }
   18337 
   18338 void Assembler::vld2(Condition cond,
   18339                      DataType dt,
   18340                      const NeonRegisterList& nreglist,
   18341                      const AlignedMemOperand& operand) {
   18342   VIXL_ASSERT(AllowAssembler());
   18343   CheckIT(cond);
   18344   if (operand.IsImmediateZero()) {
   18345     Register rn = operand.GetBaseRegister();
   18346     Alignment align = operand.GetAlignment();
   18347     Dt_size_7 encoded_dt(dt);
   18348     Align_align_2 encoded_align_1(align, nreglist);
   18349     Align_a_2 encoded_align_2(align, dt);
   18350     Align_index_align_2 encoded_align_3(align, nreglist, dt);
   18351     if (IsUsingT32()) {
   18352       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   18353       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18354           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18355            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   18356            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   18357           operand.IsOffset() && encoded_align_1.IsValid() &&
   18358           (!rn.IsPC() || AllowUnpredictable())) {
   18359         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18360           const DRegister& first = nreglist.GetFirstDRegister();
   18361           uint32_t len_encoding;
   18362           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   18363             len_encoding = 0x8;
   18364           }
   18365           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   18366             len_encoding = 0x9;
   18367           }
   18368           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   18369             len_encoding = 0x3;
   18370           }
   18371           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
   18372                      (encoded_align_1.GetEncodingValue() << 4) |
   18373                      first.Encode(22, 12) | (len_encoding << 8) |
   18374                      (rn.GetCode() << 16));
   18375           AdvanceIT();
   18376           return;
   18377         }
   18378       }
   18379       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   18380       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18381           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18382            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   18383            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   18384           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   18385           (!rn.IsPC() || AllowUnpredictable())) {
   18386         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18387           const DRegister& first = nreglist.GetFirstDRegister();
   18388           uint32_t len_encoding;
   18389           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   18390             len_encoding = 0x8;
   18391           }
   18392           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   18393             len_encoding = 0x9;
   18394           }
   18395           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   18396             len_encoding = 0x3;
   18397           }
   18398           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
   18399                      (encoded_align_1.GetEncodingValue() << 4) |
   18400                      first.Encode(22, 12) | (len_encoding << 8) |
   18401                      (rn.GetCode() << 16));
   18402           AdvanceIT();
   18403           return;
   18404         }
   18405       }
   18406       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   18407       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18408           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18409            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18410           operand.IsOffset() && encoded_align_2.IsValid() &&
   18411           (!rn.IsPC() || AllowUnpredictable())) {
   18412         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18413           const DRegister& first = nreglist.GetFirstDRegister();
   18414           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18415           EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
   18416                      (encoded_align_2.GetEncodingValue() << 4) |
   18417                      first.Encode(22, 12) | (len_encoding << 5) |
   18418                      (rn.GetCode() << 16));
   18419           AdvanceIT();
   18420           return;
   18421         }
   18422       }
   18423       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   18424       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18425           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18426            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18427           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   18428           (!rn.IsPC() || AllowUnpredictable())) {
   18429         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18430           const DRegister& first = nreglist.GetFirstDRegister();
   18431           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18432           EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
   18433                      (encoded_align_2.GetEncodingValue() << 4) |
   18434                      first.Encode(22, 12) | (len_encoding << 5) |
   18435                      (rn.GetCode() << 16));
   18436           AdvanceIT();
   18437           return;
   18438         }
   18439       }
   18440       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   18441       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18442           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18443            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18444           operand.IsOffset() && encoded_align_3.IsValid() &&
   18445           (!rn.IsPC() || AllowUnpredictable())) {
   18446         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18447           const DRegister& first = nreglist.GetFirstDRegister();
   18448           EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
   18449                      (encoded_align_3.GetEncodingValue() << 4) |
   18450                      first.Encode(22, 12) | (rn.GetCode() << 16));
   18451           AdvanceIT();
   18452           return;
   18453         }
   18454       }
   18455       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   18456       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18457           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18458            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18459           operand.IsPostIndex() && encoded_align_3.IsValid() &&
   18460           (!rn.IsPC() || AllowUnpredictable())) {
   18461         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18462           const DRegister& first = nreglist.GetFirstDRegister();
   18463           EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
   18464                      (encoded_align_3.GetEncodingValue() << 4) |
   18465                      first.Encode(22, 12) | (rn.GetCode() << 16));
   18466           AdvanceIT();
   18467           return;
   18468         }
   18469       }
   18470     } else {
   18471       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18472       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18473           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18474            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   18475            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   18476           operand.IsOffset() && encoded_align_1.IsValid() &&
   18477           (!rn.IsPC() || AllowUnpredictable())) {
   18478         if (cond.Is(al)) {
   18479           const DRegister& first = nreglist.GetFirstDRegister();
   18480           uint32_t len_encoding;
   18481           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   18482             len_encoding = 0x8;
   18483           }
   18484           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   18485             len_encoding = 0x9;
   18486           }
   18487           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   18488             len_encoding = 0x3;
   18489           }
   18490           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
   18491                   (encoded_align_1.GetEncodingValue() << 4) |
   18492                   first.Encode(22, 12) | (len_encoding << 8) |
   18493                   (rn.GetCode() << 16));
   18494           return;
   18495         }
   18496       }
   18497       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18498       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18499           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18500            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   18501            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   18502           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   18503           (!rn.IsPC() || AllowUnpredictable())) {
   18504         if (cond.Is(al)) {
   18505           const DRegister& first = nreglist.GetFirstDRegister();
   18506           uint32_t len_encoding;
   18507           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   18508             len_encoding = 0x8;
   18509           }
   18510           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   18511             len_encoding = 0x9;
   18512           }
   18513           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   18514             len_encoding = 0x3;
   18515           }
   18516           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
   18517                   (encoded_align_1.GetEncodingValue() << 4) |
   18518                   first.Encode(22, 12) | (len_encoding << 8) |
   18519                   (rn.GetCode() << 16));
   18520           return;
   18521         }
   18522       }
   18523       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18524       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18525           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18526            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18527           operand.IsOffset() && encoded_align_2.IsValid() &&
   18528           (!rn.IsPC() || AllowUnpredictable())) {
   18529         if (cond.Is(al)) {
   18530           const DRegister& first = nreglist.GetFirstDRegister();
   18531           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18532           EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
   18533                   (encoded_align_2.GetEncodingValue() << 4) |
   18534                   first.Encode(22, 12) | (len_encoding << 5) |
   18535                   (rn.GetCode() << 16));
   18536           return;
   18537         }
   18538       }
   18539       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18540       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18541           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18542            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18543           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   18544           (!rn.IsPC() || AllowUnpredictable())) {
   18545         if (cond.Is(al)) {
   18546           const DRegister& first = nreglist.GetFirstDRegister();
   18547           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18548           EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
   18549                   (encoded_align_2.GetEncodingValue() << 4) |
   18550                   first.Encode(22, 12) | (len_encoding << 5) |
   18551                   (rn.GetCode() << 16));
   18552           return;
   18553         }
   18554       }
   18555       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18556       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18557           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18558            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18559           operand.IsOffset() && encoded_align_3.IsValid() &&
   18560           (!rn.IsPC() || AllowUnpredictable())) {
   18561         if (cond.Is(al)) {
   18562           const DRegister& first = nreglist.GetFirstDRegister();
   18563           EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
   18564                   (encoded_align_3.GetEncodingValue() << 4) |
   18565                   first.Encode(22, 12) | (rn.GetCode() << 16));
   18566           return;
   18567         }
   18568       }
   18569       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18570       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18571           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18572            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18573           operand.IsPostIndex() && encoded_align_3.IsValid() &&
   18574           (!rn.IsPC() || AllowUnpredictable())) {
   18575         if (cond.Is(al)) {
   18576           const DRegister& first = nreglist.GetFirstDRegister();
   18577           EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
   18578                   (encoded_align_3.GetEncodingValue() << 4) |
   18579                   first.Encode(22, 12) | (rn.GetCode() << 16));
   18580           return;
   18581         }
   18582       }
   18583     }
   18584   }
   18585   if (operand.IsPlainRegister()) {
   18586     Register rn = operand.GetBaseRegister();
   18587     Alignment align = operand.GetAlignment();
   18588     Register rm = operand.GetOffsetRegister();
   18589     Dt_size_7 encoded_dt(dt);
   18590     Align_align_2 encoded_align_1(align, nreglist);
   18591     Align_a_2 encoded_align_2(align, dt);
   18592     Align_index_align_2 encoded_align_3(align, nreglist, dt);
   18593     if (IsUsingT32()) {
   18594       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18595       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18596           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18597            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   18598            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   18599           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18600         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18601           const DRegister& first = nreglist.GetFirstDRegister();
   18602           uint32_t len_encoding;
   18603           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   18604             len_encoding = 0x8;
   18605           }
   18606           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   18607             len_encoding = 0x9;
   18608           }
   18609           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   18610             len_encoding = 0x3;
   18611           }
   18612           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
   18613                      (encoded_align_1.GetEncodingValue() << 4) |
   18614                      first.Encode(22, 12) | (len_encoding << 8) |
   18615                      (rn.GetCode() << 16) | rm.GetCode());
   18616           AdvanceIT();
   18617           return;
   18618         }
   18619       }
   18620       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18621       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18622           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18623            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18624           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18625         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18626           const DRegister& first = nreglist.GetFirstDRegister();
   18627           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18628           EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
   18629                      (encoded_align_2.GetEncodingValue() << 4) |
   18630                      first.Encode(22, 12) | (len_encoding << 5) |
   18631                      (rn.GetCode() << 16) | rm.GetCode());
   18632           AdvanceIT();
   18633           return;
   18634         }
   18635       }
   18636       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18637       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18638           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18639            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18640           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18641         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18642           const DRegister& first = nreglist.GetFirstDRegister();
   18643           EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
   18644                      (encoded_align_3.GetEncodingValue() << 4) |
   18645                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   18646                      rm.GetCode());
   18647           AdvanceIT();
   18648           return;
   18649         }
   18650       }
   18651     } else {
   18652       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18653       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18654           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18655            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   18656            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   18657           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18658         if (cond.Is(al)) {
   18659           const DRegister& first = nreglist.GetFirstDRegister();
   18660           uint32_t len_encoding;
   18661           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   18662             len_encoding = 0x8;
   18663           }
   18664           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   18665             len_encoding = 0x9;
   18666           }
   18667           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   18668             len_encoding = 0x3;
   18669           }
   18670           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
   18671                   (encoded_align_1.GetEncodingValue() << 4) |
   18672                   first.Encode(22, 12) | (len_encoding << 8) |
   18673                   (rn.GetCode() << 16) | rm.GetCode());
   18674           return;
   18675         }
   18676       }
   18677       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18678       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18679           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18680            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18681           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18682         if (cond.Is(al)) {
   18683           const DRegister& first = nreglist.GetFirstDRegister();
   18684           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18685           EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
   18686                   (encoded_align_2.GetEncodingValue() << 4) |
   18687                   first.Encode(22, 12) | (len_encoding << 5) |
   18688                   (rn.GetCode() << 16) | rm.GetCode());
   18689           return;
   18690         }
   18691       }
   18692       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18693       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18694           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   18695            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   18696           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18697         if (cond.Is(al)) {
   18698           const DRegister& first = nreglist.GetFirstDRegister();
   18699           EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
   18700                   (encoded_align_3.GetEncodingValue() << 4) |
   18701                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   18702           return;
   18703         }
   18704       }
   18705     }
   18706   }
   18707   Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
   18708 }
   18709 
   18710 void Assembler::vld3(Condition cond,
   18711                      DataType dt,
   18712                      const NeonRegisterList& nreglist,
   18713                      const AlignedMemOperand& operand) {
   18714   VIXL_ASSERT(AllowAssembler());
   18715   CheckIT(cond);
   18716   if (operand.IsImmediateZero()) {
   18717     Register rn = operand.GetBaseRegister();
   18718     Alignment align = operand.GetAlignment();
   18719     Dt_size_7 encoded_dt(dt);
   18720     Align_align_3 encoded_align_1(align);
   18721     if (IsUsingT32()) {
   18722       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   18723       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18724           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18725            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18726           operand.IsOffset() && encoded_align_1.IsValid() &&
   18727           (!rn.IsPC() || AllowUnpredictable())) {
   18728         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18729           const DRegister& first = nreglist.GetFirstDRegister();
   18730           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   18731           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
   18732                      (encoded_align_1.GetEncodingValue() << 4) |
   18733                      first.Encode(22, 12) | (len_encoding << 8) |
   18734                      (rn.GetCode() << 16));
   18735           AdvanceIT();
   18736           return;
   18737         }
   18738       }
   18739       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   18740       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18741           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18742            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18743           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   18744           (!rn.IsPC() || AllowUnpredictable())) {
   18745         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18746           const DRegister& first = nreglist.GetFirstDRegister();
   18747           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   18748           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
   18749                      (encoded_align_1.GetEncodingValue() << 4) |
   18750                      first.Encode(22, 12) | (len_encoding << 8) |
   18751                      (rn.GetCode() << 16));
   18752           AdvanceIT();
   18753           return;
   18754         }
   18755       }
   18756     } else {
   18757       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   18758       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18759           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18760            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18761           operand.IsOffset() && encoded_align_1.IsValid() &&
   18762           (!rn.IsPC() || AllowUnpredictable())) {
   18763         if (cond.Is(al)) {
   18764           const DRegister& first = nreglist.GetFirstDRegister();
   18765           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   18766           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
   18767                   (encoded_align_1.GetEncodingValue() << 4) |
   18768                   first.Encode(22, 12) | (len_encoding << 8) |
   18769                   (rn.GetCode() << 16));
   18770           return;
   18771         }
   18772       }
   18773       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   18774       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18775           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18776            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18777           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   18778           (!rn.IsPC() || AllowUnpredictable())) {
   18779         if (cond.Is(al)) {
   18780           const DRegister& first = nreglist.GetFirstDRegister();
   18781           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   18782           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
   18783                   (encoded_align_1.GetEncodingValue() << 4) |
   18784                   first.Encode(22, 12) | (len_encoding << 8) |
   18785                   (rn.GetCode() << 16));
   18786           return;
   18787         }
   18788       }
   18789     }
   18790   }
   18791   if (operand.IsPlainRegister()) {
   18792     Register rn = operand.GetBaseRegister();
   18793     Alignment align = operand.GetAlignment();
   18794     Register rm = operand.GetOffsetRegister();
   18795     Dt_size_7 encoded_dt(dt);
   18796     Align_align_3 encoded_align_1(align);
   18797     if (IsUsingT32()) {
   18798       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   18799       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18800           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18801            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18802           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18803         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18804           const DRegister& first = nreglist.GetFirstDRegister();
   18805           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   18806           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
   18807                      (encoded_align_1.GetEncodingValue() << 4) |
   18808                      first.Encode(22, 12) | (len_encoding << 8) |
   18809                      (rn.GetCode() << 16) | rm.GetCode());
   18810           AdvanceIT();
   18811           return;
   18812         }
   18813       }
   18814     } else {
   18815       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   18816       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   18817           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18818            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18819           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   18820         if (cond.Is(al)) {
   18821           const DRegister& first = nreglist.GetFirstDRegister();
   18822           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   18823           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
   18824                   (encoded_align_1.GetEncodingValue() << 4) |
   18825                   first.Encode(22, 12) | (len_encoding << 8) |
   18826                   (rn.GetCode() << 16) | rm.GetCode());
   18827           return;
   18828         }
   18829       }
   18830     }
   18831   }
   18832   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
   18833 }
   18834 
   18835 void Assembler::vld3(Condition cond,
   18836                      DataType dt,
   18837                      const NeonRegisterList& nreglist,
   18838                      const MemOperand& operand) {
   18839   VIXL_ASSERT(AllowAssembler());
   18840   CheckIT(cond);
   18841   if (operand.IsImmediateZero()) {
   18842     Register rn = operand.GetBaseRegister();
   18843     Dt_size_7 encoded_dt(dt);
   18844     Index_1 encoded_align_1(nreglist, dt);
   18845     if (IsUsingT32()) {
   18846       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
   18847       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18848           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18849            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18850           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   18851         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18852           const DRegister& first = nreglist.GetFirstDRegister();
   18853           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18854           EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
   18855                      first.Encode(22, 12) | (len_encoding << 5) |
   18856                      (rn.GetCode() << 16));
   18857           AdvanceIT();
   18858           return;
   18859         }
   18860       }
   18861       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
   18862       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18863           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18864            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18865           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   18866         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18867           const DRegister& first = nreglist.GetFirstDRegister();
   18868           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18869           EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
   18870                      first.Encode(22, 12) | (len_encoding << 5) |
   18871                      (rn.GetCode() << 16));
   18872           AdvanceIT();
   18873           return;
   18874         }
   18875       }
   18876       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
   18877       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18878           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18879            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18880           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   18881         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18882           const DRegister& first = nreglist.GetFirstDRegister();
   18883           EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
   18884                      (encoded_align_1.GetEncodingValue() << 4) |
   18885                      first.Encode(22, 12) | (rn.GetCode() << 16));
   18886           AdvanceIT();
   18887           return;
   18888         }
   18889       }
   18890       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
   18891       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18892           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18893            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18894           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   18895         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18896           const DRegister& first = nreglist.GetFirstDRegister();
   18897           EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
   18898                      (encoded_align_1.GetEncodingValue() << 4) |
   18899                      first.Encode(22, 12) | (rn.GetCode() << 16));
   18900           AdvanceIT();
   18901           return;
   18902         }
   18903       }
   18904     } else {
   18905       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
   18906       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18907           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18908            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18909           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   18910         if (cond.Is(al)) {
   18911           const DRegister& first = nreglist.GetFirstDRegister();
   18912           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18913           EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
   18914                   first.Encode(22, 12) | (len_encoding << 5) |
   18915                   (rn.GetCode() << 16));
   18916           return;
   18917         }
   18918       }
   18919       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
   18920       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18921           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18922            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18923           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   18924         if (cond.Is(al)) {
   18925           const DRegister& first = nreglist.GetFirstDRegister();
   18926           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18927           EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
   18928                   first.Encode(22, 12) | (len_encoding << 5) |
   18929                   (rn.GetCode() << 16));
   18930           return;
   18931         }
   18932       }
   18933       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
   18934       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18935           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18936            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18937           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   18938         if (cond.Is(al)) {
   18939           const DRegister& first = nreglist.GetFirstDRegister();
   18940           EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
   18941                   (encoded_align_1.GetEncodingValue() << 4) |
   18942                   first.Encode(22, 12) | (rn.GetCode() << 16));
   18943           return;
   18944         }
   18945       }
   18946       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
   18947       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18948           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18949            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18950           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   18951         if (cond.Is(al)) {
   18952           const DRegister& first = nreglist.GetFirstDRegister();
   18953           EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
   18954                   (encoded_align_1.GetEncodingValue() << 4) |
   18955                   first.Encode(22, 12) | (rn.GetCode() << 16));
   18956           return;
   18957         }
   18958       }
   18959     }
   18960   }
   18961   if (operand.IsPlainRegister()) {
   18962     Register rn = operand.GetBaseRegister();
   18963     Sign sign = operand.GetSign();
   18964     Register rm = operand.GetOffsetRegister();
   18965     Dt_size_7 encoded_dt(dt);
   18966     Index_1 encoded_align_1(nreglist, dt);
   18967     if (IsUsingT32()) {
   18968       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
   18969       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   18970           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18971            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18972           sign.IsPlus() && operand.IsPostIndex() &&
   18973           (!rn.IsPC() || AllowUnpredictable())) {
   18974         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18975           const DRegister& first = nreglist.GetFirstDRegister();
   18976           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   18977           EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
   18978                      first.Encode(22, 12) | (len_encoding << 5) |
   18979                      (rn.GetCode() << 16) | rm.GetCode());
   18980           AdvanceIT();
   18981           return;
   18982         }
   18983       }
   18984       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
   18985       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   18986           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   18987            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   18988           sign.IsPlus() && operand.IsPostIndex() &&
   18989           (!rn.IsPC() || AllowUnpredictable())) {
   18990         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   18991           const DRegister& first = nreglist.GetFirstDRegister();
   18992           EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
   18993                      (encoded_align_1.GetEncodingValue() << 4) |
   18994                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   18995                      rm.GetCode());
   18996           AdvanceIT();
   18997           return;
   18998         }
   18999       }
   19000     } else {
   19001       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
   19002       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
   19003           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   19004            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   19005           sign.IsPlus() && operand.IsPostIndex() &&
   19006           (!rn.IsPC() || AllowUnpredictable())) {
   19007         if (cond.Is(al)) {
   19008           const DRegister& first = nreglist.GetFirstDRegister();
   19009           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19010           EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
   19011                   first.Encode(22, 12) | (len_encoding << 5) |
   19012                   (rn.GetCode() << 16) | rm.GetCode());
   19013           return;
   19014         }
   19015       }
   19016       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
   19017       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   19018           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   19019            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   19020           sign.IsPlus() && operand.IsPostIndex() &&
   19021           (!rn.IsPC() || AllowUnpredictable())) {
   19022         if (cond.Is(al)) {
   19023           const DRegister& first = nreglist.GetFirstDRegister();
   19024           EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
   19025                   (encoded_align_1.GetEncodingValue() << 4) |
   19026                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   19027           return;
   19028         }
   19029       }
   19030     }
   19031   }
   19032   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
   19033 }
   19034 
   19035 void Assembler::vld4(Condition cond,
   19036                      DataType dt,
   19037                      const NeonRegisterList& nreglist,
   19038                      const AlignedMemOperand& operand) {
   19039   VIXL_ASSERT(AllowAssembler());
   19040   CheckIT(cond);
   19041   if (operand.IsImmediateZero()) {
   19042     Register rn = operand.GetBaseRegister();
   19043     Alignment align = operand.GetAlignment();
   19044     Dt_size_7 encoded_dt(dt);
   19045     Dt_size_8 encoded_dt_2(dt, align);
   19046     Align_align_4 encoded_align_1(align);
   19047     Align_a_3 encoded_align_2(align, dt);
   19048     Align_index_align_3 encoded_align_3(align, nreglist, dt);
   19049     if (IsUsingT32()) {
   19050       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   19051       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   19052           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19053            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19054           operand.IsOffset() && encoded_align_1.IsValid() &&
   19055           (!rn.IsPC() || AllowUnpredictable())) {
   19056         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19057           const DRegister& first = nreglist.GetFirstDRegister();
   19058           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19059           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
   19060                      (encoded_align_1.GetEncodingValue() << 4) |
   19061                      first.Encode(22, 12) | (len_encoding << 8) |
   19062                      (rn.GetCode() << 16));
   19063           AdvanceIT();
   19064           return;
   19065         }
   19066       }
   19067       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   19068       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   19069           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19070            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19071           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   19072           (!rn.IsPC() || AllowUnpredictable())) {
   19073         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19074           const DRegister& first = nreglist.GetFirstDRegister();
   19075           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19076           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
   19077                      (encoded_align_1.GetEncodingValue() << 4) |
   19078                      first.Encode(22, 12) | (len_encoding << 8) |
   19079                      (rn.GetCode() << 16));
   19080           AdvanceIT();
   19081           return;
   19082         }
   19083       }
   19084       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   19085       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   19086           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19087            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19088           operand.IsOffset() && encoded_align_2.IsValid() &&
   19089           (!rn.IsPC() || AllowUnpredictable())) {
   19090         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19091           const DRegister& first = nreglist.GetFirstDRegister();
   19092           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19093           EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
   19094                      (encoded_align_2.GetEncodingValue() << 4) |
   19095                      first.Encode(22, 12) | (len_encoding << 5) |
   19096                      (rn.GetCode() << 16));
   19097           AdvanceIT();
   19098           return;
   19099         }
   19100       }
   19101       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   19102       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   19103           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19104            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19105           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   19106           (!rn.IsPC() || AllowUnpredictable())) {
   19107         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19108           const DRegister& first = nreglist.GetFirstDRegister();
   19109           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19110           EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
   19111                      (encoded_align_2.GetEncodingValue() << 4) |
   19112                      first.Encode(22, 12) | (len_encoding << 5) |
   19113                      (rn.GetCode() << 16));
   19114           AdvanceIT();
   19115           return;
   19116         }
   19117       }
   19118       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   19119       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   19120           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19121            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19122           operand.IsOffset() && encoded_align_3.IsValid() &&
   19123           (!rn.IsPC() || AllowUnpredictable())) {
   19124         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19125           const DRegister& first = nreglist.GetFirstDRegister();
   19126           EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
   19127                      (encoded_align_3.GetEncodingValue() << 4) |
   19128                      first.Encode(22, 12) | (rn.GetCode() << 16));
   19129           AdvanceIT();
   19130           return;
   19131         }
   19132       }
   19133       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   19134       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   19135           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19136            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19137           operand.IsPostIndex() && encoded_align_3.IsValid() &&
   19138           (!rn.IsPC() || AllowUnpredictable())) {
   19139         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19140           const DRegister& first = nreglist.GetFirstDRegister();
   19141           EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
   19142                      (encoded_align_3.GetEncodingValue() << 4) |
   19143                      first.Encode(22, 12) | (rn.GetCode() << 16));
   19144           AdvanceIT();
   19145           return;
   19146         }
   19147       }
   19148     } else {
   19149       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   19150       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   19151           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19152            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19153           operand.IsOffset() && encoded_align_1.IsValid() &&
   19154           (!rn.IsPC() || AllowUnpredictable())) {
   19155         if (cond.Is(al)) {
   19156           const DRegister& first = nreglist.GetFirstDRegister();
   19157           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19158           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
   19159                   (encoded_align_1.GetEncodingValue() << 4) |
   19160                   first.Encode(22, 12) | (len_encoding << 8) |
   19161                   (rn.GetCode() << 16));
   19162           return;
   19163         }
   19164       }
   19165       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   19166       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   19167           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19168            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19169           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   19170           (!rn.IsPC() || AllowUnpredictable())) {
   19171         if (cond.Is(al)) {
   19172           const DRegister& first = nreglist.GetFirstDRegister();
   19173           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19174           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
   19175                   (encoded_align_1.GetEncodingValue() << 4) |
   19176                   first.Encode(22, 12) | (len_encoding << 8) |
   19177                   (rn.GetCode() << 16));
   19178           return;
   19179         }
   19180       }
   19181       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   19182       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   19183           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19184            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19185           operand.IsOffset() && encoded_align_2.IsValid() &&
   19186           (!rn.IsPC() || AllowUnpredictable())) {
   19187         if (cond.Is(al)) {
   19188           const DRegister& first = nreglist.GetFirstDRegister();
   19189           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19190           EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
   19191                   (encoded_align_2.GetEncodingValue() << 4) |
   19192                   first.Encode(22, 12) | (len_encoding << 5) |
   19193                   (rn.GetCode() << 16));
   19194           return;
   19195         }
   19196       }
   19197       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   19198       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   19199           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19200            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19201           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   19202           (!rn.IsPC() || AllowUnpredictable())) {
   19203         if (cond.Is(al)) {
   19204           const DRegister& first = nreglist.GetFirstDRegister();
   19205           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19206           EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
   19207                   (encoded_align_2.GetEncodingValue() << 4) |
   19208                   first.Encode(22, 12) | (len_encoding << 5) |
   19209                   (rn.GetCode() << 16));
   19210           return;
   19211         }
   19212       }
   19213       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   19214       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   19215           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19216            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19217           operand.IsOffset() && encoded_align_3.IsValid() &&
   19218           (!rn.IsPC() || AllowUnpredictable())) {
   19219         if (cond.Is(al)) {
   19220           const DRegister& first = nreglist.GetFirstDRegister();
   19221           EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
   19222                   (encoded_align_3.GetEncodingValue() << 4) |
   19223                   first.Encode(22, 12) | (rn.GetCode() << 16));
   19224           return;
   19225         }
   19226       }
   19227       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   19228       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   19229           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19230            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19231           operand.IsPostIndex() && encoded_align_3.IsValid() &&
   19232           (!rn.IsPC() || AllowUnpredictable())) {
   19233         if (cond.Is(al)) {
   19234           const DRegister& first = nreglist.GetFirstDRegister();
   19235           EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
   19236                   (encoded_align_3.GetEncodingValue() << 4) |
   19237                   first.Encode(22, 12) | (rn.GetCode() << 16));
   19238           return;
   19239         }
   19240       }
   19241     }
   19242   }
   19243   if (operand.IsPlainRegister()) {
   19244     Register rn = operand.GetBaseRegister();
   19245     Alignment align = operand.GetAlignment();
   19246     Register rm = operand.GetOffsetRegister();
   19247     Dt_size_7 encoded_dt(dt);
   19248     Dt_size_8 encoded_dt_2(dt, align);
   19249     Align_align_4 encoded_align_1(align);
   19250     Align_a_3 encoded_align_2(align, dt);
   19251     Align_index_align_3 encoded_align_3(align, nreglist, dt);
   19252     if (IsUsingT32()) {
   19253       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   19254       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   19255           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19256            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19257           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   19258         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19259           const DRegister& first = nreglist.GetFirstDRegister();
   19260           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19261           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
   19262                      (encoded_align_1.GetEncodingValue() << 4) |
   19263                      first.Encode(22, 12) | (len_encoding << 8) |
   19264                      (rn.GetCode() << 16) | rm.GetCode());
   19265           AdvanceIT();
   19266           return;
   19267         }
   19268       }
   19269       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   19270       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   19271           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19272            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19273           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   19274         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19275           const DRegister& first = nreglist.GetFirstDRegister();
   19276           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19277           EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
   19278                      (encoded_align_2.GetEncodingValue() << 4) |
   19279                      first.Encode(22, 12) | (len_encoding << 5) |
   19280                      (rn.GetCode() << 16) | rm.GetCode());
   19281           AdvanceIT();
   19282           return;
   19283         }
   19284       }
   19285       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   19286       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   19287           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19288            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19289           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   19290         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19291           const DRegister& first = nreglist.GetFirstDRegister();
   19292           EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
   19293                      (encoded_align_3.GetEncodingValue() << 4) |
   19294                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   19295                      rm.GetCode());
   19296           AdvanceIT();
   19297           return;
   19298         }
   19299       }
   19300     } else {
   19301       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   19302       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   19303           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19304            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19305           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   19306         if (cond.Is(al)) {
   19307           const DRegister& first = nreglist.GetFirstDRegister();
   19308           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19309           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
   19310                   (encoded_align_1.GetEncodingValue() << 4) |
   19311                   first.Encode(22, 12) | (len_encoding << 8) |
   19312                   (rn.GetCode() << 16) | rm.GetCode());
   19313           return;
   19314         }
   19315       }
   19316       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   19317       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
   19318           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19319            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19320           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   19321         if (cond.Is(al)) {
   19322           const DRegister& first = nreglist.GetFirstDRegister();
   19323           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   19324           EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
   19325                   (encoded_align_2.GetEncodingValue() << 4) |
   19326                   first.Encode(22, 12) | (len_encoding << 5) |
   19327                   (rn.GetCode() << 16) | rm.GetCode());
   19328           return;
   19329         }
   19330       }
   19331       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   19332       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   19333           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   19334            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   19335           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   19336         if (cond.Is(al)) {
   19337           const DRegister& first = nreglist.GetFirstDRegister();
   19338           EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
   19339                   (encoded_align_3.GetEncodingValue() << 4) |
   19340                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   19341           return;
   19342         }
   19343       }
   19344     }
   19345   }
   19346   Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
   19347 }
   19348 
   19349 void Assembler::vldm(Condition cond,
   19350                      DataType dt,
   19351                      Register rn,
   19352                      WriteBack write_back,
   19353                      DRegisterList dreglist) {
   19354   VIXL_ASSERT(AllowAssembler());
   19355   CheckIT(cond);
   19356   USE(dt);
   19357   if (IsUsingT32()) {
   19358     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
   19359     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
   19360          AllowUnpredictable())) {
   19361       const DRegister& dreg = dreglist.GetFirstDRegister();
   19362       unsigned len = dreglist.GetLength() * 2;
   19363       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
   19364                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   19365                  (len & 0xff));
   19366       AdvanceIT();
   19367       return;
   19368     }
   19369   } else {
   19370     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
   19371     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   19372                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
   19373                               AllowUnpredictable())) {
   19374       const DRegister& dreg = dreglist.GetFirstDRegister();
   19375       unsigned len = dreglist.GetLength() * 2;
   19376       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   19377               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   19378               (len & 0xff));
   19379       return;
   19380     }
   19381   }
   19382   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
   19383 }
   19384 
   19385 void Assembler::vldm(Condition cond,
   19386                      DataType dt,
   19387                      Register rn,
   19388                      WriteBack write_back,
   19389                      SRegisterList sreglist) {
   19390   VIXL_ASSERT(AllowAssembler());
   19391   CheckIT(cond);
   19392   USE(dt);
   19393   if (IsUsingT32()) {
   19394     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
   19395     if ((!rn.IsPC() || AllowUnpredictable())) {
   19396       const SRegister& sreg = sreglist.GetFirstSRegister();
   19397       unsigned len = sreglist.GetLength();
   19398       EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
   19399                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   19400                  (len & 0xff));
   19401       AdvanceIT();
   19402       return;
   19403     }
   19404   } else {
   19405     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
   19406     if (cond.IsNotNever() &&
   19407         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
   19408       const SRegister& sreg = sreglist.GetFirstSRegister();
   19409       unsigned len = sreglist.GetLength();
   19410       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   19411               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   19412               (len & 0xff));
   19413       return;
   19414     }
   19415   }
   19416   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
   19417 }
   19418 
   19419 void Assembler::vldmdb(Condition cond,
   19420                        DataType dt,
   19421                        Register rn,
   19422                        WriteBack write_back,
   19423                        DRegisterList dreglist) {
   19424   VIXL_ASSERT(AllowAssembler());
   19425   CheckIT(cond);
   19426   USE(dt);
   19427   if (IsUsingT32()) {
   19428     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
   19429     if (write_back.DoesWriteBack() &&
   19430         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
   19431          AllowUnpredictable())) {
   19432       const DRegister& dreg = dreglist.GetFirstDRegister();
   19433       unsigned len = dreglist.GetLength() * 2;
   19434       EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   19435                  (len & 0xff));
   19436       AdvanceIT();
   19437       return;
   19438     }
   19439   } else {
   19440     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
   19441     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   19442         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
   19443          AllowUnpredictable())) {
   19444       const DRegister& dreg = dreglist.GetFirstDRegister();
   19445       unsigned len = dreglist.GetLength() * 2;
   19446       EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   19447               dreg.Encode(22, 12) | (len & 0xff));
   19448       return;
   19449     }
   19450   }
   19451   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
   19452 }
   19453 
   19454 void Assembler::vldmdb(Condition cond,
   19455                        DataType dt,
   19456                        Register rn,
   19457                        WriteBack write_back,
   19458                        SRegisterList sreglist) {
   19459   VIXL_ASSERT(AllowAssembler());
   19460   CheckIT(cond);
   19461   USE(dt);
   19462   if (IsUsingT32()) {
   19463     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
   19464     if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) {
   19465       const SRegister& sreg = sreglist.GetFirstSRegister();
   19466       unsigned len = sreglist.GetLength();
   19467       EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
   19468                  (len & 0xff));
   19469       AdvanceIT();
   19470       return;
   19471     }
   19472   } else {
   19473     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
   19474     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   19475         (!rn.IsPC() || AllowUnpredictable())) {
   19476       const SRegister& sreg = sreglist.GetFirstSRegister();
   19477       unsigned len = sreglist.GetLength();
   19478       EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   19479               sreg.Encode(22, 12) | (len & 0xff));
   19480       return;
   19481     }
   19482   }
   19483   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
   19484 }
   19485 
   19486 void Assembler::vldmia(Condition cond,
   19487                        DataType dt,
   19488                        Register rn,
   19489                        WriteBack write_back,
   19490                        DRegisterList dreglist) {
   19491   VIXL_ASSERT(AllowAssembler());
   19492   CheckIT(cond);
   19493   USE(dt);
   19494   if (IsUsingT32()) {
   19495     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
   19496     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
   19497          AllowUnpredictable())) {
   19498       const DRegister& dreg = dreglist.GetFirstDRegister();
   19499       unsigned len = dreglist.GetLength() * 2;
   19500       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
   19501                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   19502                  (len & 0xff));
   19503       AdvanceIT();
   19504       return;
   19505     }
   19506   } else {
   19507     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
   19508     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   19509                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
   19510                               AllowUnpredictable())) {
   19511       const DRegister& dreg = dreglist.GetFirstDRegister();
   19512       unsigned len = dreglist.GetLength() * 2;
   19513       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   19514               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   19515               (len & 0xff));
   19516       return;
   19517     }
   19518   }
   19519   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
   19520 }
   19521 
   19522 void Assembler::vldmia(Condition cond,
   19523                        DataType dt,
   19524                        Register rn,
   19525                        WriteBack write_back,
   19526                        SRegisterList sreglist) {
   19527   VIXL_ASSERT(AllowAssembler());
   19528   CheckIT(cond);
   19529   USE(dt);
   19530   if (IsUsingT32()) {
   19531     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
   19532     if ((!rn.IsPC() || AllowUnpredictable())) {
   19533       const SRegister& sreg = sreglist.GetFirstSRegister();
   19534       unsigned len = sreglist.GetLength();
   19535       EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
   19536                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   19537                  (len & 0xff));
   19538       AdvanceIT();
   19539       return;
   19540     }
   19541   } else {
   19542     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
   19543     if (cond.IsNotNever() &&
   19544         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
   19545       const SRegister& sreg = sreglist.GetFirstSRegister();
   19546       unsigned len = sreglist.GetLength();
   19547       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   19548               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   19549               (len & 0xff));
   19550       return;
   19551     }
   19552   }
   19553   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
   19554 }
   19555 
   19556 void Assembler::vldr(Condition cond,
   19557                      DataType dt,
   19558                      DRegister rd,
   19559                      Location* location) {
   19560   VIXL_ASSERT(AllowAssembler());
   19561   CheckIT(cond);
   19562   Location::Offset offset =
   19563       location->IsBound()
   19564           ? location->GetLocation() -
   19565                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   19566           : 0;
   19567   if (IsUsingT32()) {
   19568     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
   19569     if (dt.IsNoneOr(Untyped64) &&
   19570         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   19571           ((offset & 0x3) == 0)) ||
   19572          !location->IsBound())) {
   19573       static class EmitOp : public Location::EmitOperator {
   19574        public:
   19575         EmitOp() : Location::EmitOperator(T32) {}
   19576         virtual uint32_t Encode(uint32_t instr,
   19577                                 Location::Offset pc,
   19578                                 const Location* location) const VIXL_OVERRIDE {
   19579           pc += kT32PcDelta;
   19580           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   19581           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   19582                       ((offset & 0x3) == 0));
   19583           int32_t target = offset >> 2;
   19584           uint32_t U = (target >= 0);
   19585           target = abs(target) | (U << 8);
   19586           return instr | (target & 0xff) | ((target & 0x100) << 15);
   19587         }
   19588       } immop;
   19589       EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12),
   19590                       location,
   19591                       immop,
   19592                       &kT32DataInfo));
   19593       AdvanceIT();
   19594       return;
   19595     }
   19596   } else {
   19597     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
   19598     if (dt.IsNoneOr(Untyped64) &&
   19599         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   19600           ((offset & 0x3) == 0)) ||
   19601          !location->IsBound()) &&
   19602         cond.IsNotNever()) {
   19603       static class EmitOp : public Location::EmitOperator {
   19604        public:
   19605         EmitOp() : Location::EmitOperator(A32) {}
   19606         virtual uint32_t Encode(uint32_t instr,
   19607                                 Location::Offset pc,
   19608                                 const Location* location) const VIXL_OVERRIDE {
   19609           pc += kA32PcDelta;
   19610           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   19611           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   19612                       ((offset & 0x3) == 0));
   19613           int32_t target = offset >> 2;
   19614           uint32_t U = (target >= 0);
   19615           target = abs(target) | (U << 8);
   19616           return instr | (target & 0xff) | ((target & 0x100) << 15);
   19617         }
   19618       } immop;
   19619       EmitA32(
   19620           Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
   19621                location,
   19622                immop,
   19623                &kA32DataInfo));
   19624       return;
   19625     }
   19626   }
   19627   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location);
   19628 }
   19629 
   19630 bool Assembler::vldr_info(Condition cond,
   19631                           DataType dt,
   19632                           DRegister rd,
   19633                           Location* location,
   19634                           const struct ReferenceInfo** info) {
   19635   VIXL_ASSERT(!location->IsBound());
   19636   USE(location);
   19637   USE(rd);
   19638   if (IsUsingT32()) {
   19639     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
   19640     if (dt.IsNoneOr(Untyped64)) {
   19641       *info = &kT32DataInfo;
   19642       return true;
   19643     }
   19644   } else {
   19645     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
   19646     if (dt.IsNoneOr(Untyped64) && cond.IsNotNever()) {
   19647       *info = &kA32DataInfo;
   19648       return true;
   19649     }
   19650   }
   19651   return false;
   19652 }
   19653 
   19654 void Assembler::vldr(Condition cond,
   19655                      DataType dt,
   19656                      DRegister rd,
   19657                      const MemOperand& operand) {
   19658   VIXL_ASSERT(AllowAssembler());
   19659   CheckIT(cond);
   19660   if (operand.IsImmediate()) {
   19661     Register rn = operand.GetBaseRegister();
   19662     int32_t offset = operand.GetOffsetImmediate();
   19663     if (IsUsingT32()) {
   19664       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
   19665       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   19666           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
   19667         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   19668         uint32_t offset_ = abs(offset) >> 2;
   19669         EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
   19670         AdvanceIT();
   19671         return;
   19672       }
   19673       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
   19674       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   19675           ((offset % 4) == 0) && operand.IsOffset() &&
   19676           ((rn.GetCode() & 0xf) != 0xf)) {
   19677         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   19678         uint32_t offset_ = abs(offset) >> 2;
   19679         EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
   19680                    offset_ | (sign << 23));
   19681         AdvanceIT();
   19682         return;
   19683       }
   19684     } else {
   19685       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
   19686       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   19687           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
   19688           cond.IsNotNever()) {
   19689         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   19690         uint32_t offset_ = abs(offset) >> 2;
   19691         EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19692                 offset_ | (sign << 23));
   19693         return;
   19694       }
   19695       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
   19696       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   19697           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
   19698           ((rn.GetCode() & 0xf) != 0xf)) {
   19699         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   19700         uint32_t offset_ = abs(offset) >> 2;
   19701         EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19702                 (rn.GetCode() << 16) | offset_ | (sign << 23));
   19703         return;
   19704       }
   19705     }
   19706   }
   19707   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
   19708 }
   19709 
   19710 void Assembler::vldr(Condition cond,
   19711                      DataType dt,
   19712                      SRegister rd,
   19713                      Location* location) {
   19714   VIXL_ASSERT(AllowAssembler());
   19715   CheckIT(cond);
   19716   Location::Offset offset =
   19717       location->IsBound()
   19718           ? location->GetLocation() -
   19719                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
   19720           : 0;
   19721   if (IsUsingT32()) {
   19722     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
   19723     if (dt.IsNoneOr(Untyped32) &&
   19724         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   19725           ((offset & 0x3) == 0)) ||
   19726          !location->IsBound())) {
   19727       static class EmitOp : public Location::EmitOperator {
   19728        public:
   19729         EmitOp() : Location::EmitOperator(T32) {}
   19730         virtual uint32_t Encode(uint32_t instr,
   19731                                 Location::Offset pc,
   19732                                 const Location* location) const VIXL_OVERRIDE {
   19733           pc += kT32PcDelta;
   19734           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   19735           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   19736                       ((offset & 0x3) == 0));
   19737           int32_t target = offset >> 2;
   19738           uint32_t U = (target >= 0);
   19739           target = abs(target) | (U << 8);
   19740           return instr | (target & 0xff) | ((target & 0x100) << 15);
   19741         }
   19742       } immop;
   19743       EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12),
   19744                       location,
   19745                       immop,
   19746                       &kT32DataInfo));
   19747       AdvanceIT();
   19748       return;
   19749     }
   19750   } else {
   19751     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
   19752     if (dt.IsNoneOr(Untyped32) &&
   19753         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
   19754           ((offset & 0x3) == 0)) ||
   19755          !location->IsBound()) &&
   19756         cond.IsNotNever()) {
   19757       static class EmitOp : public Location::EmitOperator {
   19758        public:
   19759         EmitOp() : Location::EmitOperator(A32) {}
   19760         virtual uint32_t Encode(uint32_t instr,
   19761                                 Location::Offset pc,
   19762                                 const Location* location) const VIXL_OVERRIDE {
   19763           pc += kA32PcDelta;
   19764           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
   19765           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
   19766                       ((offset & 0x3) == 0));
   19767           int32_t target = offset >> 2;
   19768           uint32_t U = (target >= 0);
   19769           target = abs(target) | (U << 8);
   19770           return instr | (target & 0xff) | ((target & 0x100) << 15);
   19771         }
   19772       } immop;
   19773       EmitA32(
   19774           Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
   19775                location,
   19776                immop,
   19777                &kA32DataInfo));
   19778       return;
   19779     }
   19780   }
   19781   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location);
   19782 }
   19783 
   19784 bool Assembler::vldr_info(Condition cond,
   19785                           DataType dt,
   19786                           SRegister rd,
   19787                           Location* location,
   19788                           const struct ReferenceInfo** info) {
   19789   VIXL_ASSERT(!location->IsBound());
   19790   USE(location);
   19791   USE(rd);
   19792   if (IsUsingT32()) {
   19793     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
   19794     if (dt.IsNoneOr(Untyped32)) {
   19795       *info = &kT32DataInfo;
   19796       return true;
   19797     }
   19798   } else {
   19799     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
   19800     if (dt.IsNoneOr(Untyped32) && cond.IsNotNever()) {
   19801       *info = &kA32DataInfo;
   19802       return true;
   19803     }
   19804   }
   19805   return false;
   19806 }
   19807 
   19808 void Assembler::vldr(Condition cond,
   19809                      DataType dt,
   19810                      SRegister rd,
   19811                      const MemOperand& operand) {
   19812   VIXL_ASSERT(AllowAssembler());
   19813   CheckIT(cond);
   19814   if (operand.IsImmediate()) {
   19815     Register rn = operand.GetBaseRegister();
   19816     int32_t offset = operand.GetOffsetImmediate();
   19817     if (IsUsingT32()) {
   19818       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
   19819       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   19820           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
   19821         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   19822         uint32_t offset_ = abs(offset) >> 2;
   19823         EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
   19824         AdvanceIT();
   19825         return;
   19826       }
   19827       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
   19828       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   19829           ((offset % 4) == 0) && operand.IsOffset() &&
   19830           ((rn.GetCode() & 0xf) != 0xf)) {
   19831         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   19832         uint32_t offset_ = abs(offset) >> 2;
   19833         EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
   19834                    offset_ | (sign << 23));
   19835         AdvanceIT();
   19836         return;
   19837       }
   19838     } else {
   19839       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
   19840       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   19841           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
   19842           cond.IsNotNever()) {
   19843         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   19844         uint32_t offset_ = abs(offset) >> 2;
   19845         EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19846                 offset_ | (sign << 23));
   19847         return;
   19848       }
   19849       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
   19850       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   19851           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
   19852           ((rn.GetCode() & 0xf) != 0xf)) {
   19853         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   19854         uint32_t offset_ = abs(offset) >> 2;
   19855         EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   19856                 (rn.GetCode() << 16) | offset_ | (sign << 23));
   19857         return;
   19858       }
   19859     }
   19860   }
   19861   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
   19862 }
   19863 
   19864 void Assembler::vmax(
   19865     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   19866   VIXL_ASSERT(AllowAssembler());
   19867   CheckIT(cond);
   19868   Dt_U_size_1 encoded_dt(dt);
   19869   if (IsUsingT32()) {
   19870     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   19871     if (dt.Is(F32)) {
   19872       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19873         EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19874                    rm.Encode(5, 0));
   19875         AdvanceIT();
   19876         return;
   19877       }
   19878     }
   19879     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   19880     if (encoded_dt.IsValid()) {
   19881       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19882         EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   19883                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   19884                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19885         AdvanceIT();
   19886         return;
   19887       }
   19888     }
   19889   } else {
   19890     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   19891     if (dt.Is(F32)) {
   19892       if (cond.Is(al)) {
   19893         EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19894                 rm.Encode(5, 0));
   19895         return;
   19896       }
   19897     }
   19898     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   19899     if (encoded_dt.IsValid()) {
   19900       if (cond.Is(al)) {
   19901         EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   19902                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   19903                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19904         return;
   19905       }
   19906     }
   19907   }
   19908   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
   19909 }
   19910 
   19911 void Assembler::vmax(
   19912     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   19913   VIXL_ASSERT(AllowAssembler());
   19914   CheckIT(cond);
   19915   Dt_U_size_1 encoded_dt(dt);
   19916   if (IsUsingT32()) {
   19917     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   19918     if (dt.Is(F32)) {
   19919       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19920         EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19921                    rm.Encode(5, 0));
   19922         AdvanceIT();
   19923         return;
   19924       }
   19925     }
   19926     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   19927     if (encoded_dt.IsValid()) {
   19928       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   19929         EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   19930                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   19931                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19932         AdvanceIT();
   19933         return;
   19934       }
   19935     }
   19936   } else {
   19937     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   19938     if (dt.Is(F32)) {
   19939       if (cond.Is(al)) {
   19940         EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19941                 rm.Encode(5, 0));
   19942         return;
   19943       }
   19944     }
   19945     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   19946     if (encoded_dt.IsValid()) {
   19947       if (cond.Is(al)) {
   19948         EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   19949                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   19950                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   19951         return;
   19952       }
   19953     }
   19954   }
   19955   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
   19956 }
   19957 
   19958 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   19959   VIXL_ASSERT(AllowAssembler());
   19960   CheckIT(al);
   19961   if (IsUsingT32()) {
   19962     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   19963     if (OutsideITBlock() && dt.Is(F32)) {
   19964       EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19965                  rm.Encode(5, 0));
   19966       AdvanceIT();
   19967       return;
   19968     }
   19969     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   19970     if (OutsideITBlock() && dt.Is(F64)) {
   19971       EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19972                  rm.Encode(5, 0));
   19973       AdvanceIT();
   19974       return;
   19975     }
   19976   } else {
   19977     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   19978     if (dt.Is(F32)) {
   19979       EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19980               rm.Encode(5, 0));
   19981       return;
   19982     }
   19983     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   19984     if (dt.Is(F64)) {
   19985       EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   19986               rm.Encode(5, 0));
   19987       return;
   19988     }
   19989   }
   19990   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
   19991 }
   19992 
   19993 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   19994   VIXL_ASSERT(AllowAssembler());
   19995   CheckIT(al);
   19996   if (IsUsingT32()) {
   19997     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   19998     if (OutsideITBlock() && dt.Is(F32)) {
   19999       EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20000                  rm.Encode(5, 0));
   20001       AdvanceIT();
   20002       return;
   20003     }
   20004   } else {
   20005     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   20006     if (dt.Is(F32)) {
   20007       EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20008               rm.Encode(5, 0));
   20009       return;
   20010     }
   20011   }
   20012   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
   20013 }
   20014 
   20015 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   20016   VIXL_ASSERT(AllowAssembler());
   20017   CheckIT(al);
   20018   if (IsUsingT32()) {
   20019     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   20020     if (OutsideITBlock() && dt.Is(F32)) {
   20021       EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20022                  rm.Encode(5, 0));
   20023       AdvanceIT();
   20024       return;
   20025     }
   20026   } else {
   20027     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   20028     if (dt.Is(F32)) {
   20029       EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20030               rm.Encode(5, 0));
   20031       return;
   20032     }
   20033   }
   20034   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
   20035 }
   20036 
   20037 void Assembler::vmin(
   20038     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20039   VIXL_ASSERT(AllowAssembler());
   20040   CheckIT(cond);
   20041   Dt_U_size_1 encoded_dt(dt);
   20042   if (IsUsingT32()) {
   20043     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   20044     if (dt.Is(F32)) {
   20045       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20046         EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20047                    rm.Encode(5, 0));
   20048         AdvanceIT();
   20049         return;
   20050       }
   20051     }
   20052     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   20053     if (encoded_dt.IsValid()) {
   20054       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20055         EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20056                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   20057                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20058         AdvanceIT();
   20059         return;
   20060       }
   20061     }
   20062   } else {
   20063     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   20064     if (dt.Is(F32)) {
   20065       if (cond.Is(al)) {
   20066         EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20067                 rm.Encode(5, 0));
   20068         return;
   20069       }
   20070     }
   20071     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   20072     if (encoded_dt.IsValid()) {
   20073       if (cond.Is(al)) {
   20074         EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20075                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   20076                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20077         return;
   20078       }
   20079     }
   20080   }
   20081   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
   20082 }
   20083 
   20084 void Assembler::vmin(
   20085     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   20086   VIXL_ASSERT(AllowAssembler());
   20087   CheckIT(cond);
   20088   Dt_U_size_1 encoded_dt(dt);
   20089   if (IsUsingT32()) {
   20090     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   20091     if (dt.Is(F32)) {
   20092       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20093         EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20094                    rm.Encode(5, 0));
   20095         AdvanceIT();
   20096         return;
   20097       }
   20098     }
   20099     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   20100     if (encoded_dt.IsValid()) {
   20101       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20102         EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20103                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   20104                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20105         AdvanceIT();
   20106         return;
   20107       }
   20108     }
   20109   } else {
   20110     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   20111     if (dt.Is(F32)) {
   20112       if (cond.Is(al)) {
   20113         EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20114                 rm.Encode(5, 0));
   20115         return;
   20116       }
   20117     }
   20118     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   20119     if (encoded_dt.IsValid()) {
   20120       if (cond.Is(al)) {
   20121         EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   20122                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   20123                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20124         return;
   20125       }
   20126     }
   20127   }
   20128   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
   20129 }
   20130 
   20131 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20132   VIXL_ASSERT(AllowAssembler());
   20133   CheckIT(al);
   20134   if (IsUsingT32()) {
   20135     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   20136     if (OutsideITBlock() && dt.Is(F32)) {
   20137       EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20138                  rm.Encode(5, 0));
   20139       AdvanceIT();
   20140       return;
   20141     }
   20142     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   20143     if (OutsideITBlock() && dt.Is(F64)) {
   20144       EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20145                  rm.Encode(5, 0));
   20146       AdvanceIT();
   20147       return;
   20148     }
   20149   } else {
   20150     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   20151     if (dt.Is(F32)) {
   20152       EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20153               rm.Encode(5, 0));
   20154       return;
   20155     }
   20156     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   20157     if (dt.Is(F64)) {
   20158       EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20159               rm.Encode(5, 0));
   20160       return;
   20161     }
   20162   }
   20163   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
   20164 }
   20165 
   20166 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   20167   VIXL_ASSERT(AllowAssembler());
   20168   CheckIT(al);
   20169   if (IsUsingT32()) {
   20170     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   20171     if (OutsideITBlock() && dt.Is(F32)) {
   20172       EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20173                  rm.Encode(5, 0));
   20174       AdvanceIT();
   20175       return;
   20176     }
   20177   } else {
   20178     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   20179     if (dt.Is(F32)) {
   20180       EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20181               rm.Encode(5, 0));
   20182       return;
   20183     }
   20184   }
   20185   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
   20186 }
   20187 
   20188 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   20189   VIXL_ASSERT(AllowAssembler());
   20190   CheckIT(al);
   20191   if (IsUsingT32()) {
   20192     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   20193     if (OutsideITBlock() && dt.Is(F32)) {
   20194       EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20195                  rm.Encode(5, 0));
   20196       AdvanceIT();
   20197       return;
   20198     }
   20199   } else {
   20200     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   20201     if (dt.Is(F32)) {
   20202       EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20203               rm.Encode(5, 0));
   20204       return;
   20205     }
   20206   }
   20207   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
   20208 }
   20209 
   20210 void Assembler::vmla(
   20211     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
   20212   VIXL_ASSERT(AllowAssembler());
   20213   CheckIT(cond);
   20214   Dt_size_9 encoded_dt(dt);
   20215   if (IsUsingT32()) {
   20216     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
   20217     if (encoded_dt.IsValid() &&
   20218         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20219          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20220           (rm.GetLane() <= 1)))) {
   20221       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20222         EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
   20223                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20224                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20225         AdvanceIT();
   20226         return;
   20227       }
   20228     }
   20229   } else {
   20230     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
   20231     if (encoded_dt.IsValid() &&
   20232         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20233          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20234           (rm.GetLane() <= 1)))) {
   20235       if (cond.Is(al)) {
   20236         EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
   20237                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20238                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20239         return;
   20240       }
   20241     }
   20242   }
   20243   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   20244 }
   20245 
   20246 void Assembler::vmla(
   20247     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
   20248   VIXL_ASSERT(AllowAssembler());
   20249   CheckIT(cond);
   20250   Dt_size_9 encoded_dt(dt);
   20251   if (IsUsingT32()) {
   20252     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
   20253     if (encoded_dt.IsValid() &&
   20254         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20255          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20256           (rm.GetLane() <= 1)))) {
   20257       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20258         EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
   20259                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20260                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20261         AdvanceIT();
   20262         return;
   20263       }
   20264     }
   20265   } else {
   20266     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
   20267     if (encoded_dt.IsValid() &&
   20268         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20269          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20270           (rm.GetLane() <= 1)))) {
   20271       if (cond.Is(al)) {
   20272         EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
   20273                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20274                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20275         return;
   20276       }
   20277     }
   20278   }
   20279   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   20280 }
   20281 
   20282 void Assembler::vmla(
   20283     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20284   VIXL_ASSERT(AllowAssembler());
   20285   CheckIT(cond);
   20286   Dt_size_10 encoded_dt(dt);
   20287   if (IsUsingT32()) {
   20288     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   20289     if (dt.Is(F32)) {
   20290       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20291         EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20292                    rm.Encode(5, 0));
   20293         AdvanceIT();
   20294         return;
   20295       }
   20296     }
   20297     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   20298     if (dt.Is(F64)) {
   20299       EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20300                  rm.Encode(5, 0));
   20301       AdvanceIT();
   20302       return;
   20303     }
   20304     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
   20305     if (encoded_dt.IsValid()) {
   20306       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20307         EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
   20308                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20309         AdvanceIT();
   20310         return;
   20311       }
   20312     }
   20313   } else {
   20314     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   20315     if (dt.Is(F32)) {
   20316       if (cond.Is(al)) {
   20317         EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20318                 rm.Encode(5, 0));
   20319         return;
   20320       }
   20321     }
   20322     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   20323     if (dt.Is(F64) && cond.IsNotNever()) {
   20324       EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20325               rn.Encode(7, 16) | rm.Encode(5, 0));
   20326       return;
   20327     }
   20328     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
   20329     if (encoded_dt.IsValid()) {
   20330       if (cond.Is(al)) {
   20331         EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
   20332                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20333         return;
   20334       }
   20335     }
   20336   }
   20337   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   20338 }
   20339 
   20340 void Assembler::vmla(
   20341     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   20342   VIXL_ASSERT(AllowAssembler());
   20343   CheckIT(cond);
   20344   Dt_size_10 encoded_dt(dt);
   20345   if (IsUsingT32()) {
   20346     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   20347     if (dt.Is(F32)) {
   20348       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20349         EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20350                    rm.Encode(5, 0));
   20351         AdvanceIT();
   20352         return;
   20353       }
   20354     }
   20355     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
   20356     if (encoded_dt.IsValid()) {
   20357       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20358         EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
   20359                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20360         AdvanceIT();
   20361         return;
   20362       }
   20363     }
   20364   } else {
   20365     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   20366     if (dt.Is(F32)) {
   20367       if (cond.Is(al)) {
   20368         EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20369                 rm.Encode(5, 0));
   20370         return;
   20371       }
   20372     }
   20373     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
   20374     if (encoded_dt.IsValid()) {
   20375       if (cond.Is(al)) {
   20376         EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
   20377                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20378         return;
   20379       }
   20380     }
   20381   }
   20382   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   20383 }
   20384 
   20385 void Assembler::vmla(
   20386     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   20387   VIXL_ASSERT(AllowAssembler());
   20388   CheckIT(cond);
   20389   if (IsUsingT32()) {
   20390     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   20391     if (dt.Is(F32)) {
   20392       EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20393                  rm.Encode(5, 0));
   20394       AdvanceIT();
   20395       return;
   20396     }
   20397   } else {
   20398     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   20399     if (dt.Is(F32) && cond.IsNotNever()) {
   20400       EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20401               rn.Encode(7, 16) | rm.Encode(5, 0));
   20402       return;
   20403     }
   20404   }
   20405   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
   20406 }
   20407 
   20408 void Assembler::vmlal(
   20409     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
   20410   VIXL_ASSERT(AllowAssembler());
   20411   CheckIT(cond);
   20412   Dt_size_11 encoded_dt(dt);
   20413   if (IsUsingT32()) {
   20414     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
   20415     if (encoded_dt.IsValid() &&
   20416         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20417          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20418           (rm.GetLane() <= 1)))) {
   20419       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20420         EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
   20421                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20422                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20423         AdvanceIT();
   20424         return;
   20425       }
   20426     }
   20427   } else {
   20428     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
   20429     if (encoded_dt.IsValid() &&
   20430         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20431          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20432           (rm.GetLane() <= 1)))) {
   20433       if (cond.Is(al)) {
   20434         EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
   20435                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20436                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20437         return;
   20438       }
   20439     }
   20440   }
   20441   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
   20442 }
   20443 
   20444 void Assembler::vmlal(
   20445     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   20446   VIXL_ASSERT(AllowAssembler());
   20447   CheckIT(cond);
   20448   Dt_size_12 encoded_dt(dt);
   20449   if (IsUsingT32()) {
   20450     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
   20451     if (encoded_dt.IsValid()) {
   20452       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20453         EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
   20454                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20455                    rn.Encode(7, 16) | rm.Encode(5, 0));
   20456         AdvanceIT();
   20457         return;
   20458       }
   20459     }
   20460   } else {
   20461     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
   20462     if (encoded_dt.IsValid()) {
   20463       if (cond.Is(al)) {
   20464         EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
   20465                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20466                 rn.Encode(7, 16) | rm.Encode(5, 0));
   20467         return;
   20468       }
   20469     }
   20470   }
   20471   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
   20472 }
   20473 
   20474 void Assembler::vmls(
   20475     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
   20476   VIXL_ASSERT(AllowAssembler());
   20477   CheckIT(cond);
   20478   Dt_size_9 encoded_dt(dt);
   20479   if (IsUsingT32()) {
   20480     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
   20481     if (encoded_dt.IsValid() &&
   20482         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20483          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20484           (rm.GetLane() <= 1)))) {
   20485       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20486         EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
   20487                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20488                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20489         AdvanceIT();
   20490         return;
   20491       }
   20492     }
   20493   } else {
   20494     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
   20495     if (encoded_dt.IsValid() &&
   20496         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20497          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20498           (rm.GetLane() <= 1)))) {
   20499       if (cond.Is(al)) {
   20500         EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
   20501                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20502                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20503         return;
   20504       }
   20505     }
   20506   }
   20507   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   20508 }
   20509 
   20510 void Assembler::vmls(
   20511     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
   20512   VIXL_ASSERT(AllowAssembler());
   20513   CheckIT(cond);
   20514   Dt_size_9 encoded_dt(dt);
   20515   if (IsUsingT32()) {
   20516     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
   20517     if (encoded_dt.IsValid() &&
   20518         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20519          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20520           (rm.GetLane() <= 1)))) {
   20521       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20522         EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
   20523                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20524                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20525         AdvanceIT();
   20526         return;
   20527       }
   20528     }
   20529   } else {
   20530     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
   20531     if (encoded_dt.IsValid() &&
   20532         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20533          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20534           (rm.GetLane() <= 1)))) {
   20535       if (cond.Is(al)) {
   20536         EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
   20537                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20538                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20539         return;
   20540       }
   20541     }
   20542   }
   20543   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   20544 }
   20545 
   20546 void Assembler::vmls(
   20547     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   20548   VIXL_ASSERT(AllowAssembler());
   20549   CheckIT(cond);
   20550   Dt_size_10 encoded_dt(dt);
   20551   if (IsUsingT32()) {
   20552     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
   20553     if (dt.Is(F32)) {
   20554       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20555         EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20556                    rm.Encode(5, 0));
   20557         AdvanceIT();
   20558         return;
   20559       }
   20560     }
   20561     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
   20562     if (dt.Is(F64)) {
   20563       EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20564                  rm.Encode(5, 0));
   20565       AdvanceIT();
   20566       return;
   20567     }
   20568     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
   20569     if (encoded_dt.IsValid()) {
   20570       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20571         EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
   20572                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20573         AdvanceIT();
   20574         return;
   20575       }
   20576     }
   20577   } else {
   20578     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
   20579     if (dt.Is(F32)) {
   20580       if (cond.Is(al)) {
   20581         EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20582                 rm.Encode(5, 0));
   20583         return;
   20584       }
   20585     }
   20586     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
   20587     if (dt.Is(F64) && cond.IsNotNever()) {
   20588       EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20589               rn.Encode(7, 16) | rm.Encode(5, 0));
   20590       return;
   20591     }
   20592     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
   20593     if (encoded_dt.IsValid()) {
   20594       if (cond.Is(al)) {
   20595         EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
   20596                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20597         return;
   20598       }
   20599     }
   20600   }
   20601   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   20602 }
   20603 
   20604 void Assembler::vmls(
   20605     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   20606   VIXL_ASSERT(AllowAssembler());
   20607   CheckIT(cond);
   20608   Dt_size_10 encoded_dt(dt);
   20609   if (IsUsingT32()) {
   20610     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
   20611     if (dt.Is(F32)) {
   20612       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20613         EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20614                    rm.Encode(5, 0));
   20615         AdvanceIT();
   20616         return;
   20617       }
   20618     }
   20619     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
   20620     if (encoded_dt.IsValid()) {
   20621       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20622         EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
   20623                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20624         AdvanceIT();
   20625         return;
   20626       }
   20627     }
   20628   } else {
   20629     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
   20630     if (dt.Is(F32)) {
   20631       if (cond.Is(al)) {
   20632         EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20633                 rm.Encode(5, 0));
   20634         return;
   20635       }
   20636     }
   20637     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
   20638     if (encoded_dt.IsValid()) {
   20639       if (cond.Is(al)) {
   20640         EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
   20641                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   20642         return;
   20643       }
   20644     }
   20645   }
   20646   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   20647 }
   20648 
   20649 void Assembler::vmls(
   20650     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   20651   VIXL_ASSERT(AllowAssembler());
   20652   CheckIT(cond);
   20653   if (IsUsingT32()) {
   20654     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
   20655     if (dt.Is(F32)) {
   20656       EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   20657                  rm.Encode(5, 0));
   20658       AdvanceIT();
   20659       return;
   20660     }
   20661   } else {
   20662     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
   20663     if (dt.Is(F32) && cond.IsNotNever()) {
   20664       EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20665               rn.Encode(7, 16) | rm.Encode(5, 0));
   20666       return;
   20667     }
   20668   }
   20669   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
   20670 }
   20671 
   20672 void Assembler::vmlsl(
   20673     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
   20674   VIXL_ASSERT(AllowAssembler());
   20675   CheckIT(cond);
   20676   Dt_size_11 encoded_dt(dt);
   20677   if (IsUsingT32()) {
   20678     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
   20679     if (encoded_dt.IsValid() &&
   20680         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20681          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20682           (rm.GetLane() <= 1)))) {
   20683       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20684         EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
   20685                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20686                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20687         AdvanceIT();
   20688         return;
   20689       }
   20690     }
   20691   } else {
   20692     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
   20693     if (encoded_dt.IsValid() &&
   20694         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   20695          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   20696           (rm.GetLane() <= 1)))) {
   20697       if (cond.Is(al)) {
   20698         EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
   20699                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20700                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   20701         return;
   20702       }
   20703     }
   20704   }
   20705   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
   20706 }
   20707 
   20708 void Assembler::vmlsl(
   20709     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   20710   VIXL_ASSERT(AllowAssembler());
   20711   CheckIT(cond);
   20712   Dt_size_12 encoded_dt(dt);
   20713   if (IsUsingT32()) {
   20714     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
   20715     if (encoded_dt.IsValid()) {
   20716       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20717         EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
   20718                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20719                    rn.Encode(7, 16) | rm.Encode(5, 0));
   20720         AdvanceIT();
   20721         return;
   20722       }
   20723     }
   20724   } else {
   20725     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
   20726     if (encoded_dt.IsValid()) {
   20727       if (cond.Is(al)) {
   20728         EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
   20729                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
   20730                 rn.Encode(7, 16) | rm.Encode(5, 0));
   20731         return;
   20732       }
   20733     }
   20734   }
   20735   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
   20736 }
   20737 
   20738 void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
   20739   VIXL_ASSERT(AllowAssembler());
   20740   CheckIT(cond);
   20741   if (IsUsingT32()) {
   20742     // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
   20743     if ((!rt.IsPC() || AllowUnpredictable())) {
   20744       EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
   20745       AdvanceIT();
   20746       return;
   20747     }
   20748   } else {
   20749     // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
   20750     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   20751       EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
   20752               rn.Encode(7, 16));
   20753       return;
   20754     }
   20755   }
   20756   Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
   20757 }
   20758 
   20759 void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
   20760   VIXL_ASSERT(AllowAssembler());
   20761   CheckIT(cond);
   20762   if (IsUsingT32()) {
   20763     // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
   20764     if ((!rt.IsPC() || AllowUnpredictable())) {
   20765       EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
   20766       AdvanceIT();
   20767       return;
   20768     }
   20769   } else {
   20770     // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
   20771     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   20772       EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
   20773               (rt.GetCode() << 12));
   20774       return;
   20775     }
   20776   }
   20777   Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
   20778 }
   20779 
   20780 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
   20781   VIXL_ASSERT(AllowAssembler());
   20782   CheckIT(cond);
   20783   if (IsUsingT32()) {
   20784     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
   20785     if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   20786       EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
   20787                  rm.Encode(5, 0));
   20788       AdvanceIT();
   20789       return;
   20790     }
   20791   } else {
   20792     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
   20793     if (cond.IsNotNever() &&
   20794         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   20795       EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
   20796               (rt2.GetCode() << 16) | rm.Encode(5, 0));
   20797       return;
   20798     }
   20799   }
   20800   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
   20801 }
   20802 
   20803 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
   20804   VIXL_ASSERT(AllowAssembler());
   20805   CheckIT(cond);
   20806   if (IsUsingT32()) {
   20807     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
   20808     if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   20809       EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
   20810                  (rt2.GetCode() << 16));
   20811       AdvanceIT();
   20812       return;
   20813     }
   20814   } else {
   20815     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
   20816     if (cond.IsNotNever() &&
   20817         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   20818       EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
   20819               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
   20820       return;
   20821     }
   20822   }
   20823   Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
   20824 }
   20825 
   20826 void Assembler::vmov(
   20827     Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
   20828   VIXL_ASSERT(AllowAssembler());
   20829   CheckIT(cond);
   20830   if (IsUsingT32()) {
   20831     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
   20832     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
   20833         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   20834       EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
   20835                  rm.Encode(5, 0));
   20836       AdvanceIT();
   20837       return;
   20838     }
   20839   } else {
   20840     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
   20841     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
   20842         cond.IsNotNever() &&
   20843         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   20844       EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
   20845               (rt2.GetCode() << 16) | rm.Encode(5, 0));
   20846       return;
   20847     }
   20848   }
   20849   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
   20850 }
   20851 
   20852 void Assembler::vmov(
   20853     Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
   20854   VIXL_ASSERT(AllowAssembler());
   20855   CheckIT(cond);
   20856   if (IsUsingT32()) {
   20857     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
   20858     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
   20859         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   20860       EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
   20861                  (rt2.GetCode() << 16));
   20862       AdvanceIT();
   20863       return;
   20864     }
   20865   } else {
   20866     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
   20867     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
   20868         cond.IsNotNever() &&
   20869         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
   20870       EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
   20871               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
   20872       return;
   20873     }
   20874   }
   20875   Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
   20876 }
   20877 
   20878 void Assembler::vmov(Condition cond,
   20879                      DataType dt,
   20880                      DRegisterLane rd,
   20881                      Register rt) {
   20882   VIXL_ASSERT(AllowAssembler());
   20883   CheckIT(cond);
   20884   Dt_opc1_opc2_1 encoded_dt(dt, rd);
   20885   if (IsUsingT32()) {
   20886     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
   20887     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
   20888       EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
   20889                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
   20890                  rd.Encode(7, 16) | (rt.GetCode() << 12));
   20891       AdvanceIT();
   20892       return;
   20893     }
   20894   } else {
   20895     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
   20896     if (encoded_dt.IsValid() && cond.IsNotNever() &&
   20897         (!rt.IsPC() || AllowUnpredictable())) {
   20898       EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
   20899               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
   20900               ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
   20901               (rt.GetCode() << 12));
   20902       return;
   20903     }
   20904   }
   20905   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
   20906 }
   20907 
   20908 void Assembler::vmov(Condition cond,
   20909                      DataType dt,
   20910                      DRegister rd,
   20911                      const DOperand& operand) {
   20912   VIXL_ASSERT(AllowAssembler());
   20913   CheckIT(cond);
   20914   if (operand.IsImmediate()) {
   20915     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
   20916     if (IsUsingT32()) {
   20917       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
   20918       if (encoded_dt.IsValid()) {
   20919         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20920           EmitT32_32(
   20921               0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
   20922               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
   20923               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   20924               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20925               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   20926           AdvanceIT();
   20927           return;
   20928         }
   20929       }
   20930     } else {
   20931       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
   20932       if (encoded_dt.IsValid()) {
   20933         if (cond.Is(al)) {
   20934           EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
   20935                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
   20936                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   20937                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   20938                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   20939           return;
   20940         }
   20941       }
   20942     }
   20943   }
   20944   if (operand.IsImmediate()) {
   20945     ImmediateVFP vfp(operand.GetNeonImmediate());
   20946     if (IsUsingT32()) {
   20947       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
   20948       if (dt.Is(F64) && vfp.IsValid()) {
   20949         EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
   20950                    (vfp.GetEncodingValue() & 0xf) |
   20951                    ((vfp.GetEncodingValue() & 0xf0) << 12));
   20952         AdvanceIT();
   20953         return;
   20954       }
   20955     } else {
   20956       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
   20957       if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
   20958         EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20959                 (vfp.GetEncodingValue() & 0xf) |
   20960                 ((vfp.GetEncodingValue() & 0xf0) << 12));
   20961         return;
   20962       }
   20963     }
   20964   }
   20965   if (operand.IsRegister()) {
   20966     DRegister rm = operand.GetRegister();
   20967     if (IsUsingT32()) {
   20968       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
   20969       if (dt.Is(F64)) {
   20970         EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   20971         AdvanceIT();
   20972         return;
   20973       }
   20974       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
   20975       if (!dt.Is(F64)) {
   20976         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   20977           EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   20978                      rm.Encode(5, 0));
   20979           AdvanceIT();
   20980           return;
   20981         }
   20982       }
   20983     } else {
   20984       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
   20985       if (dt.Is(F64) && cond.IsNotNever()) {
   20986         EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   20987                 rm.Encode(5, 0));
   20988         return;
   20989       }
   20990       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
   20991       if (!dt.Is(F64)) {
   20992         if (cond.Is(al)) {
   20993           EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   20994                   rm.Encode(5, 0));
   20995           return;
   20996         }
   20997       }
   20998     }
   20999   }
   21000   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
   21001 }
   21002 
   21003 void Assembler::vmov(Condition cond,
   21004                      DataType dt,
   21005                      QRegister rd,
   21006                      const QOperand& operand) {
   21007   VIXL_ASSERT(AllowAssembler());
   21008   CheckIT(cond);
   21009   if (operand.IsImmediate()) {
   21010     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
   21011     if (IsUsingT32()) {
   21012       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
   21013       if (encoded_dt.IsValid()) {
   21014         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21015           EmitT32_32(
   21016               0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
   21017               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
   21018               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   21019               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21020               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   21021           AdvanceIT();
   21022           return;
   21023         }
   21024       }
   21025     } else {
   21026       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
   21027       if (encoded_dt.IsValid()) {
   21028         if (cond.Is(al)) {
   21029           EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
   21030                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
   21031                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   21032                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21033                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   21034           return;
   21035         }
   21036       }
   21037     }
   21038   }
   21039   if (operand.IsRegister()) {
   21040     QRegister rm = operand.GetRegister();
   21041     if (IsUsingT32()) {
   21042       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
   21043       if (!dt.Is(F64)) {
   21044         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21045           EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   21046                      rm.Encode(5, 0));
   21047           AdvanceIT();
   21048           return;
   21049         }
   21050       }
   21051     } else {
   21052       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
   21053       if (!dt.Is(F64)) {
   21054         if (cond.Is(al)) {
   21055           EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   21056                   rm.Encode(5, 0));
   21057           return;
   21058         }
   21059       }
   21060     }
   21061   }
   21062   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
   21063 }
   21064 
   21065 void Assembler::vmov(Condition cond,
   21066                      DataType dt,
   21067                      SRegister rd,
   21068                      const SOperand& operand) {
   21069   VIXL_ASSERT(AllowAssembler());
   21070   CheckIT(cond);
   21071   if (operand.IsImmediate()) {
   21072     ImmediateVFP vfp(operand.GetNeonImmediate());
   21073     if (IsUsingT32()) {
   21074       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
   21075       if (dt.Is(F32) && vfp.IsValid()) {
   21076         EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
   21077                    (vfp.GetEncodingValue() & 0xf) |
   21078                    ((vfp.GetEncodingValue() & 0xf0) << 12));
   21079         AdvanceIT();
   21080         return;
   21081       }
   21082     } else {
   21083       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
   21084       if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
   21085         EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21086                 (vfp.GetEncodingValue() & 0xf) |
   21087                 ((vfp.GetEncodingValue() & 0xf0) << 12));
   21088         return;
   21089       }
   21090     }
   21091   }
   21092   if (operand.IsRegister()) {
   21093     SRegister rm = operand.GetRegister();
   21094     if (IsUsingT32()) {
   21095       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
   21096       if (dt.Is(F32)) {
   21097         EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   21098         AdvanceIT();
   21099         return;
   21100       }
   21101     } else {
   21102       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
   21103       if (dt.Is(F32) && cond.IsNotNever()) {
   21104         EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21105                 rm.Encode(5, 0));
   21106         return;
   21107       }
   21108     }
   21109   }
   21110   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
   21111 }
   21112 
   21113 void Assembler::vmov(Condition cond,
   21114                      DataType dt,
   21115                      Register rt,
   21116                      DRegisterLane rn) {
   21117   VIXL_ASSERT(AllowAssembler());
   21118   CheckIT(cond);
   21119   Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
   21120   if (IsUsingT32()) {
   21121     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
   21122     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
   21123       EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
   21124                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
   21125                  ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
   21126                  (rt.GetCode() << 12) | rn.Encode(7, 16));
   21127       AdvanceIT();
   21128       return;
   21129     }
   21130   } else {
   21131     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
   21132     if (encoded_dt.IsValid() && cond.IsNotNever() &&
   21133         (!rt.IsPC() || AllowUnpredictable())) {
   21134       EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
   21135               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
   21136               ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
   21137               ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
   21138               (rt.GetCode() << 12) | rn.Encode(7, 16));
   21139       return;
   21140     }
   21141   }
   21142   Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
   21143 }
   21144 
   21145 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
   21146   VIXL_ASSERT(AllowAssembler());
   21147   CheckIT(cond);
   21148   Dt_U_imm3H_1 encoded_dt(dt);
   21149   if (IsUsingT32()) {
   21150     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
   21151     if (encoded_dt.IsValid()) {
   21152       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21153         EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   21154                    ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
   21155                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21156         AdvanceIT();
   21157         return;
   21158       }
   21159     }
   21160   } else {
   21161     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
   21162     if (encoded_dt.IsValid()) {
   21163       if (cond.Is(al)) {
   21164         EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   21165                 ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
   21166                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21167         return;
   21168       }
   21169     }
   21170   }
   21171   Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
   21172 }
   21173 
   21174 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
   21175   VIXL_ASSERT(AllowAssembler());
   21176   CheckIT(cond);
   21177   Dt_size_3 encoded_dt(dt);
   21178   if (IsUsingT32()) {
   21179     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
   21180     if (encoded_dt.IsValid()) {
   21181       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21182         EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
   21183                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21184         AdvanceIT();
   21185         return;
   21186       }
   21187     }
   21188   } else {
   21189     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
   21190     if (encoded_dt.IsValid()) {
   21191       if (cond.Is(al)) {
   21192         EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
   21193                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21194         return;
   21195       }
   21196     }
   21197   }
   21198   Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
   21199 }
   21200 
   21201 void Assembler::vmrs(Condition cond,
   21202                      RegisterOrAPSR_nzcv rt,
   21203                      SpecialFPRegister spec_reg) {
   21204   VIXL_ASSERT(AllowAssembler());
   21205   CheckIT(cond);
   21206   if (IsUsingT32()) {
   21207     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
   21208     EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
   21209     AdvanceIT();
   21210     return;
   21211   } else {
   21212     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
   21213     if (cond.IsNotNever()) {
   21214       EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
   21215               (spec_reg.GetReg() << 16));
   21216       return;
   21217     }
   21218   }
   21219   Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
   21220 }
   21221 
   21222 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
   21223   VIXL_ASSERT(AllowAssembler());
   21224   CheckIT(cond);
   21225   if (IsUsingT32()) {
   21226     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
   21227     if ((!rt.IsPC() || AllowUnpredictable())) {
   21228       EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) |
   21229                  (rt.GetCode() << 12));
   21230       AdvanceIT();
   21231       return;
   21232     }
   21233   } else {
   21234     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
   21235     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
   21236       EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
   21237               (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
   21238       return;
   21239     }
   21240   }
   21241   Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
   21242 }
   21243 
   21244 void Assembler::vmul(Condition cond,
   21245                      DataType dt,
   21246                      DRegister rd,
   21247                      DRegister rn,
   21248                      DRegister dm,
   21249                      unsigned index) {
   21250   VIXL_ASSERT(AllowAssembler());
   21251   CheckIT(cond);
   21252   Dt_F_size_3 encoded_dt(dt);
   21253   if (IsUsingT32()) {
   21254     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
   21255     if (encoded_dt.IsValid() &&
   21256         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21257          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
   21258       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21259         uint32_t shift = 4;
   21260         if (dt.Is(I16)) {
   21261           shift = 3;
   21262         }
   21263         uint32_t mvm = dm.GetCode() | index << shift;
   21264         EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21265                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   21266                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21267                    ((mvm & 0x10) << 1));
   21268         AdvanceIT();
   21269         return;
   21270       }
   21271     }
   21272   } else {
   21273     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
   21274     if (encoded_dt.IsValid() &&
   21275         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21276          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
   21277       if (cond.Is(al)) {
   21278         uint32_t shift = 4;
   21279         if (dt.Is(I16)) {
   21280           shift = 3;
   21281         }
   21282         uint32_t mvm = dm.GetCode() | index << shift;
   21283         EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21284                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   21285                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21286                 ((mvm & 0x10) << 1));
   21287         return;
   21288       }
   21289     }
   21290   }
   21291   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
   21292 }
   21293 
   21294 void Assembler::vmul(Condition cond,
   21295                      DataType dt,
   21296                      QRegister rd,
   21297                      QRegister rn,
   21298                      DRegister dm,
   21299                      unsigned index) {
   21300   VIXL_ASSERT(AllowAssembler());
   21301   CheckIT(cond);
   21302   Dt_F_size_3 encoded_dt(dt);
   21303   if (IsUsingT32()) {
   21304     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
   21305     if (encoded_dt.IsValid() &&
   21306         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21307          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
   21308       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21309         uint32_t shift = 4;
   21310         if (dt.Is(I16)) {
   21311           shift = 3;
   21312         }
   21313         uint32_t mvm = dm.GetCode() | index << shift;
   21314         EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21315                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   21316                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21317                    ((mvm & 0x10) << 1));
   21318         AdvanceIT();
   21319         return;
   21320       }
   21321     }
   21322   } else {
   21323     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
   21324     if (encoded_dt.IsValid() &&
   21325         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21326          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
   21327       if (cond.Is(al)) {
   21328         uint32_t shift = 4;
   21329         if (dt.Is(I16)) {
   21330           shift = 3;
   21331         }
   21332         uint32_t mvm = dm.GetCode() | index << shift;
   21333         EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21334                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   21335                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21336                 ((mvm & 0x10) << 1));
   21337         return;
   21338       }
   21339     }
   21340   }
   21341   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
   21342 }
   21343 
   21344 void Assembler::vmul(
   21345     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21346   VIXL_ASSERT(AllowAssembler());
   21347   CheckIT(cond);
   21348   Dt_op_size_1 encoded_dt(dt);
   21349   if (IsUsingT32()) {
   21350     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   21351     if (dt.Is(F32)) {
   21352       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21353         EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21354                    rm.Encode(5, 0));
   21355         AdvanceIT();
   21356         return;
   21357       }
   21358     }
   21359     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
   21360     if (dt.Is(F64)) {
   21361       EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21362                  rm.Encode(5, 0));
   21363       AdvanceIT();
   21364       return;
   21365     }
   21366     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   21367     if (encoded_dt.IsValid()) {
   21368       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21369         EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21370                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21371                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21372         AdvanceIT();
   21373         return;
   21374       }
   21375     }
   21376   } else {
   21377     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   21378     if (dt.Is(F32)) {
   21379       if (cond.Is(al)) {
   21380         EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21381                 rm.Encode(5, 0));
   21382         return;
   21383       }
   21384     }
   21385     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
   21386     if (dt.Is(F64) && cond.IsNotNever()) {
   21387       EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21388               rn.Encode(7, 16) | rm.Encode(5, 0));
   21389       return;
   21390     }
   21391     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   21392     if (encoded_dt.IsValid()) {
   21393       if (cond.Is(al)) {
   21394         EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21395                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21396                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21397         return;
   21398       }
   21399     }
   21400   }
   21401   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
   21402 }
   21403 
   21404 void Assembler::vmul(
   21405     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   21406   VIXL_ASSERT(AllowAssembler());
   21407   CheckIT(cond);
   21408   Dt_op_size_1 encoded_dt(dt);
   21409   if (IsUsingT32()) {
   21410     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   21411     if (dt.Is(F32)) {
   21412       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21413         EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21414                    rm.Encode(5, 0));
   21415         AdvanceIT();
   21416         return;
   21417       }
   21418     }
   21419     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   21420     if (encoded_dt.IsValid()) {
   21421       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21422         EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21423                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21424                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21425         AdvanceIT();
   21426         return;
   21427       }
   21428     }
   21429   } else {
   21430     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   21431     if (dt.Is(F32)) {
   21432       if (cond.Is(al)) {
   21433         EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21434                 rm.Encode(5, 0));
   21435         return;
   21436       }
   21437     }
   21438     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   21439     if (encoded_dt.IsValid()) {
   21440       if (cond.Is(al)) {
   21441         EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21442                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21443                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21444         return;
   21445       }
   21446     }
   21447   }
   21448   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
   21449 }
   21450 
   21451 void Assembler::vmul(
   21452     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   21453   VIXL_ASSERT(AllowAssembler());
   21454   CheckIT(cond);
   21455   if (IsUsingT32()) {
   21456     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
   21457     if (dt.Is(F32)) {
   21458       EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21459                  rm.Encode(5, 0));
   21460       AdvanceIT();
   21461       return;
   21462     }
   21463   } else {
   21464     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
   21465     if (dt.Is(F32) && cond.IsNotNever()) {
   21466       EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21467               rn.Encode(7, 16) | rm.Encode(5, 0));
   21468       return;
   21469     }
   21470   }
   21471   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
   21472 }
   21473 
   21474 void Assembler::vmull(Condition cond,
   21475                       DataType dt,
   21476                       QRegister rd,
   21477                       DRegister rn,
   21478                       DRegister dm,
   21479                       unsigned index) {
   21480   VIXL_ASSERT(AllowAssembler());
   21481   CheckIT(cond);
   21482   Dt_U_size_2 encoded_dt(dt);
   21483   if (IsUsingT32()) {
   21484     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
   21485     if (encoded_dt.IsValid() &&
   21486         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21487          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) &&
   21488           (dm.GetCode() <= 15)))) {
   21489       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21490         uint32_t shift = 4;
   21491         if (dt.Is(S16) || dt.Is(U16)) {
   21492           shift = 3;
   21493         }
   21494         uint32_t mvm = dm.GetCode() | index << shift;
   21495         EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21496                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21497                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21498                    ((mvm & 0x10) << 1));
   21499         AdvanceIT();
   21500         return;
   21501       }
   21502     }
   21503   } else {
   21504     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
   21505     if (encoded_dt.IsValid() &&
   21506         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
   21507          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) &&
   21508           (dm.GetCode() <= 15)))) {
   21509       if (cond.Is(al)) {
   21510         uint32_t shift = 4;
   21511         if (dt.Is(S16) || dt.Is(U16)) {
   21512           shift = 3;
   21513         }
   21514         uint32_t mvm = dm.GetCode() | index << shift;
   21515         EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21516                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21517                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   21518                 ((mvm & 0x10) << 1));
   21519         return;
   21520       }
   21521     }
   21522   }
   21523   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
   21524 }
   21525 
   21526 void Assembler::vmull(
   21527     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   21528   VIXL_ASSERT(AllowAssembler());
   21529   CheckIT(cond);
   21530   Dt_op_U_size_1 encoded_dt(dt);
   21531   if (IsUsingT32()) {
   21532     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   21533     if (encoded_dt.IsValid()) {
   21534       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21535         EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21536                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   21537                    ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
   21538                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21539         AdvanceIT();
   21540         return;
   21541       }
   21542     }
   21543   } else {
   21544     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   21545     if (encoded_dt.IsValid()) {
   21546       if (cond.Is(al)) {
   21547         EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   21548                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   21549                 ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
   21550                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   21551         return;
   21552       }
   21553     }
   21554   }
   21555   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
   21556 }
   21557 
   21558 void Assembler::vmvn(Condition cond,
   21559                      DataType dt,
   21560                      DRegister rd,
   21561                      const DOperand& operand) {
   21562   VIXL_ASSERT(AllowAssembler());
   21563   CheckIT(cond);
   21564   if (operand.IsImmediate()) {
   21565     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
   21566     if (IsUsingT32()) {
   21567       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
   21568       if (encoded_dt.IsValid()) {
   21569         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21570           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
   21571                      rd.Encode(22, 12) |
   21572                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   21573                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21574                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   21575           AdvanceIT();
   21576           return;
   21577         }
   21578       }
   21579     } else {
   21580       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
   21581       if (encoded_dt.IsValid()) {
   21582         if (cond.Is(al)) {
   21583           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
   21584                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   21585                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21586                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   21587           return;
   21588         }
   21589       }
   21590     }
   21591   }
   21592   if (operand.IsRegister()) {
   21593     DRegister rm = operand.GetRegister();
   21594     USE(dt);
   21595     if (IsUsingT32()) {
   21596       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
   21597       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21598         EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
   21599         AdvanceIT();
   21600         return;
   21601       }
   21602     } else {
   21603       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
   21604       if (cond.Is(al)) {
   21605         EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
   21606         return;
   21607       }
   21608     }
   21609   }
   21610   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
   21611 }
   21612 
   21613 void Assembler::vmvn(Condition cond,
   21614                      DataType dt,
   21615                      QRegister rd,
   21616                      const QOperand& operand) {
   21617   VIXL_ASSERT(AllowAssembler());
   21618   CheckIT(cond);
   21619   if (operand.IsImmediate()) {
   21620     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
   21621     if (IsUsingT32()) {
   21622       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
   21623       if (encoded_dt.IsValid()) {
   21624         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21625           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
   21626                      rd.Encode(22, 12) |
   21627                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   21628                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21629                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   21630           AdvanceIT();
   21631           return;
   21632         }
   21633       }
   21634     } else {
   21635       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
   21636       if (encoded_dt.IsValid()) {
   21637         if (cond.Is(al)) {
   21638           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
   21639                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   21640                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21641                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   21642           return;
   21643         }
   21644       }
   21645     }
   21646   }
   21647   if (operand.IsRegister()) {
   21648     QRegister rm = operand.GetRegister();
   21649     USE(dt);
   21650     if (IsUsingT32()) {
   21651       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
   21652       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21653         EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   21654         AdvanceIT();
   21655         return;
   21656       }
   21657     } else {
   21658       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
   21659       if (cond.Is(al)) {
   21660         EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   21661         return;
   21662       }
   21663     }
   21664   }
   21665   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
   21666 }
   21667 
   21668 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   21669   VIXL_ASSERT(AllowAssembler());
   21670   CheckIT(cond);
   21671   Dt_F_size_1 encoded_dt(dt);
   21672   if (IsUsingT32()) {
   21673     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   21674     if (encoded_dt.IsValid()) {
   21675       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21676         EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21677                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   21678                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21679         AdvanceIT();
   21680         return;
   21681       }
   21682     }
   21683     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
   21684     if (dt.Is(F64)) {
   21685       EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   21686       AdvanceIT();
   21687       return;
   21688     }
   21689   } else {
   21690     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   21691     if (encoded_dt.IsValid()) {
   21692       if (cond.Is(al)) {
   21693         EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21694                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   21695                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21696         return;
   21697       }
   21698     }
   21699     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
   21700     if (dt.Is(F64) && cond.IsNotNever()) {
   21701       EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21702               rm.Encode(5, 0));
   21703       return;
   21704     }
   21705   }
   21706   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
   21707 }
   21708 
   21709 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   21710   VIXL_ASSERT(AllowAssembler());
   21711   CheckIT(cond);
   21712   Dt_F_size_1 encoded_dt(dt);
   21713   if (IsUsingT32()) {
   21714     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   21715     if (encoded_dt.IsValid()) {
   21716       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21717         EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21718                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   21719                    rd.Encode(22, 12) | rm.Encode(5, 0));
   21720         AdvanceIT();
   21721         return;
   21722       }
   21723     }
   21724   } else {
   21725     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   21726     if (encoded_dt.IsValid()) {
   21727       if (cond.Is(al)) {
   21728         EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   21729                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
   21730                 rd.Encode(22, 12) | rm.Encode(5, 0));
   21731         return;
   21732       }
   21733     }
   21734   }
   21735   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
   21736 }
   21737 
   21738 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
   21739   VIXL_ASSERT(AllowAssembler());
   21740   CheckIT(cond);
   21741   if (IsUsingT32()) {
   21742     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
   21743     if (dt.Is(F32)) {
   21744       EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   21745       AdvanceIT();
   21746       return;
   21747     }
   21748   } else {
   21749     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
   21750     if (dt.Is(F32) && cond.IsNotNever()) {
   21751       EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21752               rm.Encode(5, 0));
   21753       return;
   21754     }
   21755   }
   21756   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
   21757 }
   21758 
   21759 void Assembler::vnmla(
   21760     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   21761   VIXL_ASSERT(AllowAssembler());
   21762   CheckIT(cond);
   21763   if (IsUsingT32()) {
   21764     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
   21765     if (dt.Is(F32)) {
   21766       EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21767                  rm.Encode(5, 0));
   21768       AdvanceIT();
   21769       return;
   21770     }
   21771   } else {
   21772     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
   21773     if (dt.Is(F32) && cond.IsNotNever()) {
   21774       EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21775               rn.Encode(7, 16) | rm.Encode(5, 0));
   21776       return;
   21777     }
   21778   }
   21779   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
   21780 }
   21781 
   21782 void Assembler::vnmla(
   21783     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21784   VIXL_ASSERT(AllowAssembler());
   21785   CheckIT(cond);
   21786   if (IsUsingT32()) {
   21787     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
   21788     if (dt.Is(F64)) {
   21789       EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21790                  rm.Encode(5, 0));
   21791       AdvanceIT();
   21792       return;
   21793     }
   21794   } else {
   21795     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
   21796     if (dt.Is(F64) && cond.IsNotNever()) {
   21797       EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21798               rn.Encode(7, 16) | rm.Encode(5, 0));
   21799       return;
   21800     }
   21801   }
   21802   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
   21803 }
   21804 
   21805 void Assembler::vnmls(
   21806     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   21807   VIXL_ASSERT(AllowAssembler());
   21808   CheckIT(cond);
   21809   if (IsUsingT32()) {
   21810     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
   21811     if (dt.Is(F32)) {
   21812       EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21813                  rm.Encode(5, 0));
   21814       AdvanceIT();
   21815       return;
   21816     }
   21817   } else {
   21818     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
   21819     if (dt.Is(F32) && cond.IsNotNever()) {
   21820       EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21821               rn.Encode(7, 16) | rm.Encode(5, 0));
   21822       return;
   21823     }
   21824   }
   21825   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
   21826 }
   21827 
   21828 void Assembler::vnmls(
   21829     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21830   VIXL_ASSERT(AllowAssembler());
   21831   CheckIT(cond);
   21832   if (IsUsingT32()) {
   21833     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
   21834     if (dt.Is(F64)) {
   21835       EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21836                  rm.Encode(5, 0));
   21837       AdvanceIT();
   21838       return;
   21839     }
   21840   } else {
   21841     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
   21842     if (dt.Is(F64) && cond.IsNotNever()) {
   21843       EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21844               rn.Encode(7, 16) | rm.Encode(5, 0));
   21845       return;
   21846     }
   21847   }
   21848   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
   21849 }
   21850 
   21851 void Assembler::vnmul(
   21852     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   21853   VIXL_ASSERT(AllowAssembler());
   21854   CheckIT(cond);
   21855   if (IsUsingT32()) {
   21856     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
   21857     if (dt.Is(F32)) {
   21858       EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21859                  rm.Encode(5, 0));
   21860       AdvanceIT();
   21861       return;
   21862     }
   21863   } else {
   21864     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
   21865     if (dt.Is(F32) && cond.IsNotNever()) {
   21866       EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21867               rn.Encode(7, 16) | rm.Encode(5, 0));
   21868       return;
   21869     }
   21870   }
   21871   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
   21872 }
   21873 
   21874 void Assembler::vnmul(
   21875     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   21876   VIXL_ASSERT(AllowAssembler());
   21877   CheckIT(cond);
   21878   if (IsUsingT32()) {
   21879     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
   21880     if (dt.Is(F64)) {
   21881       EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21882                  rm.Encode(5, 0));
   21883       AdvanceIT();
   21884       return;
   21885     }
   21886   } else {
   21887     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
   21888     if (dt.Is(F64) && cond.IsNotNever()) {
   21889       EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   21890               rn.Encode(7, 16) | rm.Encode(5, 0));
   21891       return;
   21892     }
   21893   }
   21894   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
   21895 }
   21896 
   21897 void Assembler::vorn(Condition cond,
   21898                      DataType dt,
   21899                      DRegister rd,
   21900                      DRegister rn,
   21901                      const DOperand& operand) {
   21902   VIXL_ASSERT(AllowAssembler());
   21903   CheckIT(cond);
   21904   if (operand.IsImmediate()) {
   21905     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
   21906     if (IsUsingT32()) {
   21907       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
   21908       if (encoded_dt.IsValid() && rd.Is(rn)) {
   21909         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21910           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
   21911                      rd.Encode(22, 12) |
   21912                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   21913                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21914                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   21915           AdvanceIT();
   21916           return;
   21917         }
   21918       }
   21919     } else {
   21920       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
   21921       if (encoded_dt.IsValid() && rd.Is(rn)) {
   21922         if (cond.Is(al)) {
   21923           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
   21924                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   21925                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21926                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   21927           return;
   21928         }
   21929       }
   21930     }
   21931   }
   21932   if (operand.IsRegister()) {
   21933     DRegister rm = operand.GetRegister();
   21934     USE(dt);
   21935     if (IsUsingT32()) {
   21936       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   21937       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21938         EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21939                    rm.Encode(5, 0));
   21940         AdvanceIT();
   21941         return;
   21942       }
   21943     } else {
   21944       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   21945       if (cond.Is(al)) {
   21946         EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21947                 rm.Encode(5, 0));
   21948         return;
   21949       }
   21950     }
   21951   }
   21952   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
   21953 }
   21954 
   21955 void Assembler::vorn(Condition cond,
   21956                      DataType dt,
   21957                      QRegister rd,
   21958                      QRegister rn,
   21959                      const QOperand& operand) {
   21960   VIXL_ASSERT(AllowAssembler());
   21961   CheckIT(cond);
   21962   if (operand.IsImmediate()) {
   21963     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
   21964     if (IsUsingT32()) {
   21965       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
   21966       if (encoded_dt.IsValid() && rd.Is(rn)) {
   21967         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21968           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
   21969                      rd.Encode(22, 12) |
   21970                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   21971                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21972                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   21973           AdvanceIT();
   21974           return;
   21975         }
   21976       }
   21977     } else {
   21978       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
   21979       if (encoded_dt.IsValid() && rd.Is(rn)) {
   21980         if (cond.Is(al)) {
   21981           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
   21982                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   21983                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   21984                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   21985           return;
   21986         }
   21987       }
   21988     }
   21989   }
   21990   if (operand.IsRegister()) {
   21991     QRegister rm = operand.GetRegister();
   21992     USE(dt);
   21993     if (IsUsingT32()) {
   21994       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   21995       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   21996         EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   21997                    rm.Encode(5, 0));
   21998         AdvanceIT();
   21999         return;
   22000       }
   22001     } else {
   22002       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   22003       if (cond.Is(al)) {
   22004         EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22005                 rm.Encode(5, 0));
   22006         return;
   22007       }
   22008     }
   22009   }
   22010   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
   22011 }
   22012 
   22013 void Assembler::vorr(Condition cond,
   22014                      DataType dt,
   22015                      DRegister rd,
   22016                      DRegister rn,
   22017                      const DOperand& operand) {
   22018   VIXL_ASSERT(AllowAssembler());
   22019   CheckIT(cond);
   22020   if (operand.IsRegister()) {
   22021     DRegister rm = operand.GetRegister();
   22022     USE(dt);
   22023     if (IsUsingT32()) {
   22024       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
   22025       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22026         EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22027                    rm.Encode(5, 0));
   22028         AdvanceIT();
   22029         return;
   22030       }
   22031     } else {
   22032       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
   22033       if (cond.Is(al)) {
   22034         EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22035                 rm.Encode(5, 0));
   22036         return;
   22037       }
   22038     }
   22039   }
   22040   if (operand.IsImmediate()) {
   22041     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
   22042     if (IsUsingT32()) {
   22043       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
   22044       if (encoded_dt.IsValid() && rd.Is(rn)) {
   22045         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22046           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
   22047                      rd.Encode(22, 12) |
   22048                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   22049                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   22050                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   22051           AdvanceIT();
   22052           return;
   22053         }
   22054       }
   22055     } else {
   22056       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
   22057       if (encoded_dt.IsValid() && rd.Is(rn)) {
   22058         if (cond.Is(al)) {
   22059           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
   22060                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   22061                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   22062                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   22063           return;
   22064         }
   22065       }
   22066     }
   22067   }
   22068   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
   22069 }
   22070 
   22071 void Assembler::vorr(Condition cond,
   22072                      DataType dt,
   22073                      QRegister rd,
   22074                      QRegister rn,
   22075                      const QOperand& operand) {
   22076   VIXL_ASSERT(AllowAssembler());
   22077   CheckIT(cond);
   22078   if (operand.IsRegister()) {
   22079     QRegister rm = operand.GetRegister();
   22080     USE(dt);
   22081     if (IsUsingT32()) {
   22082       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
   22083       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22084         EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22085                    rm.Encode(5, 0));
   22086         AdvanceIT();
   22087         return;
   22088       }
   22089     } else {
   22090       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
   22091       if (cond.Is(al)) {
   22092         EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22093                 rm.Encode(5, 0));
   22094         return;
   22095       }
   22096     }
   22097   }
   22098   if (operand.IsImmediate()) {
   22099     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
   22100     if (IsUsingT32()) {
   22101       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
   22102       if (encoded_dt.IsValid() && rd.Is(rn)) {
   22103         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22104           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
   22105                      rd.Encode(22, 12) |
   22106                      (encoded_dt.GetEncodedImmediate() & 0xf) |
   22107                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   22108                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
   22109           AdvanceIT();
   22110           return;
   22111         }
   22112       }
   22113     } else {
   22114       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
   22115       if (encoded_dt.IsValid() && rd.Is(rn)) {
   22116         if (cond.Is(al)) {
   22117           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
   22118                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
   22119                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
   22120                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
   22121           return;
   22122         }
   22123       }
   22124     }
   22125   }
   22126   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
   22127 }
   22128 
   22129 void Assembler::vpadal(Condition cond,
   22130                        DataType dt,
   22131                        DRegister rd,
   22132                        DRegister rm) {
   22133   VIXL_ASSERT(AllowAssembler());
   22134   CheckIT(cond);
   22135   Dt_op_size_2 encoded_dt(dt);
   22136   if (IsUsingT32()) {
   22137     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   22138     if (encoded_dt.IsValid()) {
   22139       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22140         EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22141                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   22142                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22143         AdvanceIT();
   22144         return;
   22145       }
   22146     }
   22147   } else {
   22148     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   22149     if (encoded_dt.IsValid()) {
   22150       if (cond.Is(al)) {
   22151         EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22152                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   22153                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22154         return;
   22155       }
   22156     }
   22157   }
   22158   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
   22159 }
   22160 
   22161 void Assembler::vpadal(Condition cond,
   22162                        DataType dt,
   22163                        QRegister rd,
   22164                        QRegister rm) {
   22165   VIXL_ASSERT(AllowAssembler());
   22166   CheckIT(cond);
   22167   Dt_op_size_2 encoded_dt(dt);
   22168   if (IsUsingT32()) {
   22169     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   22170     if (encoded_dt.IsValid()) {
   22171       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22172         EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22173                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   22174                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22175         AdvanceIT();
   22176         return;
   22177       }
   22178     }
   22179   } else {
   22180     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   22181     if (encoded_dt.IsValid()) {
   22182       if (cond.Is(al)) {
   22183         EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22184                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   22185                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22186         return;
   22187       }
   22188     }
   22189   }
   22190   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
   22191 }
   22192 
   22193 void Assembler::vpadd(
   22194     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   22195   VIXL_ASSERT(AllowAssembler());
   22196   CheckIT(cond);
   22197   Dt_size_4 encoded_dt(dt);
   22198   if (IsUsingT32()) {
   22199     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   22200     if (dt.Is(F32)) {
   22201       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22202         EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22203                    rm.Encode(5, 0));
   22204         AdvanceIT();
   22205         return;
   22206       }
   22207     }
   22208     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   22209     if (encoded_dt.IsValid()) {
   22210       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22211         EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
   22212                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22213         AdvanceIT();
   22214         return;
   22215       }
   22216     }
   22217   } else {
   22218     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   22219     if (dt.Is(F32)) {
   22220       if (cond.Is(al)) {
   22221         EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22222                 rm.Encode(5, 0));
   22223         return;
   22224       }
   22225     }
   22226     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   22227     if (encoded_dt.IsValid()) {
   22228       if (cond.Is(al)) {
   22229         EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
   22230                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22231         return;
   22232       }
   22233     }
   22234   }
   22235   Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
   22236 }
   22237 
   22238 void Assembler::vpaddl(Condition cond,
   22239                        DataType dt,
   22240                        DRegister rd,
   22241                        DRegister rm) {
   22242   VIXL_ASSERT(AllowAssembler());
   22243   CheckIT(cond);
   22244   Dt_op_size_2 encoded_dt(dt);
   22245   if (IsUsingT32()) {
   22246     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   22247     if (encoded_dt.IsValid()) {
   22248       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22249         EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22250                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   22251                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22252         AdvanceIT();
   22253         return;
   22254       }
   22255     }
   22256   } else {
   22257     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   22258     if (encoded_dt.IsValid()) {
   22259       if (cond.Is(al)) {
   22260         EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22261                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   22262                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22263         return;
   22264       }
   22265     }
   22266   }
   22267   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
   22268 }
   22269 
   22270 void Assembler::vpaddl(Condition cond,
   22271                        DataType dt,
   22272                        QRegister rd,
   22273                        QRegister rm) {
   22274   VIXL_ASSERT(AllowAssembler());
   22275   CheckIT(cond);
   22276   Dt_op_size_2 encoded_dt(dt);
   22277   if (IsUsingT32()) {
   22278     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   22279     if (encoded_dt.IsValid()) {
   22280       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22281         EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22282                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   22283                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22284         AdvanceIT();
   22285         return;
   22286       }
   22287     }
   22288   } else {
   22289     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   22290     if (encoded_dt.IsValid()) {
   22291       if (cond.Is(al)) {
   22292         EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22293                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
   22294                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22295         return;
   22296       }
   22297     }
   22298   }
   22299   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
   22300 }
   22301 
   22302 void Assembler::vpmax(
   22303     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   22304   VIXL_ASSERT(AllowAssembler());
   22305   CheckIT(cond);
   22306   Dt_U_size_1 encoded_dt(dt);
   22307   if (IsUsingT32()) {
   22308     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   22309     if (dt.Is(F32)) {
   22310       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22311         EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22312                    rm.Encode(5, 0));
   22313         AdvanceIT();
   22314         return;
   22315       }
   22316     }
   22317     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   22318     if (encoded_dt.IsValid()) {
   22319       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22320         EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22321                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22322                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22323         AdvanceIT();
   22324         return;
   22325       }
   22326     }
   22327   } else {
   22328     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   22329     if (dt.Is(F32)) {
   22330       if (cond.Is(al)) {
   22331         EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22332                 rm.Encode(5, 0));
   22333         return;
   22334       }
   22335     }
   22336     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   22337     if (encoded_dt.IsValid()) {
   22338       if (cond.Is(al)) {
   22339         EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22340                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22341                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22342         return;
   22343       }
   22344     }
   22345   }
   22346   Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
   22347 }
   22348 
   22349 void Assembler::vpmin(
   22350     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   22351   VIXL_ASSERT(AllowAssembler());
   22352   CheckIT(cond);
   22353   Dt_U_size_1 encoded_dt(dt);
   22354   if (IsUsingT32()) {
   22355     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   22356     if (dt.Is(F32)) {
   22357       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22358         EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22359                    rm.Encode(5, 0));
   22360         AdvanceIT();
   22361         return;
   22362       }
   22363     }
   22364     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   22365     if (encoded_dt.IsValid()) {
   22366       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22367         EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22368                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22369                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22370         AdvanceIT();
   22371         return;
   22372       }
   22373     }
   22374   } else {
   22375     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   22376     if (dt.Is(F32)) {
   22377       if (cond.Is(al)) {
   22378         EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   22379                 rm.Encode(5, 0));
   22380         return;
   22381       }
   22382     }
   22383     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   22384     if (encoded_dt.IsValid()) {
   22385       if (cond.Is(al)) {
   22386         EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22387                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22388                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22389         return;
   22390       }
   22391     }
   22392   }
   22393   Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
   22394 }
   22395 
   22396 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
   22397   VIXL_ASSERT(AllowAssembler());
   22398   CheckIT(cond);
   22399   USE(dt);
   22400   if (IsUsingT32()) {
   22401     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
   22402     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   22403       const DRegister& dreg = dreglist.GetFirstDRegister();
   22404       unsigned len = dreglist.GetLength() * 2;
   22405       EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
   22406       AdvanceIT();
   22407       return;
   22408     }
   22409   } else {
   22410     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
   22411     if (cond.IsNotNever() &&
   22412         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   22413       const DRegister& dreg = dreglist.GetFirstDRegister();
   22414       unsigned len = dreglist.GetLength() * 2;
   22415       EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
   22416               (len & 0xff));
   22417       return;
   22418     }
   22419   }
   22420   Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
   22421 }
   22422 
   22423 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
   22424   VIXL_ASSERT(AllowAssembler());
   22425   CheckIT(cond);
   22426   USE(dt);
   22427   if (IsUsingT32()) {
   22428     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
   22429     const SRegister& sreg = sreglist.GetFirstSRegister();
   22430     unsigned len = sreglist.GetLength();
   22431     EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
   22432     AdvanceIT();
   22433     return;
   22434   } else {
   22435     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
   22436     if (cond.IsNotNever()) {
   22437       const SRegister& sreg = sreglist.GetFirstSRegister();
   22438       unsigned len = sreglist.GetLength();
   22439       EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
   22440               (len & 0xff));
   22441       return;
   22442     }
   22443   }
   22444   Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
   22445 }
   22446 
   22447 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
   22448   VIXL_ASSERT(AllowAssembler());
   22449   CheckIT(cond);
   22450   USE(dt);
   22451   if (IsUsingT32()) {
   22452     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
   22453     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   22454       const DRegister& dreg = dreglist.GetFirstDRegister();
   22455       unsigned len = dreglist.GetLength() * 2;
   22456       EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
   22457       AdvanceIT();
   22458       return;
   22459     }
   22460   } else {
   22461     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
   22462     if (cond.IsNotNever() &&
   22463         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
   22464       const DRegister& dreg = dreglist.GetFirstDRegister();
   22465       unsigned len = dreglist.GetLength() * 2;
   22466       EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
   22467               (len & 0xff));
   22468       return;
   22469     }
   22470   }
   22471   Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
   22472 }
   22473 
   22474 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
   22475   VIXL_ASSERT(AllowAssembler());
   22476   CheckIT(cond);
   22477   USE(dt);
   22478   if (IsUsingT32()) {
   22479     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
   22480     const SRegister& sreg = sreglist.GetFirstSRegister();
   22481     unsigned len = sreglist.GetLength();
   22482     EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
   22483     AdvanceIT();
   22484     return;
   22485   } else {
   22486     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
   22487     if (cond.IsNotNever()) {
   22488       const SRegister& sreg = sreglist.GetFirstSRegister();
   22489       unsigned len = sreglist.GetLength();
   22490       EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
   22491               (len & 0xff));
   22492       return;
   22493     }
   22494   }
   22495   Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
   22496 }
   22497 
   22498 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   22499   VIXL_ASSERT(AllowAssembler());
   22500   CheckIT(cond);
   22501   Dt_size_5 encoded_dt(dt);
   22502   if (IsUsingT32()) {
   22503     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   22504     if (encoded_dt.IsValid()) {
   22505       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22506         EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
   22507                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22508         AdvanceIT();
   22509         return;
   22510       }
   22511     }
   22512   } else {
   22513     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   22514     if (encoded_dt.IsValid()) {
   22515       if (cond.Is(al)) {
   22516         EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
   22517                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22518         return;
   22519       }
   22520     }
   22521   }
   22522   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
   22523 }
   22524 
   22525 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   22526   VIXL_ASSERT(AllowAssembler());
   22527   CheckIT(cond);
   22528   Dt_size_5 encoded_dt(dt);
   22529   if (IsUsingT32()) {
   22530     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   22531     if (encoded_dt.IsValid()) {
   22532       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22533         EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
   22534                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22535         AdvanceIT();
   22536         return;
   22537       }
   22538     }
   22539   } else {
   22540     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   22541     if (encoded_dt.IsValid()) {
   22542       if (cond.Is(al)) {
   22543         EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
   22544                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22545         return;
   22546       }
   22547     }
   22548   }
   22549   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
   22550 }
   22551 
   22552 void Assembler::vqadd(
   22553     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   22554   VIXL_ASSERT(AllowAssembler());
   22555   CheckIT(cond);
   22556   Dt_U_size_3 encoded_dt(dt);
   22557   if (IsUsingT32()) {
   22558     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   22559     if (encoded_dt.IsValid()) {
   22560       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22561         EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22562                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22563                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22564         AdvanceIT();
   22565         return;
   22566       }
   22567     }
   22568   } else {
   22569     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   22570     if (encoded_dt.IsValid()) {
   22571       if (cond.Is(al)) {
   22572         EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22573                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22574                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22575         return;
   22576       }
   22577     }
   22578   }
   22579   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
   22580 }
   22581 
   22582 void Assembler::vqadd(
   22583     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   22584   VIXL_ASSERT(AllowAssembler());
   22585   CheckIT(cond);
   22586   Dt_U_size_3 encoded_dt(dt);
   22587   if (IsUsingT32()) {
   22588     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   22589     if (encoded_dt.IsValid()) {
   22590       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22591         EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22592                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   22593                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22594         AdvanceIT();
   22595         return;
   22596       }
   22597     }
   22598   } else {
   22599     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   22600     if (encoded_dt.IsValid()) {
   22601       if (cond.Is(al)) {
   22602         EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   22603                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   22604                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22605         return;
   22606       }
   22607     }
   22608   }
   22609   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
   22610 }
   22611 
   22612 void Assembler::vqdmlal(
   22613     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   22614   VIXL_ASSERT(AllowAssembler());
   22615   CheckIT(cond);
   22616   Dt_size_13 encoded_dt(dt);
   22617   if (IsUsingT32()) {
   22618     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   22619     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   22620       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22621         EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
   22622                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22623         AdvanceIT();
   22624         return;
   22625       }
   22626     }
   22627   } else {
   22628     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   22629     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   22630       if (cond.Is(al)) {
   22631         EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
   22632                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22633         return;
   22634       }
   22635     }
   22636   }
   22637   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
   22638 }
   22639 
   22640 void Assembler::vqdmlal(Condition cond,
   22641                         DataType dt,
   22642                         QRegister rd,
   22643                         DRegister rn,
   22644                         DRegister dm,
   22645                         unsigned index) {
   22646   VIXL_ASSERT(AllowAssembler());
   22647   CheckIT(cond);
   22648   Dt_size_13 encoded_dt(dt);
   22649   if (IsUsingT32()) {
   22650     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
   22651     if (encoded_dt.IsValid() &&
   22652         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   22653          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
   22654         (dt.Is(S16) || dt.Is(S32))) {
   22655       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22656         uint32_t shift = 4;
   22657         if (dt.Is(S16)) {
   22658           shift = 3;
   22659         }
   22660         uint32_t mvm = dm.GetCode() | index << shift;
   22661         EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
   22662                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   22663                    ((mvm & 0x10) << 1));
   22664         AdvanceIT();
   22665         return;
   22666       }
   22667     }
   22668   } else {
   22669     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
   22670     if (encoded_dt.IsValid() &&
   22671         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   22672          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
   22673         (dt.Is(S16) || dt.Is(S32))) {
   22674       if (cond.Is(al)) {
   22675         uint32_t shift = 4;
   22676         if (dt.Is(S16)) {
   22677           shift = 3;
   22678         }
   22679         uint32_t mvm = dm.GetCode() | index << shift;
   22680         EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
   22681                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   22682                 ((mvm & 0x10) << 1));
   22683         return;
   22684       }
   22685     }
   22686   }
   22687   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
   22688 }
   22689 
   22690 void Assembler::vqdmlsl(
   22691     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   22692   VIXL_ASSERT(AllowAssembler());
   22693   CheckIT(cond);
   22694   Dt_size_13 encoded_dt(dt);
   22695   if (IsUsingT32()) {
   22696     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   22697     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   22698       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22699         EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
   22700                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22701         AdvanceIT();
   22702         return;
   22703       }
   22704     }
   22705   } else {
   22706     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   22707     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   22708       if (cond.Is(al)) {
   22709         EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
   22710                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22711         return;
   22712       }
   22713     }
   22714   }
   22715   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
   22716 }
   22717 
   22718 void Assembler::vqdmlsl(Condition cond,
   22719                         DataType dt,
   22720                         QRegister rd,
   22721                         DRegister rn,
   22722                         DRegister dm,
   22723                         unsigned index) {
   22724   VIXL_ASSERT(AllowAssembler());
   22725   CheckIT(cond);
   22726   Dt_size_13 encoded_dt(dt);
   22727   if (IsUsingT32()) {
   22728     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
   22729     if (encoded_dt.IsValid() &&
   22730         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   22731          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
   22732         (dt.Is(S16) || dt.Is(S32))) {
   22733       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22734         uint32_t shift = 4;
   22735         if (dt.Is(S16)) {
   22736           shift = 3;
   22737         }
   22738         uint32_t mvm = dm.GetCode() | index << shift;
   22739         EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
   22740                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   22741                    ((mvm & 0x10) << 1));
   22742         AdvanceIT();
   22743         return;
   22744       }
   22745     }
   22746   } else {
   22747     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
   22748     if (encoded_dt.IsValid() &&
   22749         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
   22750          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
   22751         (dt.Is(S16) || dt.Is(S32))) {
   22752       if (cond.Is(al)) {
   22753         uint32_t shift = 4;
   22754         if (dt.Is(S16)) {
   22755           shift = 3;
   22756         }
   22757         uint32_t mvm = dm.GetCode() | index << shift;
   22758         EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
   22759                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
   22760                 ((mvm & 0x10) << 1));
   22761         return;
   22762       }
   22763     }
   22764   }
   22765   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
   22766 }
   22767 
   22768 void Assembler::vqdmulh(
   22769     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   22770   VIXL_ASSERT(AllowAssembler());
   22771   CheckIT(cond);
   22772   Dt_size_13 encoded_dt(dt);
   22773   if (IsUsingT32()) {
   22774     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   22775     if (encoded_dt.IsValid()) {
   22776       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22777         EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
   22778                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22779         AdvanceIT();
   22780         return;
   22781       }
   22782     }
   22783   } else {
   22784     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   22785     if (encoded_dt.IsValid()) {
   22786       if (cond.Is(al)) {
   22787         EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
   22788                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22789         return;
   22790       }
   22791     }
   22792   }
   22793   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
   22794 }
   22795 
   22796 void Assembler::vqdmulh(
   22797     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   22798   VIXL_ASSERT(AllowAssembler());
   22799   CheckIT(cond);
   22800   Dt_size_13 encoded_dt(dt);
   22801   if (IsUsingT32()) {
   22802     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   22803     if (encoded_dt.IsValid()) {
   22804       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22805         EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
   22806                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22807         AdvanceIT();
   22808         return;
   22809       }
   22810     }
   22811   } else {
   22812     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   22813     if (encoded_dt.IsValid()) {
   22814       if (cond.Is(al)) {
   22815         EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
   22816                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22817         return;
   22818       }
   22819     }
   22820   }
   22821   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
   22822 }
   22823 
   22824 void Assembler::vqdmulh(
   22825     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
   22826   VIXL_ASSERT(AllowAssembler());
   22827   CheckIT(cond);
   22828   Dt_size_13 encoded_dt(dt);
   22829   if (IsUsingT32()) {
   22830     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
   22831     if (encoded_dt.IsValid() &&
   22832         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   22833          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   22834           (rm.GetLane() <= 1))) &&
   22835         (dt.Is(S16) || dt.Is(S32))) {
   22836       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22837         EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
   22838                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   22839         AdvanceIT();
   22840         return;
   22841       }
   22842     }
   22843   } else {
   22844     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
   22845     if (encoded_dt.IsValid() &&
   22846         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   22847          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   22848           (rm.GetLane() <= 1))) &&
   22849         (dt.Is(S16) || dt.Is(S32))) {
   22850       if (cond.Is(al)) {
   22851         EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
   22852                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   22853         return;
   22854       }
   22855     }
   22856   }
   22857   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
   22858 }
   22859 
   22860 void Assembler::vqdmulh(
   22861     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
   22862   VIXL_ASSERT(AllowAssembler());
   22863   CheckIT(cond);
   22864   Dt_size_13 encoded_dt(dt);
   22865   if (IsUsingT32()) {
   22866     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
   22867     if (encoded_dt.IsValid() &&
   22868         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   22869          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   22870           (rm.GetLane() <= 1))) &&
   22871         (dt.Is(S16) || dt.Is(S32))) {
   22872       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22873         EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
   22874                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   22875         AdvanceIT();
   22876         return;
   22877       }
   22878     }
   22879   } else {
   22880     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
   22881     if (encoded_dt.IsValid() &&
   22882         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   22883          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   22884           (rm.GetLane() <= 1))) &&
   22885         (dt.Is(S16) || dt.Is(S32))) {
   22886       if (cond.Is(al)) {
   22887         EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
   22888                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   22889         return;
   22890       }
   22891     }
   22892   }
   22893   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
   22894 }
   22895 
   22896 void Assembler::vqdmull(
   22897     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   22898   VIXL_ASSERT(AllowAssembler());
   22899   CheckIT(cond);
   22900   Dt_size_13 encoded_dt(dt);
   22901   if (IsUsingT32()) {
   22902     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   22903     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   22904       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22905         EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
   22906                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22907         AdvanceIT();
   22908         return;
   22909       }
   22910     }
   22911   } else {
   22912     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   22913     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
   22914       if (cond.Is(al)) {
   22915         EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
   22916                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   22917         return;
   22918       }
   22919     }
   22920   }
   22921   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
   22922 }
   22923 
   22924 void Assembler::vqdmull(
   22925     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
   22926   VIXL_ASSERT(AllowAssembler());
   22927   CheckIT(cond);
   22928   Dt_size_13 encoded_dt(dt);
   22929   if (IsUsingT32()) {
   22930     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
   22931     if (encoded_dt.IsValid() &&
   22932         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   22933          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   22934           (rm.GetLane() <= 1))) &&
   22935         (dt.Is(S16) || dt.Is(S32))) {
   22936       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22937         EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
   22938                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   22939         AdvanceIT();
   22940         return;
   22941       }
   22942     }
   22943   } else {
   22944     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
   22945     if (encoded_dt.IsValid() &&
   22946         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   22947          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   22948           (rm.GetLane() <= 1))) &&
   22949         (dt.Is(S16) || dt.Is(S32))) {
   22950       if (cond.Is(al)) {
   22951         EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
   22952                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   22953         return;
   22954       }
   22955     }
   22956   }
   22957   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
   22958 }
   22959 
   22960 void Assembler::vqmovn(Condition cond,
   22961                        DataType dt,
   22962                        DRegister rd,
   22963                        QRegister rm) {
   22964   VIXL_ASSERT(AllowAssembler());
   22965   CheckIT(cond);
   22966   Dt_op_size_3 encoded_dt(dt);
   22967   if (IsUsingT32()) {
   22968     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
   22969     if (encoded_dt.IsValid()) {
   22970       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   22971         EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22972                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   22973                    rd.Encode(22, 12) | rm.Encode(5, 0));
   22974         AdvanceIT();
   22975         return;
   22976       }
   22977     }
   22978   } else {
   22979     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
   22980     if (encoded_dt.IsValid()) {
   22981       if (cond.Is(al)) {
   22982         EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   22983                 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   22984                 rd.Encode(22, 12) | rm.Encode(5, 0));
   22985         return;
   22986       }
   22987     }
   22988   }
   22989   Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
   22990 }
   22991 
   22992 void Assembler::vqmovun(Condition cond,
   22993                         DataType dt,
   22994                         DRegister rd,
   22995                         QRegister rm) {
   22996   VIXL_ASSERT(AllowAssembler());
   22997   CheckIT(cond);
   22998   Dt_size_14 encoded_dt(dt);
   22999   if (IsUsingT32()) {
   23000     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
   23001     if (encoded_dt.IsValid()) {
   23002       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23003         EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
   23004                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23005         AdvanceIT();
   23006         return;
   23007       }
   23008     }
   23009   } else {
   23010     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
   23011     if (encoded_dt.IsValid()) {
   23012       if (cond.Is(al)) {
   23013         EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
   23014                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23015         return;
   23016       }
   23017     }
   23018   }
   23019   Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
   23020 }
   23021 
   23022 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   23023   VIXL_ASSERT(AllowAssembler());
   23024   CheckIT(cond);
   23025   Dt_size_5 encoded_dt(dt);
   23026   if (IsUsingT32()) {
   23027     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   23028     if (encoded_dt.IsValid()) {
   23029       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23030         EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
   23031                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23032         AdvanceIT();
   23033         return;
   23034       }
   23035     }
   23036   } else {
   23037     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   23038     if (encoded_dt.IsValid()) {
   23039       if (cond.Is(al)) {
   23040         EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
   23041                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23042         return;
   23043       }
   23044     }
   23045   }
   23046   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
   23047 }
   23048 
   23049 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   23050   VIXL_ASSERT(AllowAssembler());
   23051   CheckIT(cond);
   23052   Dt_size_5 encoded_dt(dt);
   23053   if (IsUsingT32()) {
   23054     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   23055     if (encoded_dt.IsValid()) {
   23056       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23057         EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
   23058                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23059         AdvanceIT();
   23060         return;
   23061       }
   23062     }
   23063   } else {
   23064     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   23065     if (encoded_dt.IsValid()) {
   23066       if (cond.Is(al)) {
   23067         EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
   23068                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23069         return;
   23070       }
   23071     }
   23072   }
   23073   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
   23074 }
   23075 
   23076 void Assembler::vqrdmulh(
   23077     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   23078   VIXL_ASSERT(AllowAssembler());
   23079   CheckIT(cond);
   23080   Dt_size_13 encoded_dt(dt);
   23081   if (IsUsingT32()) {
   23082     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   23083     if (encoded_dt.IsValid()) {
   23084       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23085         EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
   23086                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23087         AdvanceIT();
   23088         return;
   23089       }
   23090     }
   23091   } else {
   23092     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   23093     if (encoded_dt.IsValid()) {
   23094       if (cond.Is(al)) {
   23095         EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
   23096                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23097         return;
   23098       }
   23099     }
   23100   }
   23101   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
   23102 }
   23103 
   23104 void Assembler::vqrdmulh(
   23105     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   23106   VIXL_ASSERT(AllowAssembler());
   23107   CheckIT(cond);
   23108   Dt_size_13 encoded_dt(dt);
   23109   if (IsUsingT32()) {
   23110     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   23111     if (encoded_dt.IsValid()) {
   23112       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23113         EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
   23114                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23115         AdvanceIT();
   23116         return;
   23117       }
   23118     }
   23119   } else {
   23120     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   23121     if (encoded_dt.IsValid()) {
   23122       if (cond.Is(al)) {
   23123         EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
   23124                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23125         return;
   23126       }
   23127     }
   23128   }
   23129   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
   23130 }
   23131 
   23132 void Assembler::vqrdmulh(
   23133     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
   23134   VIXL_ASSERT(AllowAssembler());
   23135   CheckIT(cond);
   23136   Dt_size_13 encoded_dt(dt);
   23137   if (IsUsingT32()) {
   23138     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
   23139     if (encoded_dt.IsValid() &&
   23140         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   23141          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   23142           (rm.GetLane() <= 1))) &&
   23143         (dt.Is(S16) || dt.Is(S32))) {
   23144       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23145         EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
   23146                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   23147         AdvanceIT();
   23148         return;
   23149       }
   23150     }
   23151   } else {
   23152     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
   23153     if (encoded_dt.IsValid() &&
   23154         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   23155          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   23156           (rm.GetLane() <= 1))) &&
   23157         (dt.Is(S16) || dt.Is(S32))) {
   23158       if (cond.Is(al)) {
   23159         EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
   23160                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   23161         return;
   23162       }
   23163     }
   23164   }
   23165   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
   23166 }
   23167 
   23168 void Assembler::vqrdmulh(
   23169     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
   23170   VIXL_ASSERT(AllowAssembler());
   23171   CheckIT(cond);
   23172   Dt_size_13 encoded_dt(dt);
   23173   if (IsUsingT32()) {
   23174     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
   23175     if (encoded_dt.IsValid() &&
   23176         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   23177          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   23178           (rm.GetLane() <= 1))) &&
   23179         (dt.Is(S16) || dt.Is(S32))) {
   23180       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23181         EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
   23182                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   23183         AdvanceIT();
   23184         return;
   23185       }
   23186     }
   23187   } else {
   23188     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
   23189     if (encoded_dt.IsValid() &&
   23190         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
   23191          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
   23192           (rm.GetLane() <= 1))) &&
   23193         (dt.Is(S16) || dt.Is(S32))) {
   23194       if (cond.Is(al)) {
   23195         EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
   23196                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
   23197         return;
   23198       }
   23199     }
   23200   }
   23201   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
   23202 }
   23203 
   23204 void Assembler::vqrshl(
   23205     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
   23206   VIXL_ASSERT(AllowAssembler());
   23207   CheckIT(cond);
   23208   Dt_U_size_3 encoded_dt(dt);
   23209   if (IsUsingT32()) {
   23210     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
   23211     if (encoded_dt.IsValid()) {
   23212       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23213         EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23214                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   23215                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23216         AdvanceIT();
   23217         return;
   23218       }
   23219     }
   23220   } else {
   23221     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
   23222     if (encoded_dt.IsValid()) {
   23223       if (cond.Is(al)) {
   23224         EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23225                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   23226                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23227         return;
   23228       }
   23229     }
   23230   }
   23231   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
   23232 }
   23233 
   23234 void Assembler::vqrshl(
   23235     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
   23236   VIXL_ASSERT(AllowAssembler());
   23237   CheckIT(cond);
   23238   Dt_U_size_3 encoded_dt(dt);
   23239   if (IsUsingT32()) {
   23240     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
   23241     if (encoded_dt.IsValid()) {
   23242       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23243         EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23244                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   23245                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23246         AdvanceIT();
   23247         return;
   23248       }
   23249     }
   23250   } else {
   23251     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
   23252     if (encoded_dt.IsValid()) {
   23253       if (cond.Is(al)) {
   23254         EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23255                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   23256                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23257         return;
   23258       }
   23259     }
   23260   }
   23261   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
   23262 }
   23263 
   23264 void Assembler::vqrshrn(Condition cond,
   23265                         DataType dt,
   23266                         DRegister rd,
   23267                         QRegister rm,
   23268                         const QOperand& operand) {
   23269   VIXL_ASSERT(AllowAssembler());
   23270   CheckIT(cond);
   23271   if (operand.IsImmediate()) {
   23272     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23273       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23274       Dt_op_size_3 encoded_dt(dt);
   23275       Dt_imm6_1 encoded_dt_2(dt);
   23276       if (IsUsingT32()) {
   23277         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   23278         if (encoded_dt.IsValid() && (imm == 0)) {
   23279           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23280             EmitT32_32(0xffb20280U |
   23281                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23282                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   23283                        rd.Encode(22, 12) | rm.Encode(5, 0));
   23284             AdvanceIT();
   23285             return;
   23286           }
   23287         }
   23288         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
   23289         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23290           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23291             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23292             EmitT32_32(0xef800950U |
   23293                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
   23294                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
   23295                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23296             AdvanceIT();
   23297             return;
   23298           }
   23299         }
   23300       } else {
   23301         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   23302         if (encoded_dt.IsValid() && (imm == 0)) {
   23303           if (cond.Is(al)) {
   23304             EmitA32(0xf3b20280U |
   23305                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23306                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   23307                     rd.Encode(22, 12) | rm.Encode(5, 0));
   23308             return;
   23309           }
   23310         }
   23311         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
   23312         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23313           if (cond.Is(al)) {
   23314             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23315             EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
   23316                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
   23317                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23318             return;
   23319           }
   23320         }
   23321       }
   23322     }
   23323   }
   23324   Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
   23325 }
   23326 
   23327 void Assembler::vqrshrun(Condition cond,
   23328                          DataType dt,
   23329                          DRegister rd,
   23330                          QRegister rm,
   23331                          const QOperand& operand) {
   23332   VIXL_ASSERT(AllowAssembler());
   23333   CheckIT(cond);
   23334   if (operand.IsImmediate()) {
   23335     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23336       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23337       Dt_imm6_2 encoded_dt(dt);
   23338       Dt_size_14 encoded_dt_2(dt);
   23339       if (IsUsingT32()) {
   23340         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
   23341         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23342           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23343             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23344             EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23345                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23346                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23347             AdvanceIT();
   23348             return;
   23349           }
   23350         }
   23351         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   23352         if (encoded_dt_2.IsValid() && (imm == 0)) {
   23353           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23354             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
   23355                        rd.Encode(22, 12) | rm.Encode(5, 0));
   23356             AdvanceIT();
   23357             return;
   23358           }
   23359         }
   23360       } else {
   23361         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
   23362         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23363           if (cond.Is(al)) {
   23364             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23365             EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23366                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23367                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23368             return;
   23369           }
   23370         }
   23371         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   23372         if (encoded_dt_2.IsValid() && (imm == 0)) {
   23373           if (cond.Is(al)) {
   23374             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
   23375                     rd.Encode(22, 12) | rm.Encode(5, 0));
   23376             return;
   23377           }
   23378         }
   23379       }
   23380     }
   23381   }
   23382   Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
   23383 }
   23384 
   23385 void Assembler::vqshl(Condition cond,
   23386                       DataType dt,
   23387                       DRegister rd,
   23388                       DRegister rm,
   23389                       const DOperand& operand) {
   23390   VIXL_ASSERT(AllowAssembler());
   23391   CheckIT(cond);
   23392   if (operand.IsRegister()) {
   23393     DRegister rn = operand.GetRegister();
   23394     Dt_U_size_3 encoded_dt(dt);
   23395     if (IsUsingT32()) {
   23396       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
   23397       if (encoded_dt.IsValid()) {
   23398         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23399           EmitT32_32(0xef000410U |
   23400                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23401                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   23402                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23403           AdvanceIT();
   23404           return;
   23405         }
   23406       }
   23407     } else {
   23408       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
   23409       if (encoded_dt.IsValid()) {
   23410         if (cond.Is(al)) {
   23411           EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23412                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   23413                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23414           return;
   23415         }
   23416       }
   23417     }
   23418   }
   23419   if (operand.IsImmediate()) {
   23420     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23421       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23422       Dt_L_imm6_1 encoded_dt(dt);
   23423       if (IsUsingT32()) {
   23424         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   23425         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   23426           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23427             uint32_t imm6 = imm;
   23428             EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23429                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23430                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23431                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23432             AdvanceIT();
   23433             return;
   23434           }
   23435         }
   23436       } else {
   23437         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   23438         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   23439           if (cond.Is(al)) {
   23440             uint32_t imm6 = imm;
   23441             EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23442                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23443                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23444                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23445             return;
   23446           }
   23447         }
   23448       }
   23449     }
   23450   }
   23451   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
   23452 }
   23453 
   23454 void Assembler::vqshl(Condition cond,
   23455                       DataType dt,
   23456                       QRegister rd,
   23457                       QRegister rm,
   23458                       const QOperand& operand) {
   23459   VIXL_ASSERT(AllowAssembler());
   23460   CheckIT(cond);
   23461   if (operand.IsRegister()) {
   23462     QRegister rn = operand.GetRegister();
   23463     Dt_U_size_3 encoded_dt(dt);
   23464     if (IsUsingT32()) {
   23465       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
   23466       if (encoded_dt.IsValid()) {
   23467         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23468           EmitT32_32(0xef000450U |
   23469                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23470                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   23471                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23472           AdvanceIT();
   23473           return;
   23474         }
   23475       }
   23476     } else {
   23477       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
   23478       if (encoded_dt.IsValid()) {
   23479         if (cond.Is(al)) {
   23480           EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23481                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   23482                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   23483           return;
   23484         }
   23485       }
   23486     }
   23487   }
   23488   if (operand.IsImmediate()) {
   23489     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23490       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23491       Dt_L_imm6_1 encoded_dt(dt);
   23492       if (IsUsingT32()) {
   23493         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   23494         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   23495           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23496             uint32_t imm6 = imm;
   23497             EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23498                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23499                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23500                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23501             AdvanceIT();
   23502             return;
   23503           }
   23504         }
   23505       } else {
   23506         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   23507         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   23508           if (cond.Is(al)) {
   23509             uint32_t imm6 = imm;
   23510             EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23511                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23512                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23513                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23514             return;
   23515           }
   23516         }
   23517       }
   23518     }
   23519   }
   23520   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
   23521 }
   23522 
   23523 void Assembler::vqshlu(Condition cond,
   23524                        DataType dt,
   23525                        DRegister rd,
   23526                        DRegister rm,
   23527                        const DOperand& operand) {
   23528   VIXL_ASSERT(AllowAssembler());
   23529   CheckIT(cond);
   23530   if (operand.IsImmediate()) {
   23531     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23532       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23533       Dt_L_imm6_2 encoded_dt(dt);
   23534       if (IsUsingT32()) {
   23535         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   23536         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   23537           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23538             uint32_t imm6 = imm;
   23539             EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23540                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23541                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23542                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23543             AdvanceIT();
   23544             return;
   23545           }
   23546         }
   23547       } else {
   23548         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   23549         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   23550           if (cond.Is(al)) {
   23551             uint32_t imm6 = imm;
   23552             EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23553                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23554                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23555                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23556             return;
   23557           }
   23558         }
   23559       }
   23560     }
   23561   }
   23562   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
   23563 }
   23564 
   23565 void Assembler::vqshlu(Condition cond,
   23566                        DataType dt,
   23567                        QRegister rd,
   23568                        QRegister rm,
   23569                        const QOperand& operand) {
   23570   VIXL_ASSERT(AllowAssembler());
   23571   CheckIT(cond);
   23572   if (operand.IsImmediate()) {
   23573     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23574       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23575       Dt_L_imm6_2 encoded_dt(dt);
   23576       if (IsUsingT32()) {
   23577         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   23578         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   23579           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23580             uint32_t imm6 = imm;
   23581             EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23582                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23583                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23584                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23585             AdvanceIT();
   23586             return;
   23587           }
   23588         }
   23589       } else {
   23590         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   23591         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   23592           if (cond.Is(al)) {
   23593             uint32_t imm6 = imm;
   23594             EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23595                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23596                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   23597                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23598             return;
   23599           }
   23600         }
   23601       }
   23602     }
   23603   }
   23604   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
   23605 }
   23606 
   23607 void Assembler::vqshrn(Condition cond,
   23608                        DataType dt,
   23609                        DRegister rd,
   23610                        QRegister rm,
   23611                        const QOperand& operand) {
   23612   VIXL_ASSERT(AllowAssembler());
   23613   CheckIT(cond);
   23614   if (operand.IsImmediate()) {
   23615     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23616       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23617       Dt_op_size_3 encoded_dt(dt);
   23618       Dt_imm6_1 encoded_dt_2(dt);
   23619       if (IsUsingT32()) {
   23620         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   23621         if (encoded_dt.IsValid() && (imm == 0)) {
   23622           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23623             EmitT32_32(0xffb20280U |
   23624                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23625                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   23626                        rd.Encode(22, 12) | rm.Encode(5, 0));
   23627             AdvanceIT();
   23628             return;
   23629           }
   23630         }
   23631         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
   23632         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23633           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23634             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23635             EmitT32_32(0xef800910U |
   23636                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
   23637                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
   23638                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23639             AdvanceIT();
   23640             return;
   23641           }
   23642         }
   23643       } else {
   23644         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   23645         if (encoded_dt.IsValid() && (imm == 0)) {
   23646           if (cond.Is(al)) {
   23647             EmitA32(0xf3b20280U |
   23648                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23649                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
   23650                     rd.Encode(22, 12) | rm.Encode(5, 0));
   23651             return;
   23652           }
   23653         }
   23654         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
   23655         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23656           if (cond.Is(al)) {
   23657             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23658             EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
   23659                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
   23660                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23661             return;
   23662           }
   23663         }
   23664       }
   23665     }
   23666   }
   23667   Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
   23668 }
   23669 
   23670 void Assembler::vqshrun(Condition cond,
   23671                         DataType dt,
   23672                         DRegister rd,
   23673                         QRegister rm,
   23674                         const QOperand& operand) {
   23675   VIXL_ASSERT(AllowAssembler());
   23676   CheckIT(cond);
   23677   if (operand.IsImmediate()) {
   23678     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   23679       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   23680       Dt_imm6_2 encoded_dt(dt);
   23681       Dt_size_14 encoded_dt_2(dt);
   23682       if (IsUsingT32()) {
   23683         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
   23684         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23685           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23686             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23687             EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
   23688                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23689                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23690             AdvanceIT();
   23691             return;
   23692           }
   23693         }
   23694         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   23695         if (encoded_dt_2.IsValid() && (imm == 0)) {
   23696           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23697             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
   23698                        rd.Encode(22, 12) | rm.Encode(5, 0));
   23699             AdvanceIT();
   23700             return;
   23701           }
   23702         }
   23703       } else {
   23704         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
   23705         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   23706           if (cond.Is(al)) {
   23707             uint32_t imm6 = dt.GetSize() / 2 - imm;
   23708             EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
   23709                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   23710                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   23711             return;
   23712           }
   23713         }
   23714         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   23715         if (encoded_dt_2.IsValid() && (imm == 0)) {
   23716           if (cond.Is(al)) {
   23717             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
   23718                     rd.Encode(22, 12) | rm.Encode(5, 0));
   23719             return;
   23720           }
   23721         }
   23722       }
   23723     }
   23724   }
   23725   Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
   23726 }
   23727 
   23728 void Assembler::vqsub(
   23729     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   23730   VIXL_ASSERT(AllowAssembler());
   23731   CheckIT(cond);
   23732   Dt_U_size_3 encoded_dt(dt);
   23733   if (IsUsingT32()) {
   23734     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   23735     if (encoded_dt.IsValid()) {
   23736       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23737         EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23738                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   23739                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23740         AdvanceIT();
   23741         return;
   23742       }
   23743     }
   23744   } else {
   23745     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   23746     if (encoded_dt.IsValid()) {
   23747       if (cond.Is(al)) {
   23748         EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23749                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   23750                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23751         return;
   23752       }
   23753     }
   23754   }
   23755   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
   23756 }
   23757 
   23758 void Assembler::vqsub(
   23759     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   23760   VIXL_ASSERT(AllowAssembler());
   23761   CheckIT(cond);
   23762   Dt_U_size_3 encoded_dt(dt);
   23763   if (IsUsingT32()) {
   23764     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   23765     if (encoded_dt.IsValid()) {
   23766       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23767         EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23768                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   23769                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23770         AdvanceIT();
   23771         return;
   23772       }
   23773     }
   23774   } else {
   23775     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   23776     if (encoded_dt.IsValid()) {
   23777       if (cond.Is(al)) {
   23778         EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   23779                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   23780                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23781         return;
   23782       }
   23783     }
   23784   }
   23785   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
   23786 }
   23787 
   23788 void Assembler::vraddhn(
   23789     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
   23790   VIXL_ASSERT(AllowAssembler());
   23791   CheckIT(cond);
   23792   Dt_size_3 encoded_dt(dt);
   23793   if (IsUsingT32()) {
   23794     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
   23795     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   23796       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23797         EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) |
   23798                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23799         AdvanceIT();
   23800         return;
   23801       }
   23802     }
   23803   } else {
   23804     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
   23805     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   23806       if (cond.Is(al)) {
   23807         EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
   23808                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   23809         return;
   23810       }
   23811     }
   23812   }
   23813   Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
   23814 }
   23815 
   23816 void Assembler::vrecpe(Condition cond,
   23817                        DataType dt,
   23818                        DRegister rd,
   23819                        DRegister rm) {
   23820   VIXL_ASSERT(AllowAssembler());
   23821   CheckIT(cond);
   23822   Dt_F_size_4 encoded_dt(dt);
   23823   if (IsUsingT32()) {
   23824     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   23825     if (encoded_dt.IsValid()) {
   23826       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23827         EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23828                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   23829                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23830         AdvanceIT();
   23831         return;
   23832       }
   23833     }
   23834   } else {
   23835     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   23836     if (encoded_dt.IsValid()) {
   23837       if (cond.Is(al)) {
   23838         EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23839                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   23840                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23841         return;
   23842       }
   23843     }
   23844   }
   23845   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
   23846 }
   23847 
   23848 void Assembler::vrecpe(Condition cond,
   23849                        DataType dt,
   23850                        QRegister rd,
   23851                        QRegister rm) {
   23852   VIXL_ASSERT(AllowAssembler());
   23853   CheckIT(cond);
   23854   Dt_F_size_4 encoded_dt(dt);
   23855   if (IsUsingT32()) {
   23856     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   23857     if (encoded_dt.IsValid()) {
   23858       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23859         EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23860                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   23861                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23862         AdvanceIT();
   23863         return;
   23864       }
   23865     }
   23866   } else {
   23867     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   23868     if (encoded_dt.IsValid()) {
   23869       if (cond.Is(al)) {
   23870         EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   23871                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   23872                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23873         return;
   23874       }
   23875     }
   23876   }
   23877   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
   23878 }
   23879 
   23880 void Assembler::vrecps(
   23881     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   23882   VIXL_ASSERT(AllowAssembler());
   23883   CheckIT(cond);
   23884   if (IsUsingT32()) {
   23885     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   23886     if (dt.Is(F32)) {
   23887       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23888         EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23889                    rm.Encode(5, 0));
   23890         AdvanceIT();
   23891         return;
   23892       }
   23893     }
   23894   } else {
   23895     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   23896     if (dt.Is(F32)) {
   23897       if (cond.Is(al)) {
   23898         EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23899                 rm.Encode(5, 0));
   23900         return;
   23901       }
   23902     }
   23903   }
   23904   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
   23905 }
   23906 
   23907 void Assembler::vrecps(
   23908     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   23909   VIXL_ASSERT(AllowAssembler());
   23910   CheckIT(cond);
   23911   if (IsUsingT32()) {
   23912     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   23913     if (dt.Is(F32)) {
   23914       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23915         EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23916                    rm.Encode(5, 0));
   23917         AdvanceIT();
   23918         return;
   23919       }
   23920     }
   23921   } else {
   23922     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   23923     if (dt.Is(F32)) {
   23924       if (cond.Is(al)) {
   23925         EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   23926                 rm.Encode(5, 0));
   23927         return;
   23928       }
   23929     }
   23930   }
   23931   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
   23932 }
   23933 
   23934 void Assembler::vrev16(Condition cond,
   23935                        DataType dt,
   23936                        DRegister rd,
   23937                        DRegister rm) {
   23938   VIXL_ASSERT(AllowAssembler());
   23939   CheckIT(cond);
   23940   Dt_size_1 encoded_dt(dt);
   23941   if (IsUsingT32()) {
   23942     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   23943     if (encoded_dt.IsValid()) {
   23944       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23945         EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
   23946                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23947         AdvanceIT();
   23948         return;
   23949       }
   23950     }
   23951   } else {
   23952     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   23953     if (encoded_dt.IsValid()) {
   23954       if (cond.Is(al)) {
   23955         EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
   23956                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23957         return;
   23958       }
   23959     }
   23960   }
   23961   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
   23962 }
   23963 
   23964 void Assembler::vrev16(Condition cond,
   23965                        DataType dt,
   23966                        QRegister rd,
   23967                        QRegister rm) {
   23968   VIXL_ASSERT(AllowAssembler());
   23969   CheckIT(cond);
   23970   Dt_size_1 encoded_dt(dt);
   23971   if (IsUsingT32()) {
   23972     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   23973     if (encoded_dt.IsValid()) {
   23974       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   23975         EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
   23976                    rd.Encode(22, 12) | rm.Encode(5, 0));
   23977         AdvanceIT();
   23978         return;
   23979       }
   23980     }
   23981   } else {
   23982     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   23983     if (encoded_dt.IsValid()) {
   23984       if (cond.Is(al)) {
   23985         EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
   23986                 rd.Encode(22, 12) | rm.Encode(5, 0));
   23987         return;
   23988       }
   23989     }
   23990   }
   23991   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
   23992 }
   23993 
   23994 void Assembler::vrev32(Condition cond,
   23995                        DataType dt,
   23996                        DRegister rd,
   23997                        DRegister rm) {
   23998   VIXL_ASSERT(AllowAssembler());
   23999   CheckIT(cond);
   24000   Dt_size_15 encoded_dt(dt);
   24001   if (IsUsingT32()) {
   24002     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   24003     if (encoded_dt.IsValid()) {
   24004       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24005         EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
   24006                    rd.Encode(22, 12) | rm.Encode(5, 0));
   24007         AdvanceIT();
   24008         return;
   24009       }
   24010     }
   24011   } else {
   24012     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   24013     if (encoded_dt.IsValid()) {
   24014       if (cond.Is(al)) {
   24015         EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
   24016                 rd.Encode(22, 12) | rm.Encode(5, 0));
   24017         return;
   24018       }
   24019     }
   24020   }
   24021   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
   24022 }
   24023 
   24024 void Assembler::vrev32(Condition cond,
   24025                        DataType dt,
   24026                        QRegister rd,
   24027                        QRegister rm) {
   24028   VIXL_ASSERT(AllowAssembler());
   24029   CheckIT(cond);
   24030   Dt_size_15 encoded_dt(dt);
   24031   if (IsUsingT32()) {
   24032     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   24033     if (encoded_dt.IsValid()) {
   24034       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24035         EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
   24036                    rd.Encode(22, 12) | rm.Encode(5, 0));
   24037         AdvanceIT();
   24038         return;
   24039       }
   24040     }
   24041   } else {
   24042     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   24043     if (encoded_dt.IsValid()) {
   24044       if (cond.Is(al)) {
   24045         EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
   24046                 rd.Encode(22, 12) | rm.Encode(5, 0));
   24047         return;
   24048       }
   24049     }
   24050   }
   24051   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
   24052 }
   24053 
   24054 void Assembler::vrev64(Condition cond,
   24055                        DataType dt,
   24056                        DRegister rd,
   24057                        DRegister rm) {
   24058   VIXL_ASSERT(AllowAssembler());
   24059   CheckIT(cond);
   24060   Dt_size_7 encoded_dt(dt);
   24061   if (IsUsingT32()) {
   24062     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   24063     if (encoded_dt.IsValid()) {
   24064       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24065         EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
   24066                    rd.Encode(22, 12) | rm.Encode(5, 0));
   24067         AdvanceIT();
   24068         return;
   24069       }
   24070     }
   24071   } else {
   24072     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   24073     if (encoded_dt.IsValid()) {
   24074       if (cond.Is(al)) {
   24075         EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
   24076                 rd.Encode(22, 12) | rm.Encode(5, 0));
   24077         return;
   24078       }
   24079     }
   24080   }
   24081   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
   24082 }
   24083 
   24084 void Assembler::vrev64(Condition cond,
   24085                        DataType dt,
   24086                        QRegister rd,
   24087                        QRegister rm) {
   24088   VIXL_ASSERT(AllowAssembler());
   24089   CheckIT(cond);
   24090   Dt_size_7 encoded_dt(dt);
   24091   if (IsUsingT32()) {
   24092     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   24093     if (encoded_dt.IsValid()) {
   24094       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24095         EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
   24096                    rd.Encode(22, 12) | rm.Encode(5, 0));
   24097         AdvanceIT();
   24098         return;
   24099       }
   24100     }
   24101   } else {
   24102     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   24103     if (encoded_dt.IsValid()) {
   24104       if (cond.Is(al)) {
   24105         EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
   24106                 rd.Encode(22, 12) | rm.Encode(5, 0));
   24107         return;
   24108       }
   24109     }
   24110   }
   24111   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
   24112 }
   24113 
   24114 void Assembler::vrhadd(
   24115     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   24116   VIXL_ASSERT(AllowAssembler());
   24117   CheckIT(cond);
   24118   Dt_U_size_1 encoded_dt(dt);
   24119   if (IsUsingT32()) {
   24120     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   24121     if (encoded_dt.IsValid()) {
   24122       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24123         EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24124                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   24125                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   24126         AdvanceIT();
   24127         return;
   24128       }
   24129     }
   24130   } else {
   24131     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   24132     if (encoded_dt.IsValid()) {
   24133       if (cond.Is(al)) {
   24134         EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24135                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   24136                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   24137         return;
   24138       }
   24139     }
   24140   }
   24141   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
   24142 }
   24143 
   24144 void Assembler::vrhadd(
   24145     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   24146   VIXL_ASSERT(AllowAssembler());
   24147   CheckIT(cond);
   24148   Dt_U_size_1 encoded_dt(dt);
   24149   if (IsUsingT32()) {
   24150     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   24151     if (encoded_dt.IsValid()) {
   24152       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24153         EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24154                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   24155                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   24156         AdvanceIT();
   24157         return;
   24158       }
   24159     }
   24160   } else {
   24161     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   24162     if (encoded_dt.IsValid()) {
   24163       if (cond.Is(al)) {
   24164         EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24165                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   24166                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   24167         return;
   24168       }
   24169     }
   24170   }
   24171   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
   24172 }
   24173 
   24174 void Assembler::vrinta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   24175   VIXL_ASSERT(AllowAssembler());
   24176   CheckIT(al);
   24177   if (IsUsingT32()) {
   24178     // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; T1
   24179     if (dt1.Is(F32) && dt2.Is(F32)) {
   24180       EmitT32_32(0xffba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24181       AdvanceIT();
   24182       return;
   24183     }
   24184     // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; T1
   24185     if (dt1.Is(F64) && dt2.Is(F64)) {
   24186       EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24187       AdvanceIT();
   24188       return;
   24189     }
   24190   } else {
   24191     // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; A1
   24192     if (dt1.Is(F32) && dt2.Is(F32)) {
   24193       EmitA32(0xf3ba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24194       return;
   24195     }
   24196     // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; A1
   24197     if (dt1.Is(F64) && dt2.Is(F64)) {
   24198       EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24199       return;
   24200     }
   24201   }
   24202   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
   24203 }
   24204 
   24205 void Assembler::vrinta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   24206   VIXL_ASSERT(AllowAssembler());
   24207   CheckIT(al);
   24208   if (IsUsingT32()) {
   24209     // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; T1
   24210     if (dt1.Is(F32) && dt2.Is(F32)) {
   24211       EmitT32_32(0xffba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24212       AdvanceIT();
   24213       return;
   24214     }
   24215   } else {
   24216     // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; A1
   24217     if (dt1.Is(F32) && dt2.Is(F32)) {
   24218       EmitA32(0xf3ba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24219       return;
   24220     }
   24221   }
   24222   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
   24223 }
   24224 
   24225 void Assembler::vrinta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   24226   VIXL_ASSERT(AllowAssembler());
   24227   CheckIT(al);
   24228   if (IsUsingT32()) {
   24229     // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; T1
   24230     if (dt1.Is(F32) && dt2.Is(F32)) {
   24231       EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24232       AdvanceIT();
   24233       return;
   24234     }
   24235   } else {
   24236     // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; A1
   24237     if (dt1.Is(F32) && dt2.Is(F32)) {
   24238       EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24239       return;
   24240     }
   24241   }
   24242   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
   24243 }
   24244 
   24245 void Assembler::vrintm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   24246   VIXL_ASSERT(AllowAssembler());
   24247   CheckIT(al);
   24248   if (IsUsingT32()) {
   24249     // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; T1
   24250     if (dt1.Is(F32) && dt2.Is(F32)) {
   24251       EmitT32_32(0xffba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24252       AdvanceIT();
   24253       return;
   24254     }
   24255     // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; T1
   24256     if (dt1.Is(F64) && dt2.Is(F64)) {
   24257       EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24258       AdvanceIT();
   24259       return;
   24260     }
   24261   } else {
   24262     // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; A1
   24263     if (dt1.Is(F32) && dt2.Is(F32)) {
   24264       EmitA32(0xf3ba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24265       return;
   24266     }
   24267     // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; A1
   24268     if (dt1.Is(F64) && dt2.Is(F64)) {
   24269       EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24270       return;
   24271     }
   24272   }
   24273   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
   24274 }
   24275 
   24276 void Assembler::vrintm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   24277   VIXL_ASSERT(AllowAssembler());
   24278   CheckIT(al);
   24279   if (IsUsingT32()) {
   24280     // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; T1
   24281     if (dt1.Is(F32) && dt2.Is(F32)) {
   24282       EmitT32_32(0xffba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24283       AdvanceIT();
   24284       return;
   24285     }
   24286   } else {
   24287     // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; A1
   24288     if (dt1.Is(F32) && dt2.Is(F32)) {
   24289       EmitA32(0xf3ba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24290       return;
   24291     }
   24292   }
   24293   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
   24294 }
   24295 
   24296 void Assembler::vrintm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   24297   VIXL_ASSERT(AllowAssembler());
   24298   CheckIT(al);
   24299   if (IsUsingT32()) {
   24300     // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; T1
   24301     if (dt1.Is(F32) && dt2.Is(F32)) {
   24302       EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24303       AdvanceIT();
   24304       return;
   24305     }
   24306   } else {
   24307     // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; A1
   24308     if (dt1.Is(F32) && dt2.Is(F32)) {
   24309       EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24310       return;
   24311     }
   24312   }
   24313   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
   24314 }
   24315 
   24316 void Assembler::vrintn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   24317   VIXL_ASSERT(AllowAssembler());
   24318   CheckIT(al);
   24319   if (IsUsingT32()) {
   24320     // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; T1
   24321     if (dt1.Is(F32) && dt2.Is(F32)) {
   24322       EmitT32_32(0xffba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24323       AdvanceIT();
   24324       return;
   24325     }
   24326     // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; T1
   24327     if (dt1.Is(F64) && dt2.Is(F64)) {
   24328       EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24329       AdvanceIT();
   24330       return;
   24331     }
   24332   } else {
   24333     // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; A1
   24334     if (dt1.Is(F32) && dt2.Is(F32)) {
   24335       EmitA32(0xf3ba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24336       return;
   24337     }
   24338     // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; A1
   24339     if (dt1.Is(F64) && dt2.Is(F64)) {
   24340       EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24341       return;
   24342     }
   24343   }
   24344   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
   24345 }
   24346 
   24347 void Assembler::vrintn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   24348   VIXL_ASSERT(AllowAssembler());
   24349   CheckIT(al);
   24350   if (IsUsingT32()) {
   24351     // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; T1
   24352     if (dt1.Is(F32) && dt2.Is(F32)) {
   24353       EmitT32_32(0xffba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24354       AdvanceIT();
   24355       return;
   24356     }
   24357   } else {
   24358     // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; A1
   24359     if (dt1.Is(F32) && dt2.Is(F32)) {
   24360       EmitA32(0xf3ba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24361       return;
   24362     }
   24363   }
   24364   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
   24365 }
   24366 
   24367 void Assembler::vrintn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   24368   VIXL_ASSERT(AllowAssembler());
   24369   CheckIT(al);
   24370   if (IsUsingT32()) {
   24371     // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; T1
   24372     if (dt1.Is(F32) && dt2.Is(F32)) {
   24373       EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24374       AdvanceIT();
   24375       return;
   24376     }
   24377   } else {
   24378     // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; A1
   24379     if (dt1.Is(F32) && dt2.Is(F32)) {
   24380       EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24381       return;
   24382     }
   24383   }
   24384   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
   24385 }
   24386 
   24387 void Assembler::vrintp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   24388   VIXL_ASSERT(AllowAssembler());
   24389   CheckIT(al);
   24390   if (IsUsingT32()) {
   24391     // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; T1
   24392     if (dt1.Is(F32) && dt2.Is(F32)) {
   24393       EmitT32_32(0xffba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24394       AdvanceIT();
   24395       return;
   24396     }
   24397     // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; T1
   24398     if (dt1.Is(F64) && dt2.Is(F64)) {
   24399       EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24400       AdvanceIT();
   24401       return;
   24402     }
   24403   } else {
   24404     // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; A1
   24405     if (dt1.Is(F32) && dt2.Is(F32)) {
   24406       EmitA32(0xf3ba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24407       return;
   24408     }
   24409     // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; A1
   24410     if (dt1.Is(F64) && dt2.Is(F64)) {
   24411       EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24412       return;
   24413     }
   24414   }
   24415   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
   24416 }
   24417 
   24418 void Assembler::vrintp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   24419   VIXL_ASSERT(AllowAssembler());
   24420   CheckIT(al);
   24421   if (IsUsingT32()) {
   24422     // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; T1
   24423     if (dt1.Is(F32) && dt2.Is(F32)) {
   24424       EmitT32_32(0xffba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24425       AdvanceIT();
   24426       return;
   24427     }
   24428   } else {
   24429     // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; A1
   24430     if (dt1.Is(F32) && dt2.Is(F32)) {
   24431       EmitA32(0xf3ba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24432       return;
   24433     }
   24434   }
   24435   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
   24436 }
   24437 
   24438 void Assembler::vrintp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   24439   VIXL_ASSERT(AllowAssembler());
   24440   CheckIT(al);
   24441   if (IsUsingT32()) {
   24442     // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; T1
   24443     if (dt1.Is(F32) && dt2.Is(F32)) {
   24444       EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24445       AdvanceIT();
   24446       return;
   24447     }
   24448   } else {
   24449     // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; A1
   24450     if (dt1.Is(F32) && dt2.Is(F32)) {
   24451       EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24452       return;
   24453     }
   24454   }
   24455   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
   24456 }
   24457 
   24458 void Assembler::vrintr(
   24459     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   24460   VIXL_ASSERT(AllowAssembler());
   24461   CheckIT(cond);
   24462   if (IsUsingT32()) {
   24463     // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
   24464     if (dt1.Is(F32) && dt2.Is(F32)) {
   24465       EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24466       AdvanceIT();
   24467       return;
   24468     }
   24469   } else {
   24470     // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
   24471     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
   24472       EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   24473               rm.Encode(5, 0));
   24474       return;
   24475     }
   24476   }
   24477   Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
   24478 }
   24479 
   24480 void Assembler::vrintr(
   24481     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   24482   VIXL_ASSERT(AllowAssembler());
   24483   CheckIT(cond);
   24484   if (IsUsingT32()) {
   24485     // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
   24486     if (dt1.Is(F64) && dt2.Is(F64)) {
   24487       EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24488       AdvanceIT();
   24489       return;
   24490     }
   24491   } else {
   24492     // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
   24493     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
   24494       EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   24495               rm.Encode(5, 0));
   24496       return;
   24497     }
   24498   }
   24499   Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
   24500 }
   24501 
   24502 void Assembler::vrintx(
   24503     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   24504   VIXL_ASSERT(AllowAssembler());
   24505   CheckIT(cond);
   24506   if (IsUsingT32()) {
   24507     // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; T1
   24508     if (dt1.Is(F32) && dt2.Is(F32)) {
   24509       EmitT32_32(0xffba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24510       AdvanceIT();
   24511       return;
   24512     }
   24513     // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
   24514     if (dt1.Is(F64) && dt2.Is(F64)) {
   24515       EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24516       AdvanceIT();
   24517       return;
   24518     }
   24519   } else {
   24520     // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; A1
   24521     if (dt1.Is(F32) && dt2.Is(F32)) {
   24522       EmitA32(0xf3ba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24523       return;
   24524     }
   24525     // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
   24526     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
   24527       EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   24528               rm.Encode(5, 0));
   24529       return;
   24530     }
   24531   }
   24532   Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
   24533 }
   24534 
   24535 void Assembler::vrintx(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   24536   VIXL_ASSERT(AllowAssembler());
   24537   CheckIT(al);
   24538   if (IsUsingT32()) {
   24539     // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; T1
   24540     if (dt1.Is(F32) && dt2.Is(F32)) {
   24541       EmitT32_32(0xffba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24542       AdvanceIT();
   24543       return;
   24544     }
   24545   } else {
   24546     // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; A1
   24547     if (dt1.Is(F32) && dt2.Is(F32)) {
   24548       EmitA32(0xf3ba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24549       return;
   24550     }
   24551   }
   24552   Delegate(kVrintx, &Assembler::vrintx, dt1, dt2, rd, rm);
   24553 }
   24554 
   24555 void Assembler::vrintx(
   24556     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   24557   VIXL_ASSERT(AllowAssembler());
   24558   CheckIT(cond);
   24559   if (IsUsingT32()) {
   24560     // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
   24561     if (dt1.Is(F32) && dt2.Is(F32)) {
   24562       EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24563       AdvanceIT();
   24564       return;
   24565     }
   24566   } else {
   24567     // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
   24568     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
   24569       EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   24570               rm.Encode(5, 0));
   24571       return;
   24572     }
   24573   }
   24574   Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
   24575 }
   24576 
   24577 void Assembler::vrintz(
   24578     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
   24579   VIXL_ASSERT(AllowAssembler());
   24580   CheckIT(cond);
   24581   if (IsUsingT32()) {
   24582     // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; T1
   24583     if (dt1.Is(F32) && dt2.Is(F32)) {
   24584       EmitT32_32(0xffba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24585       AdvanceIT();
   24586       return;
   24587     }
   24588     // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
   24589     if (dt1.Is(F64) && dt2.Is(F64)) {
   24590       EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24591       AdvanceIT();
   24592       return;
   24593     }
   24594   } else {
   24595     // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; A1
   24596     if (dt1.Is(F32) && dt2.Is(F32)) {
   24597       EmitA32(0xf3ba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24598       return;
   24599     }
   24600     // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
   24601     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
   24602       EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   24603               rm.Encode(5, 0));
   24604       return;
   24605     }
   24606   }
   24607   Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
   24608 }
   24609 
   24610 void Assembler::vrintz(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
   24611   VIXL_ASSERT(AllowAssembler());
   24612   CheckIT(al);
   24613   if (IsUsingT32()) {
   24614     // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; T1
   24615     if (dt1.Is(F32) && dt2.Is(F32)) {
   24616       EmitT32_32(0xffba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24617       AdvanceIT();
   24618       return;
   24619     }
   24620   } else {
   24621     // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; A1
   24622     if (dt1.Is(F32) && dt2.Is(F32)) {
   24623       EmitA32(0xf3ba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24624       return;
   24625     }
   24626   }
   24627   Delegate(kVrintz, &Assembler::vrintz, dt1, dt2, rd, rm);
   24628 }
   24629 
   24630 void Assembler::vrintz(
   24631     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
   24632   VIXL_ASSERT(AllowAssembler());
   24633   CheckIT(cond);
   24634   if (IsUsingT32()) {
   24635     // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
   24636     if (dt1.Is(F32) && dt2.Is(F32)) {
   24637       EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   24638       AdvanceIT();
   24639       return;
   24640     }
   24641   } else {
   24642     // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
   24643     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
   24644       EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   24645               rm.Encode(5, 0));
   24646       return;
   24647     }
   24648   }
   24649   Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
   24650 }
   24651 
   24652 void Assembler::vrshl(
   24653     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
   24654   VIXL_ASSERT(AllowAssembler());
   24655   CheckIT(cond);
   24656   Dt_U_size_3 encoded_dt(dt);
   24657   if (IsUsingT32()) {
   24658     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
   24659     if (encoded_dt.IsValid()) {
   24660       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24661         EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24662                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   24663                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   24664         AdvanceIT();
   24665         return;
   24666       }
   24667     }
   24668   } else {
   24669     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
   24670     if (encoded_dt.IsValid()) {
   24671       if (cond.Is(al)) {
   24672         EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24673                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   24674                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   24675         return;
   24676       }
   24677     }
   24678   }
   24679   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
   24680 }
   24681 
   24682 void Assembler::vrshl(
   24683     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
   24684   VIXL_ASSERT(AllowAssembler());
   24685   CheckIT(cond);
   24686   Dt_U_size_3 encoded_dt(dt);
   24687   if (IsUsingT32()) {
   24688     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
   24689     if (encoded_dt.IsValid()) {
   24690       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24691         EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24692                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   24693                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   24694         AdvanceIT();
   24695         return;
   24696       }
   24697     }
   24698   } else {
   24699     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
   24700     if (encoded_dt.IsValid()) {
   24701       if (cond.Is(al)) {
   24702         EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   24703                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   24704                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   24705         return;
   24706       }
   24707     }
   24708   }
   24709   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
   24710 }
   24711 
   24712 void Assembler::vrshr(Condition cond,
   24713                       DataType dt,
   24714                       DRegister rd,
   24715                       DRegister rm,
   24716                       const DOperand& operand) {
   24717   VIXL_ASSERT(AllowAssembler());
   24718   CheckIT(cond);
   24719   if (operand.IsImmediate()) {
   24720     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24721       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24722       Dt_L_imm6_1 encoded_dt(dt);
   24723       if (IsUsingT32()) {
   24724         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   24725         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24726           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24727             uint32_t imm6 = dt.GetSize() - imm;
   24728             EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
   24729                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24730                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24731                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24732             AdvanceIT();
   24733             return;
   24734           }
   24735         }
   24736         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
   24737         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   24738           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24739             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   24740                        rm.Encode(5, 0));
   24741             AdvanceIT();
   24742             return;
   24743           }
   24744         }
   24745       } else {
   24746         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   24747         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24748           if (cond.Is(al)) {
   24749             uint32_t imm6 = dt.GetSize() - imm;
   24750             EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
   24751                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24752                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24753                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24754             return;
   24755           }
   24756         }
   24757         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
   24758         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   24759           if (cond.Is(al)) {
   24760             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   24761                     rm.Encode(5, 0));
   24762             return;
   24763           }
   24764         }
   24765       }
   24766     }
   24767   }
   24768   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
   24769 }
   24770 
   24771 void Assembler::vrshr(Condition cond,
   24772                       DataType dt,
   24773                       QRegister rd,
   24774                       QRegister rm,
   24775                       const QOperand& operand) {
   24776   VIXL_ASSERT(AllowAssembler());
   24777   CheckIT(cond);
   24778   if (operand.IsImmediate()) {
   24779     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24780       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24781       Dt_L_imm6_1 encoded_dt(dt);
   24782       if (IsUsingT32()) {
   24783         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   24784         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24785           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24786             uint32_t imm6 = dt.GetSize() - imm;
   24787             EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
   24788                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24789                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24790                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24791             AdvanceIT();
   24792             return;
   24793           }
   24794         }
   24795         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
   24796         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   24797           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24798             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   24799                        rm.Encode(5, 0));
   24800             AdvanceIT();
   24801             return;
   24802           }
   24803         }
   24804       } else {
   24805         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   24806         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   24807           if (cond.Is(al)) {
   24808             uint32_t imm6 = dt.GetSize() - imm;
   24809             EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
   24810                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24811                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   24812                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24813             return;
   24814           }
   24815         }
   24816         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
   24817         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   24818           if (cond.Is(al)) {
   24819             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   24820                     rm.Encode(5, 0));
   24821             return;
   24822           }
   24823         }
   24824       }
   24825     }
   24826   }
   24827   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
   24828 }
   24829 
   24830 void Assembler::vrshrn(Condition cond,
   24831                        DataType dt,
   24832                        DRegister rd,
   24833                        QRegister rm,
   24834                        const QOperand& operand) {
   24835   VIXL_ASSERT(AllowAssembler());
   24836   CheckIT(cond);
   24837   if (operand.IsImmediate()) {
   24838     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   24839       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   24840       Dt_imm6_3 encoded_dt(dt);
   24841       Dt_size_3 encoded_dt_2(dt);
   24842       if (IsUsingT32()) {
   24843         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
   24844         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   24845           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24846             uint32_t imm6 = dt.GetSize() / 2 - imm;
   24847             EmitT32_32(0xef800850U |
   24848                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24849                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24850             AdvanceIT();
   24851             return;
   24852           }
   24853         }
   24854         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   24855         if (encoded_dt_2.IsValid() && (imm == 0)) {
   24856           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24857             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
   24858                        rd.Encode(22, 12) | rm.Encode(5, 0));
   24859             AdvanceIT();
   24860             return;
   24861           }
   24862         }
   24863       } else {
   24864         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
   24865         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   24866           if (cond.Is(al)) {
   24867             uint32_t imm6 = dt.GetSize() / 2 - imm;
   24868             EmitA32(0xf2800850U |
   24869                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   24870                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   24871             return;
   24872           }
   24873         }
   24874         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   24875         if (encoded_dt_2.IsValid() && (imm == 0)) {
   24876           if (cond.Is(al)) {
   24877             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
   24878                     rd.Encode(22, 12) | rm.Encode(5, 0));
   24879             return;
   24880           }
   24881         }
   24882       }
   24883     }
   24884   }
   24885   Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
   24886 }
   24887 
   24888 void Assembler::vrsqrte(Condition cond,
   24889                         DataType dt,
   24890                         DRegister rd,
   24891                         DRegister rm) {
   24892   VIXL_ASSERT(AllowAssembler());
   24893   CheckIT(cond);
   24894   Dt_F_size_4 encoded_dt(dt);
   24895   if (IsUsingT32()) {
   24896     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   24897     if (encoded_dt.IsValid()) {
   24898       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24899         EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   24900                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   24901                    rd.Encode(22, 12) | rm.Encode(5, 0));
   24902         AdvanceIT();
   24903         return;
   24904       }
   24905     }
   24906   } else {
   24907     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   24908     if (encoded_dt.IsValid()) {
   24909       if (cond.Is(al)) {
   24910         EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   24911                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   24912                 rd.Encode(22, 12) | rm.Encode(5, 0));
   24913         return;
   24914       }
   24915     }
   24916   }
   24917   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
   24918 }
   24919 
   24920 void Assembler::vrsqrte(Condition cond,
   24921                         DataType dt,
   24922                         QRegister rd,
   24923                         QRegister rm) {
   24924   VIXL_ASSERT(AllowAssembler());
   24925   CheckIT(cond);
   24926   Dt_F_size_4 encoded_dt(dt);
   24927   if (IsUsingT32()) {
   24928     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   24929     if (encoded_dt.IsValid()) {
   24930       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24931         EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   24932                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   24933                    rd.Encode(22, 12) | rm.Encode(5, 0));
   24934         AdvanceIT();
   24935         return;
   24936       }
   24937     }
   24938   } else {
   24939     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   24940     if (encoded_dt.IsValid()) {
   24941       if (cond.Is(al)) {
   24942         EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
   24943                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
   24944                 rd.Encode(22, 12) | rm.Encode(5, 0));
   24945         return;
   24946       }
   24947     }
   24948   }
   24949   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
   24950 }
   24951 
   24952 void Assembler::vrsqrts(
   24953     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   24954   VIXL_ASSERT(AllowAssembler());
   24955   CheckIT(cond);
   24956   if (IsUsingT32()) {
   24957     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   24958     if (dt.Is(F32)) {
   24959       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24960         EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   24961                    rm.Encode(5, 0));
   24962         AdvanceIT();
   24963         return;
   24964       }
   24965     }
   24966   } else {
   24967     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   24968     if (dt.Is(F32)) {
   24969       if (cond.Is(al)) {
   24970         EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   24971                 rm.Encode(5, 0));
   24972         return;
   24973       }
   24974     }
   24975   }
   24976   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
   24977 }
   24978 
   24979 void Assembler::vrsqrts(
   24980     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   24981   VIXL_ASSERT(AllowAssembler());
   24982   CheckIT(cond);
   24983   if (IsUsingT32()) {
   24984     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   24985     if (dt.Is(F32)) {
   24986       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   24987         EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   24988                    rm.Encode(5, 0));
   24989         AdvanceIT();
   24990         return;
   24991       }
   24992     }
   24993   } else {
   24994     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   24995     if (dt.Is(F32)) {
   24996       if (cond.Is(al)) {
   24997         EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   24998                 rm.Encode(5, 0));
   24999         return;
   25000       }
   25001     }
   25002   }
   25003   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
   25004 }
   25005 
   25006 void Assembler::vrsra(Condition cond,
   25007                       DataType dt,
   25008                       DRegister rd,
   25009                       DRegister rm,
   25010                       const DOperand& operand) {
   25011   VIXL_ASSERT(AllowAssembler());
   25012   CheckIT(cond);
   25013   if (operand.IsImmediate()) {
   25014     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25015       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25016       Dt_L_imm6_1 encoded_dt(dt);
   25017       if (IsUsingT32()) {
   25018         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   25019         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25020           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25021             uint32_t imm6 = dt.GetSize() - imm;
   25022             EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
   25023                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25024                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25025                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25026             AdvanceIT();
   25027             return;
   25028           }
   25029         }
   25030       } else {
   25031         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   25032         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25033           if (cond.Is(al)) {
   25034             uint32_t imm6 = dt.GetSize() - imm;
   25035             EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
   25036                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25037                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25038                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25039             return;
   25040           }
   25041         }
   25042       }
   25043     }
   25044   }
   25045   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
   25046 }
   25047 
   25048 void Assembler::vrsra(Condition cond,
   25049                       DataType dt,
   25050                       QRegister rd,
   25051                       QRegister rm,
   25052                       const QOperand& operand) {
   25053   VIXL_ASSERT(AllowAssembler());
   25054   CheckIT(cond);
   25055   if (operand.IsImmediate()) {
   25056     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25057       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25058       Dt_L_imm6_1 encoded_dt(dt);
   25059       if (IsUsingT32()) {
   25060         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   25061         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25062           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25063             uint32_t imm6 = dt.GetSize() - imm;
   25064             EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
   25065                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25066                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25067                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25068             AdvanceIT();
   25069             return;
   25070           }
   25071         }
   25072       } else {
   25073         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   25074         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25075           if (cond.Is(al)) {
   25076             uint32_t imm6 = dt.GetSize() - imm;
   25077             EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
   25078                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25079                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25080                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25081             return;
   25082           }
   25083         }
   25084       }
   25085     }
   25086   }
   25087   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
   25088 }
   25089 
   25090 void Assembler::vrsubhn(
   25091     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
   25092   VIXL_ASSERT(AllowAssembler());
   25093   CheckIT(cond);
   25094   Dt_size_3 encoded_dt(dt);
   25095   if (IsUsingT32()) {
   25096     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
   25097     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   25098       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25099         EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
   25100                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   25101         AdvanceIT();
   25102         return;
   25103       }
   25104     }
   25105   } else {
   25106     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
   25107     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   25108       if (cond.Is(al)) {
   25109         EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
   25110                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   25111         return;
   25112       }
   25113     }
   25114   }
   25115   Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
   25116 }
   25117 
   25118 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   25119   VIXL_ASSERT(AllowAssembler());
   25120   CheckIT(al);
   25121   if (IsUsingT32()) {
   25122     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
   25123     if (OutsideITBlock() && dt.Is(F64)) {
   25124       EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25125                  rm.Encode(5, 0));
   25126       AdvanceIT();
   25127       return;
   25128     }
   25129   } else {
   25130     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
   25131     if (dt.Is(F64)) {
   25132       EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25133               rm.Encode(5, 0));
   25134       return;
   25135     }
   25136   }
   25137   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
   25138 }
   25139 
   25140 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   25141   VIXL_ASSERT(AllowAssembler());
   25142   CheckIT(al);
   25143   if (IsUsingT32()) {
   25144     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
   25145     if (OutsideITBlock() && dt.Is(F32)) {
   25146       EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25147                  rm.Encode(5, 0));
   25148       AdvanceIT();
   25149       return;
   25150     }
   25151   } else {
   25152     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
   25153     if (dt.Is(F32)) {
   25154       EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25155               rm.Encode(5, 0));
   25156       return;
   25157     }
   25158   }
   25159   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
   25160 }
   25161 
   25162 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   25163   VIXL_ASSERT(AllowAssembler());
   25164   CheckIT(al);
   25165   if (IsUsingT32()) {
   25166     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
   25167     if (OutsideITBlock() && dt.Is(F64)) {
   25168       EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25169                  rm.Encode(5, 0));
   25170       AdvanceIT();
   25171       return;
   25172     }
   25173   } else {
   25174     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
   25175     if (dt.Is(F64)) {
   25176       EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25177               rm.Encode(5, 0));
   25178       return;
   25179     }
   25180   }
   25181   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
   25182 }
   25183 
   25184 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   25185   VIXL_ASSERT(AllowAssembler());
   25186   CheckIT(al);
   25187   if (IsUsingT32()) {
   25188     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
   25189     if (OutsideITBlock() && dt.Is(F32)) {
   25190       EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25191                  rm.Encode(5, 0));
   25192       AdvanceIT();
   25193       return;
   25194     }
   25195   } else {
   25196     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
   25197     if (dt.Is(F32)) {
   25198       EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25199               rm.Encode(5, 0));
   25200       return;
   25201     }
   25202   }
   25203   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
   25204 }
   25205 
   25206 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   25207   VIXL_ASSERT(AllowAssembler());
   25208   CheckIT(al);
   25209   if (IsUsingT32()) {
   25210     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
   25211     if (OutsideITBlock() && dt.Is(F64)) {
   25212       EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25213                  rm.Encode(5, 0));
   25214       AdvanceIT();
   25215       return;
   25216     }
   25217   } else {
   25218     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
   25219     if (dt.Is(F64)) {
   25220       EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25221               rm.Encode(5, 0));
   25222       return;
   25223     }
   25224   }
   25225   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
   25226 }
   25227 
   25228 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   25229   VIXL_ASSERT(AllowAssembler());
   25230   CheckIT(al);
   25231   if (IsUsingT32()) {
   25232     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
   25233     if (OutsideITBlock() && dt.Is(F32)) {
   25234       EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25235                  rm.Encode(5, 0));
   25236       AdvanceIT();
   25237       return;
   25238     }
   25239   } else {
   25240     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
   25241     if (dt.Is(F32)) {
   25242       EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25243               rm.Encode(5, 0));
   25244       return;
   25245     }
   25246   }
   25247   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
   25248 }
   25249 
   25250 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   25251   VIXL_ASSERT(AllowAssembler());
   25252   CheckIT(al);
   25253   if (IsUsingT32()) {
   25254     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
   25255     if (OutsideITBlock() && dt.Is(F64)) {
   25256       EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25257                  rm.Encode(5, 0));
   25258       AdvanceIT();
   25259       return;
   25260     }
   25261   } else {
   25262     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
   25263     if (dt.Is(F64)) {
   25264       EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25265               rm.Encode(5, 0));
   25266       return;
   25267     }
   25268   }
   25269   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
   25270 }
   25271 
   25272 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   25273   VIXL_ASSERT(AllowAssembler());
   25274   CheckIT(al);
   25275   if (IsUsingT32()) {
   25276     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
   25277     if (OutsideITBlock() && dt.Is(F32)) {
   25278       EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25279                  rm.Encode(5, 0));
   25280       AdvanceIT();
   25281       return;
   25282     }
   25283   } else {
   25284     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
   25285     if (dt.Is(F32)) {
   25286       EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   25287               rm.Encode(5, 0));
   25288       return;
   25289     }
   25290   }
   25291   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
   25292 }
   25293 
   25294 void Assembler::vshl(Condition cond,
   25295                      DataType dt,
   25296                      DRegister rd,
   25297                      DRegister rm,
   25298                      const DOperand& operand) {
   25299   VIXL_ASSERT(AllowAssembler());
   25300   CheckIT(cond);
   25301   if (operand.IsImmediate()) {
   25302     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25303       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25304       Dt_L_imm6_3 encoded_dt(dt);
   25305       if (IsUsingT32()) {
   25306         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
   25307         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   25308           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25309             uint32_t imm6 = imm;
   25310             EmitT32_32(0xef800510U |
   25311                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25312                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25313                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25314             AdvanceIT();
   25315             return;
   25316           }
   25317         }
   25318       } else {
   25319         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
   25320         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   25321           if (cond.Is(al)) {
   25322             uint32_t imm6 = imm;
   25323             EmitA32(0xf2800510U |
   25324                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25325                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25326                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25327             return;
   25328           }
   25329         }
   25330       }
   25331     }
   25332   }
   25333   if (operand.IsRegister()) {
   25334     DRegister rn = operand.GetRegister();
   25335     Dt_U_size_3 encoded_dt(dt);
   25336     if (IsUsingT32()) {
   25337       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
   25338       if (encoded_dt.IsValid()) {
   25339         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25340           EmitT32_32(0xef000400U |
   25341                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   25342                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   25343                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   25344           AdvanceIT();
   25345           return;
   25346         }
   25347       }
   25348     } else {
   25349       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
   25350       if (encoded_dt.IsValid()) {
   25351         if (cond.Is(al)) {
   25352           EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   25353                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   25354                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   25355           return;
   25356         }
   25357       }
   25358     }
   25359   }
   25360   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
   25361 }
   25362 
   25363 void Assembler::vshl(Condition cond,
   25364                      DataType dt,
   25365                      QRegister rd,
   25366                      QRegister rm,
   25367                      const QOperand& operand) {
   25368   VIXL_ASSERT(AllowAssembler());
   25369   CheckIT(cond);
   25370   if (operand.IsImmediate()) {
   25371     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25372       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25373       Dt_L_imm6_3 encoded_dt(dt);
   25374       if (IsUsingT32()) {
   25375         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
   25376         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   25377           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25378             uint32_t imm6 = imm;
   25379             EmitT32_32(0xef800550U |
   25380                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25381                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25382                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25383             AdvanceIT();
   25384             return;
   25385           }
   25386         }
   25387       } else {
   25388         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
   25389         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   25390           if (cond.Is(al)) {
   25391             uint32_t imm6 = imm;
   25392             EmitA32(0xf2800550U |
   25393                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25394                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25395                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25396             return;
   25397           }
   25398         }
   25399       }
   25400     }
   25401   }
   25402   if (operand.IsRegister()) {
   25403     QRegister rn = operand.GetRegister();
   25404     Dt_U_size_3 encoded_dt(dt);
   25405     if (IsUsingT32()) {
   25406       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
   25407       if (encoded_dt.IsValid()) {
   25408         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25409           EmitT32_32(0xef000440U |
   25410                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   25411                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   25412                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   25413           AdvanceIT();
   25414           return;
   25415         }
   25416       }
   25417     } else {
   25418       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
   25419       if (encoded_dt.IsValid()) {
   25420         if (cond.Is(al)) {
   25421           EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   25422                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   25423                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
   25424           return;
   25425         }
   25426       }
   25427     }
   25428   }
   25429   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
   25430 }
   25431 
   25432 void Assembler::vshll(Condition cond,
   25433                       DataType dt,
   25434                       QRegister rd,
   25435                       DRegister rm,
   25436                       const DOperand& operand) {
   25437   VIXL_ASSERT(AllowAssembler());
   25438   CheckIT(cond);
   25439   if (operand.IsImmediate()) {
   25440     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25441       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25442       Dt_imm6_4 encoded_dt(dt);
   25443       Dt_size_16 encoded_dt_2(dt);
   25444       if (IsUsingT32()) {
   25445         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
   25446         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
   25447           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25448             uint32_t imm6 = dt.GetSize() + imm;
   25449             EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
   25450                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25451                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25452             AdvanceIT();
   25453             return;
   25454           }
   25455         }
   25456         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
   25457         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
   25458           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25459             EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
   25460                        rd.Encode(22, 12) | rm.Encode(5, 0));
   25461             AdvanceIT();
   25462             return;
   25463           }
   25464         }
   25465       } else {
   25466         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
   25467         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
   25468           if (cond.Is(al)) {
   25469             uint32_t imm6 = dt.GetSize() + imm;
   25470             EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
   25471                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25472                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25473             return;
   25474           }
   25475         }
   25476         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
   25477         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
   25478           if (cond.Is(al)) {
   25479             EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
   25480                     rd.Encode(22, 12) | rm.Encode(5, 0));
   25481             return;
   25482           }
   25483         }
   25484       }
   25485     }
   25486   }
   25487   Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
   25488 }
   25489 
   25490 void Assembler::vshr(Condition cond,
   25491                      DataType dt,
   25492                      DRegister rd,
   25493                      DRegister rm,
   25494                      const DOperand& operand) {
   25495   VIXL_ASSERT(AllowAssembler());
   25496   CheckIT(cond);
   25497   if (operand.IsImmediate()) {
   25498     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25499       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25500       Dt_L_imm6_1 encoded_dt(dt);
   25501       if (IsUsingT32()) {
   25502         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   25503         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25504           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25505             uint32_t imm6 = dt.GetSize() - imm;
   25506             EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
   25507                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25508                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25509                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25510             AdvanceIT();
   25511             return;
   25512           }
   25513         }
   25514         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
   25515         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   25516           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25517             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   25518                        rm.Encode(5, 0));
   25519             AdvanceIT();
   25520             return;
   25521           }
   25522         }
   25523       } else {
   25524         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   25525         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25526           if (cond.Is(al)) {
   25527             uint32_t imm6 = dt.GetSize() - imm;
   25528             EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
   25529                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25530                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25531                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25532             return;
   25533           }
   25534         }
   25535         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
   25536         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   25537           if (cond.Is(al)) {
   25538             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   25539                     rm.Encode(5, 0));
   25540             return;
   25541           }
   25542         }
   25543       }
   25544     }
   25545   }
   25546   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
   25547 }
   25548 
   25549 void Assembler::vshr(Condition cond,
   25550                      DataType dt,
   25551                      QRegister rd,
   25552                      QRegister rm,
   25553                      const QOperand& operand) {
   25554   VIXL_ASSERT(AllowAssembler());
   25555   CheckIT(cond);
   25556   if (operand.IsImmediate()) {
   25557     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25558       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25559       Dt_L_imm6_1 encoded_dt(dt);
   25560       if (IsUsingT32()) {
   25561         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   25562         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25563           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25564             uint32_t imm6 = dt.GetSize() - imm;
   25565             EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
   25566                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25567                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25568                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25569             AdvanceIT();
   25570             return;
   25571           }
   25572         }
   25573         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
   25574         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   25575           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25576             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   25577                        rm.Encode(5, 0));
   25578             AdvanceIT();
   25579             return;
   25580           }
   25581         }
   25582       } else {
   25583         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   25584         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25585           if (cond.Is(al)) {
   25586             uint32_t imm6 = dt.GetSize() - imm;
   25587             EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
   25588                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25589                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25590                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25591             return;
   25592           }
   25593         }
   25594         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
   25595         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
   25596           if (cond.Is(al)) {
   25597             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
   25598                     rm.Encode(5, 0));
   25599             return;
   25600           }
   25601         }
   25602       }
   25603     }
   25604   }
   25605   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
   25606 }
   25607 
   25608 void Assembler::vshrn(Condition cond,
   25609                       DataType dt,
   25610                       DRegister rd,
   25611                       QRegister rm,
   25612                       const QOperand& operand) {
   25613   VIXL_ASSERT(AllowAssembler());
   25614   CheckIT(cond);
   25615   if (operand.IsImmediate()) {
   25616     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25617       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25618       Dt_imm6_3 encoded_dt(dt);
   25619       Dt_size_3 encoded_dt_2(dt);
   25620       if (IsUsingT32()) {
   25621         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
   25622         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   25623           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25624             uint32_t imm6 = dt.GetSize() / 2 - imm;
   25625             EmitT32_32(0xef800810U |
   25626                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25627                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25628             AdvanceIT();
   25629             return;
   25630           }
   25631         }
   25632         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
   25633         if (encoded_dt_2.IsValid() && (imm == 0)) {
   25634           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25635             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
   25636                        rd.Encode(22, 12) | rm.Encode(5, 0));
   25637             AdvanceIT();
   25638             return;
   25639           }
   25640         }
   25641       } else {
   25642         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
   25643         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
   25644           if (cond.Is(al)) {
   25645             uint32_t imm6 = dt.GetSize() / 2 - imm;
   25646             EmitA32(0xf2800810U |
   25647                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25648                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25649             return;
   25650           }
   25651         }
   25652         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
   25653         if (encoded_dt_2.IsValid() && (imm == 0)) {
   25654           if (cond.Is(al)) {
   25655             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
   25656                     rd.Encode(22, 12) | rm.Encode(5, 0));
   25657             return;
   25658           }
   25659         }
   25660       }
   25661     }
   25662   }
   25663   Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
   25664 }
   25665 
   25666 void Assembler::vsli(Condition cond,
   25667                      DataType dt,
   25668                      DRegister rd,
   25669                      DRegister rm,
   25670                      const DOperand& operand) {
   25671   VIXL_ASSERT(AllowAssembler());
   25672   CheckIT(cond);
   25673   if (operand.IsImmediate()) {
   25674     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25675       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25676       Dt_L_imm6_4 encoded_dt(dt);
   25677       if (IsUsingT32()) {
   25678         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
   25679         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   25680           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25681             uint32_t imm6 = imm;
   25682             EmitT32_32(0xff800510U |
   25683                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25684                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25685                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25686             AdvanceIT();
   25687             return;
   25688           }
   25689         }
   25690       } else {
   25691         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
   25692         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   25693           if (cond.Is(al)) {
   25694             uint32_t imm6 = imm;
   25695             EmitA32(0xf3800510U |
   25696                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25697                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25698                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25699             return;
   25700           }
   25701         }
   25702       }
   25703     }
   25704   }
   25705   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
   25706 }
   25707 
   25708 void Assembler::vsli(Condition cond,
   25709                      DataType dt,
   25710                      QRegister rd,
   25711                      QRegister rm,
   25712                      const QOperand& operand) {
   25713   VIXL_ASSERT(AllowAssembler());
   25714   CheckIT(cond);
   25715   if (operand.IsImmediate()) {
   25716     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25717       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25718       Dt_L_imm6_4 encoded_dt(dt);
   25719       if (IsUsingT32()) {
   25720         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
   25721         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   25722           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25723             uint32_t imm6 = imm;
   25724             EmitT32_32(0xff800550U |
   25725                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25726                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25727                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25728             AdvanceIT();
   25729             return;
   25730           }
   25731         }
   25732       } else {
   25733         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
   25734         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
   25735           if (cond.Is(al)) {
   25736             uint32_t imm6 = imm;
   25737             EmitA32(0xf3800550U |
   25738                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25739                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25740                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25741             return;
   25742           }
   25743         }
   25744       }
   25745     }
   25746   }
   25747   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
   25748 }
   25749 
   25750 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
   25751   VIXL_ASSERT(AllowAssembler());
   25752   CheckIT(cond);
   25753   if (IsUsingT32()) {
   25754     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
   25755     if (dt.Is(F32)) {
   25756       EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   25757       AdvanceIT();
   25758       return;
   25759     }
   25760   } else {
   25761     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
   25762     if (dt.Is(F32) && cond.IsNotNever()) {
   25763       EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   25764               rm.Encode(5, 0));
   25765       return;
   25766     }
   25767   }
   25768   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
   25769 }
   25770 
   25771 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   25772   VIXL_ASSERT(AllowAssembler());
   25773   CheckIT(cond);
   25774   if (IsUsingT32()) {
   25775     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
   25776     if (dt.Is(F64)) {
   25777       EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
   25778       AdvanceIT();
   25779       return;
   25780     }
   25781   } else {
   25782     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
   25783     if (dt.Is(F64) && cond.IsNotNever()) {
   25784       EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   25785               rm.Encode(5, 0));
   25786       return;
   25787     }
   25788   }
   25789   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
   25790 }
   25791 
   25792 void Assembler::vsra(Condition cond,
   25793                      DataType dt,
   25794                      DRegister rd,
   25795                      DRegister rm,
   25796                      const DOperand& operand) {
   25797   VIXL_ASSERT(AllowAssembler());
   25798   CheckIT(cond);
   25799   if (operand.IsImmediate()) {
   25800     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25801       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25802       Dt_L_imm6_1 encoded_dt(dt);
   25803       if (IsUsingT32()) {
   25804         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
   25805         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25806           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25807             uint32_t imm6 = dt.GetSize() - imm;
   25808             EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
   25809                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25810                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25811                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25812             AdvanceIT();
   25813             return;
   25814           }
   25815         }
   25816       } else {
   25817         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
   25818         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25819           if (cond.Is(al)) {
   25820             uint32_t imm6 = dt.GetSize() - imm;
   25821             EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
   25822                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25823                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25824                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25825             return;
   25826           }
   25827         }
   25828       }
   25829     }
   25830   }
   25831   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
   25832 }
   25833 
   25834 void Assembler::vsra(Condition cond,
   25835                      DataType dt,
   25836                      QRegister rd,
   25837                      QRegister rm,
   25838                      const QOperand& operand) {
   25839   VIXL_ASSERT(AllowAssembler());
   25840   CheckIT(cond);
   25841   if (operand.IsImmediate()) {
   25842     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25843       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25844       Dt_L_imm6_1 encoded_dt(dt);
   25845       if (IsUsingT32()) {
   25846         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
   25847         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25848           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25849             uint32_t imm6 = dt.GetSize() - imm;
   25850             EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
   25851                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25852                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25853                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25854             AdvanceIT();
   25855             return;
   25856           }
   25857         }
   25858       } else {
   25859         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
   25860         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25861           if (cond.Is(al)) {
   25862             uint32_t imm6 = dt.GetSize() - imm;
   25863             EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
   25864                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25865                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25866                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25867             return;
   25868           }
   25869         }
   25870       }
   25871     }
   25872   }
   25873   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
   25874 }
   25875 
   25876 void Assembler::vsri(Condition cond,
   25877                      DataType dt,
   25878                      DRegister rd,
   25879                      DRegister rm,
   25880                      const DOperand& operand) {
   25881   VIXL_ASSERT(AllowAssembler());
   25882   CheckIT(cond);
   25883   if (operand.IsImmediate()) {
   25884     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25885       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25886       Dt_L_imm6_4 encoded_dt(dt);
   25887       if (IsUsingT32()) {
   25888         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
   25889         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25890           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25891             uint32_t imm6 = dt.GetSize() - imm;
   25892             EmitT32_32(0xff800410U |
   25893                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25894                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25895                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25896             AdvanceIT();
   25897             return;
   25898           }
   25899         }
   25900       } else {
   25901         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
   25902         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25903           if (cond.Is(al)) {
   25904             uint32_t imm6 = dt.GetSize() - imm;
   25905             EmitA32(0xf3800410U |
   25906                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25907                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25908                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25909             return;
   25910           }
   25911         }
   25912       }
   25913     }
   25914   }
   25915   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
   25916 }
   25917 
   25918 void Assembler::vsri(Condition cond,
   25919                      DataType dt,
   25920                      QRegister rd,
   25921                      QRegister rm,
   25922                      const QOperand& operand) {
   25923   VIXL_ASSERT(AllowAssembler());
   25924   CheckIT(cond);
   25925   if (operand.IsImmediate()) {
   25926     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
   25927       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
   25928       Dt_L_imm6_4 encoded_dt(dt);
   25929       if (IsUsingT32()) {
   25930         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
   25931         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25932           if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25933             uint32_t imm6 = dt.GetSize() - imm;
   25934             EmitT32_32(0xff800450U |
   25935                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25936                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25937                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25938             AdvanceIT();
   25939             return;
   25940           }
   25941         }
   25942       } else {
   25943         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
   25944         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
   25945           if (cond.Is(al)) {
   25946             uint32_t imm6 = dt.GetSize() - imm;
   25947             EmitA32(0xf3800450U |
   25948                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
   25949                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
   25950                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
   25951             return;
   25952           }
   25953         }
   25954       }
   25955     }
   25956   }
   25957   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
   25958 }
   25959 
   25960 void Assembler::vst1(Condition cond,
   25961                      DataType dt,
   25962                      const NeonRegisterList& nreglist,
   25963                      const AlignedMemOperand& operand) {
   25964   VIXL_ASSERT(AllowAssembler());
   25965   CheckIT(cond);
   25966   if (operand.IsImmediateZero()) {
   25967     Register rn = operand.GetBaseRegister();
   25968     Alignment align = operand.GetAlignment();
   25969     Dt_size_6 encoded_dt(dt);
   25970     Dt_size_7 encoded_dt_2(dt);
   25971     Align_align_5 encoded_align_1(align, nreglist);
   25972     Align_index_align_1 encoded_align_2(align, nreglist, dt);
   25973     if (IsUsingT32()) {
   25974       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   25975       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   25976           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   25977           operand.IsOffset() && encoded_align_1.IsValid() &&
   25978           (!rn.IsPC() || AllowUnpredictable())) {
   25979         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   25980           const DRegister& first = nreglist.GetFirstDRegister();
   25981           uint32_t len_encoding;
   25982           switch (nreglist.GetLength()) {
   25983             default:
   25984               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   25985             case 1:
   25986               len_encoding = 0x7;
   25987               break;
   25988             case 2:
   25989               len_encoding = 0xa;
   25990               break;
   25991             case 3:
   25992               len_encoding = 0x6;
   25993               break;
   25994             case 4:
   25995               len_encoding = 0x2;
   25996               break;
   25997           }
   25998           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
   25999                      (encoded_align_1.GetEncodingValue() << 4) |
   26000                      first.Encode(22, 12) | (len_encoding << 8) |
   26001                      (rn.GetCode() << 16));
   26002           AdvanceIT();
   26003           return;
   26004         }
   26005       }
   26006       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   26007       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26008           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   26009           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   26010           (!rn.IsPC() || AllowUnpredictable())) {
   26011         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26012           const DRegister& first = nreglist.GetFirstDRegister();
   26013           uint32_t len_encoding;
   26014           switch (nreglist.GetLength()) {
   26015             default:
   26016               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   26017             case 1:
   26018               len_encoding = 0x7;
   26019               break;
   26020             case 2:
   26021               len_encoding = 0xa;
   26022               break;
   26023             case 3:
   26024               len_encoding = 0x6;
   26025               break;
   26026             case 4:
   26027               len_encoding = 0x2;
   26028               break;
   26029           }
   26030           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
   26031                      (encoded_align_1.GetEncodingValue() << 4) |
   26032                      first.Encode(22, 12) | (len_encoding << 8) |
   26033                      (rn.GetCode() << 16));
   26034           AdvanceIT();
   26035           return;
   26036         }
   26037       }
   26038       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   26039       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   26040           (nreglist.GetLength() == 1) && operand.IsOffset() &&
   26041           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   26042         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26043           const DRegister& first = nreglist.GetFirstDRegister();
   26044           EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
   26045                      (encoded_align_2.GetEncodingValue() << 4) |
   26046                      first.Encode(22, 12) | (rn.GetCode() << 16));
   26047           AdvanceIT();
   26048           return;
   26049         }
   26050       }
   26051       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   26052       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   26053           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
   26054           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   26055         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26056           const DRegister& first = nreglist.GetFirstDRegister();
   26057           EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
   26058                      (encoded_align_2.GetEncodingValue() << 4) |
   26059                      first.Encode(22, 12) | (rn.GetCode() << 16));
   26060           AdvanceIT();
   26061           return;
   26062         }
   26063       }
   26064     } else {
   26065       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   26066       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26067           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   26068           operand.IsOffset() && encoded_align_1.IsValid() &&
   26069           (!rn.IsPC() || AllowUnpredictable())) {
   26070         if (cond.Is(al)) {
   26071           const DRegister& first = nreglist.GetFirstDRegister();
   26072           uint32_t len_encoding;
   26073           switch (nreglist.GetLength()) {
   26074             default:
   26075               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   26076             case 1:
   26077               len_encoding = 0x7;
   26078               break;
   26079             case 2:
   26080               len_encoding = 0xa;
   26081               break;
   26082             case 3:
   26083               len_encoding = 0x6;
   26084               break;
   26085             case 4:
   26086               len_encoding = 0x2;
   26087               break;
   26088           }
   26089           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
   26090                   (encoded_align_1.GetEncodingValue() << 4) |
   26091                   first.Encode(22, 12) | (len_encoding << 8) |
   26092                   (rn.GetCode() << 16));
   26093           return;
   26094         }
   26095       }
   26096       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   26097       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26098           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   26099           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   26100           (!rn.IsPC() || AllowUnpredictable())) {
   26101         if (cond.Is(al)) {
   26102           const DRegister& first = nreglist.GetFirstDRegister();
   26103           uint32_t len_encoding;
   26104           switch (nreglist.GetLength()) {
   26105             default:
   26106               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   26107             case 1:
   26108               len_encoding = 0x7;
   26109               break;
   26110             case 2:
   26111               len_encoding = 0xa;
   26112               break;
   26113             case 3:
   26114               len_encoding = 0x6;
   26115               break;
   26116             case 4:
   26117               len_encoding = 0x2;
   26118               break;
   26119           }
   26120           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
   26121                   (encoded_align_1.GetEncodingValue() << 4) |
   26122                   first.Encode(22, 12) | (len_encoding << 8) |
   26123                   (rn.GetCode() << 16));
   26124           return;
   26125         }
   26126       }
   26127       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   26128       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   26129           (nreglist.GetLength() == 1) && operand.IsOffset() &&
   26130           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   26131         if (cond.Is(al)) {
   26132           const DRegister& first = nreglist.GetFirstDRegister();
   26133           EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
   26134                   (encoded_align_2.GetEncodingValue() << 4) |
   26135                   first.Encode(22, 12) | (rn.GetCode() << 16));
   26136           return;
   26137         }
   26138       }
   26139       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   26140       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   26141           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
   26142           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
   26143         if (cond.Is(al)) {
   26144           const DRegister& first = nreglist.GetFirstDRegister();
   26145           EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
   26146                   (encoded_align_2.GetEncodingValue() << 4) |
   26147                   first.Encode(22, 12) | (rn.GetCode() << 16));
   26148           return;
   26149         }
   26150       }
   26151     }
   26152   }
   26153   if (operand.IsPlainRegister()) {
   26154     Register rn = operand.GetBaseRegister();
   26155     Alignment align = operand.GetAlignment();
   26156     Register rm = operand.GetOffsetRegister();
   26157     Dt_size_6 encoded_dt(dt);
   26158     Dt_size_7 encoded_dt_2(dt);
   26159     Align_align_5 encoded_align_1(align, nreglist);
   26160     Align_index_align_1 encoded_align_2(align, nreglist, dt);
   26161     if (IsUsingT32()) {
   26162       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   26163       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26164           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   26165           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26166         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26167           const DRegister& first = nreglist.GetFirstDRegister();
   26168           uint32_t len_encoding;
   26169           switch (nreglist.GetLength()) {
   26170             default:
   26171               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   26172             case 1:
   26173               len_encoding = 0x7;
   26174               break;
   26175             case 2:
   26176               len_encoding = 0xa;
   26177               break;
   26178             case 3:
   26179               len_encoding = 0x6;
   26180               break;
   26181             case 4:
   26182               len_encoding = 0x2;
   26183               break;
   26184           }
   26185           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
   26186                      (encoded_align_1.GetEncodingValue() << 4) |
   26187                      first.Encode(22, 12) | (len_encoding << 8) |
   26188                      (rn.GetCode() << 16) | rm.GetCode());
   26189           AdvanceIT();
   26190           return;
   26191         }
   26192       }
   26193       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   26194       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   26195           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
   26196           (!rn.IsPC() || AllowUnpredictable())) {
   26197         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26198           const DRegister& first = nreglist.GetFirstDRegister();
   26199           EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
   26200                      (encoded_align_2.GetEncodingValue() << 4) |
   26201                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   26202                      rm.GetCode());
   26203           AdvanceIT();
   26204           return;
   26205         }
   26206       }
   26207     } else {
   26208       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   26209       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26210           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
   26211           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26212         if (cond.Is(al)) {
   26213           const DRegister& first = nreglist.GetFirstDRegister();
   26214           uint32_t len_encoding;
   26215           switch (nreglist.GetLength()) {
   26216             default:
   26217               VIXL_UNREACHABLE_OR_FALLTHROUGH();
   26218             case 1:
   26219               len_encoding = 0x7;
   26220               break;
   26221             case 2:
   26222               len_encoding = 0xa;
   26223               break;
   26224             case 3:
   26225               len_encoding = 0x6;
   26226               break;
   26227             case 4:
   26228               len_encoding = 0x2;
   26229               break;
   26230           }
   26231           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
   26232                   (encoded_align_1.GetEncodingValue() << 4) |
   26233                   first.Encode(22, 12) | (len_encoding << 8) |
   26234                   (rn.GetCode() << 16) | rm.GetCode());
   26235           return;
   26236         }
   26237       }
   26238       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   26239       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
   26240           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
   26241           (!rn.IsPC() || AllowUnpredictable())) {
   26242         if (cond.Is(al)) {
   26243           const DRegister& first = nreglist.GetFirstDRegister();
   26244           EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
   26245                   (encoded_align_2.GetEncodingValue() << 4) |
   26246                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   26247           return;
   26248         }
   26249       }
   26250     }
   26251   }
   26252   Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
   26253 }
   26254 
   26255 void Assembler::vst2(Condition cond,
   26256                      DataType dt,
   26257                      const NeonRegisterList& nreglist,
   26258                      const AlignedMemOperand& operand) {
   26259   VIXL_ASSERT(AllowAssembler());
   26260   CheckIT(cond);
   26261   if (operand.IsImmediateZero()) {
   26262     Register rn = operand.GetBaseRegister();
   26263     Alignment align = operand.GetAlignment();
   26264     Dt_size_7 encoded_dt(dt);
   26265     Align_align_2 encoded_align_1(align, nreglist);
   26266     Align_index_align_2 encoded_align_2(align, nreglist, dt);
   26267     if (IsUsingT32()) {
   26268       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   26269       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26270           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26271            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   26272            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   26273           operand.IsOffset() && encoded_align_1.IsValid() &&
   26274           (!rn.IsPC() || AllowUnpredictable())) {
   26275         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26276           const DRegister& first = nreglist.GetFirstDRegister();
   26277           uint32_t len_encoding;
   26278           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   26279             len_encoding = 0x8;
   26280           }
   26281           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   26282             len_encoding = 0x9;
   26283           }
   26284           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   26285             len_encoding = 0x3;
   26286           }
   26287           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
   26288                      (encoded_align_1.GetEncodingValue() << 4) |
   26289                      first.Encode(22, 12) | (len_encoding << 8) |
   26290                      (rn.GetCode() << 16));
   26291           AdvanceIT();
   26292           return;
   26293         }
   26294       }
   26295       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   26296       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26297           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26298            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   26299            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   26300           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   26301           (!rn.IsPC() || AllowUnpredictable())) {
   26302         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26303           const DRegister& first = nreglist.GetFirstDRegister();
   26304           uint32_t len_encoding;
   26305           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   26306             len_encoding = 0x8;
   26307           }
   26308           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   26309             len_encoding = 0x9;
   26310           }
   26311           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   26312             len_encoding = 0x3;
   26313           }
   26314           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
   26315                      (encoded_align_1.GetEncodingValue() << 4) |
   26316                      first.Encode(22, 12) | (len_encoding << 8) |
   26317                      (rn.GetCode() << 16));
   26318           AdvanceIT();
   26319           return;
   26320         }
   26321       }
   26322       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   26323       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26324           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26325            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   26326           operand.IsOffset() && encoded_align_2.IsValid() &&
   26327           (!rn.IsPC() || AllowUnpredictable())) {
   26328         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26329           const DRegister& first = nreglist.GetFirstDRegister();
   26330           EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
   26331                      (encoded_align_2.GetEncodingValue() << 4) |
   26332                      first.Encode(22, 12) | (rn.GetCode() << 16));
   26333           AdvanceIT();
   26334           return;
   26335         }
   26336       }
   26337       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   26338       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26339           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26340            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   26341           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   26342           (!rn.IsPC() || AllowUnpredictable())) {
   26343         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26344           const DRegister& first = nreglist.GetFirstDRegister();
   26345           EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
   26346                      (encoded_align_2.GetEncodingValue() << 4) |
   26347                      first.Encode(22, 12) | (rn.GetCode() << 16));
   26348           AdvanceIT();
   26349           return;
   26350         }
   26351       }
   26352     } else {
   26353       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   26354       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26355           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26356            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   26357            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   26358           operand.IsOffset() && encoded_align_1.IsValid() &&
   26359           (!rn.IsPC() || AllowUnpredictable())) {
   26360         if (cond.Is(al)) {
   26361           const DRegister& first = nreglist.GetFirstDRegister();
   26362           uint32_t len_encoding;
   26363           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   26364             len_encoding = 0x8;
   26365           }
   26366           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   26367             len_encoding = 0x9;
   26368           }
   26369           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   26370             len_encoding = 0x3;
   26371           }
   26372           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
   26373                   (encoded_align_1.GetEncodingValue() << 4) |
   26374                   first.Encode(22, 12) | (len_encoding << 8) |
   26375                   (rn.GetCode() << 16));
   26376           return;
   26377         }
   26378       }
   26379       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   26380       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26381           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26382            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   26383            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   26384           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   26385           (!rn.IsPC() || AllowUnpredictable())) {
   26386         if (cond.Is(al)) {
   26387           const DRegister& first = nreglist.GetFirstDRegister();
   26388           uint32_t len_encoding;
   26389           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   26390             len_encoding = 0x8;
   26391           }
   26392           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   26393             len_encoding = 0x9;
   26394           }
   26395           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   26396             len_encoding = 0x3;
   26397           }
   26398           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
   26399                   (encoded_align_1.GetEncodingValue() << 4) |
   26400                   first.Encode(22, 12) | (len_encoding << 8) |
   26401                   (rn.GetCode() << 16));
   26402           return;
   26403         }
   26404       }
   26405       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   26406       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26407           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26408            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   26409           operand.IsOffset() && encoded_align_2.IsValid() &&
   26410           (!rn.IsPC() || AllowUnpredictable())) {
   26411         if (cond.Is(al)) {
   26412           const DRegister& first = nreglist.GetFirstDRegister();
   26413           EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
   26414                   (encoded_align_2.GetEncodingValue() << 4) |
   26415                   first.Encode(22, 12) | (rn.GetCode() << 16));
   26416           return;
   26417         }
   26418       }
   26419       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   26420       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26421           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26422            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   26423           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   26424           (!rn.IsPC() || AllowUnpredictable())) {
   26425         if (cond.Is(al)) {
   26426           const DRegister& first = nreglist.GetFirstDRegister();
   26427           EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
   26428                   (encoded_align_2.GetEncodingValue() << 4) |
   26429                   first.Encode(22, 12) | (rn.GetCode() << 16));
   26430           return;
   26431         }
   26432       }
   26433     }
   26434   }
   26435   if (operand.IsPlainRegister()) {
   26436     Register rn = operand.GetBaseRegister();
   26437     Alignment align = operand.GetAlignment();
   26438     Register rm = operand.GetOffsetRegister();
   26439     Dt_size_7 encoded_dt(dt);
   26440     Align_align_2 encoded_align_1(align, nreglist);
   26441     Align_index_align_2 encoded_align_2(align, nreglist, dt);
   26442     if (IsUsingT32()) {
   26443       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   26444       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26445           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26446            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   26447            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   26448           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26449         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26450           const DRegister& first = nreglist.GetFirstDRegister();
   26451           uint32_t len_encoding;
   26452           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   26453             len_encoding = 0x8;
   26454           }
   26455           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   26456             len_encoding = 0x9;
   26457           }
   26458           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   26459             len_encoding = 0x3;
   26460           }
   26461           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
   26462                      (encoded_align_1.GetEncodingValue() << 4) |
   26463                      first.Encode(22, 12) | (len_encoding << 8) |
   26464                      (rn.GetCode() << 16) | rm.GetCode());
   26465           AdvanceIT();
   26466           return;
   26467         }
   26468       }
   26469       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   26470       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26471           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26472            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   26473           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26474         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26475           const DRegister& first = nreglist.GetFirstDRegister();
   26476           EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
   26477                      (encoded_align_2.GetEncodingValue() << 4) |
   26478                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   26479                      rm.GetCode());
   26480           AdvanceIT();
   26481           return;
   26482         }
   26483       }
   26484     } else {
   26485       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   26486       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26487           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26488            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
   26489            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
   26490           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26491         if (cond.Is(al)) {
   26492           const DRegister& first = nreglist.GetFirstDRegister();
   26493           uint32_t len_encoding;
   26494           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
   26495             len_encoding = 0x8;
   26496           }
   26497           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
   26498             len_encoding = 0x9;
   26499           }
   26500           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
   26501             len_encoding = 0x3;
   26502           }
   26503           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
   26504                   (encoded_align_1.GetEncodingValue() << 4) |
   26505                   first.Encode(22, 12) | (len_encoding << 8) |
   26506                   (rn.GetCode() << 16) | rm.GetCode());
   26507           return;
   26508         }
   26509       }
   26510       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   26511       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26512           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
   26513            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
   26514           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26515         if (cond.Is(al)) {
   26516           const DRegister& first = nreglist.GetFirstDRegister();
   26517           EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
   26518                   (encoded_align_2.GetEncodingValue() << 4) |
   26519                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   26520           return;
   26521         }
   26522       }
   26523     }
   26524   }
   26525   Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
   26526 }
   26527 
   26528 void Assembler::vst3(Condition cond,
   26529                      DataType dt,
   26530                      const NeonRegisterList& nreglist,
   26531                      const AlignedMemOperand& operand) {
   26532   VIXL_ASSERT(AllowAssembler());
   26533   CheckIT(cond);
   26534   if (operand.IsImmediateZero()) {
   26535     Register rn = operand.GetBaseRegister();
   26536     Alignment align = operand.GetAlignment();
   26537     Dt_size_7 encoded_dt(dt);
   26538     Align_align_3 encoded_align_1(align);
   26539     if (IsUsingT32()) {
   26540       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   26541       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26542           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26543            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26544           operand.IsOffset() && encoded_align_1.IsValid() &&
   26545           (!rn.IsPC() || AllowUnpredictable())) {
   26546         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26547           const DRegister& first = nreglist.GetFirstDRegister();
   26548           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   26549           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
   26550                      (encoded_align_1.GetEncodingValue() << 4) |
   26551                      first.Encode(22, 12) | (len_encoding << 8) |
   26552                      (rn.GetCode() << 16));
   26553           AdvanceIT();
   26554           return;
   26555         }
   26556       }
   26557       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   26558       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26559           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26560            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26561           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   26562           (!rn.IsPC() || AllowUnpredictable())) {
   26563         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26564           const DRegister& first = nreglist.GetFirstDRegister();
   26565           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   26566           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
   26567                      (encoded_align_1.GetEncodingValue() << 4) |
   26568                      first.Encode(22, 12) | (len_encoding << 8) |
   26569                      (rn.GetCode() << 16));
   26570           AdvanceIT();
   26571           return;
   26572         }
   26573       }
   26574     } else {
   26575       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   26576       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26577           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26578            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26579           operand.IsOffset() && encoded_align_1.IsValid() &&
   26580           (!rn.IsPC() || AllowUnpredictable())) {
   26581         if (cond.Is(al)) {
   26582           const DRegister& first = nreglist.GetFirstDRegister();
   26583           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   26584           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
   26585                   (encoded_align_1.GetEncodingValue() << 4) |
   26586                   first.Encode(22, 12) | (len_encoding << 8) |
   26587                   (rn.GetCode() << 16));
   26588           return;
   26589         }
   26590       }
   26591       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   26592       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26593           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26594            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26595           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   26596           (!rn.IsPC() || AllowUnpredictable())) {
   26597         if (cond.Is(al)) {
   26598           const DRegister& first = nreglist.GetFirstDRegister();
   26599           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   26600           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
   26601                   (encoded_align_1.GetEncodingValue() << 4) |
   26602                   first.Encode(22, 12) | (len_encoding << 8) |
   26603                   (rn.GetCode() << 16));
   26604           return;
   26605         }
   26606       }
   26607     }
   26608   }
   26609   if (operand.IsPlainRegister()) {
   26610     Register rn = operand.GetBaseRegister();
   26611     Alignment align = operand.GetAlignment();
   26612     Register rm = operand.GetOffsetRegister();
   26613     Dt_size_7 encoded_dt(dt);
   26614     Align_align_3 encoded_align_1(align);
   26615     if (IsUsingT32()) {
   26616       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   26617       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26618           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26619            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26620           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26621         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26622           const DRegister& first = nreglist.GetFirstDRegister();
   26623           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   26624           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
   26625                      (encoded_align_1.GetEncodingValue() << 4) |
   26626                      first.Encode(22, 12) | (len_encoding << 8) |
   26627                      (rn.GetCode() << 16) | rm.GetCode());
   26628           AdvanceIT();
   26629           return;
   26630         }
   26631       }
   26632     } else {
   26633       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   26634       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26635           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26636            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26637           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26638         if (cond.Is(al)) {
   26639           const DRegister& first = nreglist.GetFirstDRegister();
   26640           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
   26641           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
   26642                   (encoded_align_1.GetEncodingValue() << 4) |
   26643                   first.Encode(22, 12) | (len_encoding << 8) |
   26644                   (rn.GetCode() << 16) | rm.GetCode());
   26645           return;
   26646         }
   26647       }
   26648     }
   26649   }
   26650   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
   26651 }
   26652 
   26653 void Assembler::vst3(Condition cond,
   26654                      DataType dt,
   26655                      const NeonRegisterList& nreglist,
   26656                      const MemOperand& operand) {
   26657   VIXL_ASSERT(AllowAssembler());
   26658   CheckIT(cond);
   26659   if (operand.IsImmediateZero()) {
   26660     Register rn = operand.GetBaseRegister();
   26661     Dt_size_7 encoded_dt(dt);
   26662     Index_1 encoded_align_1(nreglist, dt);
   26663     if (IsUsingT32()) {
   26664       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
   26665       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26666           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26667            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26668           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   26669         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26670           const DRegister& first = nreglist.GetFirstDRegister();
   26671           EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
   26672                      (encoded_align_1.GetEncodingValue() << 4) |
   26673                      first.Encode(22, 12) | (rn.GetCode() << 16));
   26674           AdvanceIT();
   26675           return;
   26676         }
   26677       }
   26678       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
   26679       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26680           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26681            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26682           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   26683         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26684           const DRegister& first = nreglist.GetFirstDRegister();
   26685           EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
   26686                      (encoded_align_1.GetEncodingValue() << 4) |
   26687                      first.Encode(22, 12) | (rn.GetCode() << 16));
   26688           AdvanceIT();
   26689           return;
   26690         }
   26691       }
   26692     } else {
   26693       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
   26694       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26695           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26696            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26697           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
   26698         if (cond.Is(al)) {
   26699           const DRegister& first = nreglist.GetFirstDRegister();
   26700           EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
   26701                   (encoded_align_1.GetEncodingValue() << 4) |
   26702                   first.Encode(22, 12) | (rn.GetCode() << 16));
   26703           return;
   26704         }
   26705       }
   26706       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
   26707       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26708           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26709            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26710           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
   26711         if (cond.Is(al)) {
   26712           const DRegister& first = nreglist.GetFirstDRegister();
   26713           EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
   26714                   (encoded_align_1.GetEncodingValue() << 4) |
   26715                   first.Encode(22, 12) | (rn.GetCode() << 16));
   26716           return;
   26717         }
   26718       }
   26719     }
   26720   }
   26721   if (operand.IsPlainRegister()) {
   26722     Register rn = operand.GetBaseRegister();
   26723     Sign sign = operand.GetSign();
   26724     Register rm = operand.GetOffsetRegister();
   26725     Dt_size_7 encoded_dt(dt);
   26726     Index_1 encoded_align_1(nreglist, dt);
   26727     if (IsUsingT32()) {
   26728       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
   26729       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26730           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26731            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26732           sign.IsPlus() && operand.IsPostIndex() &&
   26733           (!rn.IsPC() || AllowUnpredictable())) {
   26734         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26735           const DRegister& first = nreglist.GetFirstDRegister();
   26736           EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
   26737                      (encoded_align_1.GetEncodingValue() << 4) |
   26738                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   26739                      rm.GetCode());
   26740           AdvanceIT();
   26741           return;
   26742         }
   26743       }
   26744     } else {
   26745       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
   26746       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26747           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
   26748            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
   26749           sign.IsPlus() && operand.IsPostIndex() &&
   26750           (!rn.IsPC() || AllowUnpredictable())) {
   26751         if (cond.Is(al)) {
   26752           const DRegister& first = nreglist.GetFirstDRegister();
   26753           EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
   26754                   (encoded_align_1.GetEncodingValue() << 4) |
   26755                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   26756           return;
   26757         }
   26758       }
   26759     }
   26760   }
   26761   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
   26762 }
   26763 
   26764 void Assembler::vst4(Condition cond,
   26765                      DataType dt,
   26766                      const NeonRegisterList& nreglist,
   26767                      const AlignedMemOperand& operand) {
   26768   VIXL_ASSERT(AllowAssembler());
   26769   CheckIT(cond);
   26770   if (operand.IsImmediateZero()) {
   26771     Register rn = operand.GetBaseRegister();
   26772     Alignment align = operand.GetAlignment();
   26773     Dt_size_7 encoded_dt(dt);
   26774     Align_align_4 encoded_align_1(align);
   26775     Align_index_align_3 encoded_align_2(align, nreglist, dt);
   26776     if (IsUsingT32()) {
   26777       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   26778       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26779           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26780            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26781           operand.IsOffset() && encoded_align_1.IsValid() &&
   26782           (!rn.IsPC() || AllowUnpredictable())) {
   26783         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26784           const DRegister& first = nreglist.GetFirstDRegister();
   26785           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   26786           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
   26787                      (encoded_align_1.GetEncodingValue() << 4) |
   26788                      first.Encode(22, 12) | (len_encoding << 8) |
   26789                      (rn.GetCode() << 16));
   26790           AdvanceIT();
   26791           return;
   26792         }
   26793       }
   26794       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   26795       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26796           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26797            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26798           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   26799           (!rn.IsPC() || AllowUnpredictable())) {
   26800         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26801           const DRegister& first = nreglist.GetFirstDRegister();
   26802           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   26803           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
   26804                      (encoded_align_1.GetEncodingValue() << 4) |
   26805                      first.Encode(22, 12) | (len_encoding << 8) |
   26806                      (rn.GetCode() << 16));
   26807           AdvanceIT();
   26808           return;
   26809         }
   26810       }
   26811       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
   26812       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26813           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26814            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26815           operand.IsOffset() && encoded_align_2.IsValid() &&
   26816           (!rn.IsPC() || AllowUnpredictable())) {
   26817         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26818           const DRegister& first = nreglist.GetFirstDRegister();
   26819           EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
   26820                      (encoded_align_2.GetEncodingValue() << 4) |
   26821                      first.Encode(22, 12) | (rn.GetCode() << 16));
   26822           AdvanceIT();
   26823           return;
   26824         }
   26825       }
   26826       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
   26827       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26828           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26829            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26830           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   26831           (!rn.IsPC() || AllowUnpredictable())) {
   26832         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26833           const DRegister& first = nreglist.GetFirstDRegister();
   26834           EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
   26835                      (encoded_align_2.GetEncodingValue() << 4) |
   26836                      first.Encode(22, 12) | (rn.GetCode() << 16));
   26837           AdvanceIT();
   26838           return;
   26839         }
   26840       }
   26841     } else {
   26842       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   26843       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26844           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26845            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26846           operand.IsOffset() && encoded_align_1.IsValid() &&
   26847           (!rn.IsPC() || AllowUnpredictable())) {
   26848         if (cond.Is(al)) {
   26849           const DRegister& first = nreglist.GetFirstDRegister();
   26850           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   26851           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
   26852                   (encoded_align_1.GetEncodingValue() << 4) |
   26853                   first.Encode(22, 12) | (len_encoding << 8) |
   26854                   (rn.GetCode() << 16));
   26855           return;
   26856         }
   26857       }
   26858       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   26859       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26860           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26861            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26862           operand.IsPostIndex() && encoded_align_1.IsValid() &&
   26863           (!rn.IsPC() || AllowUnpredictable())) {
   26864         if (cond.Is(al)) {
   26865           const DRegister& first = nreglist.GetFirstDRegister();
   26866           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   26867           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
   26868                   (encoded_align_1.GetEncodingValue() << 4) |
   26869                   first.Encode(22, 12) | (len_encoding << 8) |
   26870                   (rn.GetCode() << 16));
   26871           return;
   26872         }
   26873       }
   26874       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
   26875       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26876           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26877            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26878           operand.IsOffset() && encoded_align_2.IsValid() &&
   26879           (!rn.IsPC() || AllowUnpredictable())) {
   26880         if (cond.Is(al)) {
   26881           const DRegister& first = nreglist.GetFirstDRegister();
   26882           EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
   26883                   (encoded_align_2.GetEncodingValue() << 4) |
   26884                   first.Encode(22, 12) | (rn.GetCode() << 16));
   26885           return;
   26886         }
   26887       }
   26888       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
   26889       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26890           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26891            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26892           operand.IsPostIndex() && encoded_align_2.IsValid() &&
   26893           (!rn.IsPC() || AllowUnpredictable())) {
   26894         if (cond.Is(al)) {
   26895           const DRegister& first = nreglist.GetFirstDRegister();
   26896           EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
   26897                   (encoded_align_2.GetEncodingValue() << 4) |
   26898                   first.Encode(22, 12) | (rn.GetCode() << 16));
   26899           return;
   26900         }
   26901       }
   26902     }
   26903   }
   26904   if (operand.IsPlainRegister()) {
   26905     Register rn = operand.GetBaseRegister();
   26906     Alignment align = operand.GetAlignment();
   26907     Register rm = operand.GetOffsetRegister();
   26908     Dt_size_7 encoded_dt(dt);
   26909     Align_align_4 encoded_align_1(align);
   26910     Align_index_align_3 encoded_align_2(align, nreglist, dt);
   26911     if (IsUsingT32()) {
   26912       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   26913       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26914           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26915            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26916           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26917         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26918           const DRegister& first = nreglist.GetFirstDRegister();
   26919           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   26920           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
   26921                      (encoded_align_1.GetEncodingValue() << 4) |
   26922                      first.Encode(22, 12) | (len_encoding << 8) |
   26923                      (rn.GetCode() << 16) | rm.GetCode());
   26924           AdvanceIT();
   26925           return;
   26926         }
   26927       }
   26928       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
   26929       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26930           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26931            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26932           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26933         if (cond.Is(al) || AllowStronglyDiscouraged()) {
   26934           const DRegister& first = nreglist.GetFirstDRegister();
   26935           EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
   26936                      (encoded_align_2.GetEncodingValue() << 4) |
   26937                      first.Encode(22, 12) | (rn.GetCode() << 16) |
   26938                      rm.GetCode());
   26939           AdvanceIT();
   26940           return;
   26941         }
   26942       }
   26943     } else {
   26944       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   26945       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
   26946           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26947            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26948           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26949         if (cond.Is(al)) {
   26950           const DRegister& first = nreglist.GetFirstDRegister();
   26951           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
   26952           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
   26953                   (encoded_align_1.GetEncodingValue() << 4) |
   26954                   first.Encode(22, 12) | (len_encoding << 8) |
   26955                   (rn.GetCode() << 16) | rm.GetCode());
   26956           return;
   26957         }
   26958       }
   26959       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
   26960       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
   26961           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
   26962            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
   26963           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
   26964         if (cond.Is(al)) {
   26965           const DRegister& first = nreglist.GetFirstDRegister();
   26966           EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
   26967                   (encoded_align_2.GetEncodingValue() << 4) |
   26968                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
   26969           return;
   26970         }
   26971       }
   26972     }
   26973   }
   26974   Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
   26975 }
   26976 
   26977 void Assembler::vstm(Condition cond,
   26978                      DataType dt,
   26979                      Register rn,
   26980                      WriteBack write_back,
   26981                      DRegisterList dreglist) {
   26982   VIXL_ASSERT(AllowAssembler());
   26983   CheckIT(cond);
   26984   USE(dt);
   26985   if (IsUsingT32()) {
   26986     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
   26987     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
   26988          AllowUnpredictable())) {
   26989       const DRegister& dreg = dreglist.GetFirstDRegister();
   26990       unsigned len = dreglist.GetLength() * 2;
   26991       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
   26992                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   26993                  (len & 0xff));
   26994       AdvanceIT();
   26995       return;
   26996     }
   26997   } else {
   26998     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
   26999     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   27000                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
   27001                               AllowUnpredictable())) {
   27002       const DRegister& dreg = dreglist.GetFirstDRegister();
   27003       unsigned len = dreglist.GetLength() * 2;
   27004       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   27005               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   27006               (len & 0xff));
   27007       return;
   27008     }
   27009   }
   27010   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
   27011 }
   27012 
   27013 void Assembler::vstm(Condition cond,
   27014                      DataType dt,
   27015                      Register rn,
   27016                      WriteBack write_back,
   27017                      SRegisterList sreglist) {
   27018   VIXL_ASSERT(AllowAssembler());
   27019   CheckIT(cond);
   27020   USE(dt);
   27021   if (IsUsingT32()) {
   27022     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
   27023     if ((!rn.IsPC() || AllowUnpredictable())) {
   27024       const SRegister& sreg = sreglist.GetFirstSRegister();
   27025       unsigned len = sreglist.GetLength();
   27026       EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
   27027                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   27028                  (len & 0xff));
   27029       AdvanceIT();
   27030       return;
   27031     }
   27032   } else {
   27033     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
   27034     if (cond.IsNotNever() &&
   27035         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
   27036       const SRegister& sreg = sreglist.GetFirstSRegister();
   27037       unsigned len = sreglist.GetLength();
   27038       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   27039               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   27040               (len & 0xff));
   27041       return;
   27042     }
   27043   }
   27044   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
   27045 }
   27046 
   27047 void Assembler::vstmdb(Condition cond,
   27048                        DataType dt,
   27049                        Register rn,
   27050                        WriteBack write_back,
   27051                        DRegisterList dreglist) {
   27052   VIXL_ASSERT(AllowAssembler());
   27053   CheckIT(cond);
   27054   USE(dt);
   27055   if (IsUsingT32()) {
   27056     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
   27057     if (write_back.DoesWriteBack() &&
   27058         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
   27059          AllowUnpredictable())) {
   27060       const DRegister& dreg = dreglist.GetFirstDRegister();
   27061       unsigned len = dreglist.GetLength() * 2;
   27062       EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
   27063                  (len & 0xff));
   27064       AdvanceIT();
   27065       return;
   27066     }
   27067   } else {
   27068     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
   27069     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   27070         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
   27071          AllowUnpredictable())) {
   27072       const DRegister& dreg = dreglist.GetFirstDRegister();
   27073       unsigned len = dreglist.GetLength() * 2;
   27074       EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   27075               dreg.Encode(22, 12) | (len & 0xff));
   27076       return;
   27077     }
   27078   }
   27079   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
   27080 }
   27081 
   27082 void Assembler::vstmdb(Condition cond,
   27083                        DataType dt,
   27084                        Register rn,
   27085                        WriteBack write_back,
   27086                        SRegisterList sreglist) {
   27087   VIXL_ASSERT(AllowAssembler());
   27088   CheckIT(cond);
   27089   USE(dt);
   27090   if (IsUsingT32()) {
   27091     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
   27092     if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) {
   27093       const SRegister& sreg = sreglist.GetFirstSRegister();
   27094       unsigned len = sreglist.GetLength();
   27095       EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
   27096                  (len & 0xff));
   27097       AdvanceIT();
   27098       return;
   27099     }
   27100   } else {
   27101     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
   27102     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
   27103         (!rn.IsPC() || AllowUnpredictable())) {
   27104       const SRegister& sreg = sreglist.GetFirstSRegister();
   27105       unsigned len = sreglist.GetLength();
   27106       EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   27107               sreg.Encode(22, 12) | (len & 0xff));
   27108       return;
   27109     }
   27110   }
   27111   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
   27112 }
   27113 
   27114 void Assembler::vstmia(Condition cond,
   27115                        DataType dt,
   27116                        Register rn,
   27117                        WriteBack write_back,
   27118                        DRegisterList dreglist) {
   27119   VIXL_ASSERT(AllowAssembler());
   27120   CheckIT(cond);
   27121   USE(dt);
   27122   if (IsUsingT32()) {
   27123     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
   27124     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
   27125          AllowUnpredictable())) {
   27126       const DRegister& dreg = dreglist.GetFirstDRegister();
   27127       unsigned len = dreglist.GetLength() * 2;
   27128       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
   27129                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   27130                  (len & 0xff));
   27131       AdvanceIT();
   27132       return;
   27133     }
   27134   } else {
   27135     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
   27136     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
   27137                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
   27138                               AllowUnpredictable())) {
   27139       const DRegister& dreg = dreglist.GetFirstDRegister();
   27140       unsigned len = dreglist.GetLength() * 2;
   27141       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   27142               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
   27143               (len & 0xff));
   27144       return;
   27145     }
   27146   }
   27147   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
   27148 }
   27149 
   27150 void Assembler::vstmia(Condition cond,
   27151                        DataType dt,
   27152                        Register rn,
   27153                        WriteBack write_back,
   27154                        SRegisterList sreglist) {
   27155   VIXL_ASSERT(AllowAssembler());
   27156   CheckIT(cond);
   27157   USE(dt);
   27158   if (IsUsingT32()) {
   27159     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
   27160     if ((!rn.IsPC() || AllowUnpredictable())) {
   27161       const SRegister& sreg = sreglist.GetFirstSRegister();
   27162       unsigned len = sreglist.GetLength();
   27163       EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
   27164                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   27165                  (len & 0xff));
   27166       AdvanceIT();
   27167       return;
   27168     }
   27169   } else {
   27170     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
   27171     if (cond.IsNotNever() &&
   27172         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
   27173       const SRegister& sreg = sreglist.GetFirstSRegister();
   27174       unsigned len = sreglist.GetLength();
   27175       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
   27176               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
   27177               (len & 0xff));
   27178       return;
   27179     }
   27180   }
   27181   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
   27182 }
   27183 
   27184 void Assembler::vstr(Condition cond,
   27185                      DataType dt,
   27186                      DRegister rd,
   27187                      const MemOperand& operand) {
   27188   VIXL_ASSERT(AllowAssembler());
   27189   CheckIT(cond);
   27190   if (operand.IsImmediate()) {
   27191     Register rn = operand.GetBaseRegister();
   27192     int32_t offset = operand.GetOffsetImmediate();
   27193     if (IsUsingT32()) {
   27194       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
   27195       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   27196           ((offset % 4) == 0) && operand.IsOffset() &&
   27197           (!rn.IsPC() || AllowUnpredictable())) {
   27198         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   27199         uint32_t offset_ = abs(offset) >> 2;
   27200         EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
   27201                    offset_ | (sign << 23));
   27202         AdvanceIT();
   27203         return;
   27204       }
   27205     } else {
   27206       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
   27207       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
   27208           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
   27209         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   27210         uint32_t offset_ = abs(offset) >> 2;
   27211         EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   27212                 (rn.GetCode() << 16) | offset_ | (sign << 23));
   27213         return;
   27214       }
   27215     }
   27216   }
   27217   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
   27218 }
   27219 
   27220 void Assembler::vstr(Condition cond,
   27221                      DataType dt,
   27222                      SRegister rd,
   27223                      const MemOperand& operand) {
   27224   VIXL_ASSERT(AllowAssembler());
   27225   CheckIT(cond);
   27226   if (operand.IsImmediate()) {
   27227     Register rn = operand.GetBaseRegister();
   27228     int32_t offset = operand.GetOffsetImmediate();
   27229     if (IsUsingT32()) {
   27230       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
   27231       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   27232           ((offset % 4) == 0) && operand.IsOffset() &&
   27233           (!rn.IsPC() || AllowUnpredictable())) {
   27234         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   27235         uint32_t offset_ = abs(offset) >> 2;
   27236         EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
   27237                    offset_ | (sign << 23));
   27238         AdvanceIT();
   27239         return;
   27240       }
   27241     } else {
   27242       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
   27243       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
   27244           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
   27245         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
   27246         uint32_t offset_ = abs(offset) >> 2;
   27247         EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   27248                 (rn.GetCode() << 16) | offset_ | (sign << 23));
   27249         return;
   27250       }
   27251     }
   27252   }
   27253   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
   27254 }
   27255 
   27256 void Assembler::vsub(
   27257     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   27258   VIXL_ASSERT(AllowAssembler());
   27259   CheckIT(cond);
   27260   Dt_size_2 encoded_dt(dt);
   27261   if (IsUsingT32()) {
   27262     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
   27263     if (dt.Is(F32)) {
   27264       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27265         EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   27266                    rm.Encode(5, 0));
   27267         AdvanceIT();
   27268         return;
   27269       }
   27270     }
   27271     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
   27272     if (dt.Is(F64)) {
   27273       EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   27274                  rm.Encode(5, 0));
   27275       AdvanceIT();
   27276       return;
   27277     }
   27278     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   27279     if (encoded_dt.IsValid()) {
   27280       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27281         EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
   27282                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27283         AdvanceIT();
   27284         return;
   27285       }
   27286     }
   27287   } else {
   27288     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
   27289     if (dt.Is(F32)) {
   27290       if (cond.Is(al)) {
   27291         EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   27292                 rm.Encode(5, 0));
   27293         return;
   27294       }
   27295     }
   27296     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
   27297     if (dt.Is(F64) && cond.IsNotNever()) {
   27298       EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   27299               rn.Encode(7, 16) | rm.Encode(5, 0));
   27300       return;
   27301     }
   27302     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   27303     if (encoded_dt.IsValid()) {
   27304       if (cond.Is(al)) {
   27305         EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
   27306                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27307         return;
   27308       }
   27309     }
   27310   }
   27311   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
   27312 }
   27313 
   27314 void Assembler::vsub(
   27315     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   27316   VIXL_ASSERT(AllowAssembler());
   27317   CheckIT(cond);
   27318   Dt_size_2 encoded_dt(dt);
   27319   if (IsUsingT32()) {
   27320     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
   27321     if (dt.Is(F32)) {
   27322       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27323         EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   27324                    rm.Encode(5, 0));
   27325         AdvanceIT();
   27326         return;
   27327       }
   27328     }
   27329     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   27330     if (encoded_dt.IsValid()) {
   27331       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27332         EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
   27333                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27334         AdvanceIT();
   27335         return;
   27336       }
   27337     }
   27338   } else {
   27339     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
   27340     if (dt.Is(F32)) {
   27341       if (cond.Is(al)) {
   27342         EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   27343                 rm.Encode(5, 0));
   27344         return;
   27345       }
   27346     }
   27347     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   27348     if (encoded_dt.IsValid()) {
   27349       if (cond.Is(al)) {
   27350         EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
   27351                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27352         return;
   27353       }
   27354     }
   27355   }
   27356   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
   27357 }
   27358 
   27359 void Assembler::vsub(
   27360     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
   27361   VIXL_ASSERT(AllowAssembler());
   27362   CheckIT(cond);
   27363   if (IsUsingT32()) {
   27364     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
   27365     if (dt.Is(F32)) {
   27366       EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
   27367                  rm.Encode(5, 0));
   27368       AdvanceIT();
   27369       return;
   27370     }
   27371   } else {
   27372     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
   27373     if (dt.Is(F32) && cond.IsNotNever()) {
   27374       EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
   27375               rn.Encode(7, 16) | rm.Encode(5, 0));
   27376       return;
   27377     }
   27378   }
   27379   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
   27380 }
   27381 
   27382 void Assembler::vsubhn(
   27383     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
   27384   VIXL_ASSERT(AllowAssembler());
   27385   CheckIT(cond);
   27386   Dt_size_3 encoded_dt(dt);
   27387   if (IsUsingT32()) {
   27388     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
   27389     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   27390       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27391         EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
   27392                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27393         AdvanceIT();
   27394         return;
   27395       }
   27396     }
   27397   } else {
   27398     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
   27399     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
   27400       if (cond.Is(al)) {
   27401         EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
   27402                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27403         return;
   27404       }
   27405     }
   27406   }
   27407   Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
   27408 }
   27409 
   27410 void Assembler::vsubl(
   27411     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
   27412   VIXL_ASSERT(AllowAssembler());
   27413   CheckIT(cond);
   27414   Dt_U_size_1 encoded_dt(dt);
   27415   if (IsUsingT32()) {
   27416     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
   27417     if (encoded_dt.IsValid()) {
   27418       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27419         EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   27420                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   27421                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27422         AdvanceIT();
   27423         return;
   27424       }
   27425     }
   27426   } else {
   27427     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
   27428     if (encoded_dt.IsValid()) {
   27429       if (cond.Is(al)) {
   27430         EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   27431                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   27432                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27433         return;
   27434       }
   27435     }
   27436   }
   27437   Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
   27438 }
   27439 
   27440 void Assembler::vsubw(
   27441     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
   27442   VIXL_ASSERT(AllowAssembler());
   27443   CheckIT(cond);
   27444   Dt_U_size_1 encoded_dt(dt);
   27445   if (IsUsingT32()) {
   27446     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
   27447     if (encoded_dt.IsValid()) {
   27448       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27449         EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   27450                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
   27451                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27452         AdvanceIT();
   27453         return;
   27454       }
   27455     }
   27456   } else {
   27457     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
   27458     if (encoded_dt.IsValid()) {
   27459       if (cond.Is(al)) {
   27460         EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
   27461                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
   27462                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27463         return;
   27464       }
   27465     }
   27466   }
   27467   Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
   27468 }
   27469 
   27470 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   27471   VIXL_ASSERT(AllowAssembler());
   27472   CheckIT(cond);
   27473   USE(dt);
   27474   if (IsUsingT32()) {
   27475     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
   27476     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27477       EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
   27478       AdvanceIT();
   27479       return;
   27480     }
   27481   } else {
   27482     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
   27483     if (cond.Is(al)) {
   27484       EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
   27485       return;
   27486     }
   27487   }
   27488   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
   27489 }
   27490 
   27491 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   27492   VIXL_ASSERT(AllowAssembler());
   27493   CheckIT(cond);
   27494   USE(dt);
   27495   if (IsUsingT32()) {
   27496     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
   27497     if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27498       EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
   27499       AdvanceIT();
   27500       return;
   27501     }
   27502   } else {
   27503     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
   27504     if (cond.Is(al)) {
   27505       EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
   27506       return;
   27507     }
   27508   }
   27509   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
   27510 }
   27511 
   27512 void Assembler::vtbl(Condition cond,
   27513                      DataType dt,
   27514                      DRegister rd,
   27515                      const NeonRegisterList& nreglist,
   27516                      DRegister rm) {
   27517   VIXL_ASSERT(AllowAssembler());
   27518   CheckIT(cond);
   27519   if (IsUsingT32()) {
   27520     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
   27521     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
   27522         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
   27523       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27524         const DRegister& first = nreglist.GetFirstDRegister();
   27525         uint32_t len_encoding = nreglist.GetLength() - 1;
   27526         EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
   27527                    (len_encoding << 8) | rm.Encode(5, 0));
   27528         AdvanceIT();
   27529         return;
   27530       }
   27531     }
   27532   } else {
   27533     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
   27534     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
   27535         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
   27536       if (cond.Is(al)) {
   27537         const DRegister& first = nreglist.GetFirstDRegister();
   27538         uint32_t len_encoding = nreglist.GetLength() - 1;
   27539         EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
   27540                 (len_encoding << 8) | rm.Encode(5, 0));
   27541         return;
   27542       }
   27543     }
   27544   }
   27545   Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
   27546 }
   27547 
   27548 void Assembler::vtbx(Condition cond,
   27549                      DataType dt,
   27550                      DRegister rd,
   27551                      const NeonRegisterList& nreglist,
   27552                      DRegister rm) {
   27553   VIXL_ASSERT(AllowAssembler());
   27554   CheckIT(cond);
   27555   if (IsUsingT32()) {
   27556     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
   27557     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
   27558         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
   27559       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27560         const DRegister& first = nreglist.GetFirstDRegister();
   27561         uint32_t len_encoding = nreglist.GetLength() - 1;
   27562         EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
   27563                    (len_encoding << 8) | rm.Encode(5, 0));
   27564         AdvanceIT();
   27565         return;
   27566       }
   27567     }
   27568   } else {
   27569     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
   27570     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
   27571         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
   27572       if (cond.Is(al)) {
   27573         const DRegister& first = nreglist.GetFirstDRegister();
   27574         uint32_t len_encoding = nreglist.GetLength() - 1;
   27575         EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
   27576                 (len_encoding << 8) | rm.Encode(5, 0));
   27577         return;
   27578       }
   27579     }
   27580   }
   27581   Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
   27582 }
   27583 
   27584 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   27585   VIXL_ASSERT(AllowAssembler());
   27586   CheckIT(cond);
   27587   Dt_size_7 encoded_dt(dt);
   27588   if (IsUsingT32()) {
   27589     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   27590     if (encoded_dt.IsValid()) {
   27591       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27592         EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
   27593                    rd.Encode(22, 12) | rm.Encode(5, 0));
   27594         AdvanceIT();
   27595         return;
   27596       }
   27597     }
   27598   } else {
   27599     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   27600     if (encoded_dt.IsValid()) {
   27601       if (cond.Is(al)) {
   27602         EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
   27603                 rd.Encode(22, 12) | rm.Encode(5, 0));
   27604         return;
   27605       }
   27606     }
   27607   }
   27608   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
   27609 }
   27610 
   27611 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   27612   VIXL_ASSERT(AllowAssembler());
   27613   CheckIT(cond);
   27614   Dt_size_7 encoded_dt(dt);
   27615   if (IsUsingT32()) {
   27616     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   27617     if (encoded_dt.IsValid()) {
   27618       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27619         EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
   27620                    rd.Encode(22, 12) | rm.Encode(5, 0));
   27621         AdvanceIT();
   27622         return;
   27623       }
   27624     }
   27625   } else {
   27626     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   27627     if (encoded_dt.IsValid()) {
   27628       if (cond.Is(al)) {
   27629         EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
   27630                 rd.Encode(22, 12) | rm.Encode(5, 0));
   27631         return;
   27632       }
   27633     }
   27634   }
   27635   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
   27636 }
   27637 
   27638 void Assembler::vtst(
   27639     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
   27640   VIXL_ASSERT(AllowAssembler());
   27641   CheckIT(cond);
   27642   Dt_size_7 encoded_dt(dt);
   27643   if (IsUsingT32()) {
   27644     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
   27645     if (encoded_dt.IsValid()) {
   27646       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27647         EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
   27648                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27649         AdvanceIT();
   27650         return;
   27651       }
   27652     }
   27653   } else {
   27654     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
   27655     if (encoded_dt.IsValid()) {
   27656       if (cond.Is(al)) {
   27657         EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
   27658                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27659         return;
   27660       }
   27661     }
   27662   }
   27663   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
   27664 }
   27665 
   27666 void Assembler::vtst(
   27667     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
   27668   VIXL_ASSERT(AllowAssembler());
   27669   CheckIT(cond);
   27670   Dt_size_7 encoded_dt(dt);
   27671   if (IsUsingT32()) {
   27672     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
   27673     if (encoded_dt.IsValid()) {
   27674       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27675         EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
   27676                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27677         AdvanceIT();
   27678         return;
   27679       }
   27680     }
   27681   } else {
   27682     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
   27683     if (encoded_dt.IsValid()) {
   27684       if (cond.Is(al)) {
   27685         EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
   27686                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
   27687         return;
   27688       }
   27689     }
   27690   }
   27691   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
   27692 }
   27693 
   27694 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   27695   VIXL_ASSERT(AllowAssembler());
   27696   CheckIT(cond);
   27697   Dt_size_15 encoded_dt(dt);
   27698   if (IsUsingT32()) {
   27699     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   27700     if (encoded_dt.IsValid()) {
   27701       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27702         EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
   27703                    rd.Encode(22, 12) | rm.Encode(5, 0));
   27704         AdvanceIT();
   27705         return;
   27706       }
   27707     }
   27708     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
   27709     if (dt.Is(Untyped32)) {
   27710       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27711         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
   27712         AdvanceIT();
   27713         return;
   27714       }
   27715     }
   27716   } else {
   27717     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   27718     if (encoded_dt.IsValid()) {
   27719       if (cond.Is(al)) {
   27720         EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
   27721                 rd.Encode(22, 12) | rm.Encode(5, 0));
   27722         return;
   27723       }
   27724     }
   27725     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
   27726     if (dt.Is(Untyped32)) {
   27727       if (cond.Is(al)) {
   27728         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
   27729         return;
   27730       }
   27731     }
   27732   }
   27733   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
   27734 }
   27735 
   27736 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   27737   VIXL_ASSERT(AllowAssembler());
   27738   CheckIT(cond);
   27739   Dt_size_7 encoded_dt(dt);
   27740   if (IsUsingT32()) {
   27741     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   27742     if (encoded_dt.IsValid()) {
   27743       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27744         EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
   27745                    rd.Encode(22, 12) | rm.Encode(5, 0));
   27746         AdvanceIT();
   27747         return;
   27748       }
   27749     }
   27750   } else {
   27751     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   27752     if (encoded_dt.IsValid()) {
   27753       if (cond.Is(al)) {
   27754         EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
   27755                 rd.Encode(22, 12) | rm.Encode(5, 0));
   27756         return;
   27757       }
   27758     }
   27759   }
   27760   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
   27761 }
   27762 
   27763 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
   27764   VIXL_ASSERT(AllowAssembler());
   27765   CheckIT(cond);
   27766   Dt_size_15 encoded_dt(dt);
   27767   if (IsUsingT32()) {
   27768     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
   27769     if (encoded_dt.IsValid()) {
   27770       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27771         EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
   27772                    rd.Encode(22, 12) | rm.Encode(5, 0));
   27773         AdvanceIT();
   27774         return;
   27775       }
   27776     }
   27777     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
   27778     if (dt.Is(Untyped32)) {
   27779       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27780         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
   27781         AdvanceIT();
   27782         return;
   27783       }
   27784     }
   27785   } else {
   27786     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
   27787     if (encoded_dt.IsValid()) {
   27788       if (cond.Is(al)) {
   27789         EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
   27790                 rd.Encode(22, 12) | rm.Encode(5, 0));
   27791         return;
   27792       }
   27793     }
   27794     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
   27795     if (dt.Is(Untyped32)) {
   27796       if (cond.Is(al)) {
   27797         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
   27798         return;
   27799       }
   27800     }
   27801   }
   27802   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
   27803 }
   27804 
   27805 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
   27806   VIXL_ASSERT(AllowAssembler());
   27807   CheckIT(cond);
   27808   Dt_size_7 encoded_dt(dt);
   27809   if (IsUsingT32()) {
   27810     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
   27811     if (encoded_dt.IsValid()) {
   27812       if (cond.Is(al) || AllowStronglyDiscouraged()) {
   27813         EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
   27814                    rd.Encode(22, 12) | rm.Encode(5, 0));
   27815         AdvanceIT();
   27816         return;
   27817       }
   27818     }
   27819   } else {
   27820     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
   27821     if (encoded_dt.IsValid()) {
   27822       if (cond.Is(al)) {
   27823         EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
   27824                 rd.Encode(22, 12) | rm.Encode(5, 0));
   27825         return;
   27826       }
   27827     }
   27828   }
   27829   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
   27830 }
   27831 
   27832 void Assembler::yield(Condition cond, EncodingSize size) {
   27833   VIXL_ASSERT(AllowAssembler());
   27834   CheckIT(cond);
   27835   if (IsUsingT32()) {
   27836     // YIELD{<c>}{<q>} ; T1
   27837     if (!size.IsWide()) {
   27838       EmitT32_16(0xbf10);
   27839       AdvanceIT();
   27840       return;
   27841     }
   27842     // YIELD{<c>}.W ; T2
   27843     if (!size.IsNarrow()) {
   27844       EmitT32_32(0xf3af8001U);
   27845       AdvanceIT();
   27846       return;
   27847     }
   27848   } else {
   27849     // YIELD{<c>}{<q>} ; A1
   27850     if (cond.IsNotNever()) {
   27851       EmitA32(0x0320f001U | (cond.GetCondition() << 28));
   27852       return;
   27853     }
   27854   }
   27855   Delegate(kYield, &Assembler::yield, cond, size);
   27856 }
   27857 // End of generated code.
   27858 
   27859 }  // namespace aarch32
   27860 }  // namespace vixl
   27861